2023-02-20 10:35:04 -05:00
|
|
|
// deno-fmt-ignore-file
|
|
|
|
// deno-lint-ignore-file
|
|
|
|
|
|
|
|
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
|
2024-11-25 08:35:53 -05:00
|
|
|
// Taken from Node 20.11.1
|
2024-04-02 18:24:55 -04:00
|
|
|
// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually.
|
2023-02-20 10:35:04 -05:00
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const assert = require('assert');
|
2024-06-11 07:41:44 -04:00
|
|
|
const { spawnSync, execFileSync } = require('child_process');
|
2023-02-20 10:35:04 -05:00
|
|
|
const common = require('./');
|
2024-06-11 07:41:44 -04:00
|
|
|
const util = require('util');
|
2023-02-20 10:35:04 -05:00
|
|
|
|
|
|
|
// 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 {
|
2024-06-11 07:41:44 -04:00
|
|
|
execFileSync(`${process.env.SystemRoot}\\System32\\wbem\\WMIC.exe`, [
|
|
|
|
'process',
|
|
|
|
'where',
|
|
|
|
`commandline like '%${basename}%child'`,
|
|
|
|
'delete',
|
|
|
|
'/nointeractive',
|
|
|
|
]);
|
2023-02-20 10:35:04 -05:00
|
|
|
} 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);
|
|
|
|
}
|
|
|
|
|
2024-06-11 07:41:44 -04:00
|
|
|
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,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-02-20 10:35:04 -05:00
|
|
|
module.exports = {
|
|
|
|
cleanupStaleProcess,
|
|
|
|
logAfterTime,
|
|
|
|
kExpiringChildRunTime,
|
2023-11-24 21:35:36 -05:00
|
|
|
kExpiringParentTimer,
|
2024-06-11 07:41:44 -04:00
|
|
|
spawnSyncAndExit,
|
|
|
|
spawnSyncAndExitWithoutError,
|
2023-02-20 10:35:04 -05:00
|
|
|
};
|