Skip to content

Allow Node arguments to be configured #2272

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
Jan 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
103a243
feat: node-arguments for passing arguments to child processes node in…
Oct 17, 2019
0cc0abd
Remove unnecessary promise-wrapping
novemberborn Nov 10, 2019
3f6633c
Destructuring
novemberborn Nov 10, 2019
ae70f22
Tweak docs
novemberborn Nov 10, 2019
420c9b7
node-arguments: extend cli doc with example
Nov 24, 2019
8e51406
node-arguments simplify processing
Nov 24, 2019
d4acaeb
fixes
Nov 24, 2019
adfc212
fix(node-arguments): default value for config from file value
Nov 24, 2019
26c4448
fix: node-arguments test fix
Nov 24, 2019
5b99832
Clarify CLI use of --node-arguments
novemberborn Dec 1, 2019
9f00c05
Merge branch 'master' into node-arguments
novemberborn Dec 1, 2019
5cf8dd7
fix normalize arguments
Dec 7, 2019
28a2c06
fix all other minimist usages
Dec 7, 2019
1ae69c4
fix semicolon
Dec 7, 2019
c1a99d4
fix broken tests?
Dec 7, 2019
8e649b9
fix configuration for yargs parsing
Dec 7, 2019
e00e80f
memoize parse args
Dec 7, 2019
03fca0a
fix lint
Dec 7, 2019
9fcdc7b
fix quotes/double quotes
Dec 7, 2019
ae3836b
fix lint
Dec 7, 2019
be272c7
move _parseProcessArgs to top
Dec 7, 2019
b5d2796
remove node-arguments default for cli
Dec 9, 2019
18b7074
Merge branch 'master' into node-arguments
novemberborn Jan 12, 2020
037cc33
Simplify implementation
novemberborn Jan 12, 2020
518c44d
update lockfile to master
Jan 14, 2020
7aad65a
remove redundant \\
Jan 14, 2020
0e21309
fix quotes
Jan 14, 2020
c40194a
stdout/stderr logging for node-arguments test
Jan 14, 2020
f01a038
fix format
Jan 14, 2020
438148c
add stdout/stderr logs to another test
Jan 14, 2020
f670481
fix node-arguments integration test on windows
Jan 14, 2020
7ec7f34
Merge branch 'master' into node-arguments
novemberborn Jan 18, 2020
40e7716
Parse using arrgv
novemberborn Jan 18, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions docs/05-command-line.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Options:
--fail-fast Stop after first test failure [boolean]
--match, -m Only run tests with matching title (can be repeated)
[string]
--node-arguments Additional Node.js arguments for launching worker
processes (specify as a single string) [string]
--serial, -s Run tests serially [boolean]
--tap, -t Generate TAP output [boolean]
--timeout, -T Set global timeout (milliseconds or human-readable,
Expand Down Expand Up @@ -178,3 +180,17 @@ $ npx ava --tap | npx tap-nyan
<img src="../media/tap-reporter.png" width="420">

Please note that the TAP reporter is unavailable when using [watch mode](./recipes/watch-mode.md).

## Node arguments

The `--node-arguments` argument may be used to specify additional arguments for launching worker processes. These are combined with the `nodeArguments` configuration and any arguments passed to the `node` binary when starting AVA.

**Only pass trusted values.**

Specify the arguments as a single string:

```console
npx ava --node-arguments="--throw-deprecation --zero-fill-buffers"
```

**Only pass trusted values.**
9 changes: 9 additions & 0 deletions docs/06-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ To ignore files, prefix the pattern with an `!` (exclamation mark).
"verbose": true,
"require": [
"./my-helper-module.js"
],
"nodeArguments": [
"--trace-deprecation",
"--napi-modules"
]
}
}
Expand All @@ -53,6 +57,7 @@ Arguments passed to the CLI will always take precedence over the CLI options con
- `extensions`: extensions of test files. Setting this overrides the default `["cjs", "mjs", "js"]` value, so make sure to include those extensions in the list
- `require`: extra modules to require before tests are run. Modules are required in the [worker processes](./01-writing-tests.md#process-isolation)
- `timeout`: Timeouts in AVA behave differently than in other test frameworks. AVA resets a timer after each test, forcing tests to quit if no new test results were received within the specified timeout. This can be used to handle stalled tests. See our [timeout documentation](./07-test-timeouts.md) for more options.
- `nodeArguments`: Configure Node.js arguments used to launch worker processes.

Note that providing files on the CLI overrides the `files` option.

Expand Down Expand Up @@ -219,4 +224,8 @@ export default {
};
```

## Node arguments

The `nodeArguments` configuration may be used to specify additional arguments for launching worker processes. These are combined with `--node-arguments` passed on the CLI and any arguments passed to the `node` binary when starting AVA.

[CLI]: ./05-command-line.md
2 changes: 1 addition & 1 deletion lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ class Api extends Emittery {
options.updateSnapshots = true;
}

const worker = fork(file, options, process.execArgv);
const worker = fork(file, options, apiOptions.nodeArguments);
runStatus.observeWorker(worker, file);

pendingWorkers.add(worker);
Expand Down
16 changes: 15 additions & 1 deletion lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ const FLAGS = {
description: 'Only run tests with matching title (can be repeated)',
type: 'string'
},
'node-arguments': {
coerce: coerceLastValue,
description: 'Additional Node.js arguments for launching worker processes (specify as a single string)',
type: 'string'
},
serial: {
alias: 's',
coerce: coerceLastValue,
Expand Down Expand Up @@ -161,7 +166,7 @@ exports.run = async () => { // eslint-disable-line complexity
combined.failFast = argv[flag];
} else if (flag === 'update-snapshots') {
combined.updateSnapshots = argv[flag];
} else {
} else if (flag !== 'node-arguments') {
combined[flag] = argv[flag];
}
}
Expand Down Expand Up @@ -254,6 +259,7 @@ exports.run = async () => { // eslint-disable-line complexity
const babelManager = require('./babel-manager');
const normalizeExtensions = require('./extensions');
const {normalizeGlobs, normalizePatterns} = require('./globs');
const normalizeNodeArguments = require('./node-arguments');
const validateEnvironmentVariables = require('./environment-variables');

let pkg;
Expand Down Expand Up @@ -303,6 +309,13 @@ exports.run = async () => { // eslint-disable-line complexity
exit(error.message);
}

let nodeArguments;
try {
nodeArguments = normalizeNodeArguments(conf.nodeArguments, argv['node-arguments']);
} catch (error) {
exit(error.message);
}

let parallelRuns = null;
if (isCi && ciParallelVars) {
const {index: currentIndex, total: totalRuns} = ciParallelVars;
Expand All @@ -328,6 +341,7 @@ exports.run = async () => { // eslint-disable-line complexity
moduleTypes,
environmentVariables,
match,
nodeArguments,
parallelRuns,
projectDir,
ranFromCli: true,
Expand Down
4 changes: 2 additions & 2 deletions lib/fork.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const AVA_PATH = path.resolve(__dirname, '..');

const workerPath = require.resolve('./worker/subprocess');

module.exports = (file, opts, execArgv) => {
module.exports = (file, opts, execArgv = process.execArgv) => {
let finished = false;

const emitter = new Emittery();
Expand All @@ -34,7 +34,7 @@ module.exports = (file, opts, execArgv) => {
cwd: opts.projectDir,
silent: true,
env: {NODE_ENV: 'test', ...process.env, ...opts.environmentVariables, AVA_PATH},
execArgv: execArgv || process.execArgv
execArgv
});

subprocess.stdout.on('data', chunk => {
Expand Down
17 changes: 17 additions & 0 deletions lib/node-arguments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';
const arrgv = require('arrgv');

function normalizeNodeArguments(fromConf = [], fromArgv = '') {
let parsedArgv = [];
if (fromArgv !== '') {
try {
parsedArgv = arrgv(fromArgv);
} catch {
throw new Error('Could not parse `--node-arguments` value. Make sure all strings are closed and backslashes are used correctly.');
}
}

return [...process.execArgv, ...fromConf, ...parsedArgv];
}

module.exports = normalizeNodeArguments;
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"dependencies": {
"@concordance/react": "^2.0.0",
"ansi-styles": "^4.2.1",
"arrgv": "^1.0.2",
"arrify": "^2.0.1",
"chalk": "^3.0.0",
"chokidar": "^3.3.1",
Expand Down
7 changes: 7 additions & 0 deletions test/fixture/node-arguments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const test = require('../..');

test('exec arguments includes --throw-deprecation and --zero-fill-buffers', t => {
t.plan(2);
t.truthy(process.execArgv.includes('--throw-deprecation'));
t.truthy(process.execArgv.includes('--zero-fill-buffers'));
});
8 changes: 8 additions & 0 deletions test/fixture/node-arguments/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"ava": {
"nodeArguments": [
"--require",
"./setup.js"
]
}
}
1 change: 1 addition & 0 deletions test/fixture/node-arguments/setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
global.SETUP_CALLED = true;
7 changes: 7 additions & 0 deletions test/fixture/node-arguments/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const test = require('../../..');

test('works', t => {
t.plan(2);
t.truthy(global.SETUP_CALLED, 'setup variable set');
t.truthy(process.execArgv.some(argv => argv.startsWith('--require')), 'require passed');
});
2 changes: 1 addition & 1 deletion test/helper/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function execCli(args, opts, cb) {
const processPromise = new Promise(resolve => {
// Spawning a child with piped IO means that the CLI will never see a TTY.
// Inserting a shim here allows us to fake a TTY.
child = childProcess.spawn(process.execPath, ['-r', ttySimulator, cliPath].concat(args), {
child = childProcess.spawn(process.execPath, ['--require', ttySimulator, cliPath].concat(args), {
cwd: dirname,
env: {CI: '1', ...env}, // Force CI to ensure the correct reporter is selected
// env,
Expand Down
24 changes: 24 additions & 0 deletions test/integration/node-arguments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict';
const {test} = require('tap');
const {execCli} = require('../helper/cli');

test('passes node arguments to workers', t => {
t.plan(1);
execCli(['--node-arguments="--throw-deprecation --zero-fill-buffers"', 'node-arguments.js'],
(err, stdout, stderr) => t.ifError(err, null, {stdout, stderr}));
});

test('reads node arguments from config', t => {
t.plan(1);
execCli(['test.js'], {
dirname: 'fixture/node-arguments'
}, (err, stdout, stderr) => t.ifError(err, null, {stdout, stderr}));
});

test('detects incomplete --node-arguments', t => {
t.plan(2);
execCli(['--node-arguments="--foo=\'bar"', 'node-arguments.js'], (err, stdout, stderr) => {
t.ok(err);
t.match(stderr, /Could not parse `--node-arguments` value. Make sure all strings are closed and backslashes are used correctly./);
});
});
12 changes: 12 additions & 0 deletions test/node-arguments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict';

const {test} = require('tap');
const normalizeNodeArguments = require('../lib/node-arguments');

test('combines arguments', async t => {
t.deepEqual(
await normalizeNodeArguments(['--require setup.js'], '--throw-deprecation --zero-fill-buffers'),
[...process.execArgv, '--require setup.js', '--throw-deprecation', '--zero-fill-buffers']
);
t.end();
});