Skip to content

roger2000hk/muxy

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Muxy

Proxy for simulating real-world distributed system failures to improve resilience in your applications.

wercker status

Introduction

Muxy is a proxy that mucks with your system and application context, operating at Layers 4 and 7, allowing you to simulate common failure scenarios from the perspective of an application under test; such as an API or a web application.

If you are building a distributed system, Muxy can help you test your resilience and fault tolerance patterns.

Contents

Features

  • Ability to tamper with network devices at the transport level (Layer 4)
  • ...and HTTP requests/responses at the HTTP protocol level (Layer 7)
  • Simulate real-world network connectivity problems/partitions for mobile devices, distributed systems etc.
  • Ideal for use in CI/Test Suites to test resilience across languages/technologies
  • Simple native binary installation with no dependencies
  • Extensible and modular architecture

Installation

Download a release for your platform and put it somewhere on the PATH.

On Mac OSX using Homebrew

If you are using Homebrew you can follow these steps to install Muck:

brew install https://raw.githubusercontent.com/mefellows/muxy/master/scripts/muxy.rb

Using Go Get

go get github.com/mefellows/muxy

Using Muxy

Muxy is typically used in two ways:

  1. In local development to see how your application responds under certain conditions
  2. In test suites to automate resilience testing

5-minute example

  1. Install Muxy

  2. Create configuration file config.yml:

    # Configures a proxy to forward/mess with your requests
    # to/from www.onegeek.com.au. This example adds a 5s delay
    # to the response.
    proxy:
      - name: http_proxy
        config:
          host: 0.0.0.0
          port: 8181
          proxy_host: onegeek.com.au
          proxy_port: 80
    
    # Proxy plugins
    middleware:
    
      # HTTP response delay plugin
      - name: http_delay
        config:
          delay: 5
    
      # Log in/out messages
      - name: logger
  3. Run Muxy with your config: muxy proxy --config ./config.yml

  4. Make a request to www.onegeek.com via the proxy: time curl -v -H"Host: www.onegeek.com.au" http://localhost:8181/. Compare that with a request direct to the website: time curl -v www.onegeek.com.au - it should be approximately 5s faster.

That's it - running Muxy is a matter of configuring one or more Proxies, with 1 or more Middleware components defined in a simple YAML file.

Muxy as part of a test suite

  1. Create an application
  2. Build in fault tolerence (e.g. using something like Hystrix)
  3. Create integration tests
  4. Run Muxy configuring a proxy such as HTTP, and one or more symptoms such as network latency, partition or HTTP error
  5. Point your app at Muxy
  6. Run tests and check if system behaved as expected
  7. Profit!

Notes

Muxy is a stateful system, and mucks with your low-level (system) networking interfaces and therefore cannot be run in parallel with other tests. It is also recommended to run within a container/virtual machine to avoid unintended consequences (like breaking Internet access from the host).

Proxies and Middlewares

Proxies

HTTP Proxy

Simple HTTP Proxy that starts up on a local IP/Hostname and Port.

Example configuration snippet:

proxy:
  - name: http_proxy
    config:
      host: 0.0.0.0
      protocol: http
      port: 8181
      proxy_host: 0.0.0.0
      proxy_port: 8282
      proxy_protocol: https

TCP Proxy

Simple TCP Proxy that starts up on a local IP/Hostname and Port, forwarding traffic to the specified proxy_host on proxy_port.

Example configuration snippet:

proxy:
  - name: tcp_proxy
    config:
      host: 0.0.0.0           # Local ip/hostname to bind to and accept connections.
      port: 8080              # Local port to bind to
      proxy_host: 0.0.0.0
      proxy_port: 2000
      nagles_algorithm: true
      packet_size: 64

Middleware

Middleware have the ability to intervene upon receiving a request (Pre-Dispatch) or before sending the response back to the client (Post-Dispatch). In some cases, such as the Network Shaper, the effect is applied before any request is made (e.g. if the local network device configuration is altered).

HTTP Delay

A basic middleware that simply adds a delay of delay seconds.

Example configuration snippet:

middleware:
  - name: http_delay
    config:
      delay: 1                 # Delay in seconds to apply to response

HTTP Tamperer

A Layer 7 tamperer, this plugin allows you to modify response headers, status code or the body itself.

Example configuration snippet:

middleware:
  - name: http_tamperer
    config:
      request:
        method:           "GET"  # Override request method
        headers:
          x_my_request:   "foo"  # Override request header
          content_type: "application/x-www-form-urlencoded"
          content_length: "5"
        cookies:                 # Custom request cookies
            - name: "fooreq"
              value: "blahaoeuaoeu"
              domain: "localhost"
              path: "/foopath"
              secure: true
              rawexpires: "Sat, 12 Sep 2015 09:19:48 UTC"
              maxage: 200
              httponly: true
        body: "wow, new body!"   # Override request body
      response:
        status: 201              # Override HTTP Status code
        headers:                 # Override response headers
          content_length: "27"
          x_foo_bar:      "baz"
        body:      "my new body" # Override response body
        cookies:                 # Custom response cookies
            - name: "foo"
              value: "blahaoeuaoeu"
              domain: "localhost"
              path: "/foopath"
              secure: true
              rawexpires: "Sat, 12 Sep 2015 09:19:48 UTC"
              maxage: 200
              httponly: true

Network Shaper

The network shaper plugin is a Layer 4 tamperer, and requires root access to work, as it needs to configure the local firewall and network devices. Using the excellent Comcast library, it can shape and interfere with network traffic, including bandwidth, latency, packet loss and jitter on specified ports, IPs and protocols.

NOTE: This component only works on MacOSX, FreeBSD, Linux and common *nix flavours.

Example configuration snippet:

middleware:

  - name: network_shape
    config:
      latency:     250         # Latency to add in ms
      target_bw:   750         # Bandwidth in kbits/s
      packet_loss: 0.5         # Packet loss, as a %
      target_ips:              # Target ipv4 IP addresses
        - 0.0.0.0
      target_ips6:             # Target ipv6 IP addresses
        - "::1/128"
      target_ports:            # Target destination ports
        - "80"
      target_protos:           # Target protocols
        - "tcp"
        - "udp"
        - "icmp"

Logger

Log the in/out messages, optionally requesting the output to be hex encoded.

Example configuration snippet:

middleware:
  - name: logger
    config:
      hex_output: false        # Display output as Hex instead of a string

Configuration Reference

Refer to the example YAML file for a full reference.

Extending Muxy

Muxy is built as a series of configurable plugins (using Plugo) that must be specified in the configuration file to be activated. Start with a quick tour of Plugo before progressing.

Proxies

Proxies must implement the Proxy interface, and register themselves via PluginFactories.register to be available at runtime. Take a look at the HTTP Proxy for a good working example.

Middleware

Middlewares implement the Middleware interface and register themselves via PluginFactories.register to be available at runtime. Take a look at the HTTP Delay for a good working example.

About

Simulating real-world distributed system failures

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Go 92.6%
  • Shell 5.1%
  • Ruby 1.2%
  • Makefile 1.1%