Skip to content

Commit a80f4bb

Browse files
committed
test_runner: replace process.execArgv with getOptionsAsFlagsFromBinding
1 parent 22466e7 commit a80f4bb

File tree

6 files changed

+160
-14
lines changed

6 files changed

+160
-14
lines changed

lib/internal/test_runner/runner.js

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const { spawn } = require('child_process');
3535
const { finished } = require('internal/streams/end-of-stream');
3636
const { resolve, sep, isAbsolute } = require('path');
3737
const { DefaultDeserializer, DefaultSerializer } = require('v8');
38-
const { getOptionValue } = require('internal/options');
38+
const { getOptionValue, getOptionsAsFlagsFromBinding } = require('internal/options');
3939
const { Interface } = require('internal/readline/interface');
4040
const { deserializeError } = require('internal/error_serdes');
4141
const { Buffer } = require('buffer');
@@ -150,38 +150,39 @@ function getRunArgs(path, { forceExit,
150150
execArgv,
151151
root: { timeout },
152152
cwd }) {
153-
const argv = ArrayPrototypeFilter(process.execArgv, filterExecArgv);
153+
const processNodeOptions = getOptionsAsFlagsFromBinding();
154+
const runArgs = ArrayPrototypeFilter(processNodeOptions, filterExecArgv);
154155
if (forceExit === true) {
155-
ArrayPrototypePush(argv, '--test-force-exit');
156+
ArrayPrototypePush(runArgs, '--test-force-exit');
156157
}
157158
if (isUsingInspector()) {
158-
ArrayPrototypePush(argv, `--inspect-port=${getInspectPort(inspectPort)}`);
159+
ArrayPrototypePush(runArgs, `--inspect-port=${getInspectPort(inspectPort)}`);
159160
}
160161
if (testNamePatterns != null) {
161-
ArrayPrototypeForEach(testNamePatterns, (pattern) => ArrayPrototypePush(argv, `--test-name-pattern=${pattern}`));
162+
ArrayPrototypeForEach(testNamePatterns, (pattern) => ArrayPrototypePush(runArgs, `--test-name-pattern=${pattern}`));
162163
}
163164
if (testSkipPatterns != null) {
164-
ArrayPrototypeForEach(testSkipPatterns, (pattern) => ArrayPrototypePush(argv, `--test-skip-pattern=${pattern}`));
165+
ArrayPrototypeForEach(testSkipPatterns, (pattern) => ArrayPrototypePush(runArgs, `--test-skip-pattern=${pattern}`));
165166
}
166167
if (only === true) {
167-
ArrayPrototypePush(argv, '--test-only');
168+
ArrayPrototypePush(runArgs, '--test-only');
168169
}
169170
if (timeout != null) {
170-
ArrayPrototypePush(argv, `--test-timeout=${timeout}`);
171+
ArrayPrototypePush(runArgs, `--test-timeout=${timeout}`);
171172
}
172173

173-
ArrayPrototypePushApply(argv, execArgv);
174+
ArrayPrototypePushApply(runArgs, execArgv);
174175

175176
if (path === kIsolatedProcessName) {
176-
ArrayPrototypePush(argv, '--test');
177-
ArrayPrototypePushApply(argv, ArrayPrototypeSlice(process.argv, 1));
177+
ArrayPrototypePush(runArgs, '--test');
178+
ArrayPrototypePushApply(runArgs, ArrayPrototypeSlice(process.argv, 1));
178179
} else {
179-
ArrayPrototypePush(argv, path);
180+
ArrayPrototypePush(runArgs, path);
180181
}
181182

182-
ArrayPrototypePushApply(argv, suppliedArgs);
183+
ArrayPrototypePushApply(runArgs, suppliedArgs);
183184

184-
return argv;
185+
return runArgs;
185186
}
186187

187188
const serializer = new DefaultSerializer();

test/fixtures/test-runner/flag-propagation/.env

