// 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, };