From 86222dbade2eee5d565065355a020284bf832ec9 Mon Sep 17 00:00:00 2001 From: Yagiz Nizipli Date: Sun, 9 Feb 2025 14:13:17 -0500 Subject: [PATCH] test: lazily load modules on test runner --- test/common/child_process.js | 13 +++++++------ test/common/crypto.js | 11 +++++------ test/common/debugger.js | 10 +++++----- test/common/dns.js | 9 ++++++--- test/common/heap.js | 10 +++++----- test/common/index.js | 9 ++++++--- test/common/inspector-helper.js | 2 +- test/common/measure-memory.js | 5 +++-- test/common/net.js | 6 +++--- test/common/tls.js | 4 ++-- test/common/udp.js | 24 ++++++++++++------------ test/common/v8.js | 17 +++++++++-------- test/common/wpt.js | 10 ++++++---- 13 files changed, 70 insertions(+), 60 deletions(-) diff --git a/test/common/child_process.js b/test/common/child_process.js index 6c2bc6c9614af3..d3f876e6ccdfe7 100644 --- a/test/common/child_process.js +++ b/test/common/child_process.js @@ -2,14 +2,14 @@ const assert = require('assert'); const { spawnSync, execFileSync } = require('child_process'); -const common = require('./'); -const util = require('util'); +const { platformTimeout, isWindows } = require('./'); +let inspect; // 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) { + if (!isWindows) { return; } process.once('beforeExit', () => { @@ -30,7 +30,7 @@ function cleanupStaleProcess(filename) { // This should keep the child process running long enough to expire // the timeout. -const kExpiringChildRunTime = common.platformTimeout(20 * 1000); +const kExpiringChildRunTime = platformTimeout(20 * 1000); const kExpiringParentTimer = 1; assert(kExpiringChildRunTime > kExpiringParentTimer); @@ -43,9 +43,10 @@ function logAfterTime(time) { } function checkOutput(str, check) { + inspect ??= require('util').inspect; if ((check instanceof RegExp && !check.test(str)) || (typeof check === 'string' && check !== str)) { - return { passed: false, reason: `did not match ${util.inspect(check)}` }; + return { passed: false, reason: `did not match ${inspect(check)}` }; } if (typeof check === 'function') { try { @@ -53,7 +54,7 @@ function checkOutput(str, check) { } catch (error) { return { passed: false, - reason: `did not match expectation, checker throws:\n${util.inspect(error)}`, + reason: `did not match expectation, checker throws:\n${inspect(error)}`, }; } } diff --git a/test/common/crypto.js b/test/common/crypto.js index f50d3895a1783b..b2b152e798aca6 100644 --- a/test/common/crypto.js +++ b/test/common/crypto.js @@ -1,12 +1,11 @@ 'use strict'; -const common = require('../common'); -if (!common.hasCrypto) { - common.skip('missing crypto'); +const { hasCrypto, skip } = require('../common'); +if (!hasCrypto) { + skip('missing crypto'); } const assert = require('assert'); -const crypto = require('crypto'); const { createSign, createVerify, @@ -14,7 +13,7 @@ const { privateDecrypt, sign, verify, -} = crypto; +} = require('crypto'); /* eslint-disable-line node-core/crypto-check */ // The values below (modp2/modp2buf) are for a 1024 bits long prime from // RFC 2412 E.2, see https://tools.ietf.org/html/rfc2412. */ @@ -109,7 +108,7 @@ const opensslVersionNumber = (major = 0, minor = 0, patch = 0) => { let OPENSSL_VERSION_NUMBER; const hasOpenSSL = (major = 0, minor = 0, patch = 0) => { - if (!common.hasCrypto) return false; + if (!hasCrypto) return false; if (OPENSSL_VERSION_NUMBER === undefined) { const regexp = /(?\d+)\.(?\d+)\.(?

