11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst common = require('../common'); 41cb0ef41Sopenharmony_ciconst assert = require('assert'); 51cb0ef41Sopenharmony_ciconst { execFile, execFileSync } = require('child_process'); 61cb0ef41Sopenharmony_ciconst { getEventListeners } = require('events'); 71cb0ef41Sopenharmony_ciconst { getSystemErrorName } = require('util'); 81cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures'); 91cb0ef41Sopenharmony_ciconst os = require('os'); 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ciconst fixture = fixtures.path('exit.js'); 121cb0ef41Sopenharmony_ciconst echoFixture = fixtures.path('echo.js'); 131cb0ef41Sopenharmony_ciconst execOpts = { encoding: 'utf8', shell: true }; 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ci{ 161cb0ef41Sopenharmony_ci execFile( 171cb0ef41Sopenharmony_ci process.execPath, 181cb0ef41Sopenharmony_ci [fixture, 42], 191cb0ef41Sopenharmony_ci common.mustCall((e) => { 201cb0ef41Sopenharmony_ci // Check that arguments are included in message 211cb0ef41Sopenharmony_ci assert.strictEqual(e.message.trim(), 221cb0ef41Sopenharmony_ci `Command failed: ${process.execPath} ${fixture} 42`); 231cb0ef41Sopenharmony_ci assert.strictEqual(e.code, 42); 241cb0ef41Sopenharmony_ci }) 251cb0ef41Sopenharmony_ci ); 261cb0ef41Sopenharmony_ci} 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci{ 291cb0ef41Sopenharmony_ci // Verify that negative exit codes can be translated to UV error names. 301cb0ef41Sopenharmony_ci const errorString = `Error: Command failed: ${process.execPath}`; 311cb0ef41Sopenharmony_ci const code = -1; 321cb0ef41Sopenharmony_ci const callback = common.mustCall((err, stdout, stderr) => { 331cb0ef41Sopenharmony_ci assert.strictEqual(err.toString().trim(), errorString); 341cb0ef41Sopenharmony_ci assert.strictEqual(err.code, getSystemErrorName(code)); 351cb0ef41Sopenharmony_ci assert.strictEqual(err.killed, true); 361cb0ef41Sopenharmony_ci assert.strictEqual(err.signal, null); 371cb0ef41Sopenharmony_ci assert.strictEqual(err.cmd, process.execPath); 381cb0ef41Sopenharmony_ci assert.strictEqual(stdout.trim(), ''); 391cb0ef41Sopenharmony_ci assert.strictEqual(stderr.trim(), ''); 401cb0ef41Sopenharmony_ci }); 411cb0ef41Sopenharmony_ci const child = execFile(process.execPath, callback); 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci child.kill(); 441cb0ef41Sopenharmony_ci child.emit('close', code, null); 451cb0ef41Sopenharmony_ci} 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci{ 481cb0ef41Sopenharmony_ci // Verify the shell option works properly 491cb0ef41Sopenharmony_ci execFile(process.execPath, [fixture, 0], execOpts, common.mustSucceed()); 501cb0ef41Sopenharmony_ci} 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci{ 531cb0ef41Sopenharmony_ci // Verify that the signal option works properly 541cb0ef41Sopenharmony_ci const ac = new AbortController(); 551cb0ef41Sopenharmony_ci const { signal } = ac; 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci const test = () => { 581cb0ef41Sopenharmony_ci const check = common.mustCall((err) => { 591cb0ef41Sopenharmony_ci assert.strictEqual(err.code, 'ABORT_ERR'); 601cb0ef41Sopenharmony_ci assert.strictEqual(err.name, 'AbortError'); 611cb0ef41Sopenharmony_ci assert.strictEqual(err.signal, undefined); 621cb0ef41Sopenharmony_ci }); 631cb0ef41Sopenharmony_ci execFile(process.execPath, [echoFixture, 0], { signal }, check); 641cb0ef41Sopenharmony_ci }; 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci // Verify that it still works the same way now that the signal is aborted. 671cb0ef41Sopenharmony_ci test(); 681cb0ef41Sopenharmony_ci ac.abort(); 691cb0ef41Sopenharmony_ci} 701cb0ef41Sopenharmony_ci 711cb0ef41Sopenharmony_ci{ 721cb0ef41Sopenharmony_ci // Verify that does not spawn a child if already aborted 731cb0ef41Sopenharmony_ci const signal = AbortSignal.abort(); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci const check = common.mustCall((err) => { 761cb0ef41Sopenharmony_ci assert.strictEqual(err.code, 'ABORT_ERR'); 771cb0ef41Sopenharmony_ci assert.strictEqual(err.name, 'AbortError'); 781cb0ef41Sopenharmony_ci assert.strictEqual(err.signal, undefined); 791cb0ef41Sopenharmony_ci }); 801cb0ef41Sopenharmony_ci execFile(process.execPath, [echoFixture, 0], { signal }, check); 811cb0ef41Sopenharmony_ci} 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci{ 841cb0ef41Sopenharmony_ci // Verify that if something different than Abortcontroller.signal 851cb0ef41Sopenharmony_ci // is passed, ERR_INVALID_ARG_TYPE is thrown 861cb0ef41Sopenharmony_ci assert.throws(() => { 871cb0ef41Sopenharmony_ci const callback = common.mustNotCall(); 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci execFile(process.execPath, [echoFixture, 0], { signal: 'hello' }, callback); 901cb0ef41Sopenharmony_ci }, { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); 911cb0ef41Sopenharmony_ci} 921cb0ef41Sopenharmony_ci{ 931cb0ef41Sopenharmony_ci // Verify that the process completing removes the abort listener 941cb0ef41Sopenharmony_ci const ac = new AbortController(); 951cb0ef41Sopenharmony_ci const { signal } = ac; 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ci const callback = common.mustCall((err) => { 981cb0ef41Sopenharmony_ci assert.strictEqual(getEventListeners(ac.signal).length, 0); 991cb0ef41Sopenharmony_ci assert.strictEqual(err, null); 1001cb0ef41Sopenharmony_ci }); 1011cb0ef41Sopenharmony_ci execFile(process.execPath, [fixture, 0], { signal }, callback); 1021cb0ef41Sopenharmony_ci} 1031cb0ef41Sopenharmony_ci 1041cb0ef41Sopenharmony_ci// Verify the execFile() stdout is the same as execFileSync(). 1051cb0ef41Sopenharmony_ci{ 1061cb0ef41Sopenharmony_ci const file = 'echo'; 1071cb0ef41Sopenharmony_ci const args = ['foo', 'bar']; 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci // Test with and without `{ shell: true }` 1101cb0ef41Sopenharmony_ci [ 1111cb0ef41Sopenharmony_ci // Skipping shell-less test on Windows because its echo command is a shell built-in command. 1121cb0ef41Sopenharmony_ci ...(common.isWindows ? [] : [{ encoding: 'utf8' }]), 1131cb0ef41Sopenharmony_ci { shell: true, encoding: 'utf8' }, 1141cb0ef41Sopenharmony_ci ].forEach((options) => { 1151cb0ef41Sopenharmony_ci const execFileSyncStdout = execFileSync(file, args, options); 1161cb0ef41Sopenharmony_ci assert.strictEqual(execFileSyncStdout, `foo bar${os.EOL}`); 1171cb0ef41Sopenharmony_ci 1181cb0ef41Sopenharmony_ci execFile(file, args, options, common.mustCall((_, stdout) => { 1191cb0ef41Sopenharmony_ci assert.strictEqual(stdout, execFileSyncStdout); 1201cb0ef41Sopenharmony_ci })); 1211cb0ef41Sopenharmony_ci }); 1221cb0ef41Sopenharmony_ci} 123