Whitespace-only changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"nodeOptions": {
3+
"max-http-header-size": 10
4+
}
5+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { run } from 'node:test';
2+
import { tap } from 'node:test/reporters';
3+
import { parseArgs } from 'node:util';
4+
5+
const options = {
6+
flag: {
7+
type: 'string',
8+
default: '',
9+
},
10+
expected: {
11+
type: 'string',
12+
default: '',
13+
},
14+
description: {
15+
type: 'string',
16+
default: 'flag propagation test',
17+
},
18+
};
19+
20+
const { values } = parseArgs({ args: process.argv.slice(2), options });
21+
22+
const argv = [
23+
`--flag=${values.flag}`,
24+
`--expected=${values.expected}`,
25+
`--description="${values.description}"`,
26+
].filter(Boolean);
27+
28+
run({
29+
files: ['./test.mjs'],
30+
cwd: process.cwd(),
31+
argv,
32+
isolation: 'process',
33+
}).compose(tap).pipe(process.stdout);
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { test } from 'node:test';
2+
import { strictEqual } from 'node:assert';
3+
import internal from 'internal/options';
4+
import { parseArgs } from 'node:util';
5+
6+
const options = {
7+
flag: {
8+
type: 'string',
9+
default: '',
10+
},
11+
expected: {
12+
type: 'string',
13+
default: '',
14+
},
15+
description: {
16+
type: 'string',
17+
default: 'flag propagation test',
18+
},
19+
};
20+
21+
22+
const { values } = parseArgs({ args: process.argv.slice(2), options });
23+
24+
const { flag, expected, description } = values;
25+
26+
test(description, () => {
27+
const optionValue = internal.getOptionValue(flag);
28+
console.error(`testing flag: ${flag}, found value: ${optionValue}, expected: ${expected}`);
29+
30+
const isNumber = !isNaN(Number(expected));
31+
const booleanValue = expected === 'true' || expected === 'false';
32+
if (booleanValue) {
33+
strictEqual(optionValue, expected === 'true');
34+
return;
35+
} else if (isNumber) {
36+
strictEqual(Number(optionValue), Number(expected));
37+
} else{
38+
strictEqual(optionValue, expected);
39+
}
40+
});
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
'use strict';
2+
3+
require('../common');
4+
const fixtures = require('../common/fixtures.js');
5+
const assert = require('assert');
6+
const { spawnSync } = require('child_process');
7+
const { describe, it } = require('node:test');
8+
const path = require('path');
9+
10+
// Test flag propagation to child test processes
11+
// This validates that certain flags are/aren't propagated to child test processes
12+
// based on the specification in the Node.js documentation
13+
describe('test runner flag propagation', () => {
14+
const flagPropagationTests = [
15+
['--experimental-config-file', 'node.config.json', ''],
16+
['--experimental-default-config-file', '', false],
17+
['--env-file', '.env', '.env'],
18+
['--env-file-if-exists', '.env', '.env'],
19+
['--test-concurrency', '2', '2'],
20+
// ['--test-force-exit', '', true], // <-- this test fails as is forces exit
21+
// ['--test-only', '', true], // <-- this needs to be investigated
22+
['--test-timeout', '5000', '5000'],
23+
['--test-coverage-branches', '100', '100'],
24+
['--test-coverage-functions', '100', '100'],
25+
['--test-coverage-lines', '100', '100'],
26+
// ['--test-coverage-exclude', 'test/**', 'test/**'],
27+
// ['--test-coverage-include', 'src/**', 'src/**'],
28+
['--test-update-snapshots', '', true],
29+
];
30+
31+
// Path to the static fixture
32+
const fixtureDir = fixtures.path('test-runner', 'flag-propagation');
33+
const runner = path.join(fixtureDir, 'runner.mjs');
34+
35+
for (const [flagName, testValue, expectedValue] of flagPropagationTests) {
36+
const testDescription = `should propagate ${flagName} to child tests as expected`;
37+
38+
it(testDescription, () => {
39+
const args = [
40+
'--test-reporter=tap',
41+
'--no-warnings',
42+
'--expose-internals',
43+
// We need to pass the flag that will be propagated to the child test
44+
testValue ? `${flagName}=${testValue}` : flagName,
45+
// Use the runner fixture
46+
runner,
47+
// Pass parameters to the fixture
48+
`--flag=${flagName}`,
49+
`--expected=${expectedValue}`,
50+
`--description="${testDescription}"`,
51+
].filter(Boolean);
52+
53+
const child = spawnSync(
54+
process.execPath,
55+
args,
56+
{
57+
cwd: fixtureDir,
58+
},
59+
);
60+
61+
assert.strictEqual(child.status, 0, `Flag propagation test failed for ${flagName}.`);
62+
const stdout = child.stdout.toString();
63+
assert.match(stdout, /tests 1/, `Test should execute for ${flagName}`);
64+
assert.match(stdout, /pass 1/, `Test should pass for ${flagName} propagation check`);
65+
});
66+
}
67+
});

0 commit comments

Comments
 (0)