Browse Source

version bump, added support for printing errors and status code distribution, updated readme

master
Brett Langdon 13 years ago
parent
commit
6aa89695b7
3 changed files with 75 additions and 30 deletions
  1. +12
    -5
      Readme.md
  2. +62
    -24
      lib/index.js
  3. +1
    -1
      package.json

+ 12
- 5
Readme.md View File

@ -18,14 +18,10 @@ npm install -g
## Configuration
Tommygun uses ini files to specify what urls and settings to test. Each section corresponds to the url to test and
each property corresponds to specific settings for that given url. If the property occurs outside of a section then
tommygun those settings are used by tommygun.
each property corresponds to specific settings for that given url.
### Example
```ini
;this setting is used by tommygun globally
random = false
[localhost]
port = 8000
num = 5
@ -46,6 +42,17 @@ num = 2
### Get Help
```bash
tommygun --help
Usage: tommygun [config] [config]...
Options:
-c, --concurrency Number of Concurrent Clients to Use [default: 1]
-n, --requests Total Number Of Requests To Make
-r, --random Whether Or Not To Randomize The Url Order [boolean] [default: false]
-k, --keepalive Whether Or Not To Enable Keep Alive Support [boolean] [default: false]
-l, --log Log File To Write All Request Data To [string]
-s, --stats Whether or Not Print Result Stats [boolean] [default: true]
-q, --quiet Whether Or Not To Silence stdout [boolean] [default: false]
-h, --help Show This Help Text [boolean]
```
### Simple Usage


+ 62
- 24
lib/index.js View File

@ -12,10 +12,16 @@ var argv = require('optimist')
default: 1,
describe: 'Number of Concurrent Clients to Use'
})
.options('r', {
.options('n', {
alias: 'requests',
describe: 'Total Number Of Requests To Make'
})
.options('r', {
alias: 'random',
describe: 'Whether Or Not To Randomize The Url Order',
default: false,
boolean: true
})
.options('k', {
alias: 'keepalive',
describe: 'Whether Or Not To Enable Keep Alive Support',
@ -61,7 +67,6 @@ if( argv.log ){
}
var config = {
random: false,
urls: {},
};
var defaults = {
@ -93,6 +98,10 @@ argv._.forEach(function(file){
}
});
var results = [];
var results_length = 0;
var errors = [];
var errors_length = 0;
var urls = [];
for( var key in config.urls ){
var url = config.urls[key];
@ -101,10 +110,7 @@ for( var key in config.urls ){
}
}
if( typeof(config.random) !== 'boolean' ){
config.random = config.random.toLowerCase() === 'true';
}
if( config.random ){
if( argv.random ){
console.log('Randomizing Url List');
var i = urls.length;
if ( i == 0 ) return false;
@ -121,11 +127,12 @@ if( !argv.requests ){
argv.requests = urls.length;
}
var results = [];
var errors = [];
var save_result = function(result){
results.push(result);
var url = result.url;
results[url] = (results[url])?results[url]:[];
results[url].push(result);
results_length += 1;
if( argv.log ){
var tmp = [];
for( var i in result ){
@ -138,7 +145,15 @@ var save_result = function(result){
}
fs.writeSync(argv.log, tmp.join() + '\r\n');
}
}
};
var save_error = function(error){
var url = error.url;
errors[url] = (errors[url])?errors[url] : [];
errors[url].push(error);
errors_length += 1;
};
var run = function(options, done){
var start = new Date().getTime();
@ -168,37 +183,59 @@ var run = function(options, done){
console.log('Starting Up ' + argv.concurrency + ' Clients');
var queue = async.queue(run, argv.concurrency);
var percentiles = [.7, .8, .85, .9, .94, .96, .99];
var percentiles = [.5, .6, .7, .8, .9, .95, .98, .99];
queue.drain = function(){
var end_time = new Date().getTime();
var elapsed = end_time - start_time;
console.log('Finished');
console.log('Elapsed Time (sec): ' + (elapsed/1000));
console.log('Completed Requests: ' + results_length);
console.log('Errors: ' + errors_length);
var req_sec = results_length / (elapsed/1000);
console.log('Requests per Second: ' + req_sec);
if( argv.stats ){
console.log('Processing Results');
var tmp = results;
results = {};
tmp.forEach( function(result){
var key = result.url;
delete result.url;
if( results[key] == undefined ){
results[key] = []
}
results[key].push(result);
});
for( var url in results ){
if( typeof(results[url]) === 'function' ){
continue;
}
console.log('Results For: ' + url);
console.log('\tTotal Requests: ' + results[url].length);
var ms_data = results[url].map( function(a){ return a.ms; } );
ms_data = ms_data.sort();
var ms_set = new gauss.Vector(ms_data);
var ms_total = ms_set.sum();
console.log('\tMean Time (ms): ' + ms_set.mean());
console.log('\tMin Time (ms): ' + ms_set.min());
console.log('\tMax Time (ms): ' + ms_set.max());
console.log('\tTotal Time (ms): ' + ms_set.sum());
console.log('\tTotal Time (ms): ' + ms_total);
percentiles.forEach( function(percent){
console.log('\t' + (percent*100) + 'th Percentile: ' + ms_set.percentile(percent));
console.log('\t' + (percent*100) + '% (ms): ' + ms_set.percentile(percent));
});
var status_data = results[url].map( function(a){ return a.status; } );
var status_set = new gauss.Vector(status_data);
var status_dist = status_set.distribution();
console.log('\tStatus Code Distribution:');
for( var status in status_dist ){
console.log('\t\t' + status + '\t' + status_dist[status]);
}
}
for( var url in errors){
if( typeof(errors[url]) == 'function' ){
continue;
}
console.log('Errors For: ' + url);
console.log('\tErrors: ' + errors[url].length);
var code_errors = errors[url].map( function(a){ return a.error.code; });
var code_set = new gauss.Vector(code_errors);
var code_dist = code_set.distribution();
console.log('\tError Code Distribution:');
for( var code in code_dist ){
console.log('\t\t' + code + '\t' + code_dist[code]);
}
}
}
if( argv.log ){
@ -209,6 +246,7 @@ queue.drain = function(){
console.log('Queuing Up ' + argv.requests + ' Requests');
var offset = 0;
var start_time = new Date().getTime();
for( var i = 0; i < argv.requests; ++i ){
if( offset >= urls.length ){
offset = 0;


+ 1
- 1
package.json View File

@ -1,6 +1,6 @@
{
"name": "tommygun",
"version": "0.0.1",
"version": "0.0.2",
"description": "HTTP Benchmarking Tool",
"keywords": [
"http",


Loading…
Cancel
Save