\d+)/; const { m, n, p } = process.versions.openssl.match(regexp).groups; diff --git a/test/common/debugger.js b/test/common/debugger.js index d5d77fc7c648dd..2582cfbe3c2363 100644 --- a/test/common/debugger.js +++ b/test/common/debugger.js @@ -1,18 +1,18 @@ 'use strict'; -const common = require('../common'); -const spawn = require('child_process').spawn; +const { isWindows, platformTimeout } = require('../common'); +const { spawn } = require('child_process'); const BREAK_MESSAGE = new RegExp('(?:' + [ 'assert', 'break', 'break on start', 'debugCommand', 'exception', 'other', 'promiseRejection', 'step', ].join('|') + ') in', 'i'); -let TIMEOUT = common.platformTimeout(5000); -if (common.isWindows) { +let TIMEOUT = platformTimeout(5000); +if (isWindows) { // Some of the windows machines in the CI need more time to receive // the outputs from the client. // https://github.com/nodejs/build/issues/3014 - TIMEOUT = common.platformTimeout(15000); + TIMEOUT = platformTimeout(15000); } function isPreBreak(output) { diff --git a/test/common/dns.js b/test/common/dns.js index 738f2299dd79dc..45358ae4b31421 100644 --- a/test/common/dns.js +++ b/test/common/dns.js @@ -1,8 +1,8 @@ 'use strict'; const assert = require('assert'); -const os = require('os'); -const { isIP } = require('net'); +let endianness; +let isIP; const types = { A: 1, @@ -284,11 +284,13 @@ function writeDNSPacket(parsed) { } } + endianness ??= require('os').endianness(); + return Buffer.concat(buffers.map((typedArray) => { const buf = Buffer.from(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength); - if (os.endianness() === 'LE') { + if (endianness === 'LE') { if (typedArray.BYTES_PER_ELEMENT === 2) buf.swap16(); if (typedArray.BYTES_PER_ELEMENT === 4) buf.swap32(); } @@ -311,6 +313,7 @@ function errorLookupMock(code = mockedErrorCode, syscall = mockedSysCall) { } function createMockedLookup(...addresses) { + isIP ??= require('net').isIP; addresses = addresses.map((address) => ({ address: address, family: isIP(address) })); // Create a DNS server which replies with a AAAA and a A record for the same host diff --git a/test/common/heap.js b/test/common/heap.js index bec3b3208c0295..d763e206b065fa 100644 --- a/test/common/heap.js +++ b/test/common/heap.js @@ -1,6 +1,6 @@ 'use strict'; const assert = require('assert'); -const util = require('util'); +const { inspect } = require('util'); let _buildEmbedderGraph; function buildEmbedderGraph() { @@ -91,7 +91,7 @@ function readHeapInfo(raw, fields, types, strings) { } function inspectNode(snapshot) { - return util.inspect(snapshot, { depth: 4 }); + return inspect(snapshot, { depth: 4 }); } function isEdge(edge, { node_name, edge_name }) { @@ -144,7 +144,7 @@ class State { if (!hasChild) { throw new Error( 'expected to find child ' + - `${util.inspect(expectedEdge)} in ${inspectNode(rootNodes)}`); + `${inspect(expectedEdge)} in ${inspectNode(rootNodes)}`); } } } @@ -196,7 +196,7 @@ class State { if (!hasChild) { throw new Error( 'expected to find child ' + - `${util.inspect(expectedEdge)} in ${inspectNode(rootNodes)}`); + `${inspect(expectedEdge)} in ${inspectNode(rootNodes)}`); } } } @@ -269,7 +269,7 @@ function findByRetainingPath(rootName, retainingPath) { } if (newHaystack.length === 0) { - const format = (val) => util.inspect(val, { breakLength: 128, depth: 3 }); + const format = (val) => inspect(val, { breakLength: 128, depth: 3 }); console.error('#'); console.error('# Retaining path to search for:'); for (let j = 0; j < retainingPath.length; ++j) { diff --git a/test/common/index.js b/test/common/index.js index 8113f604dfcdb6..89a42b55721b12 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -24,7 +24,10 @@ const process = globalThis.process; // Some tests tamper with the process globa const assert = require('assert'); const fs = require('fs'); -const net = require('net'); +const { + getDefaultAutoSelectFamilyAttemptTimeout, + setDefaultAutoSelectFamilyAttemptTimeout, +} = require('net'); // Do not require 'os' until needed so that test-os-checked-function can // monkey patch it. If 'os' is required here, that test will fail. const path = require('path'); @@ -139,8 +142,8 @@ const isPi = (() => { })(); // When using high concurrency or in the CI we need much more time for each connection attempt -net.setDefaultAutoSelectFamilyAttemptTimeout(platformTimeout(net.getDefaultAutoSelectFamilyAttemptTimeout() * 10)); -const defaultAutoSelectFamilyAttemptTimeout = net.getDefaultAutoSelectFamilyAttemptTimeout(); +const defaultAutoSelectFamilyAttemptTimeout = platformTimeout(getDefaultAutoSelectFamilyAttemptTimeout() * 10); +setDefaultAutoSelectFamilyAttemptTimeout(defaultAutoSelectFamilyAttemptTimeout); const buildType = process.config.target_defaults ? process.config.target_defaults.default_configuration : diff --git a/test/common/inspector-helper.js b/test/common/inspector-helper.js index 3c7277c24a5522..8d35a256298f79 100644 --- a/test/common/inspector-helper.js +++ b/test/common/inspector-helper.js @@ -5,7 +5,7 @@ const fs = require('fs'); const http = require('http'); const fixtures = require('../common/fixtures'); const { spawn } = require('child_process'); -const { URL, pathToFileURL } = require('url'); +const { pathToFileURL } = require('url'); const { EventEmitter, once } = require('events'); const _MAINSCRIPT = fixtures.path('loop.js'); diff --git a/test/common/measure-memory.js b/test/common/measure-memory.js index ffde35f285da36..781f6f38e82455 100644 --- a/test/common/measure-memory.js +++ b/test/common/measure-memory.js @@ -1,7 +1,7 @@ 'use strict'; const assert = require('assert'); -const common = require('./'); +let expectWarning; // The formats could change when V8 is updated, then the tests should be // updated accordingly. @@ -43,7 +43,8 @@ function assertSingleDetailedShape(result) { } function expectExperimentalWarning() { - common.expectWarning( + expectWarning ??= require('./').expectWarning; + expectWarning( 'ExperimentalWarning', 'vm.measureMemory is an experimental feature and might change at any time', ); diff --git a/test/common/net.js b/test/common/net.js index 3886c542421005..ba75a5a2c5411a 100644 --- a/test/common/net.js +++ b/test/common/net.js @@ -1,11 +1,11 @@ 'use strict'; -const net = require('net'); - const options = { port: 0, reusePort: true }; +let createServer; function checkSupportReusePort() { + createServer ??= require('net').createServer; return new Promise((resolve, reject) => { - const server = net.createServer().listen(options); + const server = createServer().listen(options); server.on('listening', () => { server.close(resolve); }); diff --git a/test/common/tls.js b/test/common/tls.js index d212fbe076072c..ffdad2fa7a92ac 100644 --- a/test/common/tls.js +++ b/test/common/tls.js @@ -2,11 +2,11 @@ 'use strict'; const crypto = require('crypto'); -const net = require('net'); +const { Socket } = require('net'); exports.ccs = Buffer.from('140303000101', 'hex'); -class TestTLSSocket extends net.Socket { +class TestTLSSocket extends Socket { constructor(server_cert) { super(); this.server_cert = server_cert; diff --git a/test/common/udp.js b/test/common/udp.js index a94d76fc09e033..84b16844859bf5 100644 --- a/test/common/udp.js +++ b/test/common/udp.js @@ -1,21 +1,21 @@ 'use strict'; -const dgram = require('dgram'); +const { createSocket } = require('dgram'); const options = { type: 'udp4', reusePort: true }; function checkSupportReusePort() { - return new Promise((resolve, reject) => { - const socket = dgram.createSocket(options); - socket.bind(0); - socket.on('listening', () => { - socket.close(resolve); - }); - socket.on('error', (err) => { - console.log('The `reusePort` option is not supported:', err.message); - socket.close(); - reject(err); - }); + const { promise, resolve, reject } = Promise.withResolvers(); + const socket = createSocket(options); + socket.bind(0); + socket.on('listening', () => { + socket.close(resolve); }); + socket.on('error', (err) => { + console.log('The `reusePort` option is not supported:', err.message); + socket.close(); + reject(err); + }); + return promise; } module.exports = { diff --git a/test/common/v8.js b/test/common/v8.js index 9c247bde50eb8c..bd401528d868a7 100644 --- a/test/common/v8.js +++ b/test/common/v8.js @@ -1,15 +1,16 @@ 'use strict'; const assert = require('assert'); -const { GCProfiler } = require('v8'); +let GCProfiler; function collectGCProfile({ duration }) { - return new Promise((resolve) => { - const profiler = new GCProfiler(); - profiler.start(); - setTimeout(() => { - resolve(profiler.stop()); - }, duration); - }); + GCProfiler ??= require('v8').GCProfiler; + const { promise, resolve } = Promise.withResolvers(); + const profiler = new GCProfiler(); + profiler.start(); + setTimeout(() => { + resolve(profiler.stop()); + }, duration); + return promise; } function checkGCProfile(data) { diff --git a/test/common/wpt.js b/test/common/wpt.js index 3ead9cb23b9c46..362d40f4b68835 100644 --- a/test/common/wpt.js +++ b/test/common/wpt.js @@ -6,12 +6,13 @@ const fs = require('fs'); const fsPromises = fs.promises; const path = require('path'); const events = require('events'); -const os = require('os'); const { inspect } = require('util'); const { Worker } = require('worker_threads'); const workerPath = path.join(__dirname, 'wpt/worker.js'); +let osType; + function getBrowserProperties() { const { node: version } = process.versions; // e.g. 18.13.0, 20.0.0-nightly202302078e6e215481 const release = /^\d+\.\d+\.\d+$/.test(version); @@ -28,7 +29,8 @@ function getBrowserProperties() { * https://github.com/web-platform-tests/wpt/blob/1c6ff12/tools/wptrunner/wptrunner/tests/test_update.py#L953-L958 */ function getOs() { - switch (os.type()) { + osType ??= require('os').type(); + switch (osType) { case 'Linux': return 'linux'; case 'Darwin': @@ -512,10 +514,10 @@ const limit = (concurrency) => { }; class WPTRunner { - constructor(path, { concurrency = os.availableParallelism() - 1 || 1 } = {}) { + constructor(path, { concurrency } = {}) { this.path = path; this.resource = new ResourceLoader(path); - this.concurrency = concurrency; + this.concurrency = concurrency ?? (require('os').availableParallelism() - 1 || 1); this.flags = []; this.globalThisInitScripts = [];