toxiproxy

package
v2.1.4+incompatible Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 10, 2019 License: MIT Imports: 8 Imported by: 63

README

toxiproxy-go

This is the Go client library for the Toxiproxy API. Please read the usage section in the Toxiproxy README before attempting to use the client.

This client is compatible with Toxiproxy 2.x, for the latest 1.x client see v1.2.1.

Changes in Toxiproxy-go Client 2.x

In order to make use of the 2.0 api, and to make usage a little easier, the client api has changed:

  • client.NewProxy() no longer accepts a proxy as an argument.
  • proxy.Create() is removed in favour of using proxy.Save().
  • Proxies can be created in a single call using client.CreateProxy().
  • proxy.Disable() and proxy.Enable() have been added to simplify taking down a proxy.
  • proxy.ToxicsUpstream and proxy.ToxicsDownstream have been merged into a single ActiveToxics list.
  • `proxy.Toxics()`` no longer requires a direction to be specified, and will return toxics for both directions.
  • proxy.SetToxic() has been replaced by proxy.AddToxic(), proxy.UpdateToxic(), and proxy.RemoveToxic().

Usage

For detailed API docs please see the Godoc documentation.

First import toxiproxy and create a new client:

import "github.com/Shopify/toxiproxy/client"

client := toxiproxy.NewClient("localhost:8474")

You can then create a new proxy using the client:

proxy := client.CreateProxy("redis", "localhost:26379", "localhost:6379")

For large amounts of proxies, they can also be created using a configuration file:

var config []toxiproxy.Proxy
data, _ := ioutil.ReadFile("config.json")
json.Unmarshal(data, &config)
proxies, err = client.Populate(config)
[{
  "name": "redis",
  "listen": "localhost:26379",
  "upstream": "localhost:6379"
}]

Toxics can be added as follows:

// Add 1s latency to 100% of downstream connections
proxy.AddToxic("latency_down", "latency", "downstream", 1.0, toxiproxy.Attributes{
    "latency": 1000,
})

// Change downstream latency to add 100ms of jitter
proxy.UpdateToxic("latency_down", 1.0, toxiproxy.Attributes{
    "jitter": 100,
})

// Remove the latency toxic
proxy.RemoveToxic("latency_down")

The proxy can be taken down using Disable():

proxy.Disable()

When a proxy is no longer needed, it can be cleaned up with Delete():

proxy.Delete()

Full Example

import (
    "net/http"
    "testing"
    "time"

    "github.com/Shopify/toxiproxy/client"
    "github.com/garyburd/redigo/redis"
)

var toxiClient *toxiproxy.Client
var proxies map[string]*toxiproxy.Proxy

func init() {
    var err error
    toxiClient = toxiproxy.NewClient("localhost:8474")
    proxies, err = toxiClient.Populate([]toxiproxy.Proxy{{
        Name:     "redis",
        Listen:   "localhost:26379",
        Upstream: "localhost:6379",
    }})
    if err != nil {
        panic(err)
    }
    // Alternatively, create the proxies manually with
    // toxiClient.CreateProxy("redis", "localhost:26379", "localhost:6379")
}

func TestRedisBackendDown(t *testing.T) {
    proxies["redis"].Disable()
    defer proxies["redis"].Enable()

    // Test that redis is down
    _, err := redis.Dial("tcp", ":26379")
    if err == nil {
        t.Fatal("Connection to redis did not fail")
    }
}

func TestRedisBackendSlow(t *testing.T) {
    proxies["redis"].AddToxic("", "latency", "", 1, toxiproxy.Attributes{
        "latency": 1000,
    })
    defer proxies["redis"].RemoveToxic("latency_downstream")

    // Test that redis is slow
    start := time.Now()
    conn, err := redis.Dial("tcp", ":26379")
    if err != nil {
        t.Fatal("Connection to redis failed", err)
    }

    _, err = conn.Do("GET", "test")
    if err != nil {
        t.Fatal("Redis command failed", err)
    } else if time.Since(start) < 900*time.Millisecond {
        t.Fatal("Redis command did not take long enough:", time.Since(start))
    }
}

func TestEphemeralProxy(t *testing.T) {
    proxy, _ := toxiClient.CreateProxy("test", "", "google.com:80")
    defer proxy.Delete()

    // Test connection through proxy.Listen
    resp, err := http.Get("http://" + proxy.Listen)
    if err != nil {
        t.Fatal(err)
    } else if resp.StatusCode != 200 {
        t.Fatal("Proxy to google failed:", resp.StatusCode)
    }
}

Documentation

Overview

Package Toxiproxy provides a client wrapper around the Toxiproxy HTTP API for testing the resiliency of Go applications.

For use with Toxiproxy 2.x

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ApiError added in v1.2.0

type ApiError struct {
	Message string `json:"error"`
	Status  int    `json:"status"`
}

func (*ApiError) Error added in v1.2.0

func (err *ApiError) Error() string

type Attributes

type Attributes map[string]interface{}

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client holds information about where to connect to Toxiproxy.

func NewClient

func NewClient(endpoint string) *Client

NewClient creates a new client which provides the base of all communication with Toxiproxy. Endpoint is the address to the proxy (e.g. localhost:8474 if not overriden)

func (*Client) CreateProxy

func (client *Client) CreateProxy(name, listen, upstream string) (*Proxy, error)

CreateProxy instantiates a new proxy and starts listening on the specified address. This is an alias for `NewProxy()` + `proxy.Save()`

func (*Client) NewProxy

func (client *Client) NewProxy() *Proxy

Generates a new uncommitted proxy instance. In order to use the result, the proxy fields will need to be set and have `Save()` called.

func (*Client) Populate

func (client *Client) Populate(config []Proxy) ([]*Proxy, error)

Create a list of proxies using a configuration list. If a proxy already exists, it will be replaced with the specified configuration. For large amounts of proxies, `config` can be loaded from a file. Returns a list of the successfully created proxies.

func (*Client) Proxies

func (client *Client) Proxies() (map[string]*Proxy, error)

Proxies returns a map with all the proxies and their toxics.

func (*Client) Proxy

func (client *Client) Proxy(name string) (*Proxy, error)

Proxy returns a proxy by name.

func (*Client) ResetState

func (client *Client) ResetState() error

ResetState resets the state of all proxies and toxics in Toxiproxy.

type Proxy

type Proxy struct {
	Name     string `json:"name"`     // The name of the proxy
	Listen   string `json:"listen"`   // The address the proxy listens on
	Upstream string `json:"upstream"` // The upstream address to proxy to
	Enabled  bool   `json:"enabled"`  // Whether the proxy is enabled

	ActiveToxics Toxics `json:"toxics"` // The toxics active on this proxy
	// contains filtered or unexported fields
}

func (*Proxy) AddToxic

func (proxy *Proxy) AddToxic(name, typeName, stream string, toxicity float32, attrs Attributes) (*Toxic, error)

AddToxic adds a toxic to the given stream direction. If a name is not specified, it will default to <type>_<stream>. If a stream is not specified, it will default to downstream. See https://github.com/Shopify/toxiproxy#toxics for a list of all Toxic types.

func (*Proxy) Delete

func (proxy *Proxy) Delete() error

Delete a proxy complete and close all existing connections through it. All information about the proxy such as listen port and active toxics will be deleted as well. If you just wish to stop and later enable a proxy, use `Enable()` and `Disable()`.

func (*Proxy) Disable

func (proxy *Proxy) Disable() error

Disable a proxy so that no connections can pass through. This will drop all active connections.

func (*Proxy) Enable

func (proxy *Proxy) Enable() error

Enable a proxy again after it has been disabled.

func (*Proxy) RemoveToxic

func (proxy *Proxy) RemoveToxic(name string) error

RemoveToxic renives the toxic with the given name.

func (*Proxy) Save

func (proxy *Proxy) Save() error

Save saves changes to a proxy such as its enabled status or upstream port.

func (*Proxy) Toxics

func (proxy *Proxy) Toxics() (Toxics, error)

Toxics returns a map of all the active toxics and their attributes.

func (*Proxy) UpdateToxic

func (proxy *Proxy) UpdateToxic(name string, toxicity float32, attrs Attributes) (*Toxic, error)

UpdateToxic sets the parameters for an existing toxic with the given name. If toxicity is set to -1, the current value will be used.

type Toxic added in v1.2.0

type Toxic struct {
	Name       string     `json:"name"`
	Type       string     `json:"type"`
	Stream     string     `json:"stream,omitempty"`
	Toxicity   float32    `json:"toxicity"`
	Attributes Attributes `json:"attributes"`
}

type Toxics added in v1.2.0

type Toxics []Toxic

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL