diff --git a/node/_tools/TODO.md b/node/_tools/TODO.md index b4aabc7ff8d1..8e2c95404f03 100644 --- a/node/_tools/TODO.md +++ b/node/_tools/TODO.md @@ -3,7 +3,7 @@ NOTE: This file should not be manually edited. Please edit `config.json` and run `deno task node:setup` instead. -Total: 2810 +Total: 2793 - [abort/test-abort-backtrace.js](https://github.com/nodejs/node/tree/v18.12.1/test/abort/test-abort-backtrace.js) - [abort/test-abort-fatal-error.js](https://github.com/nodejs/node/tree/v18.12.1/test/abort/test-abort-fatal-error.js) @@ -266,21 +266,12 @@ Total: 2810 - [parallel/test-child-process-advanced-serialization-largebuffer.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-advanced-serialization-largebuffer.js) - [parallel/test-child-process-advanced-serialization.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-advanced-serialization.js) - [parallel/test-child-process-bad-stdio.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-bad-stdio.js) -- [parallel/test-child-process-can-write-to-stdout.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-can-write-to-stdout.js) - [parallel/test-child-process-constructor.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-constructor.js) - [parallel/test-child-process-cwd.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-cwd.js) -- [parallel/test-child-process-default-options.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-default-options.js) - [parallel/test-child-process-detached.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-detached.js) - [parallel/test-child-process-disconnect.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-disconnect.js) -- [parallel/test-child-process-double-pipe.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-double-pipe.js) - [parallel/test-child-process-env.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-env.js) - [parallel/test-child-process-exec-any-shells-windows.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-exec-any-shells-windows.js) -- [parallel/test-child-process-exec-timeout-expire.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-exec-timeout-expire.js) -- [parallel/test-child-process-exec-timeout-kill.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-exec-timeout-kill.js) -- [parallel/test-child-process-exec-timeout-not-expired.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-exec-timeout-not-expired.js) -- [parallel/test-child-process-execfile-maxbuf.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-execfile-maxbuf.js) -- [parallel/test-child-process-exit-code.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-exit-code.js) -- [parallel/test-child-process-flush-stdio.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-flush-stdio.js) - [parallel/test-child-process-fork-abort-signal.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-fork-abort-signal.js) - [parallel/test-child-process-fork-and-spawn.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-fork-and-spawn.js) - [parallel/test-child-process-fork-args.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-fork-args.js) @@ -305,7 +296,6 @@ Total: 2810 - [parallel/test-child-process-http-socket-leak.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-http-socket-leak.js) - [parallel/test-child-process-internal.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-internal.js) - [parallel/test-child-process-ipc-next-tick.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-ipc-next-tick.js) -- [parallel/test-child-process-ipc.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-ipc.js) - [parallel/test-child-process-no-deprecation.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-no-deprecation.js) - [parallel/test-child-process-pipe-dataflow.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-pipe-dataflow.js) - [parallel/test-child-process-promisified.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-promisified.js) @@ -317,13 +307,10 @@ Total: 2810 - [parallel/test-child-process-send-type-error.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-send-type-error.js) - [parallel/test-child-process-send-utf8.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-send-utf8.js) - [parallel/test-child-process-server-close.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-server-close.js) -- [parallel/test-child-process-set-blocking.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-set-blocking.js) - [parallel/test-child-process-silent.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-silent.js) -- [parallel/test-child-process-spawn-args.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-spawn-args.js) - [parallel/test-child-process-spawn-argv0.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-spawn-argv0.js) - [parallel/test-child-process-spawn-controller.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-spawn-controller.js) - [parallel/test-child-process-spawn-error.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-spawn-error.js) -- [parallel/test-child-process-spawn-event.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-spawn-event.js) - [parallel/test-child-process-spawn-shell.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-spawn-shell.js) - [parallel/test-child-process-spawn-timeout-kill-signal.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-spawn-timeout-kill-signal.js) - [parallel/test-child-process-spawn-typeerror.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-spawn-typeerror.js) @@ -334,13 +321,10 @@ Total: 2810 - [parallel/test-child-process-stdin-ipc.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-stdin-ipc.js) - [parallel/test-child-process-stdin.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-stdin.js) - [parallel/test-child-process-stdio-big-write-end.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-stdio-big-write-end.js) -- [parallel/test-child-process-stdio-inherit.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-stdio-inherit.js) - [parallel/test-child-process-stdio-merge-stdouts-into-cat.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-stdio-merge-stdouts-into-cat.js) - [parallel/test-child-process-stdio-overlapped.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-stdio-overlapped.js) - [parallel/test-child-process-stdio-reuse-readable-stdio.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-stdio-reuse-readable-stdio.js) - [parallel/test-child-process-stdio.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-stdio.js) -- [parallel/test-child-process-stdout-flush-exit.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-stdout-flush-exit.js) -- [parallel/test-child-process-stdout-flush.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-stdout-flush.js) - [parallel/test-child-process-stdout-ipc.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-stdout-ipc.js) - [parallel/test-child-process-uid-gid.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-uid-gid.js) - [parallel/test-child-process-validate-stdio.js](https://github.com/nodejs/node/tree/v18.12.1/test/parallel/test-child-process-validate-stdio.js) @@ -2670,7 +2654,6 @@ Total: 2810 - [sequential/test-buffer-creation-regression.js](https://github.com/nodejs/node/tree/v18.12.1/test/sequential/test-buffer-creation-regression.js) - [sequential/test-child-process-emfile.js](https://github.com/nodejs/node/tree/v18.12.1/test/sequential/test-child-process-emfile.js) - [sequential/test-child-process-execsync.js](https://github.com/nodejs/node/tree/v18.12.1/test/sequential/test-child-process-execsync.js) -- [sequential/test-child-process-exit.js](https://github.com/nodejs/node/tree/v18.12.1/test/sequential/test-child-process-exit.js) - [sequential/test-child-process-pass-fd.js](https://github.com/nodejs/node/tree/v18.12.1/test/sequential/test-child-process-pass-fd.js) - [sequential/test-cli-syntax-bad.js](https://github.com/nodejs/node/tree/v18.12.1/test/sequential/test-cli-syntax-bad.js) - [sequential/test-cli-syntax-file-not-found.js](https://github.com/nodejs/node/tree/v18.12.1/test/sequential/test-cli-syntax-file-not-found.js) diff --git a/node/_tools/config.json b/node/_tools/config.json index 2846aa1b50dc..9ac0c36a46d1 100644 --- a/node/_tools/config.json +++ b/node/_tools/config.json @@ -4,8 +4,11 @@ "common": ["index.js", "internet.js", "tmpdir.js"], "fixtures": [ "child-process-spawn-node.js", + "echo.js", "elipses.txt", "empty.txt", + "exit.js", + "print-chars.js", "x.txt" ], "internet": [ @@ -27,9 +30,18 @@ "test-child-process-exec-kill-throws.js", "test-child-process-exec-maxbuf.js", "test-child-process-exec-std-encoding.js", + "test-child-process-exec-timeout-expire.js", + "test-child-process-exec-timeout-kill.js", + "test-child-process-exec-timeout-not-expired.js", + "test-child-process-execFile-promisified-abortController.js", "test-child-process-execfile.js", "test-child-process-execsync-maxbuf.js", + "test-child-process-exit-code.js", + "test-child-process-ipc.js", "test-child-process-spawnsync-env.js", + "test-child-process-stdio-inherit.js", + "test-child-process-stdout-flush-exit.js", + "test-child-process-stdout-flush.js", "test-console-instance.js", "test-crypto-hmac.js", "test-dgram-custom-lookup.js", @@ -91,10 +103,14 @@ "pummel": [ "test-net-bytes-per-incoming-chunk-overhead.js", "test-net-write-callbacks.js" + ], + "sequential": [ + "test-child-process-exit.js" ] }, "tests": { "common": [ + "child_process.js", "countdown.js", "dns.js", "duplexpair.js", @@ -104,13 +120,16 @@ "internet.js" ], "fixtures": [ + "GH-1899-output.js", "a.js", "child-process-spawn-node.js", + "child_process_should_emit_error.js", "echo.js", "elipses.txt", "empty.txt", "exit.js", "loop.js", + "print-chars.js", "x.txt" ], "fixtures/keys": [ @@ -183,6 +202,9 @@ "test-buffer-zero-fill-cli.js", "test-buffer-zero-fill-reset.js", "test-buffer-zero-fill.js", + "test-child-process-can-write-to-stdout.js", + "test-child-process-default-options.js", + "test-child-process-double-pipe.js", "test-child-process-exec-abortcontroller-promisified.js", "test-child-process-exec-cwd.js", "test-child-process-exec-encoding.js", @@ -192,16 +214,29 @@ "test-child-process-exec-maxbuf.js", "test-child-process-exec-std-encoding.js", "test-child-process-exec-stdout-stderr-data-string.js", + "test-child-process-exec-timeout-expire.js", + "test-child-process-exec-timeout-kill.js", + "test-child-process-exec-timeout-not-expired.js", "test-child-process-execFile-promisified-abortController.js", + "test-child-process-execfile-maxbuf.js", "test-child-process-execfile.js", "test-child-process-execfilesync-maxbuf.js", "test-child-process-execsync-maxbuf.js", + "test-child-process-exit-code.js", + "test-child-process-flush-stdio.js", + "test-child-process-ipc.js", "test-child-process-kill.js", + "test-child-process-set-blocking.js", + "test-child-process-spawn-args.js", + "test-child-process-spawn-event.js", "test-child-process-spawnsync-args.js", "test-child-process-spawnsync-env.js", "test-child-process-spawnsync-maxbuf.js", "test-child-process-spawnsync-validation-errors.js", "test-child-process-spawnsync.js", + "test-child-process-stdio-inherit.js", + "test-child-process-stdout-flush-exit.js", + "test-child-process-stdout-flush.js", "test-client-request-destroy.js", "test-console-async-write-error.js", "test-console-group.js", @@ -768,7 +803,9 @@ "test-net-pingpong-delay.js", "test-net-write-callbacks.js" ], - "sequential": [] + "sequential": [ + "test-child-process-exit.js" + ] }, "windowsIgnore": { "parallel": [ diff --git a/node/_tools/test/common/child_process.js b/node/_tools/test/common/child_process.js new file mode 100644 index 000000000000..4b553ea84bf4 --- /dev/null +++ b/node/_tools/test/common/child_process.js @@ -0,0 +1,56 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; + +const assert = require('assert'); +const common = require('./'); + +// 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 { + require('child_process') + .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); +} + +module.exports = { + cleanupStaleProcess, + logAfterTime, + kExpiringChildRunTime, + kExpiringParentTimer +}; diff --git a/node/_tools/test/fixtures/GH-1899-output.js b/node/_tools/test/fixtures/GH-1899-output.js new file mode 100644 index 000000000000..013b61ba0510 --- /dev/null +++ b/node/_tools/test/fixtures/GH-1899-output.js @@ -0,0 +1,30 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +console.log('hello, world!'); + diff --git a/node/_tools/test/fixtures/child_process_should_emit_error.js b/node/_tools/test/fixtures/child_process_should_emit_error.js new file mode 100644 index 000000000000..7ceaf9209080 --- /dev/null +++ b/node/_tools/test/fixtures/child_process_should_emit_error.js @@ -0,0 +1,36 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +const exec = require('child_process').exec; + +[0, 1].forEach(function(i) { + exec('ls', function(err, stdout, stderr) { + console.log(i); + throw new Error('hello world'); + }); +}); diff --git a/node/_tools/test/fixtures/echo.js b/node/_tools/test/fixtures/echo.js index 5c439d862132..893099e9bd9d 100644 --- a/node/_tools/test/fixtures/echo.js +++ b/node/_tools/test/fixtures/echo.js @@ -31,7 +31,10 @@ const assert = require('assert'); process.stdout.write('hello world\r\n'); -var stdin = process.openStdin(); +// TODO(PolarETech): process.openStdin() is not yet implemented. +// Use process.stdin instead. +var stdin = process.stdin; +// var stdin = process.openStdin(); stdin.on('data', function(data) { process.stdout.write(data.toString()); diff --git a/node/_tools/test/fixtures/exit.js b/node/_tools/test/fixtures/exit.js index ce93ad49cfa9..ca80f48286b3 100644 --- a/node/_tools/test/fixtures/exit.js +++ b/node/_tools/test/fixtures/exit.js @@ -26,4 +26,6 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -process.exit(process.argv[2] || 1); +// TODO(PolarETech): The process.argv[3] should be argv[2]. + +process.exit(process.argv[3] || 1); diff --git a/node/_tools/test/fixtures/print-chars.js b/node/_tools/test/fixtures/print-chars.js new file mode 100644 index 000000000000..2519c77fd2e6 --- /dev/null +++ b/node/_tools/test/fixtures/print-chars.js @@ -0,0 +1,35 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// TODO(PolarETech): The process.argv[3] should be argv[2]. + +const assert = require('assert'); + +var n = parseInt(process.argv[3]); + +process.stdout.write('c'.repeat(n)); diff --git a/node/_tools/test/parallel/test-child-process-can-write-to-stdout.js b/node/_tools/test/parallel/test-child-process-can-write-to-stdout.js new file mode 100644 index 000000000000..11dbf9bcb3d2 --- /dev/null +++ b/node/_tools/test/parallel/test-child-process-can-write-to-stdout.js @@ -0,0 +1,29 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +// Tests that a spawned child process can write to stdout without throwing. +// See https://github.com/nodejs/node-v0.x-archive/issues/1899. + +require('../common'); +const fixtures = require('../common/fixtures'); +const assert = require('assert'); +const spawn = require('child_process').spawn; + +const child = spawn(process.argv[0], [ + fixtures.path('GH-1899-output.js'), +]); +let output = ''; + +child.stdout.on('data', function(data) { + output += data; +}); + +child.on('exit', function(code, signal) { + assert.strictEqual(code, 0); + assert.strictEqual(output, 'hello, world!\n'); +}); diff --git a/node/_tools/test/parallel/test-child-process-default-options.js b/node/_tools/test/parallel/test-child-process-default-options.js new file mode 100644 index 000000000000..6f91058b51d7 --- /dev/null +++ b/node/_tools/test/parallel/test-child-process-default-options.js @@ -0,0 +1,58 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const { isWindows } = require('../common'); +const assert = require('assert'); + +const spawn = require('child_process').spawn; +const debug = require('util').debuglog('test'); + +process.env.HELLO = 'WORLD'; + +let child; +if (isWindows) { + child = spawn('cmd.exe', ['/c', 'set'], {}); +} else { + child = spawn('/usr/bin/env', [], {}); +} + +let response = ''; + +child.stdout.setEncoding('utf8'); + +child.stdout.on('data', function(chunk) { + debug(`stdout: ${chunk}`); + response += chunk; +}); + +process.on('exit', function() { + assert.ok(response.includes('HELLO=WORLD'), + 'spawn did not use process.env as default ' + + `(process.env.HELLO = ${process.env.HELLO})`); +}); diff --git a/node/_tools/test/parallel/test-child-process-double-pipe.js b/node/_tools/test/parallel/test-child-process-double-pipe.js new file mode 100644 index 000000000000..081eda3cb40e --- /dev/null +++ b/node/_tools/test/parallel/test-child-process-double-pipe.js @@ -0,0 +1,129 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const { + isWindows, + mustCall, + mustCallAtLeast, +} = require('../common'); +const assert = require('assert'); +const os = require('os'); +const spawn = require('child_process').spawn; +const debug = require('util').debuglog('test'); + +// We're trying to reproduce: +// $ echo "hello\nnode\nand\nworld" | grep o | sed s/o/a/ + +let grep, sed, echo; + +if (isWindows) { + grep = spawn('grep', ['--binary', 'o']); + sed = spawn('sed', ['--binary', 's/o/O/']); + echo = spawn('cmd.exe', + ['/c', 'echo', 'hello&&', 'echo', + 'node&&', 'echo', 'and&&', 'echo', 'world']); +} else { + grep = spawn('grep', ['o']); + sed = spawn('sed', ['s/o/O/']); + echo = spawn('echo', ['hello\nnode\nand\nworld\n']); +} + +// If the spawn function leaks file descriptors to subprocesses, grep and sed +// hang. +// This happens when calling pipe(2) and then forgetting to set the +// FD_CLOEXEC flag on the resulting file descriptors. +// +// This test checks child processes exit, meaning they don't hang like +// explained above. + + +// pipe echo | grep +echo.stdout.on('data', mustCallAtLeast((data) => { + debug(`grep stdin write ${data.length}`); + if (!grep.stdin.write(data)) { + echo.stdout.pause(); + } +})); + +// TODO(@jasnell): This does not appear to ever be +// emitted. It's not clear if it is necessary. +grep.stdin.on('drain', (data) => { + echo.stdout.resume(); +}); + +// Propagate end from echo to grep +echo.stdout.on('end', mustCall((code) => { + grep.stdin.end(); +})); + +echo.on('exit', mustCall(() => { + debug('echo exit'); +})); + +grep.on('exit', mustCall(() => { + debug('grep exit'); +})); + +sed.on('exit', mustCall(() => { + debug('sed exit'); +})); + + +// pipe grep | sed +grep.stdout.on('data', mustCallAtLeast((data) => { + debug(`grep stdout ${data.length}`); + if (!sed.stdin.write(data)) { + grep.stdout.pause(); + } +})); + +// TODO(@jasnell): This does not appear to ever be +// emitted. It's not clear if it is necessary. +sed.stdin.on('drain', (data) => { + grep.stdout.resume(); +}); + +// Propagate end from grep to sed +grep.stdout.on('end', mustCall((code) => { + debug('grep stdout end'); + sed.stdin.end(); +})); + + +let result = ''; + +// print sed's output +sed.stdout.on('data', mustCallAtLeast((data) => { + result += data.toString('utf8', 0, data.length); + debug(data); +})); + +sed.stdout.on('end', mustCall((code) => { + assert.strictEqual(result, `hellO${os.EOL}nOde${os.EOL}wOrld${os.EOL}`); +})); diff --git a/node/_tools/test/parallel/test-child-process-exec-abortcontroller-promisified.js b/node/_tools/test/parallel/test-child-process-exec-abortcontroller-promisified.js index 64a39f50f25f..4ba699ba49e8 100644 --- a/node/_tools/test/parallel/test-child-process-exec-abortcontroller-promisified.js +++ b/node/_tools/test/parallel/test-child-process-exec-abortcontroller-promisified.js @@ -5,7 +5,7 @@ // Taken from Node 18.8.0 // This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually -// TODO(#2674): The "eval" subcommand passed to execPromisifed() should be the "-e" option. +// TODO(PolarETech): The "eval" subcommand passed to execPromisifed() should be the "-e" option. 'use strict'; const common = require('../common'); diff --git a/node/_tools/test/parallel/test-child-process-exec-encoding.js b/node/_tools/test/parallel/test-child-process-exec-encoding.js index e96fa1102143..fe03e98d0663 100644 --- a/node/_tools/test/parallel/test-child-process-exec-encoding.js +++ b/node/_tools/test/parallel/test-child-process-exec-encoding.js @@ -5,9 +5,9 @@ // Taken from Node 18.8.0 // This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually -// TODO(#2674): The process.argv[3] check should be argv[2], and the +// TODO(PolarETech): The process.argv[3] check should be argv[2], and the // command passed to exec() should not need to include "run", "-A", -// "--unstable", and "require.ts". +// and "require.ts". 'use strict'; const common = require('../common'); @@ -24,7 +24,7 @@ if (process.argv[3] === 'child') { const expectedStdout = `${stdoutData}\n`; const expectedStderr = `${stderrData}\n`; function run(options, callback) { - const cmd = `"${process.execPath}" run -A --unstable require.ts "${__filename}" child`; + const cmd = `"${process.execPath}" run -A require.ts "${__filename}" child`; cp.exec(cmd, options, common.mustSucceed((stdout, stderr) => { callback(stdout, stderr); diff --git a/node/_tools/test/parallel/test-child-process-exec-kill-throws.js b/node/_tools/test/parallel/test-child-process-exec-kill-throws.js index c908d15c1a24..6a28c2a18dfd 100644 --- a/node/_tools/test/parallel/test-child-process-exec-kill-throws.js +++ b/node/_tools/test/parallel/test-child-process-exec-kill-throws.js @@ -5,9 +5,9 @@ // Taken from Node 18.8.0 // This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually -// TODO(#2674): The process.argv[3] check should be argv[2], and the +// TODO(PolarETech): The process.argv[3] check should be argv[2], and the // command passed to exec() should not need to include "run", "-A", -// "--unstable", and "require.ts". +// and "require.ts". 'use strict'; // Flags: --expose-internals @@ -29,7 +29,7 @@ if (process.argv[3] === 'child') { throw new Error('mock error'); }; - const cmd = `"${process.execPath}" run -A --unstable require.ts "${__filename}" child`; + const cmd = `"${process.execPath}" run -A require.ts "${__filename}" child`; const options = { maxBuffer: 0, killSignal: 'SIGKILL' }; const child = cp.exec(cmd, options, common.mustCall((err, stdout, stderr) => { diff --git a/node/_tools/test/parallel/test-child-process-exec-maxbuf.js b/node/_tools/test/parallel/test-child-process-exec-maxbuf.js index deafc7a6e73f..2e99855c040f 100644 --- a/node/_tools/test/parallel/test-child-process-exec-maxbuf.js +++ b/node/_tools/test/parallel/test-child-process-exec-maxbuf.js @@ -5,7 +5,7 @@ // Taken from Node 18.8.0 // This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually -// TODO(#2674): The "eval" subcommand passed to exec() should be the "-e" option. +// TODO(PolarETech): The "eval" subcommand passed to exec() should be the "-e" option. 'use strict'; const common = require('../common'); diff --git a/node/_tools/test/parallel/test-child-process-exec-std-encoding.js b/node/_tools/test/parallel/test-child-process-exec-std-encoding.js index 2ef794a64277..85f3ec2bf175 100644 --- a/node/_tools/test/parallel/test-child-process-exec-std-encoding.js +++ b/node/_tools/test/parallel/test-child-process-exec-std-encoding.js @@ -5,9 +5,9 @@ // Taken from Node 18.8.0 // This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually -// TODO(#2674): The process.argv[3] check should be argv[2], and the +// TODO(PolarETech): The process.argv[3] check should be argv[2], and the // command passed to exec() should not need to include "run", "-A", -// "--unstable", and "require.ts". +// and "require.ts". 'use strict'; const common = require('../common'); @@ -23,7 +23,7 @@ if (process.argv[3] === 'child') { console.log(stdoutData); console.error(stderrData); } else { - const cmd = `"${process.execPath}" run -A --unstable require.ts "${__filename}" child`; + const cmd = `"${process.execPath}" run -A require.ts "${__filename}" child`; const child = cp.exec(cmd, common.mustSucceed((stdout, stderr) => { assert.strictEqual(stdout, expectedStdout); assert.strictEqual(stderr, expectedStderr); diff --git a/node/_tools/test/parallel/test-child-process-exec-timeout-expire.js b/node/_tools/test/parallel/test-child-process-exec-timeout-expire.js new file mode 100644 index 000000000000..67c4a7204608 --- /dev/null +++ b/node/_tools/test/parallel/test-child-process-exec-timeout-expire.js @@ -0,0 +1,61 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +// TODO(PolarETech): The process.argv[3] check should be argv[2], and the +// command passed to exec() should not need to include "run", "-A", +// and "require.ts". + +'use strict'; + +// Test exec() with a timeout that expires. + +const common = require('../common'); +const assert = require('assert'); +const cp = require('child_process'); + +const { + cleanupStaleProcess, + logAfterTime, + kExpiringChildRunTime, + kExpiringParentTimer +} = require('../common/child_process'); + +if (process.argv[3] === 'child') { + logAfterTime(kExpiringChildRunTime); + return; +} + +const cmd = `"${process.execPath}" run -A require.ts "${__filename}" child`; + +cp.exec(cmd, { + timeout: kExpiringParentTimer, +}, common.mustCall((err, stdout, stderr) => { + console.log('[stdout]', stdout.trim()); + console.log('[stderr]', stderr.trim()); + + let sigterm = 'SIGTERM'; + assert.strictEqual(err.killed, true); + // TODO OpenBSD returns a null signal and 143 for code + if (common.isOpenBSD) { + assert.strictEqual(err.code, 143); + sigterm = null; + } else { + assert.strictEqual(err.code, null); + } + // At least starting with Darwin Kernel Version 16.4.0, sending a SIGTERM to a + // process that is still starting up kills it with SIGKILL instead of SIGTERM. + // See: https://github.com/libuv/libuv/issues/1226 + if (common.isOSX) + assert.ok(err.signal === 'SIGTERM' || err.signal === 'SIGKILL'); + else + assert.strictEqual(err.signal, sigterm); + assert.strictEqual(err.cmd, cmd); + assert.strictEqual(stdout.trim(), ''); + assert.strictEqual(stderr.trim(), ''); +})); + +cleanupStaleProcess(__filename); diff --git a/node/_tools/test/parallel/test-child-process-exec-timeout-kill.js b/node/_tools/test/parallel/test-child-process-exec-timeout-kill.js new file mode 100644 index 000000000000..fd4884fc5fc8 --- /dev/null +++ b/node/_tools/test/parallel/test-child-process-exec-timeout-kill.js @@ -0,0 +1,50 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +// TODO(PolarETech): The process.argv[3] check should be argv[2], and the +// command passed to exec() should not need to include "run", "-A", +// and "require.ts". + +'use strict'; + +// Test exec() with both a timeout and a killSignal. + +const common = require('../common'); +const assert = require('assert'); +const cp = require('child_process'); + +const { + cleanupStaleProcess, + logInTimeout, + kExpiringChildRunTime, + kExpiringParentTimer, +} = require('../common/child_process'); + +if (process.argv[3] === 'child') { + logInTimeout(kExpiringChildRunTime); + return; +} + +const cmd = `"${process.execPath}" run -A require.ts "${__filename}" child`; + +// Test with a different kill signal. +cp.exec(cmd, { + timeout: kExpiringParentTimer, + killSignal: 'SIGKILL' +}, common.mustCall((err, stdout, stderr) => { + console.log('[stdout]', stdout.trim()); + console.log('[stderr]', stderr.trim()); + + assert.strictEqual(err.killed, true); + assert.strictEqual(err.code, null); + assert.strictEqual(err.signal, 'SIGKILL'); + assert.strictEqual(err.cmd, cmd); + assert.strictEqual(stdout.trim(), ''); + assert.strictEqual(stderr.trim(), ''); +})); + +cleanupStaleProcess(__filename); diff --git a/node/_tools/test/parallel/test-child-process-exec-timeout-not-expired.js b/node/_tools/test/parallel/test-child-process-exec-timeout-not-expired.js new file mode 100644 index 000000000000..31fa1f7259f7 --- /dev/null +++ b/node/_tools/test/parallel/test-child-process-exec-timeout-not-expired.js @@ -0,0 +1,45 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +// TODO(PolarETech): The process.argv[3] check should be argv[2], and the +// command passed to exec() should not need to include "run", "-A", +// and "require.ts". + +'use strict'; + +// Test exec() when a timeout is set, but not expired. + +const common = require('../common'); +const assert = require('assert'); +const cp = require('child_process'); + +const { + cleanupStaleProcess, + logAfterTime +} = require('../common/child_process'); + +const kTimeoutNotSupposedToExpire = 2 ** 30; +const childRunTime = common.platformTimeout(100); + +// The time spent in the child should be smaller than the timeout below. +assert(childRunTime < kTimeoutNotSupposedToExpire); + +if (process.argv[3] === 'child') { + logAfterTime(childRunTime); + return; +} + +const cmd = `"${process.execPath}" run -A require.ts "${__filename}" child`; + +cp.exec(cmd, { + timeout: kTimeoutNotSupposedToExpire +}, common.mustSucceed((stdout, stderr) => { + assert.strictEqual(stdout.trim(), 'child stdout'); + assert.strictEqual(stderr.trim(), 'child stderr'); +})); + +cleanupStaleProcess(__filename); diff --git a/node/_tools/test/parallel/test-child-process-execFile-promisified-abortController.js b/node/_tools/test/parallel/test-child-process-execFile-promisified-abortController.js index 7845bec1d757..fe3e8765ea26 100644 --- a/node/_tools/test/parallel/test-child-process-execFile-promisified-abortController.js +++ b/node/_tools/test/parallel/test-child-process-execFile-promisified-abortController.js @@ -5,6 +5,9 @@ // Taken from Node 18.12.1 // This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually +// TODO(PolarETech): The args passed to promisified() should not need to +// include "require.ts". + 'use strict'; const common = require('../common'); @@ -24,7 +27,7 @@ const invalidArgTypeError = { // Verify that the signal option works properly const ac = new AbortController(); const signal = ac.signal; - const promise = promisified(process.execPath, [echoFixture, 0], { signal }); + const promise = promisified(process.execPath, ['require.ts', echoFixture, 0], { signal }); ac.abort(); @@ -39,7 +42,7 @@ const invalidArgTypeError = { const signal = AbortSignal.abort(); assert.rejects( - promisified(process.execPath, [echoFixture, 0], { signal }), + promisified(process.execPath, ['require.ts', echoFixture, 0], { signal }), { name: 'AbortError' } ).then(common.mustCall()); } @@ -49,7 +52,7 @@ const invalidArgTypeError = { // is passed, ERR_INVALID_ARG_TYPE is thrown const signal = {}; assert.throws(() => { - promisified(process.execPath, [echoFixture, 0], { signal }); + promisified(process.execPath, ['require.ts', echoFixture, 0], { signal }); }, invalidArgTypeError); } @@ -58,6 +61,6 @@ const invalidArgTypeError = { // is passed, ERR_INVALID_ARG_TYPE is thrown const signal = 'world!'; assert.throws(() => { - promisified(process.execPath, [echoFixture, 0], { signal }); + promisified(process.execPath, ['require.ts', echoFixture, 0], { signal }); }, invalidArgTypeError); } diff --git a/node/_tools/test/parallel/test-child-process-execfile-maxbuf.js b/node/_tools/test/parallel/test-child-process-execfile-maxbuf.js new file mode 100644 index 000000000000..ef31f4e22520 --- /dev/null +++ b/node/_tools/test/parallel/test-child-process-execfile-maxbuf.js @@ -0,0 +1,99 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { execFile } = require('child_process'); + +function checkFactory(streamName) { + return common.mustCall((err) => { + assert(err instanceof RangeError); + assert.strictEqual(err.message, `${streamName} maxBuffer length exceeded`); + assert.strictEqual(err.code, 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER'); + }); +} + +// default value +{ + execFile( + process.execPath, + ['-e', 'console.log("a".repeat(1024 * 1024))'], + checkFactory('stdout') + ); +} + +// default value +{ + execFile( + process.execPath, + ['-e', 'console.log("a".repeat(1024 * 1024 - 1))'], + common.mustSucceed((stdout, stderr) => { + assert.strictEqual(stdout.trim(), 'a'.repeat(1024 * 1024 - 1)); + assert.strictEqual(stderr, ''); + }) + ); +} + +{ + const options = { maxBuffer: Infinity }; + + execFile( + process.execPath, + ['-e', 'console.log("hello world");'], + options, + common.mustSucceed((stdout, stderr) => { + assert.strictEqual(stdout.trim(), 'hello world'); + assert.strictEqual(stderr, ''); + }) + ); +} + +{ + execFile('echo', ['hello world'], { maxBuffer: 5 }, checkFactory('stdout')); +} + +const unicode = '中文测试'; // length = 4, byte length = 12 + +{ + execFile( + process.execPath, + ['-e', `console.log('${unicode}');`], + { maxBuffer: 10 }, + checkFactory('stdout')); +} + +{ + execFile( + process.execPath, + ['-e', `console.error('${unicode}');`], + { maxBuffer: 10 }, + checkFactory('stderr') + ); +} + +{ + const child = execFile( + process.execPath, + ['-e', `console.log('${unicode}');`], + { encoding: null, maxBuffer: 10 }, + checkFactory('stdout') + ); + + child.stdout.setEncoding('utf-8'); +} + +{ + const child = execFile( + process.execPath, + ['-e', `console.error('${unicode}');`], + { encoding: null, maxBuffer: 10 }, + checkFactory('stderr') + ); + + child.stderr.setEncoding('utf-8'); +} diff --git a/node/_tools/test/parallel/test-child-process-execfile.js b/node/_tools/test/parallel/test-child-process-execfile.js index 651a3ed105b3..9f9268407baa 100644 --- a/node/_tools/test/parallel/test-child-process-execfile.js +++ b/node/_tools/test/parallel/test-child-process-execfile.js @@ -5,6 +5,9 @@ // Taken from Node 18.8.0 // This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually +// TODO(PolarETech): The args passed to execFile() should not need to +// include "require.ts". + // TODO(cjihrig): See inline TODO comments below. 'use strict'; @@ -20,20 +23,18 @@ const fixture = fixtures.path('exit.js'); const echoFixture = fixtures.path('echo.js'); const execOpts = { encoding: 'utf8', shell: true }; -// TODO(cjihrig): The fixture depends on process.argv, which is currently -// inaccurate when passing all of the required parameters for Deno. -// { -// execFile( -// process.execPath, -// [fixture, 42], -// common.mustCall((e) => { -// // Check that arguments are included in message -// assert.strictEqual(e.message.trim(), -// `Command failed: ${process.execPath} ${fixture} 42`); -// assert.strictEqual(e.code, 42); -// }) -// ); -// } +{ + execFile( + process.execPath, + ['require.ts', fixture, 42], + common.mustCall((e) => { + // Check that arguments are included in message + assert.strictEqual(e.message.trim(), + `Command failed: ${process.execPath} require.ts ${fixture} 42`); + assert.strictEqual(e.code, 42); + }) + ); +} { // Verify that negative exit codes can be translated to UV error names. @@ -70,7 +71,7 @@ const execOpts = { encoding: 'utf8', shell: true }; assert.strictEqual(err.name, 'AbortError'); assert.strictEqual(err.signal, undefined); }); - execFile(process.execPath, [echoFixture, 0], { signal }, check); + execFile(process.execPath, ['require.ts', echoFixture, 0], { signal }, check); }; // Verify that it still works the same way now that the signal is aborted. @@ -87,7 +88,7 @@ const execOpts = { encoding: 'utf8', shell: true }; assert.strictEqual(err.name, 'AbortError'); assert.strictEqual(err.signal, undefined); }); - execFile(process.execPath, [echoFixture, 0], { signal }, check); + execFile(process.execPath, ['require.ts', echoFixture, 0], { signal }, check); } { @@ -96,7 +97,7 @@ const execOpts = { encoding: 'utf8', shell: true }; assert.throws(() => { const callback = common.mustNotCall(() => {}); - execFile(process.execPath, [echoFixture, 0], { signal: 'hello' }, callback); + execFile(process.execPath, ['require.ts', echoFixture, 0], { signal: 'hello' }, callback); }, { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); } { diff --git a/node/_tools/test/parallel/test-child-process-exit-code.js b/node/_tools/test/parallel/test-child-process-exit-code.js new file mode 100644 index 000000000000..caa57986b42b --- /dev/null +++ b/node/_tools/test/parallel/test-child-process-exit-code.js @@ -0,0 +1,51 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// TODO(PolarETech): The args passed to spawn() should not need to +// include "require.ts". + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const spawn = require('child_process').spawn; +const fixtures = require('../common/fixtures'); + +const exitScript = fixtures.path('exit.js'); +const exitChild = spawn(process.argv[0], ['require.ts', exitScript, 23]); +exitChild.on('exit', common.mustCall(function(code, signal) { + assert.strictEqual(code, 23); + assert.strictEqual(signal, null); +})); + + +const errorScript = fixtures.path('child_process_should_emit_error.js'); +const errorChild = spawn(process.argv[0], ['require.ts', errorScript]); +errorChild.on('exit', common.mustCall(function(code, signal) { + assert.ok(code !== 0); + assert.strictEqual(signal, null); +})); diff --git a/node/_tools/test/parallel/test-child-process-flush-stdio.js b/node/_tools/test/parallel/test-child-process-flush-stdio.js new file mode 100644 index 000000000000..72357bcdd42f --- /dev/null +++ b/node/_tools/test/parallel/test-child-process-flush-stdio.js @@ -0,0 +1,40 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +const common = require('../common'); +const cp = require('child_process'); +const assert = require('assert'); + +// Windows' `echo` command is a built-in shell command and not an external +// executable like on *nix +const opts = { shell: common.isWindows }; + +const p = cp.spawn('echo', [], opts); + +p.on('close', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + spawnWithReadable(); +})); + +p.stdout.read(); + +const spawnWithReadable = () => { + const buffer = []; + const p = cp.spawn('echo', ['123'], opts); + p.on('close', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + assert.strictEqual(Buffer.concat(buffer).toString().trim(), '123'); + })); + p.stdout.on('readable', () => { + let buf; + while ((buf = p.stdout.read()) !== null) + buffer.push(buf); + }); +}; diff --git a/node/_tools/test/parallel/test-child-process-ipc.js b/node/_tools/test/parallel/test-child-process-ipc.js new file mode 100644 index 000000000000..c1d7bc2b6184 --- /dev/null +++ b/node/_tools/test/parallel/test-child-process-ipc.js @@ -0,0 +1,73 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// TODO(PolarETech): The args passed to spawn() should not need to +// include "require.ts". + +'use strict'; + +const { + mustCall, + mustNotCall, +} = require('../common'); +const assert = require('assert'); +const debug = require('util').debuglog('test'); + +const { spawn } = require('child_process'); +const fixtures = require('../common/fixtures'); + +const sub = fixtures.path('echo.js'); + +const child = spawn(process.argv[0], ['require.ts', sub]); + +child.stderr.on('data', mustNotCall()); + +child.stdout.setEncoding('utf8'); + +const messages = [ + 'hello world\r\n', + 'echo me\r\n', +]; + +child.stdout.on('data', mustCall((data) => { + debug(`child said: ${JSON.stringify(data)}`); + const test = messages.shift(); + debug(`testing for '${test}'`); + assert.strictEqual(data, test); + if (messages.length) { + debug(`writing '${messages[0]}'`); + child.stdin.write(messages[0]); + } else { + assert.strictEqual(messages.length, 0); + child.stdin.end(); + } +}, messages.length)); + +child.stdout.on('end', mustCall((data) => { + debug('child end'); +})); diff --git a/node/_tools/test/parallel/test-child-process-set-blocking.js b/node/_tools/test/parallel/test-child-process-set-blocking.js new file mode 100644 index 000000000000..0c771bad8fb9 --- /dev/null +++ b/node/_tools/test/parallel/test-child-process-set-blocking.js @@ -0,0 +1,43 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const ch = require('child_process'); + +const SIZE = 100000; +const python = process.env.PYTHON || (common.isWindows ? 'python' : 'python3'); + +const cp = ch.spawn(python, ['-c', `print(${SIZE} * "C")`], { + stdio: 'inherit' +}); + +cp.on('exit', common.mustCall(function(code) { + assert.strictEqual(code, 0); +})); diff --git a/node/_tools/test/parallel/test-child-process-spawn-args.js b/node/_tools/test/parallel/test-child-process-spawn-args.js new file mode 100644 index 000000000000..1e3378935fe4 --- /dev/null +++ b/node/_tools/test/parallel/test-child-process-spawn-args.js @@ -0,0 +1,62 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; + +// This test confirms that `undefined`, `null`, and `[]` +// can be used as a placeholder for the second argument (`args`) of `spawn()`. +// Previously, there was a bug where using `undefined` for the second argument +// caused the third argument (`options`) to be ignored. +// See https://github.com/nodejs/node/issues/24912. + +const common = require('../common'); +const tmpdir = require('../common/tmpdir'); + +const assert = require('assert'); +const { spawn } = require('child_process'); + +tmpdir.refresh(); + +const command = common.isWindows ? 'cd' : 'pwd'; +const options = { cwd: tmpdir.path }; + +if (common.isWindows) { + // This test is not the case for Windows based systems + // unless the `shell` options equals to `true` + + options.shell = true; +} + +const testCases = [ + undefined, + null, + [], +]; + +const expectedResult = tmpdir.path.trim().toLowerCase(); + +(async () => { + const results = await Promise.all( + testCases.map((testCase) => { + return new Promise((resolve) => { + const subprocess = spawn(command, testCase, options); + + let accumulatedData = Buffer.alloc(0); + + subprocess.stdout.on('data', common.mustCall((data) => { + accumulatedData = Buffer.concat([accumulatedData, data]); + })); + + subprocess.stdout.on('end', () => { + resolve(accumulatedData.toString().trim().toLowerCase()); + }); + }); + }) + ); + + assert.deepStrictEqual([...new Set(results)], [expectedResult]); +})().then(common.mustCall()); diff --git a/node/_tools/test/parallel/test-child-process-spawn-event.js b/node/_tools/test/parallel/test-child-process-spawn-event.js new file mode 100644 index 000000000000..62252f829ff2 --- /dev/null +++ b/node/_tools/test/parallel/test-child-process-spawn-event.js @@ -0,0 +1,34 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +'use strict'; +const common = require('../common'); +const spawn = require('child_process').spawn; +const assert = require('assert'); + +const subprocess = spawn('echo', ['ok']); + +let didSpawn = false; +subprocess.on('spawn', function() { + didSpawn = true; +}); +function mustCallAfterSpawn() { + return common.mustCall(function() { + assert.ok(didSpawn); + }); +} + +subprocess.on('error', common.mustNotCall()); +subprocess.on('spawn', common.mustCall()); +subprocess.stdout.on('data', mustCallAfterSpawn()); +subprocess.stdout.on('end', mustCallAfterSpawn()); +subprocess.stdout.on('close', mustCallAfterSpawn()); +subprocess.stderr.on('data', common.mustNotCall()); +subprocess.stderr.on('end', mustCallAfterSpawn()); +subprocess.stderr.on('close', mustCallAfterSpawn()); +subprocess.on('exit', mustCallAfterSpawn()); +subprocess.on('close', mustCallAfterSpawn()); diff --git a/node/_tools/test/parallel/test-child-process-stdio-inherit.js b/node/_tools/test/parallel/test-child-process-stdio-inherit.js new file mode 100644 index 000000000000..e213dd6b8009 --- /dev/null +++ b/node/_tools/test/parallel/test-child-process-stdio-inherit.js @@ -0,0 +1,66 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// TODO(PolarETech): The process.argv[3] check should be argv[2], and +// the args passed to spawn() should not need to include "require.ts". + +'use strict'; +require('../common'); +const assert = require('assert'); +const spawn = require('child_process').spawn; + +if (process.argv[3] === 'parent') + parent(); +else + grandparent(); + +function grandparent() { + const child = spawn(process.execPath, ['require.ts', __filename, 'parent']); + child.stderr.pipe(process.stderr); + let output = ''; + const input = 'asdfasdf'; + + child.stdout.on('data', function(chunk) { + output += chunk; + }); + child.stdout.setEncoding('utf8'); + + child.stdin.end(input); + + child.on('close', function(code, signal) { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + // 'cat' on windows adds a \r\n at the end. + assert.strictEqual(output.trim(), input.trim()); + }); +} + +function parent() { + // Should not immediately exit. + spawn('cat', [], { stdio: 'inherit' }); +} diff --git a/node/_tools/test/parallel/test-child-process-stdout-flush-exit.js b/node/_tools/test/parallel/test-child-process-stdout-flush-exit.js new file mode 100644 index 000000000000..585cc6084062 --- /dev/null +++ b/node/_tools/test/parallel/test-child-process-stdout-flush-exit.js @@ -0,0 +1,67 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// TODO(PolarETech): The process.argv[3] check should be argv[2], +// the args passed to spawn() should not need to include "require.ts", +// and the process.argv[2] passed to spawn() should be argv[1]. + +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +// If child process output to console and exit +// The console.log statements here are part of the test. +if (process.argv[3] === 'child') { + console.log('hello'); + for (let i = 0; i < 200; i++) { + console.log('filler'); + } + console.log('goodbye'); + process.exit(0); +} else { + // parent process + const spawn = require('child_process').spawn; + + // spawn self as child + const child = spawn(process.argv[0], ['require.ts', process.argv[2], 'child']); + + let stdout = ''; + + child.stderr.on('data', common.mustNotCall()); + + // Check if we receive both 'hello' at start and 'goodbye' at end + child.stdout.setEncoding('utf8'); + child.stdout.on('data', common.mustCallAtLeast((data) => { + stdout += data; + })); + + child.on('close', common.mustCall(() => { + assert.strictEqual(stdout.slice(0, 6), 'hello\n'); + assert.strictEqual(stdout.slice(stdout.length - 8), 'goodbye\n'); + })); +} diff --git a/node/_tools/test/parallel/test-child-process-stdout-flush.js b/node/_tools/test/parallel/test-child-process-stdout-flush.js new file mode 100644 index 000000000000..4054d2189202 --- /dev/null +++ b/node/_tools/test/parallel/test-child-process-stdout-flush.js @@ -0,0 +1,58 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// TODO(PolarETech): The args passed to spawn() should not need to +// include "require.ts". + +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const spawn = require('child_process').spawn; +const fixtures = require('../common/fixtures'); + +const sub = fixtures.path('print-chars.js'); + +const n = 500000; + +const child = spawn(process.argv[0], ['require.ts', sub, n]); + +let count = 0; + +child.stderr.setEncoding('utf8'); +child.stderr.on('data', common.mustNotCall()); + +child.stdout.setEncoding('utf8'); +child.stdout.on('data', (data) => { + count += data.length; +}); + +child.on('close', common.mustCall((code, signal) => { + assert.strictEqual(code, 0); + assert.strictEqual(signal, null); + assert.strictEqual(n, count); +})); diff --git a/node/_tools/test/parallel/test-stdin-from-file-spawn.js b/node/_tools/test/parallel/test-stdin-from-file-spawn.js index fd81113b1f17..89a0860a325d 100644 --- a/node/_tools/test/parallel/test-stdin-from-file-spawn.js +++ b/node/_tools/test/parallel/test-stdin-from-file-spawn.js @@ -5,7 +5,7 @@ // Taken from Node 18.8.0 // This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually -// TODO(cjihrig): 'run -A --unstable require.ts' should not be needed in +// TODO(cjihrig): 'run -A require.ts' should not be needed in // execSync() call at the bottom of this test. 'use strict'; @@ -49,4 +49,4 @@ setTimeout(() => { }, 100); `); -execSync(`${process.argv[0]} run -A --unstable require.ts ${tmpJsFile} < ${tmpCmdFile}`); +execSync(`${process.argv[0]} run -A require.ts ${tmpJsFile} < ${tmpCmdFile}`); diff --git a/node/_tools/test/sequential/test-child-process-exit.js b/node/_tools/test/sequential/test-child-process-exit.js new file mode 100644 index 000000000000..c8930b05917e --- /dev/null +++ b/node/_tools/test/sequential/test-child-process-exit.js @@ -0,0 +1,69 @@ +// 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 "node/_tools/setup.ts". Do not modify this file manually + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// TODO(PolarETech): The process.argv[3] to be assigned to gen should be argv[2], +// and the arguments array passed to spawn() should not need to include "require.ts". + +'use strict'; +require('../common'); + +// Open a chain of five Node processes each a child of the next. The final +// process exits immediately. Each process in the chain is instructed to exit +// when its child exits. +// https://github.com/joyent/node/issues/1726 + +const assert = require('assert'); +const ch = require('child_process'); + +const gen = +(process.argv[3] || 0); +const maxGen = 5; + + +if (gen === maxGen) { + console.error('hit maxGen, exiting', maxGen); + return; +} + +const child = ch.spawn(process.execPath, ['require.ts', __filename, gen + 1], { + stdio: [ 'ignore', 'pipe', 'ignore' ] +}); +assert.ok(!child.stdin); +assert.ok(child.stdout); +assert.ok(!child.stderr); + +console.error('gen=%d, pid=%d', gen, process.pid); + +child.on('exit', function(code) { + console.error('exit %d from gen %d', code, gen + 1); +}); + +child.stdout.pipe(process.stdout); + +child.stdout.on('close', function() { + console.error('child.stdout close gen=%d', gen); +}); diff --git a/node/child_process_test.ts b/node/child_process_test.ts index de7f476374a6..76a5b26f7994 100644 --- a/node/child_process_test.ts +++ b/node/child_process_test.ts @@ -191,53 +191,6 @@ Deno.test({ // Copyright Joyent and Node contributors. All rights reserved. MIT license. // Ported from Node 15.5.1 -// TODO(uki00a): Remove this case once Node's `parallel/test-child-process-spawn-event.js` works. -Deno.test("[child_process spawn] 'spawn' event", async () => { - const timeout = withTimeout(3000); - const subprocess = spawn(Deno.execPath(), ["eval", "console.log('ok')"]); - - let didSpawn = false; - subprocess.on("spawn", function () { - didSpawn = true; - }); - - function mustNotBeCalled() { - timeout.reject(new Error("function should not have been called")); - } - - const promises = [] as Promise[]; - function mustBeCalledAfterSpawn() { - const promise = deferred(); - promises.push(promise); - return () => { - if (didSpawn) { - promise.resolve(); - } else { - promise.reject( - new Error("function should be called after the 'spawn' event"), - ); - } - }; - } - - subprocess.on("error", mustNotBeCalled); - subprocess.stdout!.on("data", mustBeCalledAfterSpawn()); - subprocess.stdout!.on("end", mustBeCalledAfterSpawn()); - subprocess.stdout!.on("close", mustBeCalledAfterSpawn()); - subprocess.stderr!.on("data", mustNotBeCalled); - subprocess.stderr!.on("end", mustBeCalledAfterSpawn()); - subprocess.stderr!.on("close", mustBeCalledAfterSpawn()); - subprocess.on("exit", mustBeCalledAfterSpawn()); - subprocess.on("close", mustBeCalledAfterSpawn()); - - try { - await Promise.race([Promise.all(promises), timeout]); - timeout.resolve(); - } finally { - subprocess.kill(); - } -}); - // TODO(uki00a): Remove this case once Node's `parallel/test-child-process-spawn-shell.js` works. Deno.test("[child_process spawn] Verify that a shell is executed", async () => { const promise = withTimeout(3000); diff --git a/node/internal/child_process.ts b/node/internal/child_process.ts index a89f5451e19c..ef25b40c6d8b 100644 --- a/node/internal/child_process.ts +++ b/node/internal/child_process.ts @@ -996,6 +996,7 @@ function toDenoArgs(args: string[]): string[] { export default { ChildProcess, + normalizeSpawnArguments, stdioStringToArray, spawnSync, }; diff --git a/node/module_all_test.ts b/node/module_all_test.ts index 8c5c11041b2e..d12e1530534c 100644 --- a/node/module_all_test.ts +++ b/node/module_all_test.ts @@ -31,6 +31,7 @@ import * as http from "./http.ts"; import * as http2 from "./http2.ts"; import * as https from "./https.ts"; import * as inspector from "./inspector.ts"; +import * as internalCp from "./internal/child_process.ts"; import * as internalCryptoCertificate from "./internal/crypto/certificate.ts"; import * as internalCryptoCipher from "./internal/crypto/cipher.ts"; import * as internalCryptoDiffiehellman from "./internal/crypto/diffiehellman.ts"; @@ -122,6 +123,10 @@ Deno.test("modules", () => { assertEquals(keys(moduleAll.http2), keys(http2)); assertEquals(keys(moduleAll.https), keys(https)); assertEquals(keys(moduleAll.inspector), keys(inspector)); + assertEquals( + keys(moduleAll["internal/child_process"]), + keys(internalCp), + ); assertEquals( keys(moduleAll["internal/crypto/certificate"]), keys(internalCryptoCertificate),