Skip to content

Commit 3eb61b0

Browse files
jasnelladdaleax
authored andcommitted
http2: add tests and benchmarks
Backport-PR-URL: #14813 Backport-Reviewed-By: Anna Henningsen <[email protected]> Backport-Reviewed-By: Timothy Gu <[email protected]> PR-URL: #14239 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent 9623ee0 commit 3eb61b0

File tree

95 files changed

+5327
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+5327
-2
lines changed

benchmark/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ directory, see [the guide on benchmarks](../doc/guides/writing-and-running-bench
9797
Benchmarks for the <code>http</code> subsystem.
9898
</td>
9999
</tr>
100+
<tr>
101+
<td>http2</td>
102+
<td>
103+
Benchmarks for the <code>http2</code> subsystem.
104+
</td>
105+
</tr>
100106
<tr>
101107
<td>misc</td>
102108
<td>

benchmark/_http-benchmarkers.js

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,63 @@ class TestDoubleBenchmarker {
111111
}
112112
}
113113

114+
/**
115+
* HTTP/2 Benchmarker
116+
*/
117+
class H2LoadBenchmarker {
118+
constructor() {
119+
this.name = 'h2load';
120+
this.executable = 'h2load';
121+
const result = child_process.spawnSync(this.executable, ['-h']);
122+
this.present = !(result.error && result.error.code === 'ENOENT');
123+
}
124+
125+
create(options) {
126+
const args = [];
127+
if (typeof options.requests === 'number')
128+
args.push('-n', options.requests);
129+
if (typeof options.clients === 'number')
130+
args.push('-c', options.clients);
131+
if (typeof options.threads === 'number')
132+
args.push('-t', options.threads);
133+
if (typeof options.maxConcurrentStreams === 'number')
134+
args.push('-m', options.maxConcurrentStreams);
135+
if (typeof options.initialWindowSize === 'number')
136+
args.push('-w', options.initialWindowSize);
137+
if (typeof options.sessionInitialWindowSize === 'number')
138+
args.push('-W', options.sessionInitialWindowSize);
139+
if (typeof options.rate === 'number')
140+
args.push('-r', options.rate);
141+
if (typeof options.ratePeriod === 'number')
142+
args.push(`--rate-period=${options.ratePeriod}`);
143+
if (typeof options.duration === 'number')
144+
args.push('-T', options.duration);
145+
if (typeof options.timeout === 'number')
146+
args.push('-N', options.timeout);
147+
if (typeof options.headerTableSize === 'number')
148+
args.push(`--header-table-size=${options.headerTableSize}`);
149+
if (typeof options.encoderHeaderTableSize === 'number') {
150+
args.push(
151+
`--encoder-header-table-size=${options.encoderHeaderTableSize}`);
152+
}
153+
const scheme = options.scheme || 'http';
154+
const host = options.host || '127.0.0.1';
155+
args.push(`${scheme}://${host}:${options.port}${options.path}`);
156+
const child = child_process.spawn(this.executable, args);
157+
return child;
158+
}
159+
160+
processResults(output) {
161+
const rex = /(\d+(?:\.\d+)) req\/s/;
162+
return rex.exec(output)[1];
163+
}
164+
}
165+
114166
const http_benchmarkers = [
115167
new WrkBenchmarker(),
116168
new AutocannonBenchmarker(),
117-
new TestDoubleBenchmarker()
169+
new TestDoubleBenchmarker(),
170+
new H2LoadBenchmarker()
118171
];
119172

120173
const benchmarkers = {};

benchmark/http2/respond-with-fd.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict';
2+
3+
const common = require('../common.js');
4+
const PORT = common.PORT;
5+
const path = require('path');
6+
const fs = require('fs');
7+
8+
const file = path.join(path.resolve(__dirname, '../fixtures'), 'alice.html');
9+
10+
var bench = common.createBenchmark(main, {
11+
requests: [100, 1000, 10000, 100000, 1000000],
12+
streams: [100, 200, 1000],
13+
clients: [1, 2]
14+
}, { flags: ['--expose-http2', '--no-warnings'] });
15+
16+
function main(conf) {
17+
18+
fs.open(file, 'r', (err, fd) => {
19+
if (err)
20+
throw err;
21+
22+
const n = +conf.requests;
23+
const m = +conf.streams;
24+
const c = +conf.clients;
25+
const http2 = require('http2');
26+
const server = http2.createServer();
27+
server.on('stream', (stream) => {
28+
stream.respondWithFD(fd);
29+
stream.on('error', (err) => {});
30+
});
31+
server.listen(PORT, () => {
32+
bench.http({
33+
path: '/',
34+
requests: n,
35+
maxConcurrentStreams: m,
36+
clients: c,
37+
threads: c
38+
}, () => server.close());
39+
});
40+
41+
});
42+
43+
}

benchmark/http2/simple.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
'use strict';
2+
3+
const common = require('../common.js');
4+
const PORT = common.PORT;
5+
6+
const path = require('path');
7+
const fs = require('fs');
8+
9+
const file = path.join(path.resolve(__dirname, '../fixtures'), 'alice.html');
10+
11+
var bench = common.createBenchmark(main, {
12+
requests: [100, 1000, 10000, 100000],
13+
streams: [100, 200, 1000],
14+
clients: [1, 2]
15+
}, { flags: ['--expose-http2', '--no-warnings'] });
16+
17+
function main(conf) {
18+
const n = +conf.requests;
19+
const m = +conf.streams;
20+
const c = +conf.clients;
21+
const http2 = require('http2');
22+
const server = http2.createServer();
23+
server.on('stream', (stream) => {
24+
const out = fs.createReadStream(file);
25+
stream.respond();
26+
out.pipe(stream);
27+
stream.on('error', (err) => {});
28+
});
29+
server.listen(PORT, () => {
30+
bench.http({
31+
path: '/',
32+
requests: n,
33+
maxConcurrentStreams: m,
34+
clients: c,
35+
threads: c
36+
}, () => { server.close(); });
37+
});
38+
}

test/common/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,3 +816,12 @@ exports.hijackStdout = hijackStdWritable.bind(null, 'stdout');
816816
exports.hijackStderr = hijackStdWritable.bind(null, 'stderr');
817817
exports.restoreStdout = restoreWritable.bind(null, 'stdout');
818818
exports.restoreStderr = restoreWritable.bind(null, 'stderr');
819+
820+
let fd = 2;
821+
exports.firstInvalidFD = function firstInvalidFD() {
822+
// Get first known bad file descriptor.
823+
try {
824+
while (fs.fstatSync(++fd));
825+
} catch (e) {}
826+
return fd;
827+
};

test/parallel/test-async-wrap-getasyncid.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ const providers = Object.assign({}, process.binding('async_wrap').Providers);
1919
process.removeAllListeners('uncaughtException');
2020
hooks.disable();
2121
delete providers.NONE; // Should never be used.
22+
23+
// TODO(jasnell): Test for these
24+
delete providers.HTTP2SESSION;
25+
delete providers.HTTP2SESSIONSHUTDOWNWRAP;
26+
2227
const obj_keys = Object.keys(providers);
2328
if (obj_keys.length > 0)
2429
process._rawDebug(obj_keys);

test/parallel/test-dgram-bind-default-address.js

100755100644
File mode changed.

0 commit comments

Comments
 (0)