Description

Spray is a load testing tool designed for HTTP testing. It allows for easy testing of RESTful APIs and provides useful statistics. Spray integrates with cube to provide realtime graphs of the running load test. To use multiple cores, just run the same test in parallel. Cube can handle the aggregation.

Example

varasync=require('async'),

Load =require('spray'),

inspect =require('util').inspect

;

process.on('exit',function(){

console.log(load.stats);

});

var options ={

protocol:'https',

hostname:'example.com',

port:8000,

rate:100,// req/sec

time:300,// sec

timeout:20000,//ms -- socket timeout

max_sessions:500,

enable_cube:true,

sessions:[{

weight:1,

start: start_session

}]

};

var load =newLoad(options);

load.run(function(err,results){

if(err)returnconsole.error("Err = "+err);

console.log("\nresults = "+require('util').inspect(results));

});

load.on('sec',function(stats){

console.log("ONE SEC!");

});

load.on('min',function(stats){

console.log("ONE MIN");

console.log(stats);

});

functionstart_session(http,callback){

returnhttp.request({

headers:{'content-type':'application/json'},

encoding:'utf-8',

path:'/api',

method:'GET'

},function(err,res){

if(err)returncallback(err);

if(res.statusCode!=200)returncallback(res.statusCode);

returncallback(null);

});

}

API

Constructor

var Spray =require('spray');

var config ={

protocol:'https',

hostname:'example.com',

port:8000,

rate:100,// req/sec

time:300,// sec

timeout:20000,//ms -- socket timeout

max_sessions:500,

enable_cube:true,

sessions:[{

weight:1,

start: start_session // function defined elsewhere

}]

};

var spray =newSpray(config);

config object

protocol: string - 'http' || 'https'

hostname: string - The hostname used in http.request

port: number - The port used in http.request

rate: number - Requests/second

time: number - Duration of the test in seconds

timeout: number - The timeout for http requests (ms)

max_sessions: number - The maximum number of concurrent sessions to run

sessions: [sessions]

weight: number - A weight which changes the probabilities for session selection.

start: function - start_session(http, callback). Make http requests with the http.request method and call callback when the session is over.

agent: mixed - the http agent setting for http.request - Defaults to a custom agent implementation with maxSockets set to 1. Can be passed another agent or false to use no agent.

http.request

An http object gets passed to the session start function. This function keeps stats on all requests and should be used to send all requests. The options are the same as the http.request function provided by node. The only difference is the agent option described in the Sessions section below.

functionstart_session(http,callback){

returnhttp.request({

headers:{

'content-type':'application/json',

'connection':'keep-alive'// use the same socket for the next request

},

encoding:'utf-8',

path:'/api',

method:'GET'

},function(err,res){

if(err)returncallback(err);

if(res.statusCode!=200)returncallback(res.statusCode);

var user =JSON.parse(res.body);

returnhttp.request({

headers:{

'content-type':'application/json'

// no 'connection': 'keep-alive' header closes the socket as this is the last req in this session

},

encoding:'utf-8',

path:user.links.checkin+'/?token='+token,

method:'POST',

body:JSON.stringify({

ll:[42.3,-71.8]

})

},function(err,res){

if(err)returncallback(err);

if(res.statusCode!=200)returncallback(res.statusCode);

returncallback(null);

});

});

}

Sessions

In order to simulate real clients we want each client to use the same socket for each request in the same session if the 'connection' header is set to 'keep-alive'. A custom agent is used to facilitate this, and the default is to use that agent. A different agent can be used by passing it in the agent parameter of the Spray constructor options. Setting agent to false uses no agent. It is recommended to use the custom agent if keep-alive is used by clients of your API.

Install

npm install spray

If you would like live charts with cube, you must install cube and MongoDb

Cube properties

Event Type: 'random'

This event type is used because it allows us to use cube's default collections.

Properties:

Spray reports to cube every second. The properties below are totals for that second, except for latency, which is the average latency of all packets during that second.

sent

received

latency

timeouts

errors

Example Cube Query

median(random(latency))

License

The MIT License (MIT)

Copyright (c) 2011 Bozuko, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.