Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 7aedda9

Browse filesBrowse files
puzpuzpuzdanielleadams
authored andcommitted
benchmark: add simple https benchmark
Adds a simple benchmark for https server based on the http simple benchmark. Updates benchmarker integration for autocannon and wrk, so that they support https scheme. Also adds a new HTTPS section and improves HTTP/2 section in the benchmark guide. PR-URL: #36612 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 822ac48 commit 7aedda9
Copy full SHA for 7aedda9

File tree

Expand file treeCollapse file tree

5 files changed

+132
-9
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

5 files changed

+132
-9
lines changed
Open diff view settings
Collapse file

‎benchmark/_http-benchmarkers.js‎

Copy file name to clipboardExpand all lines: benchmark/_http-benchmarkers.js
+9-5Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ class AutocannonBenchmarker {
2929
for (const field in options.headers) {
3030
args.push('-H', `${field}=${options.headers[field]}`);
3131
}
32-
args.push(`http://127.0.0.1:${options.port}${options.path}`);
32+
const scheme = options.scheme || 'http';
33+
args.push(`${scheme}://127.0.0.1:${options.port}${options.path}`);
3334
const child = child_process.spawn(this.executable, args);
3435
return child;
3536
}
@@ -60,11 +61,12 @@ class WrkBenchmarker {
6061
const duration = typeof options.duration === 'number' ?
6162
Math.max(options.duration, 1) :
6263
options.duration;
64+
const scheme = options.scheme || 'http';
6365
const args = [
6466
'-d', duration,
6567
'-c', options.connections,
6668
'-t', Math.min(options.connections, require('os').cpus().length || 8),
67-
`http://127.0.0.1:${options.port}${options.path}`,
69+
`${scheme}://127.0.0.1:${options.port}${options.path}`,
6870
];
6971
for (const field in options.headers) {
7072
args.push('-H', `${field}: ${options.headers[field]}`);
@@ -90,8 +92,8 @@ class WrkBenchmarker {
9092
*/
9193
class TestDoubleBenchmarker {
9294
constructor(type) {
93-
// `type` is the type of benchmarker. Possible values are 'http' and
94-
// 'http2'.
95+
// `type` is the type of benchmarker. Possible values are 'http', 'https',
96+
// and 'http2'.
9597
this.name = `test-double-${type}`;
9698
this.executable = path.resolve(__dirname, '_test-double-benchmarker.js');
9799
this.present = fs.existsSync(this.executable);
@@ -101,8 +103,9 @@ class TestDoubleBenchmarker {
101103
create(options) {
102104
process.env.duration = process.env.duration || options.duration || 5;
103105

106+
const scheme = options.scheme || 'http';
104107
const env = {
105-
test_url: `http://127.0.0.1:${options.port}${options.path}`,
108+
test_url: `${scheme}://127.0.0.1:${options.port}${options.path}`,
106109
...process.env
107110
};
108111

@@ -179,6 +182,7 @@ const http_benchmarkers = [
179182
new WrkBenchmarker(),
180183
new AutocannonBenchmarker(),
181184
new TestDoubleBenchmarker('http'),
185+
new TestDoubleBenchmarker('https'),
182186
new TestDoubleBenchmarker('http2'),
183187
new H2LoadBenchmarker(),
184188
];
Collapse file

‎benchmark/_test-double-benchmarker.js‎

Copy file name to clipboardExpand all lines: benchmark/_test-double-benchmarker.js
+12-3Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
'use strict';
22

33
const myModule = process.argv[2];
4-
if (!['http', 'http2'].includes(myModule)) {
4+
if (!['http', 'https', 'http2'].includes(myModule)) {
55
throw new Error(`Invalid module for benchmark test double: ${myModule}`);
66
}
77

8+
let options;
9+
if (myModule === 'https') {
10+
options = { rejectUnauthorized: false };
11+
}
12+
813
const http = require(myModule);
914

1015
const duration = +process.env.duration;
@@ -33,8 +38,12 @@ function request(res, client) {
3338
}
3439

3540
function run() {
36-
if (http.get) { // HTTP
37-
http.get(url, request);
41+
if (http.get) { // HTTP or HTTPS
42+
if (options) {
43+
http.get(url, options, request);
44+
} else {
45+
http.get(url, request);
46+
}
3847
} else { // HTTP/2
3948
const client = http.connect(url);
4049
client.on('error', (e) => { throw e; });
Collapse file
+72Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'use strict';
2+
3+
const fixtures = require('../../test/common/fixtures');
4+
const https = require('https');
5+
6+
const options = {
7+
key: fixtures.readKey('rsa_private.pem'),
8+
cert: fixtures.readKey('rsa_cert.crt')
9+
};
10+
11+
const storedBytes = Object.create(null);
12+
const storedBuffer = Object.create(null);
13+
14+
module.exports = https.createServer(options, (req, res) => {
15+
// URL format: /<type>/<length>/<chunks>/chunkedEnc
16+
const params = req.url.split('/');
17+
const command = params[1];
18+
let body = '';
19+
const arg = params[2];
20+
const n_chunks = parseInt(params[3], 10);
21+
const chunkedEnc = params.length >= 5 && params[4] === '0' ? false : true;
22+
let status = 200;
23+
24+
let n, i;
25+
if (command === 'bytes') {
26+
n = ~~arg;
27+
if (n <= 0)
28+
throw new Error('bytes called with n <= 0');
29+
if (storedBytes[n] === undefined) {
30+
storedBytes[n] = 'C'.repeat(n);
31+
}
32+
body = storedBytes[n];
33+
} else if (command === 'buffer') {
34+
n = ~~arg;
35+
if (n <= 0)
36+
throw new Error('buffer called with n <= 0');
37+
if (storedBuffer[n] === undefined) {
38+
storedBuffer[n] = Buffer.allocUnsafe(n);
39+
for (i = 0; i < n; i++) {
40+
storedBuffer[n][i] = 'C'.charCodeAt(0);
41+
}
42+
}
43+
body = storedBuffer[n];
44+
} else {
45+
status = 404;
46+
body = 'not found\n';
47+
}
48+
49+
// example: https://localhost:port/bytes/512/4
50+
// sends a 512 byte body in 4 chunks of 128 bytes
51+
const len = body.length;
52+
if (chunkedEnc) {
53+
res.writeHead(status, {
54+
'Content-Type': 'text/plain',
55+
'Transfer-Encoding': 'chunked'
56+
});
57+
} else {
58+
res.writeHead(status, {
59+
'Content-Type': 'text/plain',
60+
'Content-Length': len.toString()
61+
});
62+
}
63+
// send body in chunks
64+
if (n_chunks > 1) {
65+
const step = Math.floor(len / n_chunks) || 1;
66+
for (i = 0, n = (n_chunks - 1); i < n; ++i)
67+
res.write(body.slice(i * step, i * step + step));
68+
res.end(body.slice((n_chunks - 1) * step));
69+
} else {
70+
res.end(body);
71+
}
72+
});
Collapse file

‎benchmark/https/simple.js‎

Copy file name to clipboard
+29Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
4+
const bench = common.createBenchmark(main, {
5+
type: ['bytes', 'buffer'],
6+
len: [4, 1024, 102400],
7+
chunks: [1, 4],
8+
c: [50, 500],
9+
chunkedEnc: [1, 0],
10+
benchmarker: ['test-double-https'],
11+
duration: 5
12+
});
13+
14+
function main({ type, len, chunks, c, chunkedEnc, duration }) {
15+
const server = require('../fixtures/simple-https-server.js')
16+
.listen(common.PORT)
17+
.on('listening', () => {
18+
const path = `/${type}/${len}/${chunks}/${chunkedEnc}`;
19+
20+
bench.http({
21+
path,
22+
connections: c,
23+
scheme: 'https',
24+
duration
25+
}, () => {
26+
server.close();
27+
});
28+
});
29+
}
Collapse file

‎doc/guides/writing-and-running-benchmarks.md‎

Copy file name to clipboardExpand all lines: doc/guides/writing-and-running-benchmarks.md
+10-1Lines changed: 10 additions & 1 deletion
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
* [Prerequisites](#prerequisites)
66
* [HTTP Benchmark Requirements](#http-benchmark-requirements)
7+
* [HTTPS Benchmark Requirements](#https-benchmark-requirements)
8+
* [HTTP/2 Benchmark Requirements](#http2-benchmark-requirements)
79
* [Benchmark Analysis Requirements](#benchmark-analysis-requirements)
810
* [Running benchmarks](#running-benchmarks)
911
* [Running individual benchmarks](#running-individual-benchmarks)
@@ -43,13 +45,20 @@ benchmarker to be used should be specified by providing it as an argument:
4345

4446
`node benchmark/http/simple.js benchmarker=autocannon`
4547

48+
#### HTTPS Benchmark Requirements
49+
50+
To run the `https` benchmarks, one of `autocannon` or `wrk` benchmarkers must
51+
be used.
52+
53+
`node benchmark/https/simple.js benchmarker=autocannon`
54+
4655
#### HTTP/2 Benchmark Requirements
4756

4857
To run the `http2` benchmarks, the `h2load` benchmarker must be used. The
4958
`h2load` tool is a component of the `nghttp2` project and may be installed
5059
from [nghttp2.org][] or built from source.
5160

52-
`node benchmark/http2/simple.js benchmarker=autocannon`
61+
`node benchmark/http2/simple.js benchmarker=h2load`
5362

5463
### Benchmark Analysis Requirements
5564

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.