mirror of
https://github.com/nodejs/node.git
synced 2025-05-02 18:44:40 +00:00
test: add escapePOSIXShell
util
PR-URL: https://github.com/nodejs/node/pull/55125 Reviewed-By: Jacob Smith <jacob@frende.me> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: LiviaMedeiros <livia@cirno.name> Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
This commit is contained in:
parent
858bce5698
commit
99e0d0d218
@ -27,11 +27,12 @@ if (common.isWindows)
|
|||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const exec = require('child_process').exec;
|
const exec = require('child_process').exec;
|
||||||
|
|
||||||
let cmdline = `ulimit -c 0; ${process.execPath}`;
|
const cmdline =
|
||||||
cmdline += ' --max-old-space-size=16 --max-semi-space-size=4';
|
common.escapePOSIXShell`ulimit -c 0; "${
|
||||||
cmdline += ' -e "a = []; for (i = 0; i < 1e9; i++) { a.push({}) }"';
|
process.execPath
|
||||||
|
}" --max-old-space-size=16 --max-semi-space-size=4 -e "a = []; for (i = 0; i < 1e9; i++) { a.push({}) }"`;
|
||||||
|
|
||||||
exec(cmdline, function(err, stdout, stderr) {
|
exec(...cmdline, common.mustCall((err, stdout, stderr) => {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
console.log(stdout);
|
console.log(stdout);
|
||||||
console.log(stderr);
|
console.log(stderr);
|
||||||
@ -39,4 +40,4 @@ exec(cmdline, function(err, stdout, stderr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(common.nodeProcessAborted(err.code, err.signal));
|
assert(common.nodeProcessAborted(err.code, err.signal));
|
||||||
});
|
}));
|
||||||
|
@ -62,12 +62,14 @@ assert.ok(!arg);
|
|||||||
let program = process.execPath;
|
let program = process.execPath;
|
||||||
let args = [
|
let args = [
|
||||||
'--abort-on-uncaught-exception', __filename, 'test_callback_abort' ];
|
'--abort-on-uncaught-exception', __filename, 'test_callback_abort' ];
|
||||||
const options = { encoding: 'utf8' };
|
let options = {};
|
||||||
if (!common.isWindows) {
|
if (!common.isWindows) {
|
||||||
program = `ulimit -c 0 && exec ${program} ${args.join(' ')}`;
|
[program, options] = common.escapePOSIXShell`ulimit -c 0 && exec "${program}" ${args[0]} "${args[1]}" ${args[2]}`;
|
||||||
args = [];
|
args = [];
|
||||||
options.shell = true;
|
options.shell = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.encoding = 'utf8';
|
||||||
const child = spawnSync(program, args, options);
|
const child = spawnSync(program, args, options);
|
||||||
if (common.isWindows) {
|
if (common.isWindows) {
|
||||||
assert.strictEqual(child.status, 134);
|
assert.strictEqual(child.status, 134);
|
||||||
|
@ -112,6 +112,33 @@ Creates a 10 MiB file of all null characters.
|
|||||||
|
|
||||||
Indicates if there is more than 1gb of total memory.
|
Indicates if there is more than 1gb of total memory.
|
||||||
|
|
||||||
|
### ``escapePOSIXShell`shell command` ``
|
||||||
|
|
||||||
|
Escapes values in a string template literal to pass them as env variable. On Windows, this function
|
||||||
|
does not escape anything (which is fine for most paths, as `"` is not a valid
|
||||||
|
char in a path on Windows), so for tests that must pass on Windows, you should
|
||||||
|
use it only to escape paths, inside double quotes.
|
||||||
|
This function is meant to be used for tagged template strings.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const { escapePOSIXShell } = require('../common');
|
||||||
|
const fixtures = require('../common/fixtures');
|
||||||
|
const { execSync } = require('node:child_process');
|
||||||
|
const origin = fixtures.path('origin');
|
||||||
|
const destination = fixtures.path('destination');
|
||||||
|
|
||||||
|
execSync(...escapePOSIXShell`cp "${origin}" "${destination}"`);
|
||||||
|
|
||||||
|
// When you need to specify specific options, and/or additional env variables:
|
||||||
|
const [cmd, opts] = escapePOSIXShell`cp "${origin}" "${destination}"`;
|
||||||
|
console.log(typeof cmd === 'string'); // true
|
||||||
|
console.log(opts === undefined || typeof opts.env === 'object'); // true
|
||||||
|
execSync(cmd, { ...opts, stdio: 'ignore' });
|
||||||
|
execSync(cmd, { stdio: 'ignore', env: { ...opts?.env, KEY: 'value' } });
|
||||||
|
```
|
||||||
|
|
||||||
|
When possible, avoid using a shell; that way, there's no need to escape values.
|
||||||
|
|
||||||
### `expectsError(validator[, exact])`
|
### `expectsError(validator[, exact])`
|
||||||
|
|
||||||
* `validator` [\<Object>][<Object>] | [\<RegExp>][<RegExp>] |
|
* `validator` [\<Object>][<Object>] | [\<RegExp>][<RegExp>] |
|
||||||
|
@ -249,15 +249,13 @@ const PIPE = (() => {
|
|||||||
// `$node --abort-on-uncaught-exception $file child`
|
// `$node --abort-on-uncaught-exception $file child`
|
||||||
// the process aborts.
|
// the process aborts.
|
||||||
function childShouldThrowAndAbort() {
|
function childShouldThrowAndAbort() {
|
||||||
let testCmd = '';
|
const escapedArgs = escapePOSIXShell`"${process.argv[0]}" --abort-on-uncaught-exception "${process.argv[1]}" child`;
|
||||||
if (!isWindows) {
|
if (!isWindows) {
|
||||||
// Do not create core files, as it can take a lot of disk space on
|
// Do not create core files, as it can take a lot of disk space on
|
||||||
// continuous testing and developers' machines
|
// continuous testing and developers' machines
|
||||||
testCmd += 'ulimit -c 0 && ';
|
escapedArgs[0] = 'ulimit -c 0 && ' + escapedArgs[0];
|
||||||
}
|
}
|
||||||
testCmd += `"${process.argv[0]}" --abort-on-uncaught-exception `;
|
const child = exec(...escapedArgs);
|
||||||
testCmd += `"${process.argv[1]}" child`;
|
|
||||||
const child = exec(testCmd);
|
|
||||||
child.on('exit', function onExit(exitCode, signal) {
|
child.on('exit', function onExit(exitCode, signal) {
|
||||||
const errMsg = 'Test should have aborted ' +
|
const errMsg = 'Test should have aborted ' +
|
||||||
`but instead exited with exit code ${exitCode}` +
|
`but instead exited with exit code ${exitCode}` +
|
||||||
@ -888,6 +886,32 @@ function spawnPromisified(...args) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape values in a string template literal. On Windows, this function
|
||||||
|
* does not escape anything (which is fine for paths, as `"` is not a valid char
|
||||||
|
* in a path on Windows), so you should use it only to escape paths – or other
|
||||||
|
* values on tests which are skipped on Windows.
|
||||||
|
* This function is meant to be used for tagged template strings.
|
||||||
|
* @returns {[string, object | undefined]} An array that can be passed as
|
||||||
|
* arguments to `exec` or `execSync`.
|
||||||
|
*/
|
||||||
|
function escapePOSIXShell(cmdParts, ...args) {
|
||||||
|
if (common.isWindows) {
|
||||||
|
// On Windows, paths cannot contain `"`, so we can return the string unchanged.
|
||||||
|
return [String.raw({ raw: cmdParts }, ...args)];
|
||||||
|
}
|
||||||
|
// On POSIX shells, we can pass values via the env, as there's a standard way for referencing a variable.
|
||||||
|
const env = { ...process.env };
|
||||||
|
let cmd = cmdParts[0];
|
||||||
|
for (let i = 0; i < args.length; i++) {
|
||||||
|
const envVarName = `ESCAPED_${i}`;
|
||||||
|
env[envVarName] = args[i];
|
||||||
|
cmd += '${' + envVarName + '}' + cmdParts[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [cmd, { env }];
|
||||||
|
};
|
||||||
|
|
||||||
function getPrintedStackTrace(stderr) {
|
function getPrintedStackTrace(stderr) {
|
||||||
const lines = stderr.split('\n');
|
const lines = stderr.split('\n');
|
||||||
|
|
||||||
@ -951,6 +975,7 @@ const common = {
|
|||||||
childShouldThrowAndAbort,
|
childShouldThrowAndAbort,
|
||||||
createZeroFilledFile,
|
createZeroFilledFile,
|
||||||
defaultAutoSelectFamilyAttemptTimeout,
|
defaultAutoSelectFamilyAttemptTimeout,
|
||||||
|
escapePOSIXShell,
|
||||||
expectsError,
|
expectsError,
|
||||||
expectRequiredModule,
|
expectRequiredModule,
|
||||||
expectWarning,
|
expectWarning,
|
||||||
|
@ -11,6 +11,7 @@ const {
|
|||||||
childShouldThrowAndAbort,
|
childShouldThrowAndAbort,
|
||||||
createZeroFilledFile,
|
createZeroFilledFile,
|
||||||
enoughTestMem,
|
enoughTestMem,
|
||||||
|
escapePOSIXShell,
|
||||||
expectsError,
|
expectsError,
|
||||||
expectWarning,
|
expectWarning,
|
||||||
getArrayBufferViews,
|
getArrayBufferViews,
|
||||||
@ -64,6 +65,7 @@ export {
|
|||||||
createRequire,
|
createRequire,
|
||||||
createZeroFilledFile,
|
createZeroFilledFile,
|
||||||
enoughTestMem,
|
enoughTestMem,
|
||||||
|
escapePOSIXShell,
|
||||||
expectsError,
|
expectsError,
|
||||||
expectWarning,
|
expectWarning,
|
||||||
getArrayBufferViews,
|
getArrayBufferViews,
|
||||||
|
@ -27,7 +27,8 @@ ChildProcess.prototype.spawn = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function createChild(options, callback) {
|
function createChild(options, callback) {
|
||||||
const cmd = `"${process.execPath}" "${__filename}" child`;
|
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`;
|
||||||
|
options = { ...options, env: { ...opts?.env, ...options.env } };
|
||||||
|
|
||||||
return cp.exec(cmd, options, common.mustCall(callback));
|
return cp.exec(cmd, options, common.mustCall(callback));
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,8 @@ if (process.argv[2] === 'child') {
|
|||||||
const expectedStdout = `${stdoutData}\n`;
|
const expectedStdout = `${stdoutData}\n`;
|
||||||
const expectedStderr = `${stderrData}\n`;
|
const expectedStderr = `${stderrData}\n`;
|
||||||
function run(options, callback) {
|
function run(options, callback) {
|
||||||
const cmd = `"${process.execPath}" "${__filename}" child`;
|
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`;
|
||||||
|
options = { ...options, env: { ...opts?.env, ...options.env } };
|
||||||
|
|
||||||
cp.exec(cmd, options, common.mustSucceed((stdout, stderr) => {
|
cp.exec(cmd, options, common.mustSucceed((stdout, stderr) => {
|
||||||
callback(stdout, stderr);
|
callback(stdout, stderr);
|
||||||
|
@ -14,14 +14,15 @@ function runChecks(err, stdio, streamName, expected) {
|
|||||||
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
||||||
// Windows, so we can simply pass the path.
|
// Windows, so we can simply pass the path.
|
||||||
const execNode = (args, optionsOrCallback, callback) => {
|
const execNode = (args, optionsOrCallback, callback) => {
|
||||||
|
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" `;
|
||||||
let options = optionsOrCallback;
|
let options = optionsOrCallback;
|
||||||
if (typeof optionsOrCallback === 'function') {
|
if (typeof optionsOrCallback === 'function') {
|
||||||
options = undefined;
|
options = undefined;
|
||||||
callback = optionsOrCallback;
|
callback = optionsOrCallback;
|
||||||
}
|
}
|
||||||
return cp.exec(
|
return cp.exec(
|
||||||
`"${common.isWindows ? process.execPath : '$NODE'}" ${args}`,
|
cmd + args,
|
||||||
common.isWindows ? options : { ...options, env: { ...process.env, NODE: process.execPath } },
|
{ ...opts, ...options },
|
||||||
callback,
|
callback,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -12,8 +12,7 @@ if (process.argv[2] === 'child') {
|
|||||||
console.log(stdoutData);
|
console.log(stdoutData);
|
||||||
console.error(stderrData);
|
console.error(stderrData);
|
||||||
} else {
|
} else {
|
||||||
const cmd = `"${process.execPath}" "${__filename}" child`;
|
const child = cp.exec(...common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`, common.mustSucceed((stdout, stderr) => {
|
||||||
const child = cp.exec(cmd, common.mustSucceed((stdout, stderr) => {
|
|
||||||
assert.strictEqual(stdout, expectedStdout);
|
assert.strictEqual(stdout, expectedStdout);
|
||||||
assert.strictEqual(stderr, expectedStderr);
|
assert.strictEqual(stderr, expectedStderr);
|
||||||
}));
|
}));
|
||||||
|
@ -18,9 +18,10 @@ if (process.argv[2] === 'child') {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cmd = `"${process.execPath}" "${__filename}" child`;
|
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`;
|
||||||
|
|
||||||
cp.exec(cmd, {
|
cp.exec(cmd, {
|
||||||
|
...opts,
|
||||||
timeout: kExpiringParentTimer,
|
timeout: kExpiringParentTimer,
|
||||||
}, common.mustCall((err, stdout, stderr) => {
|
}, common.mustCall((err, stdout, stderr) => {
|
||||||
console.log('[stdout]', stdout.trim());
|
console.log('[stdout]', stdout.trim());
|
||||||
|
@ -18,10 +18,11 @@ if (process.argv[2] === 'child') {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cmd = `"${process.execPath}" "${__filename}" child`;
|
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`;
|
||||||
|
|
||||||
// Test with a different kill signal.
|
// Test with a different kill signal.
|
||||||
cp.exec(cmd, {
|
cp.exec(cmd, {
|
||||||
|
...opts,
|
||||||
timeout: kExpiringParentTimer,
|
timeout: kExpiringParentTimer,
|
||||||
killSignal: 'SIGKILL'
|
killSignal: 'SIGKILL'
|
||||||
}, common.mustCall((err, stdout, stderr) => {
|
}, common.mustCall((err, stdout, stderr) => {
|
||||||
|
@ -22,10 +22,11 @@ if (process.argv[2] === 'child') {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cmd = `"${process.execPath}" "${__filename}" child`;
|
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`;
|
||||||
|
|
||||||
cp.exec(cmd, {
|
cp.exec(cmd, {
|
||||||
timeout: kTimeoutNotSupposedToExpire
|
...opts,
|
||||||
|
timeout: kTimeoutNotSupposedToExpire,
|
||||||
}, common.mustSucceed((stdout, stderr) => {
|
}, common.mustSucceed((stdout, stderr) => {
|
||||||
assert.strictEqual(stdout.trim(), 'child stdout');
|
assert.strictEqual(stdout.trim(), 'child stdout');
|
||||||
assert.strictEqual(stderr.trim(), 'child stderr');
|
assert.strictEqual(stderr.trim(), 'child stderr');
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
require('../common');
|
const { escapePOSIXShell } = require('../common');
|
||||||
|
|
||||||
// This test checks that the maxBuffer option for child_process.spawnSync()
|
// This test checks that the maxBuffer option for child_process.spawnSync()
|
||||||
// works as expected.
|
// works as expected.
|
||||||
@ -10,15 +10,12 @@ const { execSync } = require('child_process');
|
|||||||
const msgOut = 'this is stdout';
|
const msgOut = 'this is stdout';
|
||||||
const msgOutBuf = Buffer.from(`${msgOut}\n`);
|
const msgOutBuf = Buffer.from(`${msgOut}\n`);
|
||||||
|
|
||||||
const args = [
|
const [cmd, opts] = escapePOSIXShell`"${process.execPath}" -e "${`console.log('${msgOut}')`}"`;
|
||||||
'-e',
|
|
||||||
`"console.log('${msgOut}')";`,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Verify that an error is returned if maxBuffer is surpassed.
|
// Verify that an error is returned if maxBuffer is surpassed.
|
||||||
{
|
{
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
execSync(`"${process.execPath}" ${args.join(' ')}`, { maxBuffer: 1 });
|
execSync(cmd, { ...opts, maxBuffer: 1 });
|
||||||
}, (e) => {
|
}, (e) => {
|
||||||
assert.ok(e, 'maxBuffer should error');
|
assert.ok(e, 'maxBuffer should error');
|
||||||
assert.strictEqual(e.code, 'ENOBUFS');
|
assert.strictEqual(e.code, 'ENOBUFS');
|
||||||
@ -33,8 +30,8 @@ const args = [
|
|||||||
// Verify that a maxBuffer size of Infinity works.
|
// Verify that a maxBuffer size of Infinity works.
|
||||||
{
|
{
|
||||||
const ret = execSync(
|
const ret = execSync(
|
||||||
`"${process.execPath}" ${args.join(' ')}`,
|
cmd,
|
||||||
{ maxBuffer: Infinity }
|
{ ...opts, maxBuffer: Infinity },
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.deepStrictEqual(ret, msgOutBuf);
|
assert.deepStrictEqual(ret, msgOutBuf);
|
||||||
@ -43,9 +40,7 @@ const args = [
|
|||||||
// Default maxBuffer size is 1024 * 1024.
|
// Default maxBuffer size is 1024 * 1024.
|
||||||
{
|
{
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
execSync(
|
execSync(...escapePOSIXShell`"${process.execPath}" -e "console.log('a'.repeat(1024 * 1024))"`);
|
||||||
`"${process.execPath}" -e "console.log('a'.repeat(1024 * 1024))"`
|
|
||||||
);
|
|
||||||
}, (e) => {
|
}, (e) => {
|
||||||
assert.ok(e, 'maxBuffer should error');
|
assert.ok(e, 'maxBuffer should error');
|
||||||
assert.strictEqual(e.code, 'ENOBUFS');
|
assert.strictEqual(e.code, 'ENOBUFS');
|
||||||
@ -56,9 +51,7 @@ const args = [
|
|||||||
|
|
||||||
// Default maxBuffer size is 1024 * 1024.
|
// Default maxBuffer size is 1024 * 1024.
|
||||||
{
|
{
|
||||||
const ret = execSync(
|
const ret = execSync(...escapePOSIXShell`"${process.execPath}" -e "console.log('a'.repeat(1024 * 1024 - 1))"`);
|
||||||
`"${process.execPath}" -e "console.log('a'.repeat(1024 * 1024 - 1))"`
|
|
||||||
);
|
|
||||||
|
|
||||||
assert.deepStrictEqual(
|
assert.deepStrictEqual(
|
||||||
ret.toString().trim(),
|
ret.toString().trim(),
|
||||||
|
@ -7,16 +7,8 @@ const { promisify } = require('util');
|
|||||||
const exec = promisify(child_process.exec);
|
const exec = promisify(child_process.exec);
|
||||||
const execFile = promisify(child_process.execFile);
|
const execFile = promisify(child_process.execFile);
|
||||||
|
|
||||||
// The execPath might contain chars that should be escaped in a shell context.
|
|
||||||
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
|
||||||
// Windows, so we can simply pass the path.
|
|
||||||
const execNode = (args) => exec(
|
|
||||||
`"${common.isWindows ? process.execPath : '$NODE'}" ${args}`,
|
|
||||||
common.isWindows ? undefined : { env: { ...process.env, NODE: process.execPath } },
|
|
||||||
);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const promise = execNode('-p 42');
|
const promise = exec(...common.escapePOSIXShell`"${process.execPath}" -p 42`);
|
||||||
|
|
||||||
assert(promise.child instanceof child_process.ChildProcess);
|
assert(promise.child instanceof child_process.ChildProcess);
|
||||||
promise.then(common.mustCall((obj) => {
|
promise.then(common.mustCall((obj) => {
|
||||||
@ -53,7 +45,7 @@ const execNode = (args) => exec(
|
|||||||
const failingCodeWithStdoutErr =
|
const failingCodeWithStdoutErr =
|
||||||
'console.log(42);console.error(43);process.exit(1)';
|
'console.log(42);console.error(43);process.exit(1)';
|
||||||
{
|
{
|
||||||
execNode(`-e "${failingCodeWithStdoutErr}"`)
|
exec(...common.escapePOSIXShell`"${process.execPath}" -e "${failingCodeWithStdoutErr}"`)
|
||||||
.catch(common.mustCall((err) => {
|
.catch(common.mustCall((err) => {
|
||||||
assert.strictEqual(err.code, 1);
|
assert.strictEqual(err.code, 1);
|
||||||
assert.strictEqual(err.stdout, '42\n');
|
assert.strictEqual(err.stdout, '42\n');
|
||||||
|
@ -32,7 +32,6 @@ const assert = require('assert');
|
|||||||
const child = require('child_process');
|
const child = require('child_process');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fixtures = require('../common/fixtures');
|
const fixtures = require('../common/fixtures');
|
||||||
const nodejs = `"${process.execPath}"`;
|
|
||||||
|
|
||||||
if (process.argv.length > 2) {
|
if (process.argv.length > 2) {
|
||||||
console.log(process.argv.slice(2).join(' '));
|
console.log(process.argv.slice(2).join(' '));
|
||||||
@ -40,13 +39,13 @@ if (process.argv.length > 2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Assert that nothing is written to stdout.
|
// Assert that nothing is written to stdout.
|
||||||
child.exec(`${nodejs} --eval 42`, common.mustSucceed((stdout, stderr) => {
|
child.exec(...common.escapePOSIXShell`"${process.execPath}" --eval 42`, common.mustSucceed((stdout, stderr) => {
|
||||||
assert.strictEqual(stdout, '');
|
assert.strictEqual(stdout, '');
|
||||||
assert.strictEqual(stderr, '');
|
assert.strictEqual(stderr, '');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Assert that "42\n" is written to stderr.
|
// Assert that "42\n" is written to stderr.
|
||||||
child.exec(`${nodejs} --eval "console.error(42)"`,
|
child.exec(...common.escapePOSIXShell`"${process.execPath}" --eval "console.error(42)"`,
|
||||||
common.mustSucceed((stdout, stderr) => {
|
common.mustSucceed((stdout, stderr) => {
|
||||||
assert.strictEqual(stdout, '');
|
assert.strictEqual(stdout, '');
|
||||||
assert.strictEqual(stderr, '42\n');
|
assert.strictEqual(stderr, '42\n');
|
||||||
@ -54,14 +53,14 @@ child.exec(`${nodejs} --eval "console.error(42)"`,
|
|||||||
|
|
||||||
// Assert that the expected output is written to stdout.
|
// Assert that the expected output is written to stdout.
|
||||||
['--print', '-p -e', '-pe', '-p'].forEach((s) => {
|
['--print', '-p -e', '-pe', '-p'].forEach((s) => {
|
||||||
const cmd = `${nodejs} ${s} `;
|
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" ${s}`;
|
||||||
|
|
||||||
child.exec(`${cmd}42`, common.mustSucceed((stdout, stderr) => {
|
child.exec(`${cmd} 42`, opts, common.mustSucceed((stdout, stderr) => {
|
||||||
assert.strictEqual(stdout, '42\n');
|
assert.strictEqual(stdout, '42\n');
|
||||||
assert.strictEqual(stderr, '');
|
assert.strictEqual(stderr, '');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
child.exec(`${cmd} '[]'`, common.mustSucceed((stdout, stderr) => {
|
child.exec(`${cmd} '[]'`, opts, common.mustSucceed((stdout, stderr) => {
|
||||||
assert.strictEqual(stdout, '[]\n');
|
assert.strictEqual(stdout, '[]\n');
|
||||||
assert.strictEqual(stderr, '');
|
assert.strictEqual(stderr, '');
|
||||||
}));
|
}));
|
||||||
@ -69,29 +68,26 @@ child.exec(`${nodejs} --eval "console.error(42)"`,
|
|||||||
|
|
||||||
// Assert that module loading works.
|
// Assert that module loading works.
|
||||||
{
|
{
|
||||||
// Replace \ by / because Windows uses backslashes in paths, but they're still
|
common.spawnPromisified(process.execPath, ['--eval', `require(${JSON.stringify(__filename)})`])
|
||||||
// interpreted as the escape character when put between quotes.
|
.then(common.mustCall(({ stdout, stderr, code }) => {
|
||||||
const filename = __filename.replace(/\\/g, '/');
|
assert.strictEqual(stderr, '');
|
||||||
|
|
||||||
child.exec(`${nodejs} --eval "require('${filename}')"`,
|
|
||||||
common.mustCall((err, stdout, stderr) => {
|
|
||||||
assert.strictEqual(err.code, 42);
|
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
stdout, 'Loaded as a module, exiting with status code 42.\n');
|
stdout, 'Loaded as a module, exiting with status code 42.\n');
|
||||||
assert.strictEqual(stderr, '');
|
assert.strictEqual(code, 42);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that builtin modules are pre-defined.
|
// Check that builtin modules are pre-defined.
|
||||||
child.exec(`${nodejs} --print "os.platform()"`,
|
child.exec(...common.escapePOSIXShell`"${process.execPath}" --print "os.platform()"`,
|
||||||
common.mustSucceed((stdout, stderr) => {
|
common.mustSucceed((stdout, stderr) => {
|
||||||
assert.strictEqual(stderr, '');
|
assert.strictEqual(stderr, '');
|
||||||
assert.strictEqual(stdout.trim(), require('os').platform());
|
assert.strictEqual(stdout.trim(), require('os').platform());
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Module path resolve bug regression test.
|
// Module path resolve bug regression test.
|
||||||
child.exec(`${nodejs} --eval "require('./test/parallel/test-cli-eval.js')"`,
|
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" --eval "require('./test/parallel/test-cli-eval.js')"`;
|
||||||
{ cwd: path.resolve(__dirname, '../../') },
|
child.exec(cmd,
|
||||||
|
{ ...opts, cwd: path.resolve(__dirname, '../../') },
|
||||||
common.mustCall((err, stdout, stderr) => {
|
common.mustCall((err, stdout, stderr) => {
|
||||||
assert.strictEqual(err.code, 42);
|
assert.strictEqual(err.code, 42);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
@ -100,7 +96,7 @@ child.exec(`${nodejs} --eval "require('./test/parallel/test-cli-eval.js')"`,
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Missing argument should not crash.
|
// Missing argument should not crash.
|
||||||
child.exec(`${nodejs} -e`, common.mustCall((err, stdout, stderr) => {
|
child.exec(...common.escapePOSIXShell`"${process.execPath}" -e`, common.mustCall((err, stdout, stderr) => {
|
||||||
assert.strictEqual(err.code, 9);
|
assert.strictEqual(err.code, 9);
|
||||||
assert.strictEqual(stdout, '');
|
assert.strictEqual(stdout, '');
|
||||||
assert.strictEqual(stderr.trim(),
|
assert.strictEqual(stderr.trim(),
|
||||||
@ -108,18 +104,18 @@ child.exec(`${nodejs} -e`, common.mustCall((err, stdout, stderr) => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Empty program should do nothing.
|
// Empty program should do nothing.
|
||||||
child.exec(`${nodejs} -e ""`, common.mustSucceed((stdout, stderr) => {
|
child.exec(...common.escapePOSIXShell`"${process.execPath}" -e ""`, common.mustSucceed((stdout, stderr) => {
|
||||||
assert.strictEqual(stdout, '');
|
assert.strictEqual(stdout, '');
|
||||||
assert.strictEqual(stderr, '');
|
assert.strictEqual(stderr, '');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// "\\-42" should be interpreted as an escaped expression, not a switch.
|
// "\\-42" should be interpreted as an escaped expression, not a switch.
|
||||||
child.exec(`${nodejs} -p "\\-42"`, common.mustSucceed((stdout, stderr) => {
|
child.exec(...common.escapePOSIXShell`"${process.execPath}" -p "\\-42"`, common.mustSucceed((stdout, stderr) => {
|
||||||
assert.strictEqual(stdout, '-42\n');
|
assert.strictEqual(stdout, '-42\n');
|
||||||
assert.strictEqual(stderr, '');
|
assert.strictEqual(stderr, '');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
child.exec(`${nodejs} --use-strict -p process.execArgv`,
|
child.exec(...common.escapePOSIXShell`"${process.execPath}" --use-strict -p process.execArgv`,
|
||||||
common.mustSucceed((stdout, stderr) => {
|
common.mustSucceed((stdout, stderr) => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
stdout, "[ '--use-strict', '-p', 'process.execArgv' ]\n"
|
stdout, "[ '--use-strict', '-p', 'process.execArgv' ]\n"
|
||||||
@ -129,25 +125,25 @@ child.exec(`${nodejs} --use-strict -p process.execArgv`,
|
|||||||
|
|
||||||
// Regression test for https://github.com/nodejs/node/issues/3574.
|
// Regression test for https://github.com/nodejs/node/issues/3574.
|
||||||
{
|
{
|
||||||
let emptyFile = fixtures.path('empty.js');
|
const emptyFile = fixtures.path('empty.js');
|
||||||
if (common.isWindows) {
|
|
||||||
emptyFile = emptyFile.replace(/\\/g, '\\\\');
|
|
||||||
}
|
|
||||||
|
|
||||||
child.exec(`${nodejs} -e 'require("child_process").fork("${emptyFile}")'`,
|
common.spawnPromisified(process.execPath, ['-e', `require("child_process").fork(${JSON.stringify(emptyFile)})`])
|
||||||
common.mustSucceed((stdout, stderr) => {
|
.then(common.mustCall(({ stdout, stderr, code }) => {
|
||||||
assert.strictEqual(stdout, '');
|
assert.strictEqual(stdout, '');
|
||||||
assert.strictEqual(stderr, '');
|
assert.strictEqual(stderr, '');
|
||||||
|
assert.strictEqual(code, 0);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Make sure that monkey-patching process.execArgv doesn't cause child_process
|
// Make sure that monkey-patching process.execArgv doesn't cause child_process
|
||||||
// to incorrectly munge execArgv.
|
// to incorrectly munge execArgv.
|
||||||
child.exec(
|
common.spawnPromisified(process.execPath, [
|
||||||
`${nodejs} -e "process.execArgv = ['-e', 'console.log(42)', 'thirdArg'];` +
|
'-e',
|
||||||
`require('child_process').fork('${emptyFile}')"`,
|
'process.execArgv = [\'-e\', \'console.log(42)\', \'thirdArg\'];' +
|
||||||
common.mustSucceed((stdout, stderr) => {
|
`require('child_process').fork(${JSON.stringify(emptyFile)})`,
|
||||||
|
]).then(common.mustCall(({ stdout, stderr, code }) => {
|
||||||
assert.strictEqual(stdout, '42\n');
|
assert.strictEqual(stdout, '42\n');
|
||||||
assert.strictEqual(stderr, '');
|
assert.strictEqual(stderr, '');
|
||||||
|
assert.strictEqual(code, 0);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,28 +188,30 @@ child.exec(`${nodejs} --use-strict -p process.execArgv`,
|
|||||||
].forEach(function(args) {
|
].forEach(function(args) {
|
||||||
|
|
||||||
// Ensure that arguments are successfully passed to eval.
|
// Ensure that arguments are successfully passed to eval.
|
||||||
const opt = ' --eval "console.log(process.argv.slice(1).join(\' \'))"';
|
child.exec(
|
||||||
const cmd = `${nodejs}${opt} -- ${args}`;
|
...common.escapePOSIXShell`"${process.execPath}" --eval "console.log(process.argv.slice(1).join(' '))" -- ${args}`,
|
||||||
child.exec(cmd, common.mustCall(function(err, stdout, stderr) {
|
common.mustCall(function(err, stdout, stderr) {
|
||||||
assert.strictEqual(stdout, `${args}\n`);
|
assert.strictEqual(stdout, `${args}\n`);
|
||||||
assert.strictEqual(stderr, '');
|
assert.strictEqual(stderr, '');
|
||||||
assert.strictEqual(err, null);
|
assert.strictEqual(err, null);
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
// Ensure that arguments are successfully passed to print.
|
// Ensure that arguments are successfully passed to print.
|
||||||
const popt = ' --print "process.argv.slice(1).join(\' \')"';
|
child.exec(
|
||||||
const pcmd = `${nodejs}${popt} -- ${args}`;
|
...common.escapePOSIXShell`"${process.execPath}" --print "process.argv.slice(1).join(' ')" -- ${args}`,
|
||||||
child.exec(pcmd, common.mustCall(function(err, stdout, stderr) {
|
common.mustCall(function(err, stdout, stderr) {
|
||||||
assert.strictEqual(stdout, `${args}\n`);
|
assert.strictEqual(stdout, `${args}\n`);
|
||||||
assert.strictEqual(stderr, '');
|
assert.strictEqual(stderr, '');
|
||||||
assert.strictEqual(err, null);
|
assert.strictEqual(err, null);
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
|
|
||||||
// Ensure that arguments are successfully passed to a script.
|
// Ensure that arguments are successfully passed to a script.
|
||||||
// The first argument after '--' should be interpreted as a script
|
// The first argument after '--' should be interpreted as a script
|
||||||
// filename.
|
// filename.
|
||||||
const filecmd = `${nodejs} -- "${__filename}" ${args}`;
|
child.exec(...common.escapePOSIXShell`"${process.execPath}" -- "${__filename}" ${args}`,
|
||||||
child.exec(filecmd, common.mustCall(function(err, stdout, stderr) {
|
common.mustCall(function(err, stdout, stderr) {
|
||||||
assert.strictEqual(stdout, `${args}\n`);
|
assert.strictEqual(stdout, `${args}\n`);
|
||||||
assert.strictEqual(stderr, '');
|
assert.strictEqual(stderr, '');
|
||||||
assert.strictEqual(err, null);
|
assert.strictEqual(err, null);
|
||||||
@ -226,14 +224,14 @@ child.exec(`${nodejs} --use-strict -p process.execArgv`,
|
|||||||
// Assert that "42\n" is written to stdout on module eval.
|
// Assert that "42\n" is written to stdout on module eval.
|
||||||
const execOptions = '--input-type module';
|
const execOptions = '--input-type module';
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ${execOptions} --eval "console.log(42)"`,
|
...common.escapePOSIXShell`"${process.execPath}" ${execOptions} --eval "console.log(42)"`,
|
||||||
common.mustSucceed((stdout) => {
|
common.mustSucceed((stdout) => {
|
||||||
assert.strictEqual(stdout, '42\n');
|
assert.strictEqual(stdout, '42\n');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Assert that "42\n" is written to stdout with print option.
|
// Assert that "42\n" is written to stdout with print option.
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ${execOptions} --print --eval "42"`,
|
...common.escapePOSIXShell`"${process.execPath}" ${execOptions} --print --eval "42"`,
|
||||||
common.mustCall((err, stdout, stderr) => {
|
common.mustCall((err, stdout, stderr) => {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, '');
|
assert.strictEqual(stdout, '');
|
||||||
@ -242,7 +240,7 @@ child.exec(
|
|||||||
|
|
||||||
// Assert that error is written to stderr on invalid input.
|
// Assert that error is written to stderr on invalid input.
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ${execOptions} --eval "!!!!"`,
|
...common.escapePOSIXShell`"${process.execPath}" ${execOptions} --eval "!!!!"`,
|
||||||
common.mustCall((err, stdout, stderr) => {
|
common.mustCall((err, stdout, stderr) => {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, '');
|
assert.strictEqual(stdout, '');
|
||||||
@ -251,22 +249,25 @@ child.exec(
|
|||||||
|
|
||||||
// Assert that require is undefined in ESM support
|
// Assert that require is undefined in ESM support
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ${execOptions} --eval "console.log(typeof require);"`,
|
...common.escapePOSIXShell`"${process.execPath}" ${execOptions} --eval "console.log(typeof require);"`,
|
||||||
common.mustSucceed((stdout) => {
|
common.mustSucceed((stdout) => {
|
||||||
assert.strictEqual(stdout, 'undefined\n');
|
assert.strictEqual(stdout, 'undefined\n');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Assert that import.meta is defined in ESM
|
// Assert that import.meta is defined in ESM
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ${execOptions} --eval "console.log(typeof import.meta);"`,
|
...common.escapePOSIXShell`"${process.execPath}" ${execOptions} --eval "console.log(typeof import.meta);"`,
|
||||||
common.mustSucceed((stdout) => {
|
common.mustSucceed((stdout) => {
|
||||||
assert.strictEqual(stdout, 'object\n');
|
assert.strictEqual(stdout, 'object\n');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
{
|
||||||
// Assert that packages can be imported cwd-relative with --eval
|
// Assert that packages can be imported cwd-relative with --eval
|
||||||
|
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" ${execOptions} --eval`;
|
||||||
|
const options = { ...opts, cwd: path.join(__dirname, '../..') };
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ${execOptions} ` +
|
`${cmd} "import './test/fixtures/es-modules/mjs-file.mjs'"`,
|
||||||
'--eval "import \'./test/fixtures/es-modules/mjs-file.mjs\'"',
|
options,
|
||||||
common.mustSucceed((stdout) => {
|
common.mustSucceed((stdout) => {
|
||||||
assert.strictEqual(stdout, '.mjs file\n');
|
assert.strictEqual(stdout, '.mjs file\n');
|
||||||
}));
|
}));
|
||||||
@ -274,77 +275,69 @@ child.exec(
|
|||||||
|
|
||||||
// Assert that packages can be dynamic imported initial cwd-relative with --eval
|
// Assert that packages can be dynamic imported initial cwd-relative with --eval
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ${execOptions} ` +
|
cmd + ' "process.chdir(\'..\');' +
|
||||||
'--eval "process.chdir(\'..\');' +
|
|
||||||
'import(\'./test/fixtures/es-modules/mjs-file.mjs\')"',
|
'import(\'./test/fixtures/es-modules/mjs-file.mjs\')"',
|
||||||
|
options,
|
||||||
common.mustSucceed((stdout) => {
|
common.mustSucceed((stdout) => {
|
||||||
assert.strictEqual(stdout, '.mjs file\n');
|
assert.strictEqual(stdout, '.mjs file\n');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ` +
|
cmd + ' "process.chdir(\'..\');' +
|
||||||
'--eval "process.chdir(\'..\');' +
|
|
||||||
'import(\'./test/fixtures/es-modules/mjs-file.mjs\')"',
|
'import(\'./test/fixtures/es-modules/mjs-file.mjs\')"',
|
||||||
|
options,
|
||||||
common.mustSucceed((stdout) => {
|
common.mustSucceed((stdout) => {
|
||||||
assert.strictEqual(stdout, '.mjs file\n');
|
assert.strictEqual(stdout, '.mjs file\n');
|
||||||
}));
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
if (common.hasCrypto) {
|
if (common.hasCrypto) {
|
||||||
// Assert that calls to crypto utils work without require.
|
// Assert that calls to crypto utils work without require.
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ` +
|
...common.escapePOSIXShell`"${process.execPath}" -e "console.log(crypto.randomBytes(16).toString('hex'))"`,
|
||||||
'-e "console.log(crypto.randomBytes(16).toString(\'hex\'))"',
|
|
||||||
common.mustSucceed((stdout) => {
|
common.mustSucceed((stdout) => {
|
||||||
assert.match(stdout, /[0-9a-f]{32}/i);
|
assert.match(stdout, /[0-9a-f]{32}/i);
|
||||||
}));
|
}));
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ` +
|
...common.escapePOSIXShell`"${process.execPath}" -p "crypto.randomBytes(16).toString('hex')"`,
|
||||||
'-p "crypto.randomBytes(16).toString(\'hex\')"',
|
|
||||||
common.mustSucceed((stdout) => {
|
common.mustSucceed((stdout) => {
|
||||||
assert.match(stdout, /[0-9a-f]{32}/i);
|
assert.match(stdout, /[0-9a-f]{32}/i);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
// Assert that overriding crypto works.
|
// Assert that overriding crypto works.
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ` +
|
...common.escapePOSIXShell`"${process.execPath}" -p "crypto=Symbol('test')"`,
|
||||||
'-p "crypto=Symbol(\'test\')"',
|
|
||||||
common.mustSucceed((stdout) => {
|
common.mustSucceed((stdout) => {
|
||||||
assert.match(stdout, /Symbol\(test\)/i);
|
assert.match(stdout, /Symbol\(test\)/i);
|
||||||
}));
|
}));
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ` +
|
...common.escapePOSIXShell`"${process.execPath}" -e "crypto = {};console.log('randomBytes', typeof crypto.randomBytes)"`,
|
||||||
'-e "crypto = {};console.log(\'randomBytes\', typeof crypto.randomBytes)"',
|
|
||||||
common.mustSucceed((stdout) => {
|
common.mustSucceed((stdout) => {
|
||||||
assert.match(stdout, /randomBytes\sundefined/);
|
assert.match(stdout, /randomBytes\sundefined/);
|
||||||
}));
|
}));
|
||||||
// Assert that overriding crypto with a local variable works.
|
// Assert that overriding crypto with a local variable works.
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ` +
|
...common.escapePOSIXShell`"${process.execPath}" -e "const crypto = {};console.log('randomBytes', typeof crypto.randomBytes)"`,
|
||||||
'-e "const crypto = {};console.log(\'randomBytes\', typeof crypto.randomBytes)"',
|
|
||||||
common.mustSucceed((stdout) => {
|
common.mustSucceed((stdout) => {
|
||||||
assert.match(stdout, /randomBytes\sundefined/);
|
assert.match(stdout, /randomBytes\sundefined/);
|
||||||
}));
|
}));
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ` +
|
...common.escapePOSIXShell`"${process.execPath}" -e "let crypto = {};console.log('randomBytes', typeof crypto.randomBytes)"`,
|
||||||
'-e "let crypto = {};console.log(\'randomBytes\', typeof crypto.randomBytes)"',
|
|
||||||
common.mustSucceed((stdout) => {
|
common.mustSucceed((stdout) => {
|
||||||
assert.match(stdout, /randomBytes\sundefined/);
|
assert.match(stdout, /randomBytes\sundefined/);
|
||||||
}));
|
}));
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ` +
|
...common.escapePOSIXShell`"${process.execPath}" -e "var crypto = {};console.log('randomBytes', typeof crypto.randomBytes)"`,
|
||||||
'-e "var crypto = {};console.log(\'randomBytes\', typeof crypto.randomBytes)"',
|
|
||||||
common.mustSucceed((stdout) => {
|
common.mustSucceed((stdout) => {
|
||||||
assert.match(stdout, /randomBytes\sundefined/);
|
assert.match(stdout, /randomBytes\sundefined/);
|
||||||
}));
|
}));
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ` +
|
...common.escapePOSIXShell`"${process.execPath}" -p "const crypto = {randomBytes:1};typeof crypto.randomBytes"`,
|
||||||
'-p "const crypto = {randomBytes:1};typeof crypto.randomBytes"',
|
|
||||||
common.mustSucceed((stdout) => {
|
common.mustSucceed((stdout) => {
|
||||||
assert.match(stdout, /^number/);
|
assert.match(stdout, /^number/);
|
||||||
}));
|
}));
|
||||||
child.exec(
|
child.exec(
|
||||||
`${nodejs} ` +
|
...common.escapePOSIXShell`"${process.execPath}" -p "let crypto = {randomBytes:1};typeof crypto.randomBytes"`,
|
||||||
'-p "let crypto = {randomBytes:1};typeof crypto.randomBytes"',
|
|
||||||
common.mustSucceed((stdout) => {
|
common.mustSucceed((stdout) => {
|
||||||
assert.match(stdout, /^number/);
|
assert.match(stdout, /^number/);
|
||||||
}));
|
}));
|
||||||
|
@ -11,18 +11,8 @@ const { exec, spawn } = require('child_process');
|
|||||||
const { once } = require('events');
|
const { once } = require('events');
|
||||||
let stdOut;
|
let stdOut;
|
||||||
|
|
||||||
// The execPath might contain chars that should be escaped in a shell context.
|
|
||||||
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
|
||||||
// Windows, so we can simply pass the path.
|
|
||||||
const execNode = (args, callback) => exec(
|
|
||||||
`"${common.isWindows ? process.execPath : '$NODE'}" ${args}`,
|
|
||||||
common.isWindows ? undefined : { env: { ...process.env, NODE: process.execPath } },
|
|
||||||
callback,
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
function startPrintHelpTest() {
|
function startPrintHelpTest() {
|
||||||
execNode('--help', common.mustSucceed((stdout, stderr) => {
|
exec(...common.escapePOSIXShell`"${process.execPath}" --help`, common.mustSucceed((stdout, stderr) => {
|
||||||
stdOut = stdout;
|
stdOut = stdout;
|
||||||
validateNodePrintHelp();
|
validateNodePrintHelp();
|
||||||
}));
|
}));
|
||||||
|
@ -4,21 +4,10 @@ const common = require('../common');
|
|||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const { exec } = require('child_process');
|
const { exec } = require('child_process');
|
||||||
|
|
||||||
// The execPath might contain chars that should be escaped in a shell context.
|
|
||||||
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
|
||||||
// Windows, so we can simply pass the path.
|
|
||||||
const execNode = (args, callback) => exec(
|
|
||||||
`"${common.isWindows ? process.execPath : '$NODE'}" ${args}`,
|
|
||||||
common.isWindows ? undefined : { env: { ...process.env, NODE: process.execPath } },
|
|
||||||
callback,
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Should throw if -c and -e flags are both passed
|
// Should throw if -c and -e flags are both passed
|
||||||
['-c', '--check'].forEach(function(checkFlag) {
|
['-c', '--check'].forEach(function(checkFlag) {
|
||||||
['-e', '--eval'].forEach(function(evalFlag) {
|
['-e', '--eval'].forEach(function(evalFlag) {
|
||||||
const args = [checkFlag, evalFlag, 'foo'];
|
exec(...common.escapePOSIXShell`"${process.execPath}" ${checkFlag} ${evalFlag} foo`, common.mustCall((err, stdout, stderr) => {
|
||||||
execNode(args.join(' '), common.mustCall((err, stdout, stderr) => {
|
|
||||||
assert.strictEqual(err instanceof Error, true);
|
assert.strictEqual(err instanceof Error, true);
|
||||||
assert.strictEqual(err.code, 9);
|
assert.strictEqual(err.code, 9);
|
||||||
assert(
|
assert(
|
||||||
|
@ -621,12 +621,10 @@ assert.throws(
|
|||||||
const msgfile = tmpdir.resolve('s5.msg');
|
const msgfile = tmpdir.resolve('s5.msg');
|
||||||
fs.writeFileSync(msgfile, msg);
|
fs.writeFileSync(msgfile, msg);
|
||||||
|
|
||||||
const cmd =
|
exec(...common.escapePOSIXShell`"${
|
||||||
`"${common.opensslCli}" dgst -sha256 -verify "${pubfile}" -signature "${
|
common.opensslCli}" dgst -sha256 -verify "${pubfile}" -signature "${
|
||||||
sigfile}" -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-2 "${
|
sigfile}" -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-2 "${msgfile
|
||||||
msgfile}"`;
|
}"`, common.mustCall((err, stdout, stderr) => {
|
||||||
|
|
||||||
exec(cmd, common.mustCall((err, stdout, stderr) => {
|
|
||||||
assert(stdout.includes('Verified OK'));
|
assert(stdout.includes('Verified OK'));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -202,18 +202,15 @@ if (process.argv[2] === 'child') {
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
tests.forEach(function(test, testIndex) {
|
tests.forEach(function(test, testIndex) {
|
||||||
let testCmd = '';
|
const escapedArgs = common.escapePOSIXShell`"${process.execPath}" --abort-on-uncaught-exception "${__filename}" child ${testIndex}`;
|
||||||
if (!common.isWindows) {
|
if (!common.isWindows) {
|
||||||
// Do not create core files, as it can take a lot of disk space on
|
// Do not create core files, as it can take a lot of disk space on
|
||||||
// continuous testing and developers' machines
|
// continuous testing and developers' machines
|
||||||
testCmd += 'ulimit -c 0 && ';
|
escapedArgs[0] = 'ulimit -c 0 && ' + escapedArgs[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
testCmd += `"${process.argv[0]}" --abort-on-uncaught-exception ` +
|
|
||||||
`"${process.argv[1]}" child ${testIndex}`;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
child_process.execSync(testCmd);
|
child_process.execSync(...escapedArgs);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
assert.fail(`Test index ${testIndex} failed: ${e}`);
|
assert.fail(`Test index ${testIndex} failed: ${e}`);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ if (process.argv[2] === 'child') {
|
|||||||
|
|
||||||
function runTestWithoutAbortOnUncaughtException() {
|
function runTestWithoutAbortOnUncaughtException() {
|
||||||
child_process.exec(
|
child_process.exec(
|
||||||
createTestCmdLine(),
|
...createTestCmdLine(),
|
||||||
function onTestDone(err, stdout, stderr) {
|
function onTestDone(err, stdout, stderr) {
|
||||||
// When _not_ passing --abort-on-uncaught-exception, the process'
|
// When _not_ passing --abort-on-uncaught-exception, the process'
|
||||||
// uncaughtException handler _must_ be called, and thus the error
|
// uncaughtException handler _must_ be called, and thus the error
|
||||||
@ -70,7 +70,7 @@ function runTestWithoutAbortOnUncaughtException() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function runTestWithAbortOnUncaughtException() {
|
function runTestWithAbortOnUncaughtException() {
|
||||||
child_process.exec(createTestCmdLine({
|
child_process.exec(...createTestCmdLine({
|
||||||
withAbortOnUncaughtException: true
|
withAbortOnUncaughtException: true
|
||||||
}), function onTestDone(err, stdout, stderr) {
|
}), function onTestDone(err, stdout, stderr) {
|
||||||
assert.notStrictEqual(err.code, RAN_UNCAUGHT_EXCEPTION_HANDLER_EXIT_CODE,
|
assert.notStrictEqual(err.code, RAN_UNCAUGHT_EXCEPTION_HANDLER_EXIT_CODE,
|
||||||
@ -82,21 +82,14 @@ function runTestWithAbortOnUncaughtException() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createTestCmdLine(options) {
|
function createTestCmdLine(options) {
|
||||||
let testCmd = '';
|
const escapedArgs = common.escapePOSIXShell`"${process.execPath}" ${
|
||||||
|
options?.withAbortOnUncaughtException ? '--abort-on-uncaught-exception' : ''
|
||||||
|
} "${__filename}" child`;
|
||||||
|
|
||||||
if (!common.isWindows) {
|
if (!common.isWindows) {
|
||||||
// Do not create core files, as it can take a lot of disk space on
|
// Do not create core files, as it can take a lot of disk space on
|
||||||
// continuous testing and developers' machines
|
// continuous testing and developers' machines
|
||||||
testCmd += 'ulimit -c 0 && ';
|
escapedArgs[0] = 'ulimit -c 0 && ' + escapedArgs[0];
|
||||||
}
|
}
|
||||||
|
return escapedArgs;
|
||||||
testCmd += `"${process.argv[0]}"`;
|
|
||||||
|
|
||||||
if (options?.withAbortOnUncaughtException) {
|
|
||||||
testCmd += ' --abort-on-uncaught-exception';
|
|
||||||
}
|
|
||||||
|
|
||||||
testCmd += ` "${process.argv[1]}" child`;
|
|
||||||
|
|
||||||
return testCmd;
|
|
||||||
}
|
}
|
||||||
|
@ -91,21 +91,17 @@ if (process.argv[2] === 'child') {
|
|||||||
if (options.throwInDomainErrHandler)
|
if (options.throwInDomainErrHandler)
|
||||||
throwInDomainErrHandlerOpt = 'throwInDomainErrHandler';
|
throwInDomainErrHandlerOpt = 'throwInDomainErrHandler';
|
||||||
|
|
||||||
let cmdToExec = '';
|
|
||||||
if (!common.isWindows) {
|
|
||||||
// Do not create core files, as it can take a lot of disk space on
|
|
||||||
// continuous testing and developers' machines
|
|
||||||
cmdToExec += 'ulimit -c 0 && ';
|
|
||||||
}
|
|
||||||
|
|
||||||
let useTryCatchOpt;
|
let useTryCatchOpt;
|
||||||
if (options.useTryCatch)
|
if (options.useTryCatch)
|
||||||
useTryCatchOpt = 'useTryCatch';
|
useTryCatchOpt = 'useTryCatch';
|
||||||
|
|
||||||
cmdToExec += `"${process.argv[0]}" ${cmdLineOption ? cmdLineOption : ''} "${
|
const escapedArgs = common.escapePOSIXShell`"${process.execPath}" ${cmdLineOption || ''} "${__filename}" child ${throwInDomainErrHandlerOpt || ''} ${useTryCatchOpt || ''}`;
|
||||||
process.argv[1]}" child ${throwInDomainErrHandlerOpt} ${useTryCatchOpt}`;
|
if (!common.isWindows) {
|
||||||
|
// Do not create core files, as it can take a lot of disk space on
|
||||||
const child = exec(cmdToExec);
|
// continuous testing and developers' machines
|
||||||
|
escapedArgs[0] = 'ulimit -c 0 && ' + escapedArgs[0];
|
||||||
|
}
|
||||||
|
const child = exec(...escapedArgs);
|
||||||
|
|
||||||
if (child) {
|
if (child) {
|
||||||
child.on('exit', function onChildExited(exitCode, signal) {
|
child.on('exit', function onChildExited(exitCode, signal) {
|
||||||
|
@ -7,14 +7,13 @@ if (process.argv[2] === 'child') {
|
|||||||
process.emitWarning('foo');
|
process.emitWarning('foo');
|
||||||
} else {
|
} else {
|
||||||
function test(newEnv) {
|
function test(newEnv) {
|
||||||
const env = { ...process.env, ...newEnv };
|
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child`;
|
||||||
const cmd = `"${process.execPath}" "${__filename}" child`;
|
|
||||||
|
|
||||||
cp.exec(cmd, { env }, common.mustCall((err, stdout, stderr) => {
|
cp.exec(cmd, { ...opts, env: { ...opts?.env, ...newEnv } }, common.mustCall((err, stdout, stderr) => {
|
||||||
assert.strictEqual(err, null);
|
assert.strictEqual(err, null);
|
||||||
assert.strictEqual(stdout, '');
|
assert.strictEqual(stdout, '');
|
||||||
|
|
||||||
if (env.NODE_NO_WARNINGS === '1')
|
if (newEnv.NODE_NO_WARNINGS === '1')
|
||||||
assert.strictEqual(stderr, '');
|
assert.strictEqual(stderr, '');
|
||||||
else
|
else
|
||||||
assert.match(stderr.trim(), /Warning: foo\n/);
|
assert.match(stderr.trim(), /Warning: foo\n/);
|
||||||
|
@ -28,8 +28,7 @@ const fixtures = require('../common/fixtures');
|
|||||||
function errExec(script, option, callback) {
|
function errExec(script, option, callback) {
|
||||||
callback = typeof option === 'function' ? option : callback;
|
callback = typeof option === 'function' ? option : callback;
|
||||||
option = typeof option === 'string' ? option : '';
|
option = typeof option === 'string' ? option : '';
|
||||||
const cmd = `"${process.argv[0]}" ${option} "${fixtures.path(script)}"`;
|
return exec(...common.escapePOSIXShell`"${process.execPath}" ${option} "${fixtures.path(script)}"`, (err, stdout, stderr) => {
|
||||||
return exec(cmd, (err, stdout, stderr) => {
|
|
||||||
// There was some error
|
// There was some error
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ if (!common.isWindows) {
|
|||||||
const filename = `${tmpdir.path}/foo.pipe`;
|
const filename = `${tmpdir.path}/foo.pipe`;
|
||||||
const mkfifoResult = child_process.spawnSync('mkfifo', [filename]);
|
const mkfifoResult = child_process.spawnSync('mkfifo', [filename]);
|
||||||
if (!mkfifoResult.error) {
|
if (!mkfifoResult.error) {
|
||||||
child_process.exec(`echo "xyz foobar" > '${filename}'`);
|
child_process.exec(...common.escapePOSIXShell`echo "xyz foobar" > "${filename}"`);
|
||||||
const stream = new fs.createReadStream(filename, common.mustNotMutateObjectDeep({ end: 1 }));
|
const stream = new fs.createReadStream(filename, common.mustNotMutateObjectDeep({ end: 1 }));
|
||||||
stream.data = '';
|
stream.data = '';
|
||||||
|
|
||||||
|
@ -25,12 +25,10 @@ const data2 = 'World';
|
|||||||
const expected = `${data1}\n${data2}\n`;
|
const expected = `${data1}\n${data2}\n`;
|
||||||
|
|
||||||
const exec = require('child_process').exec;
|
const exec = require('child_process').exec;
|
||||||
const f = JSON.stringify(__filename);
|
|
||||||
const node = JSON.stringify(process.execPath);
|
|
||||||
|
|
||||||
function test(child) {
|
function test(child) {
|
||||||
const cmd = `(echo ${data1}; sleep 0.5; echo ${data2}) | ${node} ${f} ${child}`;
|
exec(...common.escapePOSIXShell`(echo "${data1}"; sleep 0.5; echo "${data2}") | "${process.execPath}" "${__filename}" "${child}"`,
|
||||||
exec(cmd, common.mustSucceed((stdout, stderr) => {
|
common.mustSucceed((stdout, stderr) => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
stdout,
|
stdout,
|
||||||
expected,
|
expected,
|
||||||
|
@ -36,9 +36,7 @@ const fixtures = require('../common/fixtures');
|
|||||||
|
|
||||||
function test(env, cb) {
|
function test(env, cb) {
|
||||||
const filename = fixtures.path('test-fs-readfile-error.js');
|
const filename = fixtures.path('test-fs-readfile-error.js');
|
||||||
const execPath = `"${process.execPath}" "${filename}"`;
|
exec(...common.escapePOSIXShell`"${process.execPath}" "${filename}"`, (err, stdout, stderr) => {
|
||||||
const options = { env: { ...process.env, ...env } };
|
|
||||||
exec(execPath, options, (err, stdout, stderr) => {
|
|
||||||
assert(err);
|
assert(err);
|
||||||
assert.strictEqual(stdout, '');
|
assert.strictEqual(stdout, '');
|
||||||
assert.notStrictEqual(stderr, '');
|
assert.notStrictEqual(stderr, '');
|
||||||
|
@ -25,10 +25,8 @@ tmpdir.refresh();
|
|||||||
fs.writeFileSync(filename, dataExpected);
|
fs.writeFileSync(filename, dataExpected);
|
||||||
|
|
||||||
const exec = require('child_process').exec;
|
const exec = require('child_process').exec;
|
||||||
const f = JSON.stringify(__filename);
|
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child < "${filename}"`;
|
||||||
const node = JSON.stringify(process.execPath);
|
exec(cmd, { ...opts, maxBuffer: 1000000 }, common.mustSucceed((stdout, stderr) => {
|
||||||
const cmd = `cat ${filename} | ${node} ${f} child`;
|
|
||||||
exec(cmd, { maxBuffer: 1000000 }, common.mustSucceed((stdout, stderr) => {
|
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
stdout,
|
stdout,
|
||||||
dataExpected,
|
dataExpected,
|
||||||
|
@ -43,10 +43,7 @@ const filename = fixtures.path('readfile_pipe_test.txt');
|
|||||||
const dataExpected = fs.readFileSync(filename).toString();
|
const dataExpected = fs.readFileSync(filename).toString();
|
||||||
|
|
||||||
const exec = require('child_process').exec;
|
const exec = require('child_process').exec;
|
||||||
const f = JSON.stringify(__filename);
|
exec(...common.escapePOSIXShell`"${process.execPath}" "${__filename}" child < "${filename}"`, common.mustSucceed((stdout, stderr) => {
|
||||||
const node = JSON.stringify(process.execPath);
|
|
||||||
const cmd = `cat ${filename} | ${node} ${f} child`;
|
|
||||||
exec(cmd, common.mustSucceed((stdout, stderr) => {
|
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
stdout,
|
stdout,
|
||||||
dataExpected,
|
dataExpected,
|
||||||
|
@ -22,12 +22,10 @@ tmpdir.refresh();
|
|||||||
fs.writeFileSync(filename, dataExpected);
|
fs.writeFileSync(filename, dataExpected);
|
||||||
|
|
||||||
const exec = require('child_process').exec;
|
const exec = require('child_process').exec;
|
||||||
const f = JSON.stringify(__filename);
|
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child < "${filename}"`;
|
||||||
const node = JSON.stringify(process.execPath);
|
|
||||||
const cmd = `cat ${filename} | ${node} ${f} child`;
|
|
||||||
exec(
|
exec(
|
||||||
cmd,
|
cmd,
|
||||||
{ maxBuffer: 1000000 },
|
{ ...opts, maxBuffer: 1_000_000 },
|
||||||
common.mustSucceed((stdout, stderr) => {
|
common.mustSucceed((stdout, stderr) => {
|
||||||
assert.strictEqual(stdout, dataExpected);
|
assert.strictEqual(stdout, dataExpected);
|
||||||
assert.strictEqual(stderr, '');
|
assert.strictEqual(stderr, '');
|
||||||
|
@ -19,8 +19,8 @@ if (process.argv[2] === 'child') {
|
|||||||
tmpdir.refresh();
|
tmpdir.refresh();
|
||||||
fs.writeFileSync(filename, '.'.repeat(1 << 16)); // Exceeds RLIMIT_FSIZE.
|
fs.writeFileSync(filename, '.'.repeat(1 << 16)); // Exceeds RLIMIT_FSIZE.
|
||||||
} else {
|
} else {
|
||||||
const cmd = `ulimit -f 1 && '${process.execPath}' '${__filename}' child`;
|
const [cmd, opts] = common.escapePOSIXShell`ulimit -f 1 && "${process.execPath}" "${__filename}" child`;
|
||||||
const result = child_process.spawnSync('/bin/sh', ['-c', cmd]);
|
const result = child_process.spawnSync('/bin/sh', ['-c', cmd], opts);
|
||||||
const haystack = result.stderr.toString();
|
const haystack = result.stderr.toString();
|
||||||
const needle = 'Error: EFBIG: file too large, write';
|
const needle = 'Error: EFBIG: file too large, write';
|
||||||
const ok = haystack.includes(needle);
|
const ok = haystack.includes(needle);
|
||||||
|
@ -15,20 +15,12 @@ if (process.argv[2] === 'child') {
|
|||||||
assert.ok(process.permission.has('child'));
|
assert.ok(process.permission.has('child'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The execPath might contain chars that should be escaped in a shell context.
|
|
||||||
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
|
||||||
// Windows, so we can simply pass the path.
|
|
||||||
const execNode = (args) => childProcess.execSync(
|
|
||||||
`"${common.isWindows ? process.execPath : '$NODE'}" ${args}`,
|
|
||||||
common.isWindows ? undefined : { env: { ...process.env, NODE: process.execPath } },
|
|
||||||
);
|
|
||||||
|
|
||||||
// When a permission is set by cli, the process shouldn't be able
|
// When a permission is set by cli, the process shouldn't be able
|
||||||
// to spawn unless --allow-child-process is sent
|
// to spawn unless --allow-child-process is sent
|
||||||
{
|
{
|
||||||
// doesNotThrow
|
// doesNotThrow
|
||||||
childProcess.spawnSync(process.execPath, ['--version']);
|
childProcess.spawnSync(process.execPath, ['--version']);
|
||||||
execNode('--version');
|
childProcess.execSync(...common.escapePOSIXShell`"${process.execPath}" --version`);
|
||||||
childProcess.fork(__filename, ['child']);
|
childProcess.fork(__filename, ['child']);
|
||||||
childProcess.execFileSync(process.execPath, ['--version']);
|
childProcess.execFileSync(process.execPath, ['--version']);
|
||||||
}
|
}
|
||||||
|
@ -15,14 +15,6 @@ if (process.argv[2] === 'child') {
|
|||||||
assert.ok(!process.permission.has('child'));
|
assert.ok(!process.permission.has('child'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The execPath might contain chars that should be escaped in a shell context.
|
|
||||||
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
|
||||||
// Windows, so we can simply pass the path.
|
|
||||||
const execNode = (args) => [
|
|
||||||
`"${common.isWindows ? process.execPath : '$NODE'}" ${args}`,
|
|
||||||
common.isWindows ? undefined : { env: { ...process.env, NODE: process.execPath } },
|
|
||||||
];
|
|
||||||
|
|
||||||
// When a permission is set by cli, the process shouldn't be able
|
// When a permission is set by cli, the process shouldn't be able
|
||||||
// to spawn
|
// to spawn
|
||||||
{
|
{
|
||||||
@ -39,13 +31,13 @@ const execNode = (args) => [
|
|||||||
permission: 'ChildProcess',
|
permission: 'ChildProcess',
|
||||||
}));
|
}));
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
childProcess.exec(...execNode('--version'));
|
childProcess.exec(...common.escapePOSIXShell`"${process.execPath}" --version`);
|
||||||
}, common.expectsError({
|
}, common.expectsError({
|
||||||
code: 'ERR_ACCESS_DENIED',
|
code: 'ERR_ACCESS_DENIED',
|
||||||
permission: 'ChildProcess',
|
permission: 'ChildProcess',
|
||||||
}));
|
}));
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
childProcess.execSync(...execNode('--version'));
|
childProcess.execSync(...common.escapePOSIXShell`"${process.execPath}" --version`);
|
||||||
}, common.expectsError({
|
}, common.expectsError({
|
||||||
code: 'ERR_ACCESS_DENIED',
|
code: 'ERR_ACCESS_DENIED',
|
||||||
permission: 'ChildProcess',
|
permission: 'ChildProcess',
|
||||||
@ -57,13 +49,13 @@ const execNode = (args) => [
|
|||||||
permission: 'ChildProcess',
|
permission: 'ChildProcess',
|
||||||
}));
|
}));
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
childProcess.execFile(...execNode('--version'));
|
childProcess.execFile(...common.escapePOSIXShell`"${process.execPath}" --version`);
|
||||||
}, common.expectsError({
|
}, common.expectsError({
|
||||||
code: 'ERR_ACCESS_DENIED',
|
code: 'ERR_ACCESS_DENIED',
|
||||||
permission: 'ChildProcess',
|
permission: 'ChildProcess',
|
||||||
}));
|
}));
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
childProcess.execFileSync(...execNode('--version'));
|
childProcess.execFileSync(...common.escapePOSIXShell`"${process.execPath}" --version`);
|
||||||
}, common.expectsError({
|
}, common.expectsError({
|
||||||
code: 'ERR_ACCESS_DENIED',
|
code: 'ERR_ACCESS_DENIED',
|
||||||
permission: 'ChildProcess',
|
permission: 'ChildProcess',
|
||||||
|
@ -13,8 +13,8 @@ if (!common.isMainThread)
|
|||||||
const selfRefModule = fixtures.path('self_ref_module');
|
const selfRefModule = fixtures.path('self_ref_module');
|
||||||
const fixtureA = fixtures.path('printA.js');
|
const fixtureA = fixtures.path('printA.js');
|
||||||
|
|
||||||
exec(`"${nodeBinary}" -r self_ref "${fixtureA}"`, { cwd: selfRefModule },
|
const [cmd, opts] = common.escapePOSIXShell`"${nodeBinary}" -r self_ref "${fixtureA}"`;
|
||||||
(err, stdout, stderr) => {
|
exec(cmd, { ...opts, cwd: selfRefModule },
|
||||||
assert.ifError(err);
|
common.mustSucceed((stdout, stderr) => {
|
||||||
assert.strictEqual(stdout, 'A\n');
|
assert.strictEqual(stdout, 'A\n');
|
||||||
});
|
}));
|
||||||
|
@ -7,4 +7,4 @@ const { exec } = require('child_process');
|
|||||||
const kNodeBinary = process.argv[0];
|
const kNodeBinary = process.argv[0];
|
||||||
|
|
||||||
|
|
||||||
exec(`"${kNodeBinary}" -r "${worker}" -pe "1+1"`, common.mustSucceed());
|
exec(...common.escapePOSIXShell`"${kNodeBinary}" -r "${worker}" -pe "1+1"`, common.mustSucceed());
|
||||||
|
@ -10,15 +10,11 @@ const stdoutScript = fixtures.path('echo-close-check.js');
|
|||||||
const tmpFile = tmpdir.resolve('stdin.txt');
|
const tmpFile = tmpdir.resolve('stdin.txt');
|
||||||
const string = fixtures.utf8TestText;
|
const string = fixtures.utf8TestText;
|
||||||
|
|
||||||
const cmd = `"${process.argv[0]}" "${stdoutScript}" < "${tmpFile}"`;
|
|
||||||
|
|
||||||
tmpdir.refresh();
|
tmpdir.refresh();
|
||||||
|
|
||||||
console.log(`${cmd}\n\n`);
|
|
||||||
|
|
||||||
fs.writeFileSync(tmpFile, string);
|
fs.writeFileSync(tmpFile, string);
|
||||||
|
|
||||||
childProcess.exec(cmd, common.mustCall(function(err, stdout, stderr) {
|
childProcess.exec(...common.escapePOSIXShell`"${process.argv0}" "${stdoutScript}" < "${tmpFile}"`, common.mustCall(function(err, stdout, stderr) {
|
||||||
fs.unlinkSync(tmpFile);
|
fs.unlinkSync(tmpFile);
|
||||||
|
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
|
@ -29,8 +29,8 @@ if (process.argv[2] === 'child') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run the script in a shell but close stdout and stderr.
|
// Run the script in a shell but close stdout and stderr.
|
||||||
const cmd = `"${process.execPath}" "${__filename}" child 1>&- 2>&-`;
|
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" "${__filename}" child 1>&- 2>&-`;
|
||||||
const proc = spawn('/bin/sh', ['-c', cmd], { stdio: 'inherit' });
|
const proc = spawn('/bin/sh', ['-c', cmd], { ...opts, stdio: 'inherit' });
|
||||||
|
|
||||||
proc.on('exit', common.mustCall(function(exitCode) {
|
proc.on('exit', common.mustCall(function(exitCode) {
|
||||||
assert.strictEqual(exitCode, 0);
|
assert.strictEqual(exitCode, 0);
|
||||||
|
@ -7,12 +7,9 @@ const { getSystemErrorName } = require('util');
|
|||||||
|
|
||||||
const testScript = fixtures.path('catch-stdout-error.js');
|
const testScript = fixtures.path('catch-stdout-error.js');
|
||||||
|
|
||||||
const cmd = `${JSON.stringify(process.execPath)} ` +
|
const child = child_process.exec(
|
||||||
`${JSON.stringify(testScript)} | ` +
|
...common.escapePOSIXShell`"${process.execPath}" "${testScript}" | "${process.execPath}" -pe "process.stdin.on('data' , () => process.exit(1))"`
|
||||||
`${JSON.stringify(process.execPath)} ` +
|
);
|
||||||
'-pe "process.stdin.on(\'data\' , () => process.exit(1))"';
|
|
||||||
|
|
||||||
const child = child_process.exec(cmd);
|
|
||||||
let output = '';
|
let output = '';
|
||||||
|
|
||||||
child.stderr.on('data', function(c) {
|
child.stderr.on('data', function(c) {
|
||||||
@ -21,12 +18,7 @@ child.stderr.on('data', function(c) {
|
|||||||
|
|
||||||
|
|
||||||
child.on('close', common.mustCall(function(code) {
|
child.on('close', common.mustCall(function(code) {
|
||||||
try {
|
|
||||||
output = JSON.parse(output);
|
output = JSON.parse(output);
|
||||||
} catch {
|
|
||||||
console.error(output);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.strictEqual(output.code, 'EPIPE');
|
assert.strictEqual(output.code, 'EPIPE');
|
||||||
assert.strictEqual(getSystemErrorName(output.errno), 'EPIPE');
|
assert.strictEqual(getSystemErrorName(output.errno), 'EPIPE');
|
||||||
|
@ -13,9 +13,6 @@ const tmpFile = tmpdir.resolve('stdout.txt');
|
|||||||
tmpdir.refresh();
|
tmpdir.refresh();
|
||||||
|
|
||||||
function test(size, useBuffer, cb) {
|
function test(size, useBuffer, cb) {
|
||||||
const cmd = `"${process.argv[0]}" "${
|
|
||||||
useBuffer ? scriptBuffer : scriptString}" ${size} > "${tmpFile}"`;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs.unlinkSync(tmpFile);
|
fs.unlinkSync(tmpFile);
|
||||||
} catch {
|
} catch {
|
||||||
@ -24,7 +21,9 @@ function test(size, useBuffer, cb) {
|
|||||||
|
|
||||||
console.log(`${size} chars to ${tmpFile}...`);
|
console.log(`${size} chars to ${tmpFile}...`);
|
||||||
|
|
||||||
childProcess.exec(cmd, common.mustSucceed(() => {
|
childProcess.exec(...common.escapePOSIXShell`"${
|
||||||
|
process.execPath}" "${useBuffer ? scriptBuffer : scriptString}" ${size} > "${tmpFile
|
||||||
|
}"`, common.mustSucceed(() => {
|
||||||
console.log('done!');
|
console.log('done!');
|
||||||
|
|
||||||
const stat = fs.statSync(tmpFile);
|
const stat = fs.statSync(tmpFile);
|
||||||
|
@ -13,14 +13,7 @@ if (process.argv[2] === 'child') {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const cp = require('child_process');
|
const cp = require('child_process');
|
||||||
cp.exec([
|
cp.exec(...common.escapePOSIXShell`echo hello | "${process.execPath}" "${__filename}" child`, common.mustSucceed((stdout) => {
|
||||||
'echo',
|
|
||||||
'hello',
|
|
||||||
'|',
|
|
||||||
`"${process.execPath}"`,
|
|
||||||
`"${__filename}"`,
|
|
||||||
'child',
|
|
||||||
].join(' '), common.mustSucceed((stdout) => {
|
|
||||||
assert.strictEqual(stdout.split(os.EOL).shift().trim(), 'hello');
|
assert.strictEqual(stdout.split(os.EOL).shift().trim(), 'hello');
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -49,10 +49,10 @@ const server = tls.createServer(options, common.mustCall(function(conn) {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
server.listen(0, '127.0.0.1', common.mustCall(function() {
|
server.listen(0, '127.0.0.1', common.mustCall(function() {
|
||||||
const cmd = `"${common.opensslCli}" s_client -cipher ${
|
const cmd = common.escapePOSIXShell`"${common.opensslCli}" s_client -cipher ${
|
||||||
options.ciphers} -connect 127.0.0.1:${this.address().port}`;
|
options.ciphers} -connect 127.0.0.1:${this.address().port}`;
|
||||||
|
|
||||||
exec(cmd, common.mustSucceed((stdout, stderr) => {
|
exec(...cmd, common.mustSucceed((stdout, stderr) => {
|
||||||
assert(stdout.includes(reply));
|
assert(stdout.includes(reply));
|
||||||
server.close();
|
server.close();
|
||||||
}));
|
}));
|
||||||
|
@ -47,9 +47,7 @@ if (process.argv[2] === 'child') {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Limit the number of open files, to force workers to fail.
|
// Limit the number of open files, to force workers to fail.
|
||||||
let testCmd = `ulimit -n ${OPENFILES} && `;
|
const cp = child_process.exec(...common.escapePOSIXShell`ulimit -n ${OPENFILES} && "${process.execPath}" "${__filename}" child`);
|
||||||
testCmd += `${process.execPath} ${__filename} child`;
|
|
||||||
const cp = child_process.exec(testCmd);
|
|
||||||
|
|
||||||
// Turn on the child streams for debugging purposes.
|
// Turn on the child streams for debugging purposes.
|
||||||
let stdout = '';
|
let stdout = '';
|
||||||
|
@ -30,12 +30,14 @@ const fs = require('fs');
|
|||||||
|
|
||||||
const ulimit = Number(child_process.execSync('ulimit -Hn'));
|
const ulimit = Number(child_process.execSync('ulimit -Hn'));
|
||||||
if (ulimit > 64 || Number.isNaN(ulimit)) {
|
if (ulimit > 64 || Number.isNaN(ulimit)) {
|
||||||
|
const [cmd, opts] = common.escapePOSIXShell`ulimit -n 64 && "${process.execPath}" "${__filename}"`;
|
||||||
// Sorry about this nonsense. It can be replaced if
|
// Sorry about this nonsense. It can be replaced if
|
||||||
// https://github.com/nodejs/node-v0.x-archive/pull/2143#issuecomment-2847886
|
// https://github.com/nodejs/node-v0.x-archive/pull/2143#issuecomment-2847886
|
||||||
// ever happens.
|
// ever happens.
|
||||||
const result = child_process.spawnSync(
|
const result = child_process.spawnSync(
|
||||||
'/bin/sh',
|
'/bin/sh',
|
||||||
['-c', `ulimit -n 64 && '${process.execPath}' '${__filename}'`]
|
['-c', cmd],
|
||||||
|
opts,
|
||||||
);
|
);
|
||||||
assert.strictEqual(result.stdout.toString(), '');
|
assert.strictEqual(result.stdout.toString(), '');
|
||||||
assert.strictEqual(result.stderr.toString(), '');
|
assert.strictEqual(result.stderr.toString(), '');
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
require('../common');
|
const common = require('../common');
|
||||||
const { exec } = require('child_process');
|
const { exec } = require('child_process');
|
||||||
const { test } = require('node:test');
|
const { test } = require('node:test');
|
||||||
const fixtures = require('../common/fixtures');
|
const fixtures = require('../common/fixtures');
|
||||||
|
|
||||||
const node = process.execPath;
|
|
||||||
|
|
||||||
// Test both sets of arguments that check syntax
|
// Test both sets of arguments that check syntax
|
||||||
const syntaxArgs = [
|
const syntaxArgs = [
|
||||||
['-c'],
|
'-c',
|
||||||
['--check'],
|
'--check',
|
||||||
];
|
];
|
||||||
|
|
||||||
// Match on the name of the `Error` but not the message as it is different
|
// Match on the name of the `Error` but not the message as it is different
|
||||||
@ -27,13 +25,10 @@ const syntaxErrorRE = /^SyntaxError: \b/m;
|
|||||||
const path = fixtures.path(file);
|
const path = fixtures.path(file);
|
||||||
|
|
||||||
// Loop each possible option, `-c` or `--check`
|
// Loop each possible option, `-c` or `--check`
|
||||||
syntaxArgs.forEach((args) => {
|
syntaxArgs.forEach((flag) => {
|
||||||
test(`Checking syntax for ${file} with ${args.join(' ')}`, async (t) => {
|
test(`Checking syntax for ${file} with ${flag}`, async (t) => {
|
||||||
const _args = args.concat(path);
|
|
||||||
const cmd = [node, ..._args].join(' ');
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { stdout, stderr } = await execPromise(cmd);
|
const { stdout, stderr } = await execNode(flag, path);
|
||||||
|
|
||||||
// No stdout should be produced
|
// No stdout should be produced
|
||||||
t.assert.strictEqual(stdout, '');
|
t.assert.strictEqual(stdout, '');
|
||||||
@ -51,9 +46,9 @@ const syntaxErrorRE = /^SyntaxError: \b/m;
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Helper function to promisify exec
|
// Helper function to promisify exec
|
||||||
function execPromise(cmd) {
|
function execNode(flag, path) {
|
||||||
const { promise, resolve, reject } = Promise.withResolvers();
|
const { promise, resolve, reject } = Promise.withResolvers();
|
||||||
exec(cmd, (err, stdout, stderr) => {
|
exec(...common.escapePOSIXShell`"${process.execPath}" ${flag} "${path}"`, (err, stdout, stderr) => {
|
||||||
if (err) return reject({ ...err, stdout, stderr });
|
if (err) return reject({ ...err, stdout, stderr });
|
||||||
resolve({ stdout, stderr });
|
resolve({ stdout, stderr });
|
||||||
});
|
});
|
||||||
|
@ -5,15 +5,6 @@ const assert = require('assert');
|
|||||||
const { exec } = require('child_process');
|
const { exec } = require('child_process');
|
||||||
const fixtures = require('../common/fixtures');
|
const fixtures = require('../common/fixtures');
|
||||||
|
|
||||||
// The execPath might contain chars that should be escaped in a shell context.
|
|
||||||
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
|
||||||
// Windows, so we can simply pass the path.
|
|
||||||
const execNode = (flag, file, callback) => exec(
|
|
||||||
`"${common.isWindows ? process.execPath : '$NODE'}" ${flag} "${common.isWindows ? file : '$FILE'}"`,
|
|
||||||
common.isWindows ? undefined : { env: { ...process.env, NODE: process.execPath, FILE: file } },
|
|
||||||
callback,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Test both sets of arguments that check syntax
|
// Test both sets of arguments that check syntax
|
||||||
const syntaxArgs = [
|
const syntaxArgs = [
|
||||||
'-c',
|
'-c',
|
||||||
@ -31,7 +22,7 @@ const notFoundRE = /^Error: Cannot find module/m;
|
|||||||
|
|
||||||
// Loop each possible option, `-c` or `--check`
|
// Loop each possible option, `-c` or `--check`
|
||||||
syntaxArgs.forEach(function(flag) {
|
syntaxArgs.forEach(function(flag) {
|
||||||
execNode(flag, file, common.mustCall((err, stdout, stderr) => {
|
exec(...common.escapePOSIXShell`"${process.execPath}" ${flag} "${file}"`, common.mustCall((err, stdout, stderr) => {
|
||||||
// No stdout should be produced
|
// No stdout should be produced
|
||||||
assert.strictEqual(stdout, '');
|
assert.strictEqual(stdout, '');
|
||||||
|
|
||||||
|
@ -5,15 +5,6 @@ const assert = require('assert');
|
|||||||
const { exec } = require('child_process');
|
const { exec } = require('child_process');
|
||||||
const fixtures = require('../common/fixtures');
|
const fixtures = require('../common/fixtures');
|
||||||
|
|
||||||
// The execPath might contain chars that should be escaped in a shell context.
|
|
||||||
// On non-Windows, we can pass the path via the env; `"` is not a valid char on
|
|
||||||
// Windows, so we can simply pass the path.
|
|
||||||
const execNode = (flag, file, callback) => exec(
|
|
||||||
`"${common.isWindows ? process.execPath : '$NODE'}" ${flag} "${common.isWindows ? file : '$FILE'}"`,
|
|
||||||
common.isWindows ? undefined : { env: { ...process.env, NODE: process.execPath, FILE: file } },
|
|
||||||
callback,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Test both sets of arguments that check syntax
|
// Test both sets of arguments that check syntax
|
||||||
const syntaxArgs = [
|
const syntaxArgs = [
|
||||||
'-c',
|
'-c',
|
||||||
@ -33,7 +24,7 @@ const syntaxArgs = [
|
|||||||
|
|
||||||
// Loop each possible option, `-c` or `--check`
|
// Loop each possible option, `-c` or `--check`
|
||||||
syntaxArgs.forEach(function(flag) {
|
syntaxArgs.forEach(function(flag) {
|
||||||
execNode(flag, file, common.mustCall((err, stdout, stderr) => {
|
exec(...common.escapePOSIXShell`"${process.execPath}" ${flag} "${file}"`, common.mustCall((err, stdout, stderr) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('-- stdout --');
|
console.log('-- stdout --');
|
||||||
console.log(stdout);
|
console.log(stdout);
|
||||||
|
@ -35,8 +35,7 @@ if (process.env.TEST_INIT) {
|
|||||||
process.env.TEST_INIT = 1;
|
process.env.TEST_INIT = 1;
|
||||||
|
|
||||||
function test(file, expected) {
|
function test(file, expected) {
|
||||||
const path = `"${process.execPath}" ${file}`;
|
child.exec(...common.escapePOSIXShell`"${process.execPath}" "${file}"`, common.mustSucceed((out) => {
|
||||||
child.exec(path, { env: process.env }, common.mustSucceed((out) => {
|
|
||||||
assert.strictEqual(out, expected, `'node ${file}' failed!`);
|
assert.strictEqual(out, expected, `'node ${file}' failed!`);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user