Skip to content

Commit

Permalink
Refactor for SIGINT
Browse files Browse the repository at this point in the history
  • Loading branch information
Josh Mervine committed Feb 27, 2014
1 parent e9fe227 commit 88e96f4
Show file tree
Hide file tree
Showing 11 changed files with 831 additions and 497 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/node_modules
npm-debug.log
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ language: node_js
node_js:
- "0.8"
- "0.10"
- "0.11"
23 changes: 0 additions & 23 deletions Makefile

This file was deleted.

17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ works pretty much the same way.
> What hasn't been ported or is different from the [ruby version](http:https://mervine.net/gems/httperfrb):
>
> - `parse` is true by default.
> - `#fork` isn't currently supported.
> - `tee` isn't currently supported.
> - `httperf` must be in your `PATH`
Expand All @@ -24,8 +23,7 @@ Tested on the following node versions (via [Travis-ci.org](http:https://travis-ci.org/

- 0.8
- 0.10

> I have only actually used this on `0.10.12`.
- 0.11

### Installation

Expand All @@ -47,6 +45,8 @@ Tested on the following node versions (via [Travis-ci.org](http:https://travis-ci.org/
// Note:runSync is far less efficent because of
// how execSync.exec works. I do not recommend it
// when running larger/longer tests.
//
// This might be removed in a future release.
var first_run = httperf.runSync();
console.log(first_run);
// => { object with httperf values }
Expand All @@ -67,14 +67,17 @@ Tested on the following node versions (via [Travis-ci.org](http:https://travis-ci.org/
// => '123.4'

httperf.parse = false;
httperf.run(function (result) {
httperf.result = result;
var child = httperf.run(function (result) {
console.log(result);
});
// => "string with httperf stdout"

console.log(httperf.results);
// => "string with httperf stdout"
// httperf dumps data on SIGINT (crtl-c), HTTPerf's run
// supports this as well, with the following addition
// to your scripts
process.on('SIGINT', function() {
child.send('SIGINT');
});


#### NodeUnit Benchmark Example
Expand Down
56 changes: 50 additions & 6 deletions lib/httperf.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var execSync = require('execSync').exec;
var exec = require('child_process').exec;
var spawn = require('child_process').spawn;
var Parser = require('./parser');

/* Valid options:
Expand Down Expand Up @@ -73,25 +73,69 @@ HTTPerf.prototype = {
},

run: function (callback) {
var parse = this.parse;
return exec(this.command(), function (error, stdout, stderr) {
if (error) {
throw new Error(error);
}
var that = this;
var parse = that.parse;

var stderr = '';
var stdout = '';

var child = spawn('httperf', that.paramsToArray(), {
detached: true
});

var finished = false;
function finish(code) {
if (finished) return;

finished = true;
var result;
if (parse) {
result = new Parser(stdout);
} else {
result = stdout;
}
callback(result);
}

child.stderr.on('data', function(data) {
stderr += data;
stdout += data; // merge stderr to stdout

if (data.toString().match(/connection failed with unexpected error 99/)) {
console.error(stderr);
throw new Error('Out of file descriptors.');
}
});

child.stdout.on('data', function(data) {
stdout += data;
});

child.on('close' , finish);
child.on('SIGTERM' , finish);
child.on('SIGINT' , finish);
child.on('exit' , finish);
child.on('error' , finish);


return child;
},

command: function () {
return "httperf " + this.paramsToString();
},

paramsToArray: function () {
var ret = [];
for (key in this.params) {
ret.push("--"+key);
if (typeof this.params[key] !== 'boolean') {
ret.push(this.params[key]);
}
}
return ret;
},

paramsToString: function () {
var ret = [];
var key;
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "httperfjs",
"version": "0.0.7",
"version": "0.0.8",
"description": "Node.js binding for HTTPerf",
"keywords": [
"httperf",
Expand All @@ -10,8 +10,7 @@
"author": "Joshua Mervine <[email protected]> (http:https://mervine.net)",
"main": "./lib/httperf.js",
"devDependencies": {
"nodeunit": "*",
"istanbul": "~0.1.39"
"tape": "^2.5.0"
},
"engines": {
"node": ">= 0.8"
Expand All @@ -20,6 +19,7 @@
"execSync": "~1.0.1-pre"
},
"scripts": {
"test": "make unit"
"test": "tape ./test/*_test.js",
"int": "node ./test/integration.js"
}
}
46 changes: 0 additions & 46 deletions test/functional.js

This file was deleted.

133 changes: 57 additions & 76 deletions test/httperf_test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var HTTPerf = require('lib/httperf');
var HTTPerf = require('../lib/httperf');
var tape = require('tape');

process.env.PATH = "./test/support:"+process.env.PATH;

Expand All @@ -11,91 +12,71 @@ var default_options = {
'num-conns' : 10
};

module.exports = {
"new HTTPerf(options)": function (test) {
var h = new HTTPerf(default_options);
test.equal('localhost', h.params.server);
test.equal('80', h.params.port);
test.equal('/foo?foo=bar&bar=foo' , h.params.uri);
test.equal('10', h.params['num-conns']);
test.done();
},
var httperf = new HTTPerf(default_options);
var httperf_san_parse = new HTTPerf(default_options);
httperf_san_parse.parse = false;

"#command": function (test) {
var h = new HTTPerf(default_options);
test.equal("httperf --server=localhost --port=80 --verbose --hog --uri='/foo?foo=bar&bar=foo' --num-conns=10",
h.command());
test.expect(1);
test.done();
},
tape('HTTPerf', function(group) {
group.test('command', function(test) {
test.equal(httperf.command(),
"httperf --server=localhost --port=80 --verbose --hog --uri='/foo?foo=bar&bar=foo' --num-conns=10");
test.end();
});

"#paramsToString": function (test) {
var h = new HTTPerf(default_options);
test.equal('--server=localhost --port=80 --verbose --hog --uri=\'/foo?foo=bar&bar=foo\' --num-conns=10',
h.paramsToString());
test.expect(1);
test.done();
},
group.test('paramsToString', function(test) {
test.equal(httperf.paramsToString(),
'--server=localhost --port=80 --verbose --hog --uri=\'/foo?foo=bar&bar=foo\' --num-conns=10');
test.end();
});

"#parse": function (test) {
var h = new HTTPerf(default_options);
test.ok(h.parse);
h.parse = false;
test.equal(false, h.parse);
test.expect(2);
test.done();
},
group.test('paramsToArray', function(test) {
test.deepEqual(httperf.paramsToArray(),
[ '--server', 'localhost', '--port', 80, '--verbose', '--hog',
'--uri', '/foo?foo=bar&bar=foo', '--num-conns', 10 ]);
test.end();
});

group.test('parse', function(test) {
test.ok(httperf.parse, 'truthy');
test.notOk(httperf_san_parse.parse, 'falsy');
test.end();
});

"#update_option": function (test) {
group.test('update_option', function(test) {
var h = new HTTPerf(default_options);
h.update_option("num-conns", 100);
test.equal("100", h.params["num-conns"]);
test.expect(1);
test.done();
},
test.equal(100, h.params["num-conns"]);
test.end();
});

"#runSync -- with parse": function (test) {
var h = new HTTPerf(default_options);
var result = h.runSync();
test.ok( result );
test.ok( result.command );
test.ok( result.connection_time_avg );
test.expect(3);
test.done();
},
group.test('runSync w/ parse', function(test) {
var result = httperf.runSync();
test.ok(typeof result === 'object', 'returns object');
test.ok(result.command, 'has result.command');
test.ok(result.connection_time_avg, 'has result.connection_time_avg');
test.end();
});

"#runSync -- without parse": function (test) {
var h = new HTTPerf(default_options);
h.parse = false;
var result = h.runSync();
test.ok( result.indexOf("httperf --server=localhost --port=80") === 0 );
test.ok( result.indexOf("Connection time [ms]: min 0.2 avg 0.2 max 0.2 median 0.5 stddev 0.0") !== -1 );
test.expect(2);
test.done();
},
group.test('runSync w/o parse', function(test) {
var result = httperf_san_parse.runSync();
test.ok(typeof result === 'string', 'returns object');
test.end();
});

"#run -- with parse": function (test) {
test.expect(3);
var h = new HTTPerf(default_options);
h.run( function (result) {
test.ok(result);
test.ok(result.command);
test.ok(result.connection_time_avg);
test.done();
group.test('run w/ parse', function(test) {
httperf.run( function (result) {
test.ok(typeof result === 'object', 'returns object');
test.ok(result.command, 'has result.command');
test.ok(result.connection_time_avg, 'has result.connection_time_avg');
test.end();
});
},
});

"#run -- without parse": function (test) {
test.expect(3);
var h = new HTTPerf(default_options);
h.parse = false;
h.run( function (result) {
test.ok(result);
test.ok(result.indexOf("httperf --server=localhost --port=80") === 0 );
test.ok(result.indexOf("Connection time [ms]: min 0.2 avg 0.2 max 0.2 median 0.5 stddev 0.0") !== -1 );
test.done();
group.test('run w/o parse', function(test) {
httperf_san_parse.run( function (result) {
test.ok(typeof result === 'string', 'returns object');
test.end();
});
},
};
});
});

// vim: ft=javascript
Loading

0 comments on commit 88e96f4

Please sign in to comment.