Skip to content

Commit ca343ca

Browse files
BridgeARcodebytere
authored andcommitted
benchmark: add test and all options and improve errors
This adds a new `test` option. Using it automatically uses a single minimal option matrix to verify the benchmark works as expected. Using the new `all` option makes sure all test suites are run. On top of that the benchmarks will from now on report properly what category might have a typo, if any. The http duration was also refactored to use a option instead of relying on a configuration setting. The fixture folder is ignored as test suite from now on. PR-URL: #31396Fixes: #31083 Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
1 parent 9f2c742 commit ca343ca

37 files changed

Lines changed: 292 additions & 189 deletions

‎benchmark/_cli.js‎

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,24 @@ const path = require('path');
66
// Create an object of all benchmark scripts
77
constbenchmarks={};
88
fs.readdirSync(__dirname)
9-
.filter((name)=>fs.statSync(path.resolve(__dirname,name)).isDirectory())
9+
.filter((name)=>{
10+
returnname!=='fixtures'&&
11+
fs.statSync(path.resolve(__dirname,name)).isDirectory();
12+
})
1013
.forEach((category)=>{
1114
benchmarks[category]=fs.readdirSync(path.resolve(__dirname,category))
1215
.filter((filename)=>filename[0]!=='.'&&filename[0]!=='_');
1316
});
1417

