airstrike

package module
v0.0.0-...-8b09216 Latest Latest
Warning

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

Go to latest
Published: Apr 13, 2016 License: MIT Imports: 11 Imported by: 1

README

airstrike

Load-testing or stress-testing an API can be imagined as an air strike, which consists of:

1. a Mission that describes when and what ordnance will be deployed
2. a Squadron of planes that can simultaneously deploy their Arsenals
3. an Arsenal on each plane consisting of Bombs and Missiles

The default mission (1) causes the configured squadron to simultaneously deploy their configured arsenals every 5 seconds.

Some ordnance will hit its target and result in reportable damage (response time) sooner than others, and the output logging will reflect this, as the reports will typically arrive "out of order" as the concurrent weapon deployments finish.

Bombs are used for API transactions where all inputs can be known before runtime. If you know the HTTP verb, URL, and (optional) payload ahead of time, you can use a Bomb.

Missiles are used for API transactions that depend on the current state of your account, such as deleting the most-recently-created object. You provide them with a function that will be executed when the Missile is deployed.

Documentation

Overview

Package airstrike conducts workflow and/or stress-testing against an API.

Load-testing or stress-testing an API can be imagined as an air strike, which consists of:

  1. a Mission that describes when and what ordnance will be deployed
  2. a Squadron of planes that will simultaneously deploy their Arsenals
  3. an Arsenal on each plane consisting of Bombs and Missiles

The default Mission simultaneously commands each plane in the configured Squadron to deploy its configured arsenal every 5 seconds. Some ordnance will hit its target and result in reportable damage (response time) sooner than others, and the output logging will reflect this, as the reports will typically arrive "out of order" as the concurrent weapon deployments finish.

Bombs are used for API transactions where all inputs are known before runtime. If you know the HTTP verb, URL, and (optional) payload ahead of time, you can use a Bomb. Bombs assume the state of objects associated with your account and as such must be trusted to hit their target. If they "miss" with a 404 or other 4xx, this will be logged as an error.

Missiles are used for API transactions that depend on the current state of your account, such as deleting the most-recently-created object. You provide them with a function that will be executed when the Missile is deployed. Unlike a Bomb, Missiles need to be "guided" in this fashion to ensure they will hit their target. As with Bombs, 4xx responses are reported as errors.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Mission

type Mission struct {
	Enabled         bool          `json:"enabled"`
	EnabledCh       chan bool     `json:"-"`
	Inception       time.Time     `json:"inception"`
	Interval        float64       `json:"interval"`
	IntervalDeltaCh chan float64  `json:"-"`
	MaxResponseTime time.Duration `json:"max_response_time"`
	Planes          []Plane       `json:"planes"`
	RaidCount       int           `json:"raid_count"`
	Reporter        *Reporter     `json:"-"`
	Status          int           `json:"status"`
	StatusCh        chan int      `json:"-"`
}

A Mission is a plan for the execution of "attacks" against an API and a representation of its history since inception, including the number of attacks that have occurred and how many Planes make up its Squadron.

Enabled missions are eligible for indefinite execution, with each attack commencing every Interval seconds.

func NewMission

func NewMission(l *logrus.Logger) *Mission

func (*Mission) Prosecute

func (m *Mission) Prosecute(config Raid)

runs in a goroutine

func (*Mission) SetInterval

func (m *Mission) SetInterval(logCh chan map[string]interface{}, newInterval float64)

SetInterval changes the length of the pause that occurs between the commencement of attacks.

NOTE: Because each Plane deploys its arsenal simultaneously, it is possible that a new attack will commence before some of the results from the previous attack cycle have been reported. It is possible to overwhelm an API's infrastructure if your account is not subject to rate limits. The shortest possible interval is one second, because seconds represented as integers are easier to reason about than sub-second ones.

type Plane

type Plane struct {
	Name    string                 `json:"name"`
	Client  sleepwalker.RESTClient `json:"-"`
	Arsenal ordnance.Arsenal       `json:"arsenal"`
}

A Plane has an arsenal of deployable weapons. It represents a list of tasks that, perfored serially, compose a workflow.

