1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-27 01:29:14 -05:00
denoland-deno/tests/node_compat/test/common/child_process.js
Bartek Iwańczuk 03436e8f50
chore: sync up Node.js test files for v20.11.1 (#24066)
Co-authored-by: Yoshiya Hinosawa <stibium121@gmail.com>
2024-06-12 17:15:01 -07:00

146 lines
4.3 KiB
JavaScript

// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 18.12.1
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
'use strict';
const assert = require('assert');
const { spawnSync, execFileSync } = require('child_process');
const common = require('./');
const util = require('util');
// Workaround for Windows Server 2008R2
// When CMD is used to launch a process and CMD is killed too quickly, the
// process can stay behind running in suspended state, never completing.
function cleanupStaleProcess(filename) {
if (!common.isWindows) {
return;
}
process.once('beforeExit', () => {
const basename = filename.replace(/.*[/\\]/g, '');
try {
execFileSync(`${process.env.SystemRoot}\\System32\\wbem\\WMIC.exe`, [
'process',
'where',
`commandline like '%${basename}%child'`,
'delete',
'/nointeractive',
]);
} catch {
// Ignore failures, there might not be any stale process to clean up.
}
});
}
// This should keep the child process running long enough to expire
// the timeout.
const kExpiringChildRunTime = common.platformTimeout(20 * 1000);
const kExpiringParentTimer = 1;
assert(kExpiringChildRunTime > kExpiringParentTimer);
function logAfterTime(time) {
setTimeout(() => {
// The following console statements are part of the test.
console.log('child stdout');
console.error('child stderr');
}, time);
}
function checkOutput(str, check) {
if ((check instanceof RegExp && !check.test(str)) ||
(typeof check === 'string' && check !== str)) {
return { passed: false, reason: `did not match ${util.inspect(check)}` };
}
if (typeof check === 'function') {
try {
check(str);
} catch (error) {
return {
passed: false,
reason: `did not match expectation, checker throws:\n${util.inspect(error)}`,
};
}
}
return { passed: true };
}
function expectSyncExit(child, {
status,
signal,
stderr: stderrCheck,
stdout: stdoutCheck,
trim = false,
}) {
const failures = [];
let stderrStr, stdoutStr;
if (status !== undefined && child.status !== status) {
failures.push(`- process terminated with status ${child.status}, expected ${status}`);
}
if (signal !== undefined && child.signal !== signal) {
failures.push(`- process terminated with signal ${child.signal}, expected ${signal}`);
}
function logAndThrow() {
const tag = `[process ${child.pid}]:`;
console.error(`${tag} --- stderr ---`);
console.error(stderrStr === undefined ? child.stderr.toString() : stderrStr);
console.error(`${tag} --- stdout ---`);
console.error(stdoutStr === undefined ? child.stdout.toString() : stdoutStr);
console.error(`${tag} status = ${child.status}, signal = ${child.signal}`);
throw new Error(`${failures.join('\n')}`);
}
// If status and signal are not matching expectations, fail early.
if (failures.length !== 0) {
logAndThrow();
}
if (stderrCheck !== undefined) {
stderrStr = child.stderr.toString();
const { passed, reason } = checkOutput(trim ? stderrStr.trim() : stderrStr, stderrCheck);
if (!passed) {
failures.push(`- stderr ${reason}`);
}
}
if (stdoutCheck !== undefined) {
stdoutStr = child.stdout.toString();
const { passed, reason } = checkOutput(trim ? stdoutStr.trim() : stdoutStr, stdoutCheck);
if (!passed) {
failures.push(`- stdout ${reason}`);
}
}
if (failures.length !== 0) {
logAndThrow();
}
return { child, stderr: stderrStr, stdout: stdoutStr };
}
function spawnSyncAndExit(...args) {
const spawnArgs = args.slice(0, args.length - 1);
const expectations = args[args.length - 1];
const child = spawnSync(...spawnArgs);
return expectSyncExit(child, expectations);
}
function spawnSyncAndExitWithoutError(...args) {
const spawnArgs = args.slice(0, args.length);
const expectations = args[args.length - 1];
const child = spawnSync(...spawnArgs);
return expectSyncExit(child, {
status: 0,
signal: null,
...expectations,
});
}
module.exports = {
cleanupStaleProcess,
logAfterTime,
kExpiringChildRunTime,
kExpiringParentTimer,
spawnSyncAndExit,
spawnSyncAndExitWithoutError,
};