1518
functionCLI(usage,settings){
16-
if(!(thisinstanceofCLI))returnnewCLI(usage,settings);
17-
1819
if(process.argv.length<3){
1920
this.abort(usage);// Abort will exit the process
2021
}
2122

2223
this.usage=usage;
2324
this.optional={};
2425
this.items=[];
26+
this.test=false;
2527

2628
for(constargNameofsettings.arrayArgs){
2729
this.optional[argName]=[];
@@ -34,7 +36,7 @@ function CLI(usage, settings) {
3436
if(arg==='--'){
3537
// Only items can follow --
3638
mode='item';
37-
}elseif('both'===mode&&arg[0]==='-'){
39+
}elseif(mode==='both'&&arg[0]==='-'){
3840
// Optional arguments declaration
3941

4042
if(arg[1]==='-'){
@@ -61,6 +63,8 @@ function CLI(usage, settings) {
6163

6264
// The next value can be either an option or an item
6365
mode='both';
66+
}elseif(arg==='test'){
67+
this.test=true;
6468
}elseif(['both','item'].includes(mode)){
6569
// item arguments
6670
this.items.push(arg);
@@ -83,9 +87,15 @@ CLI.prototype.abort = function(msg) {
8387
CLI.prototype.benchmarks=function(){
8488
constpaths=[];
8589

90+
if(this.items.includes('all')){
91+
this.items=Object.keys(benchmarks);
92+
}
93+
8694
for(constcategoryofthis.items){
87-
if(benchmarks[category]===undefined)
88-
continue;
95+
if(benchmarks[category]===undefined){
96+
console.error(`The "${category}" category does not exist.`);
97+
process.exit(1);
98+
}
8999
for(constscriptsofbenchmarks[category]){
90100
if(this.shouldSkip(scripts))continue;
91101

‎benchmark/_http-benchmarkers.js‎

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ class AutocannonBenchmarker {
4343
}
4444
if(!result||!result.requests||!result.requests.average){
4545
returnundefined;
46-
}else{
47-
returnresult.requests.average;
4846
}
47+
returnresult.requests.average;
4948
}
5049
}
5150

@@ -77,9 +76,8 @@ class WrkBenchmarker {
7776
constthroughput=match&&+match[1];
7877
if(!isFinite(throughput)){
7978
returnundefined;
80-
}else{
81-
returnthroughput;
8279
}
80+
returnthroughput;
8381
}
8482
}
8583

@@ -89,18 +87,20 @@ class WrkBenchmarker {
8987
*/
9088
classTestDoubleBenchmarker{
9189
constructor(type){
92-
// `type` is the type ofbenchmarker. Possible values are 'http' and 'http2'.
90+
// `type` is the type of benchmarker. Possible values are 'http' and
91+
// 'http2'.
9392
this.name=`test-double-${type}`;
9493
this.executable=path.resolve(__dirname,'_test-double-benchmarker.js');
9594
this.present=fs.existsSync(this.executable);
9695
this.type=type;
9796
}
9897

9998
create(options){
100-
constenv=Object.assign({
99+
constenv={
101100
duration: options.duration,
102101
test_url: `http://127.0.0.1:${options.port}${options.path}`,
103-
},process.env);
102+
...process.env
103+
};
104104

105105
constchild=child_process.fork(this.executable,
106106
[this.type],
@@ -189,13 +189,14 @@ http_benchmarkers.forEach((benchmarker) => {
189189
});
190190

191191
exports.run=function(options,callback){
192-
options=Object.assign({
192+
options={
193193
port: exports.PORT,
194194
path: '/',
195195
connections: 100,
196196
duration: 5,
197197
benchmarker: exports.default_http_benchmarker,
198-
},options);
198+
...options
199+
};
199200
if(!options.benchmarker){
200201
callback(newError('Could not locate required http benchmarker. See '+
201202
`${requirementsURL} for further instructions.`));
@@ -212,6 +213,7 @@ exports.run = function(options, callback) {
212213
'is not installed'));
213214
return;
214215
}
216+
process.env.duration=process.env.duration||options.duration||5;
215217

216218
constbenchmarker_start=process.hrtime();
217219

@@ -220,7 +222,8 @@ exports.run = function(options, callback) {
220222
child.stderr.pipe(process.stderr);
221223

222224
letstdout='';
223-
child.stdout.on('data',(chunk)=>stdout+=chunk.toString());
225+
child.stdout.setEncoding('utf8');
226+
child.stdout.on('data',(chunk)=>stdout+=chunk);
224227

225228
child.once('close',(code)=>{
226229
constelapsed=process.hrtime(benchmarker_start);

‎benchmark/_test-double-benchmarker.js‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ if (!['http', 'http2'].includes(myModule)) {
77

88
consthttp=require(myModule);
99

10-
constduration=process.env.duration||0;
10+
constduration=+process.env.duration;
1111
consturl=process.env.test_url;
1212

1313
conststart=process.hrtime();
@@ -18,13 +18,15 @@ function request(res, client) {
1818
res.on('error',()=>{});
1919
res.on('end',()=>{
2020
throughput++;
21-
constdiff=process.hrtime(start);
22-
if(duration>0&&diff[0]<duration){
21+
const[sec,nanosec]=process.hrtime(start);
22+
constms=sec*1000+nanosec/1e6;
23+
if(ms<duration*1000){
2324
run();
2425
}else{
2526
console.log(JSON.stringify({ throughput }));
2627
if(client){
2728
client.destroy();
29+
process.exit(0);
2830
}
2931
}
3032
});
@@ -33,7 +35,7 @@ function request(res, client) {
3335
functionrun(){
3436
if(http.get){// HTTP
3537
http.get(url,request);
36-
}else{// HTTP/2
38+
}else{// HTTP/2
3739
constclient=http.connect(url);
3840
client.on('error',(e)=>{throwe;});
3941
request(client.request(),client);

‎benchmark/async_hooks/http-server.js‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ const common = require('../common.js');
33

44
constbench=common.createBenchmark(main,{
55
asyncHooks: ['init','before','after','all','disabled','none'],
6-
connections: [50,500]
6+
connections: [50,500],
7+
duration: 5
78
});
89

9-
functionmain({ asyncHooks, connections }){
10+
functionmain({ asyncHooks, connections, duration}){
1011
if(asyncHooks!=='none'){
1112
lethooks={
1213
init(){},
@@ -33,6 +34,7 @@ function main({ asyncHooks, connections }) {
3334
bench.http({
3435
connections,
3536
path,
37+
duration
3638
},()=>{
3739
server.close();
3840
});

‎benchmark/buffers/buffer-base64-encode.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ const common = require('../common.js');
2525
constbench=common.createBenchmark(main,{
2626
len: [64*1024*1024],
2727
n: [32]
28+
},{
29+
test: {len: 256}
2830
});
2931

3032
functionmain({ n, len }){

‎benchmark/buffers/buffer-swap.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ const bench = common.createBenchmark(main, {
77
method: ['swap16','swap32','swap64'/* , 'htons', 'htonl', 'htonll' */],
88
len: [64,256,768,1024,2056,8192],
99
n: [1e6]
10+
},{
11+
test: {len: 16}
1012
});
1113

1214
// The htons and htonl methods below are used to benchmark the

0 commit comments

Comments
 (0)