Many planes can deploy their arsenal at the same time, but each weapon in a plane's arsenal must be deployed one at a time.

For example, a common workflow would be:

  1. GET index - list all items in a collection
  2. GET show - get the metadata for an item
  3. POST create - create and/or associate an item related to the first

func NewPlane

func NewPlane(name string, client sleepwalker.RESTClient) Plane

NewPlane ensures that the creation of each Plane is logged.

func (*Plane) Arm

func (p *Plane) Arm(weapons ordnance.Arsenal)

Arm loads the given arsenal into the Plane and logs error conditions.

func (Plane) Launch

func (p Plane) Launch(logCh chan map[string]interface{}) ([]sleepwalker.Result, error)

Launch tells a Plane to sequentially fires all of its weapons and report the results.

type Raid

type Raid struct {
	Planes []Plane `json:"planes"`
}

A Raid is a collection of bombs capable of reporting summary statistics.

func NewRaid

func NewRaid(inputPlanes ...Plane) (Raid, error)

NewRaid returns a new Raid. It notifies the user if no planes were given.

func (*Raid) Conduct

func (r *Raid) Conduct(urlInvariant string, logCh chan map[string]interface{})

Conduct tells the Squadron to launch all of its planes. Each Plane serially fires its weapons and sends the result of each weapon down a channel.

func (*Raid) String

func (r *Raid) String() string

type Reporter

type Reporter struct {
	// Display an ANSI-colorized graph of response times on STDOUT.
	Gauge bool

	// The Glyph is the character that will make up the horizontal bar gauge
	// if gauge output is enabled.
	Glyph byte

	// A reference to a logger.
	Logger *logrus.Logger

	// This channel receives types that fulfill the logrus.Fields interface.
	LogCh chan map[string]interface{}

	// Number of columns the gauge will occupy.
	GaugeWidth int

	// A string to omit from URLs in order to shorten log messages, i.e.,
	// the API's base URL.
	URLInvariant string

	// Response times over this threshold will be logged at the WARN level.
	WarningThreshold time.Duration

	// Values received on this channel will become the new WarningThreshold.
	ThresholdCh chan time.Duration

	// This channel holds the response time of the last result.
	LastResponseTimeCh chan time.Duration
}

A Reporter manages logging and console ouput.

func NewReporter

func NewReporter(logger *logrus.Logger) *Reporter

func (*Reporter) Listen

func (r *Reporter) Listen()

Run should be invoked in a goroutine. Log data fulfilling the logrus.Fields interface should be sent down its channel.

type SimpleRaid

type SimpleRaid struct {
	Planes []struct {
		Name    string `json:"name"`
		Weapons []struct {
			Name string `json:"name"`
		} `json:"weapons"`
	} `json:"planes"`
}

A SimpleRaid reports only the name of each object to simplify output.

type Squadron

type Squadron struct {
	ID     string  `json:"id"`
	Planes []Plane `json:"planes"`
}

A Squadron is a collection of Planes that will simultaneously begin deploying their weapons.

func NewSquadron

func NewSquadron() Squadron

NewSquadron assigns each new Squadron a unique ID and logs its creation.

func (*Squadron) Add

func (s *Squadron) Add(plane Plane)

Add associates the provided Plane with the Squadron, logging its addition.

func (*Squadron) AddChaos

func (s *Squadron) AddChaos(clones int, deadliness int, client sleepwalker.RESTClient, armory ordnance.Armory)

AddChaos creates the specified number of Planes that each have their own random selection of n weapons, quantified by their "deadliness."

func (*Squadron) AddClones

func (s *Squadron) AddClones(clones int, client sleepwalker.RESTClient, armory ordnance.Armory, weaponNames ...string)

AddClones creates the specified number of Planes, each armed with the payload described, which can be one or more weapons.

Directories

Path Synopsis
Package ordnance is concerned with constructing and storing weapons and providing access to them by name.
Package ordnance is concerned with constructing and storing weapons and providing access to them by name.

Jump to

Keyboard shortcuts

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