class Toxiproxy

Constants

DEFAULT_URI
VALID_DIRECTIONS
VERSION

Attributes

enabled[R]
listen[R]
name[R]

Public Class Methods

[](query) click to toggle source

If given a regex, it'll use `grep` to return a Toxiproxy::Collection. Otherwise, it'll convert the passed object to a string and find the proxy by name.

# File lib/toxiproxy.rb, line 93
def self.[](query)
  return grep(query) if query.is_a?(Regexp)
  find_by_name!(query)
end
all() click to toggle source

Returns a collection of all currently active Toxiproxies.

# File lib/toxiproxy.rb, line 51
def self.all
  request = Net::HTTP::Get.new("/proxies")
  response = http_request(request)
  assert_response(response)

  proxies = JSON.parse(response.body).map { |name, attrs|
    self.new({
      upstream: attrs["upstream"],
      listen: attrs["listen"],
      name: attrs["name"],
      enabled: attrs["enabled"]
    })
  }

  ProxyCollection.new(proxies)
end
create(options) click to toggle source

Convenience method to create a proxy.

# File lib/toxiproxy.rb, line 74
def self.create(options)
  self.new(options).create
end
find_by_name(name = nil, &block) click to toggle source

Find a single proxy by name.

# File lib/toxiproxy.rb, line 79
def self.find_by_name(name = nil, &block)
  self.all.find { |p| p.name == name.to_s }
end
find_by_name!(*args) click to toggle source

Calls find_by_name and raises NotFound if not found

# File lib/toxiproxy.rb, line 84
def self.find_by_name!(*args)
  proxy = find_by_name(*args)
  raise NotFound, "#{name} not found in #{self.all.map(&:name).join(', ')}" unless proxy
  proxy
end
host=(host) click to toggle source

Sets the toxiproxy host to use.

# File lib/toxiproxy.rb, line 69
def self.host=(host)
  @uri = host.is_a?(::URI) ? host : ::URI.parse(host)
end
new(options) click to toggle source
# File lib/toxiproxy.rb, line 22
def initialize(options)
  @upstream = options[:upstream]
  @listen   = options[:listen] || "localhost:0"
  @name     = options[:name]
  @enabled  = options[:enabled]
end
populate(*proxies) click to toggle source
# File lib/toxiproxy.rb, line 98
def self.populate(*proxies)
  proxies = proxies.first if proxies.first.is_a?(Array)

  request = Net::HTTP::Post.new("/populate")
  request.body = proxies.to_json
  request["Content-Type"] = "application/json"

  response = http_request(request)
  assert_response(response)

  proxies = JSON.parse(response.body).fetch('proxies', []).map do |attrs|
    self.new({
      upstream: attrs["upstream"],
      listen: attrs["listen"],
      name: attrs["name"],
      enabled: attrs["enabled"]
    })
  end

  ProxyCollection.new(proxies)
end
reset() click to toggle source

Re-enables all proxies and disables all toxics.

# File lib/toxiproxy.rb, line 32
def self.reset
  request = Net::HTTP::Post.new("/reset")
  request["Content-Type"] = "application/json"

  response = http_request(request)
  assert_response(response)
  self
end
running?() click to toggle source
# File lib/toxiproxy.rb, line 120
def self.running?
  TCPSocket.new(uri.host, uri.port).close
  true
rescue Errno::ECONNREFUSED, Errno::ECONNRESET
  false
end
version() click to toggle source
# File lib/toxiproxy.rb, line 41
def self.version
  return false unless running?

  request = Net::HTTP::Get.new("/version")
  response = http_request(request)
  assert_response(response)
  response.body
end

Private Class Methods

assert_response(response) click to toggle source
# File lib/toxiproxy.rb, line 257
def self.assert_response(response)
  case response
  when Net::HTTPConflict
    raise Toxiproxy::ProxyExists, response.body
  when Net::HTTPNotFound
    raise Toxiproxy::NotFound, response.body
  when Net::HTTPBadRequest
    raise Toxiproxy::InvalidToxic, response.body
  else
    response.value # raises if not OK
  end
end
ensure_webmock_whitelists_toxiproxy() click to toggle source
# File lib/toxiproxy.rb, line 237
def self.ensure_webmock_whitelists_toxiproxy
  endpoint = "#{uri.host}:#{uri.port}"
  WebMock::Config.instance.allow ||= []
  unless WebMock::Config.instance.allow.include?(endpoint)
    WebMock::Config.instance.allow << endpoint
  end
