From 29934d558c188fdc3406706da19921ca5a389383 Mon Sep 17 00:00:00 2001 From: Nathan Whitaker <17734409+nathanwhit@users.noreply.github.com> Date: Tue, 23 Jul 2024 20:12:08 -0700 Subject: [PATCH] fix(node): Run node compat tests listed in the `ignore` field (and fix the ones that fail) (#24631) The intent is that those tests will be executed, but our check that the files are up to date won't overwrite the contents of the tests. This is useful when a test needs some manual edits to work. It turns out we weren't actually running them. --- This ended up turning into a couple of small bug fixes to get the tests passing: - We weren't canonicalizing the exec path properly (it sometimes still had `..` or `.` in it) - We weren't accepting strings in `process.exit` There was one failure I couldn't figure out quickly, so I disabled the test for now, and filed a follow up issue: #24694 --- ext/node/polyfills/internal/errors.ts | 30 +- ext/node/polyfills/os.ts | 2 +- ext/node/polyfills/process.ts | 4 +- runtime/ops/os/mod.rs | 8 +- tests/node_compat/config.jsonc | 5 +- tests/node_compat/test.ts | 4 +- .../test-child-process-exec-encoding.js | 4 +- .../test-child-process-exec-kill-throws.js | 4 +- .../test-child-process-exec-std-encoding.js | 4 +- ...-child-process-exec-timeout-not-expired.js | 4 +- .../parallel/test-child-process-execfile.js | 16 +- .../parallel/test-child-process-exit-code.js | 6 +- .../test/parallel/test-child-process-ipc.js | 4 +- .../test-child-process-spawnsync-env.js | 4 +- .../test-child-process-stdio-inherit.js | 4 +- .../test-child-process-stdout-flush-exit.js | 4 +- .../test-child-process-stdout-flush.js | 4 +- .../parallel/test-dgram-socket-buffer-size.js | 25 +- .../test-dgram-udp6-link-local-address.js | 61 ---- tests/node_compat/test/parallel/test-os.js | 280 ------------------ .../sequential/test-child-process-exit.js | 4 +- 21 files changed, 79 insertions(+), 402 deletions(-) delete mode 100644 tests/node_compat/test/parallel/test-dgram-udp6-link-local-address.js delete mode 100644 tests/node_compat/test/parallel/test-os.js diff --git a/ext/node/polyfills/internal/errors.ts b/ext/node/polyfills/internal/errors.ts index 6529e98947..9ec9f99491 100644 --- a/ext/node/polyfills/internal/errors.ts +++ b/ext/node/polyfills/internal/errors.ts @@ -18,7 +18,7 @@ */ import { primordials } from "ext:core/mod.js"; -const { JSONStringify } = primordials; +const { JSONStringify, SymbolFor } = primordials; import { format, inspect } from "ext:deno_node/internal/util/inspect.mjs"; import { codes } from "ext:deno_node/internal/error_codes.ts"; import { @@ -421,8 +421,11 @@ export interface NodeSystemErrorCtx { // `err.info`. // The context passed into this error must have .code, .syscall and .message, // and may have .path and .dest. -class NodeSystemError extends NodeErrorAbstraction { +class NodeSystemError extends Error { + code: string; constructor(key: string, context: NodeSystemErrorCtx, msgPrefix: string) { + super(); + this.code = key; let message = `${msgPrefix}: ${context.syscall} returned ` + `${context.code} (${context.message})`; @@ -433,8 +436,6 @@ class NodeSystemError extends NodeErrorAbstraction { message += ` => ${context.dest}`; } - super("SystemError", key, message); - captureLargerStackTrace(this); Object.defineProperties(this, { @@ -444,6 +445,18 @@ class NodeSystemError extends NodeErrorAbstraction { writable: false, configurable: true, }, + name: { + value: "SystemError", + enumerable: false, + writable: true, + configurable: true, + }, + message: { + value: message, + enumerable: false, + writable: true, + configurable: true, + }, info: { value: context, enumerable: true, @@ -502,6 +515,15 @@ class NodeSystemError extends NodeErrorAbstraction { override toString() { return `${this.name} [${this.code}]: ${this.message}`; } + + // deno-lint-ignore no-explicit-any + [SymbolFor("nodejs.util.inspect.custom")](_recurseTimes: number, ctx: any) { + return inspect(this, { + ...ctx, + getters: true, + customInspect: false, + }); + } } function makeSystemErrorWithCode(key: string, msgPrfix: string) { diff --git a/ext/node/polyfills/os.ts b/ext/node/polyfills/os.ts index 753e393198..1cd466ec21 100644 --- a/ext/node/polyfills/os.ts +++ b/ext/node/polyfills/os.ts @@ -340,7 +340,7 @@ export function userInfo( if (!_homedir) { throw new ERR_OS_NO_HOMEDIR(); } - let shell = isWindows ? (Deno.env.get("SHELL") || null) : null; + let shell = isWindows ? null : (Deno.env.get("SHELL") || null); let username = op_node_os_username(); if (options?.encoding === "buffer") { diff --git a/ext/node/polyfills/process.ts b/ext/node/polyfills/process.ts index ec8671122d..8d54429354 100644 --- a/ext/node/polyfills/process.ts +++ b/ext/node/polyfills/process.ts @@ -84,9 +84,9 @@ let ProcessExitCode: undefined | null | string | number; /** https://nodejs.org/api/process.html#process_process_exit_code */ export const exit = (code?: number | string) => { if (code || code === 0) { - denoOs.setExitCode(code); + process.exitCode = code; } else if (Number.isNaN(code)) { - denoOs.setExitCode(1); + process.exitCode = 1; } ProcessExitCode = denoOs.getExitCode(); diff --git a/runtime/ops/os/mod.rs b/runtime/ops/os/mod.rs index c2611f869b..544031dd7b 100644 --- a/runtime/ops/os/mod.rs +++ b/runtime/ops/os/mod.rs @@ -4,8 +4,8 @@ use super::utils::into_string; use crate::worker::ExitCode; use deno_core::error::type_error; use deno_core::error::AnyError; +use deno_core::normalize_path; use deno_core::op2; -use deno_core::url::Url; use deno_core::v8; use deno_core::OpState; use deno_node::NODE_ENV_VAR_ALLOWLIST; @@ -80,10 +80,8 @@ fn op_exec_path(state: &mut OpState) -> Result { state .borrow_mut::() .check_read_blind(¤t_exe, "exec_path", "Deno.execPath()")?; - // Now apply URL parser to current exe to get fully resolved path, otherwise - // we might get `./` and `../` bits in `exec_path` - let exe_url = Url::from_file_path(current_exe).unwrap(); - let path = exe_url.to_file_path().unwrap(); + // normalize path so it doesn't include '.' or '..' components + let path = normalize_path(current_exe); into_string(path.into_os_string()) } diff --git a/tests/node_compat/config.jsonc b/tests/node_compat/config.jsonc index 0c8d380774..819a56da75 100644 --- a/tests/node_compat/config.jsonc +++ b/tests/node_compat/config.jsonc @@ -35,7 +35,6 @@ // TODO(bartlomieju): this test was flaky on macOS CI // "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", @@ -60,7 +59,6 @@ "test-dgram-ipv6only.js", "test-dgram-send-cb-quelches-error.js", "test-dgram-socket-buffer-size.js", - "test-dgram-udp6-link-local-address.js", "test-dns-lookup.js", "test-dns-resolveany.js", "test-dns.js", @@ -88,7 +86,8 @@ "test-net-server-try-ports.js", "test-net-socket-timeout.js", "test-net-write-arguments.js", - "test-os.js", + // TODO(nathanwhit): Disable os.userInfo is slightly incorrect + // "test-os.js", "test-path-resolve.js", "test-querystring.js", "test-readline-interface.js", diff --git a/tests/node_compat/test.ts b/tests/node_compat/test.ts index 077abc2290..3f8655169e 100644 --- a/tests/node_compat/test.ts +++ b/tests/node_compat/test.ts @@ -30,7 +30,9 @@ const filters = Deno.args; const hasFilters = filters.length > 0; const toolsPath = dirname(fromFileUrl(import.meta.url)); const testPaths = partitionParallelTestPaths( - getPathsFromTestSuites(config.tests), + getPathsFromTestSuites(config.tests).concat( + getPathsFromTestSuites(config.ignore), + ), ); const cwd = new URL(".", import.meta.url); const windowsIgnorePaths = new Set( diff --git a/tests/node_compat/test/parallel/test-child-process-exec-encoding.js b/tests/node_compat/test/parallel/test-child-process-exec-encoding.js index fe03e98d06..2f261494a6 100644 --- a/tests/node_compat/test/parallel/test-child-process-exec-encoding.js +++ b/tests/node_compat/test/parallel/test-child-process-exec-encoding.js @@ -7,7 +7,7 @@ // 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". +// and "runner.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 require.ts "${__filename}" child`; + const cmd = `"${process.execPath}" run -A runner.ts "${__filename}" child`; cp.exec(cmd, options, common.mustSucceed((stdout, stderr) => { callback(stdout, stderr); diff --git a/tests/node_compat/test/parallel/test-child-process-exec-kill-throws.js b/tests/node_compat/test/parallel/test-child-process-exec-kill-throws.js index 6a28c2a18d..9d727bf641 100644 --- a/tests/node_compat/test/parallel/test-child-process-exec-kill-throws.js +++ b/tests/node_compat/test/parallel/test-child-process-exec-kill-throws.js @@ -7,7 +7,7 @@ // 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". +// and "runner.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 require.ts "${__filename}" child`; + const cmd = `"${process.execPath}" run -A runner.ts "${__filename}" child`; const options = { maxBuffer: 0, killSignal: 'SIGKILL' }; const child = cp.exec(cmd, options, common.mustCall((err, stdout, stderr) => { diff --git a/tests/node_compat/test/parallel/test-child-process-exec-std-encoding.js b/tests/node_compat/test/parallel/test-child-process-exec-std-encoding.js index 85f3ec2bf1..e2f5452b38 100644 --- a/tests/node_compat/test/parallel/test-child-process-exec-std-encoding.js +++ b/tests/node_compat/test/parallel/test-child-process-exec-std-encoding.js @@ -7,7 +7,7 @@ // 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". +// and "runner.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 require.ts "${__filename}" child`; + const cmd = `"${process.execPath}" run -A runner.ts "${__filename}" child`; const child = cp.exec(cmd, common.mustSucceed((stdout, stderr) => { assert.strictEqual(stdout, expectedStdout); assert.strictEqual(stderr, expectedStderr); diff --git a/tests/node_compat/test/parallel/test-child-process-exec-timeout-not-expired.js b/tests/node_compat/test/parallel/test-child-process-exec-timeout-not-expired.js index 31fa1f7259..d140bcbdd8 100644 --- a/tests/node_compat/test/parallel/test-child-process-exec-timeout-not-expired.js +++ b/tests/node_compat/test/parallel/test-child-process-exec-timeout-not-expired.js @@ -7,7 +7,7 @@ // 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". +// and "runner.ts". 'use strict'; @@ -33,7 +33,7 @@ if (process.argv[3] === 'child') { return; } -const cmd = `"${process.execPath}" run -A require.ts "${__filename}" child`; +const cmd = `"${process.execPath}" run -A runner.ts "${__filename}" child`; cp.exec(cmd, { timeout: kTimeoutNotSupposedToExpire diff --git a/tests/node_compat/test/parallel/test-child-process-execfile.js b/tests/node_compat/test/parallel/test-child-process-execfile.js index 9f9268407b..df04e447f6 100644 --- a/tests/node_compat/test/parallel/test-child-process-execfile.js +++ b/tests/node_compat/test/parallel/test-child-process-execfile.js @@ -6,7 +6,7 @@ // 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". +// include "runner.ts". // TODO(cjihrig): See inline TODO comments below. @@ -26,11 +26,11 @@ const execOpts = { encoding: 'utf8', shell: true }; { execFile( process.execPath, - ['require.ts', fixture, 42], + ['runner.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`); + `Command failed: ${process.execPath} runner.ts ${fixture} 42`); assert.strictEqual(e.code, 42); }) ); @@ -57,7 +57,7 @@ const execOpts = { encoding: 'utf8', shell: true }; { // Verify the shell option works properly - execFile(process.execPath, ['require.ts', fixture, 0], execOpts, common.mustSucceed()); + execFile(process.execPath, ['runner.ts', fixture, 0], execOpts, common.mustSucceed()); } { @@ -71,7 +71,7 @@ const execOpts = { encoding: 'utf8', shell: true }; assert.strictEqual(err.name, 'AbortError'); assert.strictEqual(err.signal, undefined); }); - execFile(process.execPath, ['require.ts', echoFixture, 0], { signal }, check); + execFile(process.execPath, ['runner.ts', echoFixture, 0], { signal }, check); }; // Verify that it still works the same way now that the signal is aborted. @@ -88,7 +88,7 @@ const execOpts = { encoding: 'utf8', shell: true }; assert.strictEqual(err.name, 'AbortError'); assert.strictEqual(err.signal, undefined); }); - execFile(process.execPath, ['require.ts', echoFixture, 0], { signal }, check); + execFile(process.execPath, ['runner.ts', echoFixture, 0], { signal }, check); } { @@ -97,7 +97,7 @@ const execOpts = { encoding: 'utf8', shell: true }; assert.throws(() => { const callback = common.mustNotCall(() => {}); - execFile(process.execPath, ['require.ts', echoFixture, 0], { signal: 'hello' }, callback); + execFile(process.execPath, ['runner.ts', echoFixture, 0], { signal: 'hello' }, callback); }, { code: 'ERR_INVALID_ARG_TYPE', name: 'TypeError' }); } { @@ -111,7 +111,7 @@ const execOpts = { encoding: 'utf8', shell: true }; // assert.strictEqual(getEventListeners(ac.signal).length, 0); assert.strictEqual(err, null); }); - execFile(process.execPath, ['require.ts', fixture, 0], { signal }, callback); + execFile(process.execPath, ['runner.ts', fixture, 0], { signal }, callback); } // Verify the execFile() stdout is the same as execFileSync(). diff --git a/tests/node_compat/test/parallel/test-child-process-exit-code.js b/tests/node_compat/test/parallel/test-child-process-exit-code.js index caa57986b4..47309fb9c0 100644 --- a/tests/node_compat/test/parallel/test-child-process-exit-code.js +++ b/tests/node_compat/test/parallel/test-child-process-exit-code.js @@ -27,7 +27,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. // TODO(PolarETech): The args passed to spawn() should not need to -// include "require.ts". +// include "runner.ts". 'use strict'; const common = require('../common'); @@ -36,7 +36,7 @@ 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]); +const exitChild = spawn(process.argv[0], ['runner.ts', exitScript, 23]); exitChild.on('exit', common.mustCall(function(code, signal) { assert.strictEqual(code, 23); assert.strictEqual(signal, null); @@ -44,7 +44,7 @@ exitChild.on('exit', common.mustCall(function(code, signal) { const errorScript = fixtures.path('child_process_should_emit_error.js'); -const errorChild = spawn(process.argv[0], ['require.ts', errorScript]); +const errorChild = spawn(process.argv[0], ['runner.ts', errorScript]); errorChild.on('exit', common.mustCall(function(code, signal) { assert.ok(code !== 0); assert.strictEqual(signal, null); diff --git a/tests/node_compat/test/parallel/test-child-process-ipc.js b/tests/node_compat/test/parallel/test-child-process-ipc.js index c1d7bc2b61..163ee56aa4 100644 --- a/tests/node_compat/test/parallel/test-child-process-ipc.js +++ b/tests/node_compat/test/parallel/test-child-process-ipc.js @@ -27,7 +27,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. // TODO(PolarETech): The args passed to spawn() should not need to -// include "require.ts". +// include "runner.ts". 'use strict'; @@ -43,7 +43,7 @@ const fixtures = require('../common/fixtures'); const sub = fixtures.path('echo.js'); -const child = spawn(process.argv[0], ['require.ts', sub]); +const child = spawn(process.argv[0], ['runner.ts', sub]); child.stderr.on('data', mustNotCall()); diff --git a/tests/node_compat/test/parallel/test-child-process-spawnsync-env.js b/tests/node_compat/test/parallel/test-child-process-spawnsync-env.js index d08ed48d95..ca7c7fcdd7 100644 --- a/tests/node_compat/test/parallel/test-child-process-spawnsync-env.js +++ b/tests/node_compat/test/parallel/test-child-process-spawnsync-env.js @@ -28,7 +28,7 @@ // TODO(cjihrig): The process.argv[3] check should be argv[2], and the // arguments array passed to spawnSync() should not need to include -// "require.ts". +// "runner.ts". 'use strict'; require('../common'); @@ -39,7 +39,7 @@ if (process.argv[3] === 'child') { console.log(process.env.foo); } else { const expected = 'bar'; - const child = cp.spawnSync(process.execPath, ["require.ts", __filename, 'child'], { + const child = cp.spawnSync(process.execPath, ["runner.ts", __filename, 'child'], { env: Object.assign(process.env, { foo: expected }) }); diff --git a/tests/node_compat/test/parallel/test-child-process-stdio-inherit.js b/tests/node_compat/test/parallel/test-child-process-stdio-inherit.js index e213dd6b80..4a260b2876 100644 --- a/tests/node_compat/test/parallel/test-child-process-stdio-inherit.js +++ b/tests/node_compat/test/parallel/test-child-process-stdio-inherit.js @@ -27,7 +27,7 @@ // 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". +// the args passed to spawn() should not need to include "runner.ts". 'use strict'; require('../common'); @@ -40,7 +40,7 @@ else grandparent(); function grandparent() { - const child = spawn(process.execPath, ['require.ts', __filename, 'parent']); + const child = spawn(process.execPath, ['runner.ts', __filename, 'parent']); child.stderr.pipe(process.stderr); let output = ''; const input = 'asdfasdf'; diff --git a/tests/node_compat/test/parallel/test-child-process-stdout-flush-exit.js b/tests/node_compat/test/parallel/test-child-process-stdout-flush-exit.js index 585cc60840..58e97eb433 100644 --- a/tests/node_compat/test/parallel/test-child-process-stdout-flush-exit.js +++ b/tests/node_compat/test/parallel/test-child-process-stdout-flush-exit.js @@ -27,7 +27,7 @@ // 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", +// the args passed to spawn() should not need to include "runner.ts", // and the process.argv[2] passed to spawn() should be argv[1]. 'use strict'; @@ -48,7 +48,7 @@ if (process.argv[3] === 'child') { const spawn = require('child_process').spawn; // spawn self as child - const child = spawn(process.argv[0], ['require.ts', process.argv[2], 'child']); + const child = spawn(process.argv[0], ['runner.ts', process.argv[2], 'child']); let stdout = ''; diff --git a/tests/node_compat/test/parallel/test-child-process-stdout-flush.js b/tests/node_compat/test/parallel/test-child-process-stdout-flush.js index 4054d21892..983ccefda7 100644 --- a/tests/node_compat/test/parallel/test-child-process-stdout-flush.js +++ b/tests/node_compat/test/parallel/test-child-process-stdout-flush.js @@ -27,7 +27,7 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. // TODO(PolarETech): The args passed to spawn() should not need to -// include "require.ts". +// include "runner.ts". 'use strict'; const common = require('../common'); @@ -39,7 +39,7 @@ const sub = fixtures.path('print-chars.js'); const n = 500000; -const child = spawn(process.argv[0], ['require.ts', sub, n]); +const child = spawn(process.argv[0], ['runner.ts', sub, n]); let count = 0; diff --git a/tests/node_compat/test/parallel/test-dgram-socket-buffer-size.js b/tests/node_compat/test/parallel/test-dgram-socket-buffer-size.js index b2fc332626..85cc583cc3 100644 --- a/tests/node_compat/test/parallel/test-dgram-socket-buffer-size.js +++ b/tests/node_compat/test/parallel/test-dgram-socket-buffer-size.js @@ -2,8 +2,8 @@ // deno-lint-ignore-file // Copyright Joyent and Node contributors. All rights reserved. MIT license. -// Taken from Node 16.13.0 -// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually +// Taken from Node 18.12.1 +// This file is automatically generated by `tests/node_compat/runner/setup.ts`. Do not modify this file manually. // Flags: --expose-internals 'use strict'; @@ -19,8 +19,6 @@ const { UV_ENOTSOCK } = internalBinding('uv'); -// Note error test amendments from Node due to Deno formatting errors slightly -// differently. function getExpectedError(type) { const code = common.isWindows ? 'ENOTSOCK' : 'EBADF'; const message = common.isWindows ? @@ -53,18 +51,18 @@ function getExpectedError(type) { socket.setSendBufferSize(8192); }, (err) => { assert.strictEqual( - inspect(err).replace(/^ +at .*\n/gm, ""), - `ERR_SOCKET_BUFFER_SIZE [SystemError]: ${errorObj.message}\n` + + inspect(err).replace(/^ +at .*\n/gm, ''), + `SystemError: ${errorObj.message}\n` + " code: 'ERR_SOCKET_BUFFER_SIZE',\n" + - " info: {\n" + + ' info: {\n' + ` errno: ${errorObj.info.errno},\n` + ` code: '${errorObj.info.code}',\n` + ` message: '${errorObj.info.message}',\n` + ` syscall: '${errorObj.info.syscall}'\n` + - " },\n" + - ` errno: [Getter/Setter],\n` + - ` syscall: [Getter/Setter]\n` + - "}" + ' },\n' + + ` errno: [Getter/Setter: ${errorObj.info.errno}],\n` + + ` syscall: [Getter/Setter: '${errorObj.info.syscall}']\n` + + '}' ); return true; }); @@ -102,15 +100,14 @@ function getExpectedError(type) { const socket = dgram.createSocket('udp4'); socket.bind(common.mustCall(() => { - badBufferSizes.forEach((badBufferSize) => { + for (const badBufferSize of badBufferSizes) { assert.throws(() => { socket.setRecvBufferSize(badBufferSize); }, errorObj); - assert.throws(() => { socket.setSendBufferSize(badBufferSize); }, errorObj); - }); + } socket.close(); })); } diff --git a/tests/node_compat/test/parallel/test-dgram-udp6-link-local-address.js b/tests/node_compat/test/parallel/test-dgram-udp6-link-local-address.js deleted file mode 100644 index c828413a20..0000000000 --- a/tests/node_compat/test/parallel/test-dgram-udp6-link-local-address.js +++ /dev/null @@ -1,61 +0,0 @@ -// deno-fmt-ignore-file -// deno-lint-ignore-file - -// Copyright Joyent and Node contributors. All rights reserved. MIT license. -// Taken from Node 16.13.0 -// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually - -'use strict'; -const common = require('../common'); -if (!common.hasIPv6) - common.skip('no IPv6 support'); - -const assert = require('assert'); -const dgram = require('dgram'); -const os = require('os'); - -const { isWindows } = common; - -function linklocal() { - for (const [ifname, entries] of Object.entries(os.networkInterfaces())) { - for (const { address, family, scopeid } of entries) { - if (family === 'IPv6' && address.startsWith('fe80:')) { - return { address, ifname, scopeid }; - } - } - } -} -const iface = linklocal(); - -if (!iface) - common.skip('cannot find any IPv6 interfaces with a link local address'); - -const address = isWindows ? iface.address : `${iface.address}%${iface.ifname}`; -const message = 'Hello, local world!'; - -// Create a client socket for sending to the link-local address. -const client = dgram.createSocket('udp6'); - -// Create the server socket listening on the link-local address. -const server = dgram.createSocket('udp6'); - -server.on('listening', common.mustCall(() => { - const port = server.address().port; - client.send(message, 0, message.length, port, address); -})); - -server.on('message', common.mustCall((buf, info) => { - const received = buf.toString(); - assert.strictEqual(received, message); - // Check that the sender address is the one bound, - // including the link local scope identifier. - // TODO(cmorten): info.address is missing the link local scope identifier - // assert.strictEqual( - // info.address, - // isWindows ? `${iface.address}%${iface.scopeid}` : address - // ); - server.close(); - client.close(); -}, 1)); - -server.bind({ address }); diff --git a/tests/node_compat/test/parallel/test-os.js b/tests/node_compat/test/parallel/test-os.js deleted file mode 100644 index 9de4f516f3..0000000000 --- a/tests/node_compat/test/parallel/test-os.js +++ /dev/null @@ -1,280 +0,0 @@ -// deno-fmt-ignore-file -// deno-lint-ignore-file - -// Copyright Joyent and Node contributors. All rights reserved. MIT license. -// Taken from Node 16.13.0 -// 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 os = require('os'); -const path = require('path'); -const { inspect } = require('util'); - -const is = { - number: (value, key) => { - assert(!Number.isNaN(value), `${key} should not be NaN`); - assert.strictEqual(typeof value, 'number'); - }, - string: (value) => { assert.strictEqual(typeof value, 'string'); }, - array: (value) => { assert.ok(Array.isArray(value)); }, - object: (value) => { - assert.strictEqual(typeof value, 'object'); - assert.notStrictEqual(value, null); - } -}; - -/* TODO(kt3k): Enable this test -process.env.TMPDIR = '/tmpdir'; -process.env.TMP = '/tmp'; -process.env.TEMP = '/temp'; -if (common.isWindows) { - assert.strictEqual(os.tmpdir(), '/temp'); - process.env.TEMP = ''; - assert.strictEqual(os.tmpdir(), '/tmp'); - process.env.TMP = ''; - const expected = `${process.env.SystemRoot || process.env.windir}\\temp`; - assert.strictEqual(os.tmpdir(), expected); - process.env.TEMP = '\\temp\\'; - assert.strictEqual(os.tmpdir(), '\\temp'); - process.env.TEMP = '\\tmpdir/'; - assert.strictEqual(os.tmpdir(), '\\tmpdir/'); - process.env.TEMP = '\\'; - assert.strictEqual(os.tmpdir(), '\\'); - process.env.TEMP = 'C:\\'; - assert.strictEqual(os.tmpdir(), 'C:\\'); -} else { - assert.strictEqual(os.tmpdir(), '/tmpdir'); - process.env.TMPDIR = ''; - assert.strictEqual(os.tmpdir(), '/tmp'); - process.env.TMP = ''; - assert.strictEqual(os.tmpdir(), '/temp'); - process.env.TEMP = ''; - assert.strictEqual(os.tmpdir(), '/tmp'); - process.env.TMPDIR = '/tmpdir/'; - assert.strictEqual(os.tmpdir(), '/tmpdir'); - process.env.TMPDIR = '/tmpdir\\'; - assert.strictEqual(os.tmpdir(), '/tmpdir\\'); - process.env.TMPDIR = '/'; - assert.strictEqual(os.tmpdir(), '/'); -} -*/ - -const endianness = os.endianness(); -is.string(endianness); -assert.match(endianness, /[BL]E/); - -const hostname = os.hostname(); -is.string(hostname); -assert.ok(hostname.length > 0); - -// On IBMi, os.uptime() returns 'undefined' -if (!common.isIBMi) { - const uptime = os.uptime(); - is.number(uptime); - assert.ok(uptime > 0); -} - -const cpus = os.cpus(); -is.array(cpus); -assert.ok(cpus.length > 0); -for (const cpu of cpus) { - assert.strictEqual(typeof cpu.model, 'string'); - assert.strictEqual(typeof cpu.speed, 'number'); - assert.strictEqual(typeof cpu.times.user, 'number'); - assert.strictEqual(typeof cpu.times.nice, 'number'); - assert.strictEqual(typeof cpu.times.sys, 'number'); - assert.strictEqual(typeof cpu.times.idle, 'number'); - assert.strictEqual(typeof cpu.times.irq, 'number'); -} - -const type = os.type(); -is.string(type); -assert.ok(type.length > 0); - -const release = os.release(); -is.string(release); -assert.ok(release.length > 0); -// TODO: Check format on more than just AIX -if (common.isAIX) - assert.match(release, /^\d+\.\d+$/); - -const platform = os.platform(); -is.string(platform); -assert.ok(platform.length > 0); - -const availableParallelism = os.availableParallelism(); -assert.ok(availableParallelism === navigator.hardwareConcurrency); - -const arch = os.arch(); -is.string(arch); -assert.ok(arch.length > 0); - -if (!common.isSunOS) { - // not implemented yet - assert.ok(os.loadavg().length > 0); - assert.ok(os.freemem() > 0); - assert.ok(os.totalmem() > 0); -} - -const interfaces = os.networkInterfaces(); -switch (platform) { - case 'linux': { - const filter = (e) => - e.address === '127.0.0.1' && - e.netmask === '255.0.0.0'; - - const actual = interfaces.lo.filter(filter); - const expected = [{ - address: '127.0.0.1', - netmask: '255.0.0.0', - family: 'IPv4', - mac: '00:00:00:00:00:00', - internal: true, - cidr: '127.0.0.1/8' - }]; - assert.deepStrictEqual(actual, expected); - break; - } - case 'win32': { - const filter = (e) => - e.address === '127.0.0.1'; - - const actual = interfaces['Loopback Pseudo-Interface 1'].filter(filter); - const expected = [{ - address: '127.0.0.1', - netmask: '255.0.0.0', - family: 'IPv4', - mac: '00:00:00:00:00:00', - internal: true, - cidr: '127.0.0.1/8' - }]; - assert.deepStrictEqual(actual, expected); - break; - } -} -const netmaskToCIDRSuffixMap = new Map(Object.entries({ - '255.0.0.0': 8, - '255.255.255.0': 24, - 'ffff:ffff:ffff:ffff::': 64, - 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff': 128 -})); - -Object.values(interfaces) - .flat(Infinity) - .map((v) => ({ v, mask: netmaskToCIDRSuffixMap.get(v.netmask) })) - .forEach(({ v, mask }) => { - assert.ok('cidr' in v, `"cidr" prop not found in ${inspect(v)}`); - if (mask) { - assert.strictEqual(v.cidr, `${v.address}/${mask}`); - } - }); - -const EOL = os.EOL; -if (common.isWindows) { - assert.strictEqual(EOL, '\r\n'); -} else { - assert.strictEqual(EOL, '\n'); -} - -const home = os.homedir(); -is.string(home); -assert.ok(home.includes(path.sep)); - -const version = os.version(); -assert.strictEqual(typeof version, 'string'); -assert(version); - -if (common.isWindows && process.env.USERPROFILE) { - assert.strictEqual(home, process.env.USERPROFILE); - delete process.env.USERPROFILE; - assert.ok(os.homedir().includes(path.sep)); - process.env.USERPROFILE = home; -} else if (!common.isWindows && process.env.HOME) { - assert.strictEqual(home, process.env.HOME); - delete process.env.HOME; - assert.ok(os.homedir().includes(path.sep)); - process.env.HOME = home; -} - -const pwd = os.userInfo(); -is.object(pwd); -const pwdBuf = os.userInfo({ encoding: 'buffer' }); - -if (common.isWindows) { - assert.strictEqual(pwd.uid, -1); - assert.strictEqual(pwd.gid, -1); - assert.strictEqual(pwd.shell, null); - assert.strictEqual(pwdBuf.uid, -1); - assert.strictEqual(pwdBuf.gid, -1); - assert.strictEqual(pwdBuf.shell, null); -} else { - is.number(pwd.uid); - is.number(pwd.gid); - assert.strictEqual(typeof pwd.shell, 'string'); - // It's possible for /etc/passwd to leave the user's shell blank. - if (pwd.shell.length > 0) { - assert(pwd.shell.includes(path.sep)); - } - assert.strictEqual(pwd.uid, pwdBuf.uid); - assert.strictEqual(pwd.gid, pwdBuf.gid); - assert.strictEqual(pwd.shell, pwdBuf.shell.toString('utf8')); -} - -is.string(pwd.username); -assert.ok(pwd.homedir.includes(path.sep)); -assert.strictEqual(pwd.username, pwdBuf.username.toString('utf8')); -assert.strictEqual(pwd.homedir, pwdBuf.homedir.toString('utf8')); - - -assert.strictEqual(`${os.hostname}`, os.hostname()); -assert.strictEqual(`${os.homedir}`, os.homedir()); -assert.strictEqual(`${os.release}`, os.release()); -assert.strictEqual(`${os.type}`, os.type()); -assert.strictEqual(`${os.endianness}`, os.endianness()); -// TODO(kt3k): Enable this test -// assert.strictEqual(`${os.tmpdir}`, os.tmpdir()); -assert.strictEqual(`${os.arch}`, os.arch()); -assert.strictEqual(`${os.platform}`, os.platform()); -assert.strictEqual(`${os.version}`, os.version()); - -assert.strictEqual(+os.totalmem, os.totalmem()); - -// Assert that the following values are coercible to numbers. -// On IBMi, os.uptime() returns 'undefined' -if (!common.isIBMi) { - is.number(+os.uptime, 'uptime'); - is.number(os.uptime(), 'uptime'); -} - -is.number(+os.freemem, 'freemem'); -is.number(os.freemem(), 'freemem'); - -const devNull = os.devNull; -if (common.isWindows) { - assert.strictEqual(devNull, '\\\\.\\nul'); -} else { - assert.strictEqual(devNull, '/dev/null'); -} diff --git a/tests/node_compat/test/sequential/test-child-process-exit.js b/tests/node_compat/test/sequential/test-child-process-exit.js index c8930b0591..01910d72fc 100644 --- a/tests/node_compat/test/sequential/test-child-process-exit.js +++ b/tests/node_compat/test/sequential/test-child-process-exit.js @@ -27,7 +27,7 @@ // 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". +// and the arguments array passed to spawn() should not need to include "runner.ts". 'use strict'; require('../common'); @@ -49,7 +49,7 @@ if (gen === maxGen) { return; } -const child = ch.spawn(process.execPath, ['require.ts', __filename, gen + 1], { +const child = ch.spawn(process.execPath, ['runner.ts', __filename, gen + 1], { stdio: [ 'ignore', 'pipe', 'ignore' ] }); assert.ok(!child.stdin);