0
0
mirror of https://github.com/nodejs/node.git synced 2024-11-29 23:16:30 +01:00
nodejs/benchmark/_http-benchmarkers.js
Rich Trott 874b6b948c benchmark: update obsolete information pointer
A doc suggested in an error message is no longer the place to get the
information about required http benchmarkers. Update the error message
to point to the current location for the information.

PR-URL: https://github.com/nodejs/node/pull/12026
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
2017-03-26 11:30:29 +02:00

139 lines
3.9 KiB
JavaScript

'use strict';
const child_process = require('child_process');
// The port used by servers and wrk
exports.PORT = process.env.PORT || 12346;
function AutocannonBenchmarker() {
this.name = 'autocannon';
this.autocannon_exe = process.platform === 'win32' ?
'autocannon.cmd' :
'autocannon';
const result = child_process.spawnSync(this.autocannon_exe, ['-h']);
this.present = !(result.error && result.error.code === 'ENOENT');
}
AutocannonBenchmarker.prototype.create = function(options) {
const args = [
'-d', options.duration,
'-c', options.connections,
'-j',
'-n',
`http://127.0.0.1:${options.port}${options.path}`
];
const child = child_process.spawn(this.autocannon_exe, args);
return child;
};
AutocannonBenchmarker.prototype.processResults = function(output) {
let result;
try {
result = JSON.parse(output);
} catch (err) {
// Do nothing, let next line handle this
}
if (!result || !result.requests || !result.requests.average) {
return undefined;
} else {
return result.requests.average;
}
};
function WrkBenchmarker() {
this.name = 'wrk';
this.regexp = /Requests\/sec:[ \t]+([0-9.]+)/;
const result = child_process.spawnSync('wrk', ['-h']);
this.present = !(result.error && result.error.code === 'ENOENT');
}
WrkBenchmarker.prototype.create = function(options) {
const args = [
'-d', options.duration,
'-c', options.connections,
'-t', 8,
`http://127.0.0.1:${options.port}${options.path}`
];
const child = child_process.spawn('wrk', args);
return child;
};
WrkBenchmarker.prototype.processResults = function(output) {
const match = output.match(this.regexp);
const result = match && +match[1];
if (!isFinite(result)) {
return undefined;
} else {
return result;
}
};
const http_benchmarkers = [new WrkBenchmarker(), new AutocannonBenchmarker()];
const benchmarkers = {};
http_benchmarkers.forEach((benchmarker) => {
benchmarkers[benchmarker.name] = benchmarker;
if (!exports.default_http_benchmarker && benchmarker.present) {
exports.default_http_benchmarker = benchmarker.name;
}
});
exports.run = function(options, callback) {
options = Object.assign({
port: exports.PORT,
path: '/',
connections: 100,
duration: 10,
benchmarker: exports.default_http_benchmarker
}, options);
if (!options.benchmarker) {
callback(new Error('Could not locate required http benchmarker. See ' +
'https://github.com/nodejs/node/blob/master/doc/guides/writing-and-running-benchmarks.md##http-benchmark-requirements ' +
'for further instructions.'));
return;
}
const benchmarker = benchmarkers[options.benchmarker];
if (!benchmarker) {
callback(new Error(`Requested benchmarker '${options.benchmarker}' is ` +
'not supported'));
return;
}
if (!benchmarker.present) {
callback(new Error(`Requested benchmarker '${options.benchmarker}' is ` +
'not installed'));
return;
}
const benchmarker_start = process.hrtime();
const child = benchmarker.create(options);
child.stderr.pipe(process.stderr);
let stdout = '';
child.stdout.on('data', (chunk) => stdout += chunk.toString());
child.once('close', function(code) {
const elapsed = process.hrtime(benchmarker_start);
if (code) {
let error_message = `${options.benchmarker} failed with ${code}.`;
if (stdout !== '') {
error_message += ` Output: ${stdout}`;
}
callback(new Error(error_message), code);
return;
}
const result = benchmarker.processResults(stdout);
if (result === undefined) {
callback(new Error(`${options.benchmarker} produced strange output: ` +
stdout, code));
return;
}
callback(null, code, options.benchmarker, result, elapsed);
});
};