end
http() click to toggle source
# File lib/toxiproxy.rb, line 249
def self.http
  @http ||= Net::HTTP.new(uri.host, uri.port)
end
http_request(request) click to toggle source
# File lib/toxiproxy.rb, line 228
def self.http_request(request)
  ensure_webmock_whitelists_toxiproxy if defined? WebMock
  http.request(request)
end
uri() click to toggle source
# File lib/toxiproxy.rb, line 245
def self.uri
  @uri ||= ::URI.parse(DEFAULT_URI)
end

Public Instance Methods

create() click to toggle source

Create a Toxiproxy, proxying traffic from `@listen` (optional argument to the constructor) to `@upstream`. `#down` `#upstream` or `#downstream` can at any time alter the health of this connection.

# File lib/toxiproxy.rb, line 184
def create
  request = Net::HTTP::Post.new("/proxies")
  request["Content-Type"] = "application/json"

  hash = {upstream: upstream, name: name, listen: listen, enabled: enabled}
  request.body = hash.to_json

  response = http_request(request)
  assert_response(response)

  new = JSON.parse(response.body)
  @listen = new["listen"]

  self
end
destroy() click to toggle source

Destroys a Toxiproxy.

# File lib/toxiproxy.rb, line 201
def destroy
  request = Net::HTTP::Delete.new("/proxies/#{name}")
  response = http_request(request)
  assert_response(response)
  self
end
disable() click to toggle source

Disables a Toxiproxy. This will drop all active connections and stop the proxy from listening.

# File lib/toxiproxy.rb, line 156
def disable
  request = Net::HTTP::Post.new("/proxies/#{name}")
  request["Content-Type"] = "application/json"

  hash = {enabled: false}
  request.body = hash.to_json

  response = http_request(request)
  assert_response(response)
  self
end
down() { || ... } click to toggle source

Simulates the endpoint is down, by closing the connection and no longer accepting connections. This is useful to simulate critical system failure, such as a data store becoming completely unavailable.

# File lib/toxiproxy.rb, line 148
def down(&block)
  disable
  yield
ensure
  enable
end
downstream(type, attrs = {}) click to toggle source

Set a downstream toxic.

# File lib/toxiproxy.rb, line 137
def downstream(type, attrs = {})
  collection = ToxicCollection.new([self])
  collection.downstream(type, attrs)
  collection
end
Also aliased as: toxic, toxicate
enable() click to toggle source

Enables a Toxiproxy. This will cause the proxy to start listening again.

# File lib/toxiproxy.rb, line 169
def enable
  request = Net::HTTP::Post.new("/proxies/#{name}")
  request["Content-Type"] = "application/json"

  hash = {enabled: true}
  request.body = hash.to_json

  response = http_request(request)
  assert_response(response)
  self
end
toxic(type, attrs = {})
Alias for: downstream
toxicate(type, attrs = {})
Alias for: downstream
toxics() click to toggle source

Returns an array of the current toxics for a direction.

# File lib/toxiproxy.rb, line 209
def toxics
  request = Net::HTTP::Get.new("/proxies/#{name}/toxics")
  response = http_request(request)
  assert_response(response)

  JSON.parse(response.body).map { |attrs|
    Toxic.new(
      type: attrs['type'],
      name: attrs['name'],
      proxy: self,
      stream: attrs['stream'],
      toxicity: attrs['toxicity'],
      attributes: attrs['attributes'],
    )
  }
end
upstream(type = nil, attrs = {}) click to toggle source

Set an upstream toxic.

# File lib/toxiproxy.rb, line 128
def upstream(type = nil, attrs = {})
  return @upstream unless type # also alias for the upstream endpoint

  collection = ToxicCollection.new([self])
  collection.upstream(type, attrs)
  collection
end

Private Instance Methods

assert_response(*args) click to toggle source
# File lib/toxiproxy.rb, line 270
def assert_response(*args)
  self.class.assert_response(*args)
end
http() click to toggle source
# File lib/toxiproxy.rb, line 253
def http
  self.class.http
end
http_request(request) click to toggle source
# File lib/toxiproxy.rb, line 233
def http_request(request)
  self.class.http_request(request)
end