Skip to content

Commit 5ee6ecd

Browse files
richardlautargos
authored andcommitted
doc,test: test documentation consistency for NODE_OPTIONS
Add a test that checks that the documented allowed options for the `NODE_OPTIONS` environment variable are consistent with the actually allowed options. PR-URL: #28179 Reviewed-By: Rich Trott <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
1 parent dba5983 commit 5ee6ecd

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

doc/api/cli.md

+4
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,7 @@ In case an option value happens to contain a space (for example a path listed in
980980
```
981981

982982
Node.js options that are allowed are:
983+
<!-- node-options-node start -->
983984
- `--enable-fips`
984985
- `--es-module-specifier-resolution`
985986
- `--experimental-modules`
@@ -1040,15 +1041,18 @@ Node.js options that are allowed are:
10401041
- `--use-openssl-ca`
10411042
- `--v8-pool-size`
10421043
- `--zero-fill-buffers`
1044+
<!-- node-options-node end -->
10431045

10441046
V8 options that are allowed are:
1047+
<!-- node-options-v8 start -->
10451048
- `--abort-on-uncaught-exception`
10461049
- `--max-old-space-size`
10471050
- `--perf-basic-prof-only-functions`
10481051
- `--perf-basic-prof`
10491052
- `--perf-prof-unwinding-info`
10501053
- `--perf-prof`
10511054
- `--stack-trace-limit`
1055+
<!-- node-options-v8 end -->
10521056

10531057
### `NODE_PATH=path[:…]`
10541058
<!-- YAML
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
5+
const assert = require('assert');
6+
const fs = require('fs');
7+
const path = require('path');
8+
9+
const rootDir = path.resolve(__dirname, '..', '..');
10+
const cliMd = path.join(rootDir, 'doc', 'api', 'cli.md');
11+
const cliText = fs.readFileSync(cliMd, { encoding: 'utf8' });
12+
13+
const parseSection = (text, startMarker, endMarker) => {
14+
const regExp = new RegExp(`${startMarker}\r?\n([^]*)\r?\n${endMarker}`);
15+
const match = text.match(regExp);
16+
assert(match,
17+
`Unable to locate text between '${startMarker}' and '${endMarker}'.`);
18+
return match[1].split(/\r?\n/);
19+
};
20+
21+
const nodeOptionsLines = parseSection(cliText,
22+
'<!-- node-options-node start -->',
23+
'<!-- node-options-node end -->');
24+
const v8OptionsLines = parseSection(cliText,
25+
'<!-- node-options-v8 start -->',
26+
'<!-- node-options-v8 end -->');
27+
// Check the options are documented in alphabetical order.
28+
assert.deepStrictEqual(nodeOptionsLines, [...nodeOptionsLines].sort());
29+
assert.deepStrictEqual(v8OptionsLines, [...v8OptionsLines].sort());
30+
31+
const documented = new Set();
32+
for (const line of [...nodeOptionsLines, ...v8OptionsLines]) {
33+
for (const match of line.matchAll(/`(-[^`]+)`/g)) {
34+
const option = match[1];
35+
assert(!documented.has(option),
36+
`Option '${option}' was documented more than once as an ` +
37+
`allowed option for NODE_OPTIONS in ${cliMd}.`);
38+
documented.add(option);
39+
}
40+
}
41+
42+
// Filter out options that are conditionally present.
43+
const conditionalOpts = [
44+
{ include: common.hasCrypto,
45+
filter: (opt) => {
46+
return ['--openssl-config', '--tls-cipher-list', '--use-bundled-ca',
47+
'--use-openssl-ca' ].includes(opt);
48+
} },
49+
{ include: common.hasFipsCrypto,
50+
filter: (opt) => opt.includes('-fips') },
51+
{ include: common.hasIntl,
52+
filter: (opt) => opt === '--icu-data-dir' },
53+
{ include: process.features.inspector,
54+
filter: (opt) => opt.startsWith('--inspect') || opt === '--debug-port' },
55+
{ include: process.config.variables.node_report,
56+
filter: (opt) => opt.includes('-report') },
57+
];
58+
documented.forEach((opt) => {
59+
conditionalOpts.forEach(({ include, filter }) => {
60+
if (!include && filter(opt)) {
61+
documented.delete(opt);
62+
}
63+
});
64+
});
65+
66+
const difference = (setA, setB) => {
67+
return new Set([...setA].filter((x) => !setB.has(x)));
68+
};
69+
70+
const overdocumented = difference(documented,
71+
process.allowedNodeEnvironmentFlags);
72+
assert.strictEqual(overdocumented.size, 0,
73+
'The following options are documented as allowed in ' +
74+
`NODE_OPTIONS in ${cliMd}: ` +
75+
`${[...overdocumented].join(' ')} ` +
76+
'but are not in process.allowedNodeEnvironmentFlags');
77+
const undocumented = difference(process.allowedNodeEnvironmentFlags,
78+
documented);
79+
// Remove intentionally undocumented options.
80+
assert(undocumented.delete('--debug-arraybuffer-allocations'));
81+
assert(undocumented.delete('--experimental-worker'));
82+
assert.strictEqual(undocumented.size, 0,
83+
'The following options are not documented as allowed in ' +
84+
`NODE_OPTIONS in ${cliMd}: ${[...undocumented].join(' ')}`);

0 commit comments

Comments
 (0)