View on GitHub

Gimbal

An HTTP testing system

Download this project as a .zip file Download this project as a tar.gz file

Introduction

Gimbal is designed for testing HTTP APIs (REST or otherwise) and web sites. It allows the developer to describe requests and the responses those requests are expected to generate using a simple JSON or YAML document. Since Gimbal ships as a single, compiled binary it is easy to run in a variety of cases, including during a CI build process. It can also be scheduled using cron or similar.

Example Test Spec

Below is an extremely simple (trivially so) test suite for use with Gimbal. If you'd like to see a more complete example, check out httpbin.json, which tests a number of the httpbin endpoints. For now, let's take a quick look at the simple example.

A Gimbal test suite is defined using a JSON file (YAML and other formats will be supported soon). The configuration is called a "spec". Specs are recursive, they can contain other specs. Configuration options contained in the parent are pushed down into the children. This forms a kind of tree, of which only the leaf nodes will actually result in HTTP requests.

Each spec can describe an HTTP request and the response that is expected back. There are also some additional parameters, like how many times a request should be attempted before giving up. A request can be minimally specified by a host (which will result in a request for the URI /). The host will be inherited by child specs, which means you can define it just once on the parent and then specify URIs on the children.

{
    "host": "gimbal.datamaglia.com",
    "maxAttempts": 1,
    "name": "Simple Tests",
    "specs": [
        {
            "name": "root",
            "responseHeaders": {
                "Content-Type": [
                    "text/html; charset=utf-8"
                ]
            },
            "statusCode": 200,
            "uri": "/"
        },
        {
            "name": "404",
            "responseHeaders": {
                "Content-Type": [
                    "text/html; charset=utf-8"
                ]
            },
            "statusCode": 404,
            "uri": "/404"
        }
    ]
}

A couple things to point out. First, notice that the header value is a list. This is in case there are multiple instance of a given header. All values are included in a single key (to make it valid JSON). Next, and probably self-explanatory, the statusCode key asserts which status code we expect back from the request.

Building

Right now Gimbal is under heavy development and there aren't any releases. However, you can try it out by cloning the repository (see the link the left) and building it yourself. First, you'll need a functioning Go toolchain. There are instructions on the Go web site. The Go article at "How I Start" is also an excellent read if you want to become more familiar with how Go development "works".

Once you've got that set up, you can run go get github.com/datamaglia/gimbal to grab the repo (or fork it and change the GitHub path to your fork). Switch to the source directory and run go get && go build and you'll have a binary in no time. Then you can run one of the examples. Try ./gimbal -f examples/httpbin.json.

Specification

The following is a list of valid spec configuration parameters. Some of these have not yet been implemented.

name

String. A descriptive name for the spec. Not used internally but will be logged in some cases for debugging and on failures. Parent names will be prepended, so if a spec named A has a child spec named B when the child spec is run its name will appear as "A :: B". Default is "".

concurrentRequests

Integer. The maximum number of concurrent requests that will be made. If this is set to 1, requests will be run in serial. Default is 1.

outputLevel

String. The type of messages that should be included in the output. One of "success", "warning", and "failure". Levels include subsequent levels. Default is "success".

maxAttempts

Integer. The maximum number of times to attempt a request before it is declared a failure. Default is 10.

timeElapsedDelta

Float. If the time a request takes is greater than maxTimeElapsed, but by less than this amount, the result will be a warning, not a failure. This allows for some "wiggle room". Default is 0.0.

host

String. The host to contact, such as httpbin.org.

port

Integer. The port on which to contact the host. Default is 80 when SSL is false and 443 when SSL is true.

ssl

Boolean. Whether to use SSL for the request. Default is false.

method

String. The HTTP verb to use for the request. Default is "GET".

statusCode

Integer. The expected status code of the response. Default is 200.

maxTimeElapsed

Float. The maximum time the request can take and still be considered a success, in seconds. Default is 10.0.

requestHeaders

Object. Mapping of header names to lists of header values that will be included in the request. Default is {}.

responseHeaders

Object. Mapping of header names to lists of header values that are expected to be included in the response. Unless exactResponseHeaders is true, the response can contain additional headers, so this represents a minimum. Default is {}.

exactResponseHeaders

Boolean. If true, the responseHeaders value will be treated as an exact enumeration of headers and values, if the response includes additional headers the spec will fail. Default is false.

uri

String. The URI to request from the host. Default is "/".

specs

List. A recursive list of specs to run. Each of these will inherit properties from the parent as necessary. If this is set, then the spec that contains the list will not run on its own. In other words, if you think about the configuration as a tree, only leaf nodes actually cause a test to be run. Default is [].

requestData

String. The raw data to include with the request. Default is "".

responseData

String. The raw data that should be included with the response. If set to the empty string, no check is performed. Default is "".

vars (not yet implemented)

Object. A map of variable assignments that can be used in the given spec and all its children. The keys must be strings. For now, the values must be strings or numbers. Eventually lists will be supported and a forEach option will be added to run a given spec once for each value in the list. Default is {}.

Why "Gimbal"

Gimbals help sailors, photographers, astronauts, and others keep their tools properly aligned. Gimbal helps developers keep their production systems aligned with their specifications.