diff --git a/test/es-module/test-wasm-web-api.js b/test/es-module/test-wasm-web-api.js index ee1971133be5..6177c909e56c 100644 --- a/test/es-module/test-wasm-web-api.js +++ b/test/es-module/test-wasm-web-api.js @@ -16,7 +16,13 @@ const simpleWasmBytes = fixtures.readSync('simple.wasm'); // Sets up an HTTP server with the given response handler and calls fetch() to // obtain a Response from the newly created server. async function testRequest(handler) { - const server = createServer((_, res) => handler(res)).unref().listen(0); + const server = createServer(common.mustCall((_, res) => { + res.setHeader('Connection', 'close'); + res.once('close', common.mustCall(() => { + server.close(common.mustCall()); + })); + handler(res); + })).listen(0); await events.once(server, 'listening'); const { port } = server.address(); return fetch(`http://127.0.0.1:${port}/foo.wasm`); diff --git a/test/fixtures/test-runner/execution-ordered-bypass/slow.mjs b/test/fixtures/test-runner/execution-ordered-bypass/slow.mjs index 4ee60ffe8537..21f6f2b68676 100644 --- a/test/fixtures/test-runner/execution-ordered-bypass/slow.mjs +++ b/test/fixtures/test-runner/execution-ordered-bypass/slow.mjs @@ -1,9 +1,11 @@ import { test } from 'node:test'; -import { setTimeout as sleep } from 'node:timers/promises'; +import { once } from 'node:events'; +import { connect } from 'node:net'; test('slow', async () => { - // Long enough that fast-fail's process can spawn, run, and round-trip its - // bypassed test:complete to the host on slow CI, but short enough that the - // test does not waste much time when the bypass is working. - await sleep(30_000); + // The host closes this connection after receiving fast-fail's bypassed + // test:complete event, so this test cannot finish before that event arrives. + const socket = connect(Number(process.argv[2]), '127.0.0.1'); + socket.resume(); + await once(socket, 'end'); }); diff --git a/test/parallel/test-abort-controller-any-timeout.js b/test/parallel/test-abort-controller-any-timeout.js index 2d94afaa63d9..675be3af703c 100644 --- a/test/parallel/test-abort-controller-any-timeout.js +++ b/test/parallel/test-abort-controller-any-timeout.js @@ -1,28 +1,42 @@ +// Flags: --expose-gc 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const { once } = require('node:events'); const { describe, it } = require('node:test'); describe('AbortSignal.any() with timeout signals', () => { it('should abort when the first timeout signal fires', async () => { - const signal = AbortSignal.any([AbortSignal.timeout(9000), AbortSignal.timeout(110000)]); + const signal = AbortSignal.any([ + AbortSignal.timeout(common.platformTimeout(1000)), + AbortSignal.timeout(110000), + ]); + let timeout; const abortPromise = Promise.race([ once(signal, 'abort').then(() => { throw signal.reason; }), - new Promise((resolve) => setTimeout(resolve, 10000)), + new Promise((resolve) => { + timeout = setTimeout(resolve, common.platformTimeout(10000)); + }), ]); - // The promise should be aborted by the 9000ms timeout - await assert.rejects( - () => abortPromise, - { - name: 'TimeoutError', - message: 'The operation was aborted due to timeout' - } - ); + // Collect after this turn so the WeakRefs no longer keep the timeout + // signals alive by themselves. + setImmediate(common.mustCall(() => globalThis.gc())); + + try { + await assert.rejects( + () => abortPromise, + { + name: 'TimeoutError', + message: 'The operation was aborted due to timeout' + } + ); + } finally { + clearTimeout(timeout); + } }); }); diff --git a/test/parallel/test-crypto-dh-constructor.js b/test/parallel/test-crypto-dh-constructor.js index 28747ac3a726..edf7ab08e44c 100644 --- a/test/parallel/test-crypto-dh-constructor.js +++ b/test/parallel/test-crypto-dh-constructor.js @@ -5,17 +5,14 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); +const { hasFIPS } = require('../common/crypto'); -const size = hasFIPS(3) ? - 2048 : (crypto.getFips() === 1 || hasOpenSSL(3) ? 1024 : 256); -const dh1 = crypto.createDiffieHellman(size); -const p1 = dh1.getPrime('buffer'); +const prime = crypto.getDiffieHellman('modp14').getPrime('buffer'); { const DiffieHellman = crypto.DiffieHellman; - const dh = DiffieHellman(p1, 'buffer'); + const dh = DiffieHellman(prime, 'buffer'); assert(dh instanceof DiffieHellman, 'DiffieHellman is expected to return a ' + 'new instance when called without `new`'); } diff --git a/test/parallel/test-crypto-dh-generate-keys.js b/test/parallel/test-crypto-dh-generate-keys.js index d074ba957516..65efb369c08e 100644 --- a/test/parallel/test-crypto-dh-generate-keys.js +++ b/test/parallel/test-crypto-dh-generate-keys.js @@ -6,11 +6,9 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); { - const size = hasFIPS(3) ? - 2048 : (crypto.getFips() === 1 || hasOpenSSL(3) ? 1024 : 256); + const prime = crypto.getDiffieHellman('modp14').getPrime(); function unlessInvalidState(f) { try { @@ -23,7 +21,7 @@ const { hasOpenSSL, hasFIPS } = require('../common/crypto'); } function testGenerateKeysChangesKeys(setup, expected) { - const dh = crypto.createDiffieHellman(size); + const dh = crypto.createDiffieHellman(prime); setup(dh); const firstPublicKey = unlessInvalidState(() => dh.getPublicKey()); const firstPrivateKey = unlessInvalidState(() => dh.getPrivateKey()); diff --git a/test/parallel/test-crypto-dh-leak.js b/test/parallel/test-crypto-dh-leak.js index 8d5141eef4b1..f58a5a152b78 100644 --- a/test/parallel/test-crypto-dh-leak.js +++ b/test/parallel/test-crypto-dh-leak.js @@ -9,13 +9,11 @@ if (common.isASan) const assert = require('assert'); const crypto = require('crypto'); -const { hasOpenSSL, hasFIPS } = require('../common/crypto'); const before = process.memoryUsage.rss(); { - const size = hasFIPS(3) ? - 2048 : (crypto.getFips() === 1 || hasOpenSSL(3) ? 1024 : 256); - const dh = crypto.createDiffieHellman(size); + const prime = crypto.getDiffieHellman('modp14').getPrime(); + const dh = crypto.createDiffieHellman(prime); const publicKey = dh.generateKeys(); const privateKey = dh.getPrivateKey(); for (let i = 0; i < 5e4; i += 1) { diff --git a/test/parallel/test-dns-channel-timeout.js b/test/parallel/test-dns-channel-timeout.js index 1e4dac548973..0c9c7c31caee 100644 --- a/test/parallel/test-dns-channel-timeout.js +++ b/test/parallel/test-dns-channel-timeout.js @@ -22,10 +22,11 @@ for (const ctor of [dns.Resolver, dns.promises.Resolver]) { for (const timeout of [-1, 0, 1]) new ctor({ timeout }); // OK } +// One attempt is enough to exercise the timeout without retry backoff. for (const timeout of [0, 1, 2]) { const server = dgram.createSocket('udp4'); server.bind(0, '127.0.0.1', common.mustCall(() => { - const resolver = new dns.Resolver({ timeout }); + const resolver = new dns.Resolver({ timeout, tries: 1 }); resolver.setServers([`127.0.0.1:${server.address().port}`]); resolver.resolve4('nodejs.org', common.mustCall((err) => { assert.throws(() => { throw err; }, { @@ -40,7 +41,7 @@ for (const timeout of [0, 1, 2]) { for (const timeout of [0, 1, 2]) { const server = dgram.createSocket('udp4'); server.bind(0, '127.0.0.1', common.mustCall(() => { - const resolver = new dns.promises.Resolver({ timeout }); + const resolver = new dns.promises.Resolver({ timeout, tries: 1 }); resolver.setServers([`127.0.0.1:${server.address().port}`]); resolver.resolve4('nodejs.org').catch(common.mustCall((err) => { assert.throws(() => { throw err; }, { diff --git a/test/parallel/test-http-buffer-sanity.js b/test/parallel/test-http-buffer-sanity.js index 4a4435b20abd..919118ea53b5 100644 --- a/test/parallel/test-http-buffer-sanity.js +++ b/test/parallel/test-http-buffer-sanity.js @@ -55,6 +55,7 @@ const server = new http.Server(common.mustCallAtLeast(function(req, res) { server.listen(0, common.mustCall(() => { const req = http.request({ + agent: false, port: server.address().port, method: 'POST', path: '/', diff --git a/test/parallel/test-http-byteswritten.js b/test/parallel/test-http-byteswritten.js index 003b7dfbd049..475176e6c976 100644 --- a/test/parallel/test-http-byteswritten.js +++ b/test/parallel/test-http-byteswritten.js @@ -51,5 +51,5 @@ const httpServer = http.createServer(common.mustCall(function(req, res) { })); httpServer.listen(0, function() { - http.get({ port: this.address().port }); + http.get({ port: this.address().port, agent: false }); }); diff --git a/test/parallel/test-http-client-check-http-token.js b/test/parallel/test-http-client-check-http-token.js index ef2445ec66e5..7ab9aa83d761 100644 --- a/test/parallel/test-http-client-check-http-token.js +++ b/test/parallel/test-http-client-check-http-token.js @@ -29,6 +29,6 @@ server.listen(0, common.mustCall(() => { }); expectedSuccesses.forEach((method) => { - http.request({ method, port: server.address().port }).end(); + http.request({ method, port: server.address().port, agent: false }).end(); }); })); diff --git a/test/parallel/test-http-client-encoding.js b/test/parallel/test-http-client-encoding.js index a4701cdbd0ab..253496307286 100644 --- a/test/parallel/test-http-client-encoding.js +++ b/test/parallel/test-http-client-encoding.js @@ -29,6 +29,7 @@ const server = http.createServer((req, res) => { server.close(); }).listen(0, common.mustCall(() => { http.request({ + agent: false, port: server.address().port, encoding: 'utf8' }, common.mustCall((res) => { diff --git a/test/parallel/test-http-client-response-domain.js b/test/parallel/test-http-client-response-domain.js index 9975ca3f9498..da3d3a09ff0f 100644 --- a/test/parallel/test-http-client-response-domain.js +++ b/test/parallel/test-http-client-response-domain.js @@ -49,6 +49,7 @@ function test() { })); const req = http.get({ + agent: false, socketPath: common.PIPE, headers: { 'Content-Length': '1' }, method: 'POST', diff --git a/test/parallel/test-http-decoded-auth.js b/test/parallel/test-http-decoded-auth.js index 076c056253b6..4f7847133f58 100644 --- a/test/parallel/test-http-decoded-auth.js +++ b/test/parallel/test-http-decoded-auth.js @@ -43,6 +43,6 @@ for (const testCase of testCases) { server.listen(0, function() { // make the request const url = new URL(`http://${testCase.username}:${testCase.password}@localhost:${this.address().port}`); - http.request(url).end(); + http.request(url, { agent: false }).end(); }); } diff --git a/test/parallel/test-http-default-port.js b/test/parallel/test-http-default-port.js index 2005487502fe..874affcdf23c 100644 --- a/test/parallel/test-http-default-port.js +++ b/test/parallel/test-http-default-port.js @@ -44,7 +44,6 @@ for (const { mod, createServer } of [ assert.strictEqual(req.headers['x-port'], `${server.address().port}`); res.writeHead(200); res.end('ok'); - server.close(); })).listen(0, common.mustCall(() => { mod.globalAgent.defaultPort = server.address().port; mod.get({ @@ -54,6 +53,7 @@ for (const { mod, createServer } of [ 'x-port': server.address().port } }, common.mustCall((res) => { + res.on('end', common.mustCall(() => server.close())); res.resume(); })); })); diff --git a/test/parallel/test-http-dont-set-default-headers-with-setHost.js b/test/parallel/test-http-dont-set-default-headers-with-setHost.js index e2a4e39c24b8..418051127859 100644 --- a/test/parallel/test-http-dont-set-default-headers-with-setHost.js +++ b/test/parallel/test-http-dont-set-default-headers-with-setHost.js @@ -14,6 +14,7 @@ const server = http.createServer(common.mustCall(function(req, res) { })); server.listen(0, common.localhostIPv4, function() { http.request({ + agent: false, method: 'POST', host: common.localhostIPv4, port: this.address().port, diff --git a/test/parallel/test-http-dont-set-default-headers.js b/test/parallel/test-http-dont-set-default-headers.js index 3f73c11e5112..0b8e4c58f56b 100644 --- a/test/parallel/test-http-dont-set-default-headers.js +++ b/test/parallel/test-http-dont-set-default-headers.js @@ -17,6 +17,7 @@ const server = http.createServer(common.mustCall(function(req, res) { })); server.listen(0, common.localhostIPv4, function() { http.request({ + agent: false, method: 'POST', host: common.localhostIPv4, port: this.address().port, diff --git a/test/parallel/test-http-early-hints-invalid-argument.js b/test/parallel/test-http-early-hints-invalid-argument.js index edf613614bc7..b426ca3e840f 100644 --- a/test/parallel/test-http-early-hints-invalid-argument.js +++ b/test/parallel/test-http-early-hints-invalid-argument.js @@ -38,7 +38,7 @@ const testResBody = 'response content\n'; server.listen(0, common.mustCall(() => { const req = http.request({ - port: server.address().port, path: '/' + port: server.address().port, path: '/', agent: false }); req.end(); @@ -79,7 +79,7 @@ const testResBody = 'response content\n'; server.listen(0, common.mustCall(() => { const req = http.request({ - port: server.address().port, path: '/' + port: server.address().port, path: '/', agent: false }); req.end(); diff --git a/test/parallel/test-http-head-request.js b/test/parallel/test-http-head-request.js index 26d490d357dc..a9fcb2c166b3 100644 --- a/test/parallel/test-http-head-request.js +++ b/test/parallel/test-http-head-request.js @@ -35,6 +35,7 @@ function test(headers) { server.listen(0, common.mustCall(function() { const request = http.request({ + agent: false, port: this.address().port, method: 'HEAD', path: '/' diff --git a/test/parallel/test-http-hex-write.js b/test/parallel/test-http-hex-write.js index a3cbec6b36c0..4162811276d9 100644 --- a/test/parallel/test-http-hex-write.js +++ b/test/parallel/test-http-hex-write.js @@ -34,7 +34,7 @@ http.createServer(function(q, s) { s.end(); this.close(); }).listen(0, common.mustCall(function() { - http.request({ port: this.address().port }) + http.request({ port: this.address().port, agent: false }) .on('response', common.mustCall(function(res) { let data = ''; diff --git a/test/parallel/test-http-outgoing-end-types.js b/test/parallel/test-http-outgoing-end-types.js index 20b443bff2c1..48372a98e81b 100644 --- a/test/parallel/test-http-outgoing-end-types.js +++ b/test/parallel/test-http-outgoing-end-types.js @@ -14,5 +14,5 @@ const httpServer = http.createServer(common.mustCall(function(req, res) { })); httpServer.listen(0, common.mustCall(function() { - http.get({ port: this.address().port }); + http.get({ port: this.address().port, agent: false }); })); diff --git a/test/parallel/test-http-outgoing-finish-writable.js b/test/parallel/test-http-outgoing-finish-writable.js index e3c870164bac..e0d9b73702cf 100644 --- a/test/parallel/test-http-outgoing-finish-writable.js +++ b/test/parallel/test-http-outgoing-finish-writable.js @@ -25,6 +25,7 @@ server.listen(0); server.on('listening', common.mustCall(function() { const clientRequest = http.request({ + agent: false, port: server.address().port, method: 'GET', path: '/' diff --git a/test/parallel/test-http-outgoing-finish.js b/test/parallel/test-http-outgoing-finish.js index 0f71cccdf810..f2378d9e05b2 100644 --- a/test/parallel/test-http-outgoing-finish.js +++ b/test/parallel/test-http-outgoing-finish.js @@ -33,6 +33,7 @@ http.createServer(function(req, res) { this.close(); }).listen(0, function() { const req = http.request({ + agent: false, port: this.address().port, method: 'PUT' }); diff --git a/test/parallel/test-http-outgoing-properties.js b/test/parallel/test-http-outgoing-properties.js index 85c5b659a36d..a831765322b8 100644 --- a/test/parallel/test-http-outgoing-properties.js +++ b/test/parallel/test-http-outgoing-properties.js @@ -36,6 +36,7 @@ const OutgoingMessage = http.OutgoingMessage; server.on('listening', common.mustCall(function() { const clientRequest = http.request({ + agent: false, port: server.address().port, method: 'GET', path: '/' @@ -62,6 +63,7 @@ const OutgoingMessage = http.OutgoingMessage; server.on('listening', common.mustCall(() => { const req = http.request({ + agent: false, port: server.address().port, method: 'GET', path: '/' diff --git a/test/parallel/test-http-outgoing-write-types.js b/test/parallel/test-http-outgoing-write-types.js index 6257b87eea8e..0f2c686d5a7a 100644 --- a/test/parallel/test-http-outgoing-write-types.js +++ b/test/parallel/test-http-outgoing-write-types.js @@ -20,5 +20,5 @@ const httpServer = http.createServer(common.mustCall(function(req, res) { })); httpServer.listen(0, common.mustCall(function() { - http.get({ port: this.address().port }); + http.get({ port: this.address().port, agent: false }); })); diff --git a/test/parallel/test-http-request-arguments.js b/test/parallel/test-http-request-arguments.js index 5cdd514fd506..b08da9bc5256 100644 --- a/test/parallel/test-http-request-arguments.js +++ b/test/parallel/test-http-request-arguments.js @@ -18,7 +18,7 @@ const http = require('http'); common.mustCall(() => { http.get( 'http://example.com/testpath', - { hostname: 'localhost', port: server.address().port }, + { hostname: 'localhost', port: server.address().port, agent: false }, common.mustCall((res) => { res.resume(); }) diff --git a/test/parallel/test-http-request-large-payload.js b/test/parallel/test-http-request-large-payload.js index 3be100b74041..08fada1381f2 100644 --- a/test/parallel/test-http-request-large-payload.js +++ b/test/parallel/test-http-request-large-payload.js @@ -16,6 +16,7 @@ const server = http.createServer(function(req, res) { server.listen(0, function() { const req = http.request({ + agent: false, method: 'POST', port: this.address().port }); diff --git a/test/parallel/test-http-server-connection-list-when-close.js b/test/parallel/test-http-server-connection-list-when-close.js index a530b710c490..0c8308b63c53 100644 --- a/test/parallel/test-http-server-connection-list-when-close.js +++ b/test/parallel/test-http-server-connection-list-when-close.js @@ -5,6 +5,7 @@ const http = require('http'); function request(server) { http.get({ + agent: false, port: server.address().port, path: '/', }, (res) => { diff --git a/test/parallel/test-http-server-delete-parser.js b/test/parallel/test-http-server-delete-parser.js index 4215ee2f9df7..6b5a3e13f503 100644 --- a/test/parallel/test-http-server-delete-parser.js +++ b/test/parallel/test-http-server-delete-parser.js @@ -14,6 +14,7 @@ const server = http.createServer(common.mustCall((req, res) => { server.listen(0, '127.0.0.1', common.mustCall(() => { const req = http.request({ + agent: false, port: server.address().port, host: '127.0.0.1', method: 'GET', diff --git a/test/parallel/test-http-server-multiheaders.js b/test/parallel/test-http-server-multiheaders.js index fea84a8d4a7e..e15dbd0fcaed 100644 --- a/test/parallel/test-http-server-multiheaders.js +++ b/test/parallel/test-http-server-multiheaders.js @@ -48,6 +48,7 @@ const server = http.createServer(common.mustCall((req, res) => { server.listen(0, function() { http.get({ + agent: false, host: 'localhost', port: this.address().port, path: '/', diff --git a/test/parallel/test-http-server-multiheaders2.js b/test/parallel/test-http-server-multiheaders2.js index 0408afa1b13e..85f2fb09f931 100644 --- a/test/parallel/test-http-server-multiheaders2.js +++ b/test/parallel/test-http-server-multiheaders2.js @@ -100,6 +100,7 @@ const headers = [] server.listen(0, function() { http.get({ + agent: false, host: 'localhost', port: this.address().port, path: '/', diff --git a/test/parallel/test-http-url.parse-auth-with-header-in-request.js b/test/parallel/test-http-url.parse-auth-with-header-in-request.js index ea5793ee18ae..e4834c32a644 100644 --- a/test/parallel/test-http-url.parse-auth-with-header-in-request.js +++ b/test/parallel/test-http-url.parse-auth-with-header-in-request.js @@ -41,6 +41,7 @@ const server = http.createServer(function(request, response) { server.listen(0, function() { const testURL = url.parse(`http://asdf:qwer@localhost:${this.address().port}`); + testURL.agent = false; // The test here is if you set a specific authorization header in the // request we should not override that with basic auth testURL.headers = { diff --git a/test/parallel/test-http-url.parse-auth.js b/test/parallel/test-http-url.parse-auth.js index 2bb531158645..287c27b9eb91 100644 --- a/test/parallel/test-http-url.parse-auth.js +++ b/test/parallel/test-http-url.parse-auth.js @@ -42,6 +42,7 @@ server.listen(0, function() { const port = this.address().port; // username = "user", password = "pass:" const testURL = url.parse(`http://user:pass%3A@localhost:${port}`); + testURL.agent = false; // make the request http.request(testURL).end(); diff --git a/test/parallel/test-http-url.parse-basic.js b/test/parallel/test-http-url.parse-basic.js index d0c230977178..223d1d7af25a 100644 --- a/test/parallel/test-http-url.parse-basic.js +++ b/test/parallel/test-http-url.parse-basic.js @@ -43,7 +43,6 @@ const server = http.createServer(function(request, response) { check(request); response.writeHead(200, {}); response.end('ok'); - server.close(); }); server.listen(0, common.mustCall(function() { @@ -54,5 +53,9 @@ server.listen(0, common.mustCall(function() { // Since there is a little magic with the agent // make sure that an http request uses the http.Agent assert.ok(clientRequest.agent instanceof http.Agent); + clientRequest.on('response', common.mustCall((response) => { + response.on('end', common.mustCall(() => server.close())); + response.resume(); + })); clientRequest.end(); })); diff --git a/test/parallel/test-http-url.parse-https.request.js b/test/parallel/test-http-url.parse-https.request.js index ff819adc2b84..e20c3a0ec7bc 100644 --- a/test/parallel/test-http-url.parse-https.request.js +++ b/test/parallel/test-http-url.parse-https.request.js @@ -45,7 +45,6 @@ const server = https.createServer(httpsOptions, function(request, response) { check(request); response.writeHead(200, {}); response.end('ok'); - server.close(); }); server.listen(0, common.mustCall(function() { @@ -57,5 +56,9 @@ server.listen(0, common.mustCall(function() { // Since there is a little magic with the agent // make sure that the request uses the https.Agent assert.ok(clientRequest.agent instanceof https.Agent); + clientRequest.on('response', common.mustCall((response) => { + response.on('end', common.mustCall(() => server.close())); + response.resume(); + })); clientRequest.end(); })); diff --git a/test/parallel/test-http-url.parse-path.js b/test/parallel/test-http-url.parse-path.js index 25e4838c4afa..04fe12a4ff1f 100644 --- a/test/parallel/test-http-url.parse-path.js +++ b/test/parallel/test-http-url.parse-path.js @@ -40,6 +40,7 @@ const server = http.createServer(function(request, response) { server.listen(0, function() { const testURL = url.parse(`http://localhost:${this.address().port}/asdf`); + testURL.agent = false; // make the request http.request(testURL).end(); diff --git a/test/parallel/test-http-url.parse-post.js b/test/parallel/test-http-url.parse-post.js index db5ee78fe6eb..447a1b6a3fdc 100644 --- a/test/parallel/test-http-url.parse-post.js +++ b/test/parallel/test-http-url.parse-post.js @@ -47,6 +47,7 @@ const server = http.createServer(function(request, response) { server.listen(0, function() { testURL = url.parse(`http://localhost:${this.address().port}/asdf?qwer=zxcv`); + testURL.agent = false; testURL.method = 'POST'; // make the request diff --git a/test/parallel/test-http-url.parse-search.js b/test/parallel/test-http-url.parse-search.js index 0759c779d3ff..80f435a6789a 100644 --- a/test/parallel/test-http-url.parse-search.js +++ b/test/parallel/test-http-url.parse-search.js @@ -41,6 +41,7 @@ const server = http.createServer(function(request, response) { server.listen(0, function() { const port = this.address().port; const testURL = url.parse(`http://localhost:${port}/asdf?qwer=zxcv`); + testURL.agent = false; // make the request http.request(testURL).end(); diff --git a/test/parallel/test-http-write-callbacks.js b/test/parallel/test-http-write-callbacks.js index 1f90e5135be6..3b29f7c2f5d6 100644 --- a/test/parallel/test-http-write-callbacks.js +++ b/test/parallel/test-http-write-callbacks.js @@ -71,6 +71,7 @@ server.on('checkContinue', common.mustCall((req, res) => { server.listen(0, common.mustCall(function() { const req = http.request({ + agent: false, port: this.address().port, method: 'PUT', headers: { 'expect': '100-continue' } diff --git a/test/parallel/test-http-write-empty-string.js b/test/parallel/test-http-write-empty-string.js index 88eff08f7666..05e97a4865c3 100644 --- a/test/parallel/test-http-write-empty-string.js +++ b/test/parallel/test-http-write-empty-string.js @@ -39,7 +39,7 @@ const server = http.createServer(function(request, response) { }); server.listen(0, common.mustCall(() => { - http.get({ port: server.address().port }, common.mustCall((res) => { + http.get({ port: server.address().port, agent: false }, common.mustCall((res) => { let response = ''; assert.strictEqual(res.statusCode, 200); diff --git a/test/parallel/test-http-zero-length-write.js b/test/parallel/test-http-zero-length-write.js index dfaa7b92fb7d..92905fd9755a 100644 --- a/test/parallel/test-http-zero-length-write.js +++ b/test/parallel/test-http-zero-length-write.js @@ -75,7 +75,7 @@ const server = http.createServer(common.mustCall((req, res) => { })); server.listen(0, common.mustCall(function() { - const req = http.request({ port: this.address().port, method: 'POST' }); + const req = http.request({ port: this.address().port, method: 'POST', agent: false }); let actual = ''; req.on('response', common.mustCall((res) => { res.setEncoding('utf8'); diff --git a/test/parallel/test-https-drain.js b/test/parallel/test-https-drain.js index 5d7bf9736458..b9a5c3d3bda8 100644 --- a/test/parallel/test-https-drain.js +++ b/test/parallel/test-https-drain.js @@ -45,6 +45,7 @@ const server = https.createServer(options, function(req, res) { server.listen(0, common.mustCall(function() { let resumed = false; const req = https.request({ + agent: false, method: 'POST', port: this.address().port, rejectUnauthorized: false diff --git a/test/parallel/test-https-request-arguments.js b/test/parallel/test-https-request-arguments.js index 9dc80094be0d..e68f757be81b 100644 --- a/test/parallel/test-https-request-arguments.js +++ b/test/parallel/test-https-request-arguments.js @@ -32,6 +32,7 @@ const options = { 'https://example.com/testpath', { + agent: false, hostname: 'localhost', port: server.address().port, rejectUnauthorized: false diff --git a/test/parallel/test-https-truncate.js b/test/parallel/test-https-truncate.js index beed36cd7c08..eaaedea1afc7 100644 --- a/test/parallel/test-https-truncate.js +++ b/test/parallel/test-https-truncate.js @@ -47,7 +47,7 @@ function httpsTest() { }); server.listen(0, function() { - const opts = { port: this.address().port, rejectUnauthorized: false }; + const opts = { port: this.address().port, rejectUnauthorized: false, agent: false }; https.get(opts).on('response', function(res) { test(res); }); diff --git a/test/parallel/test-https-unix-socket-self-signed.js b/test/parallel/test-https-unix-socket-self-signed.js index 9db92ac2aed4..5a3b76e11794 100644 --- a/test/parallel/test-https-unix-socket-self-signed.js +++ b/test/parallel/test-https-unix-socket-self-signed.js @@ -21,6 +21,7 @@ const server = https.createServer(options, common.mustCall((req, res) => { server.listen(common.PIPE, common.mustCall(() => { https.get({ + agent: false, socketPath: common.PIPE, rejectUnauthorized: false }); diff --git a/test/parallel/test-runner-execution-ordered-bypass.mjs b/test/parallel/test-runner-execution-ordered-bypass.mjs index ac1c97ee007d..75e9eb51d7d9 100644 --- a/test/parallel/test-runner-execution-ordered-bypass.mjs +++ b/test/parallel/test-runner-execution-ordered-bypass.mjs @@ -1,8 +1,10 @@ // Flags: --no-warnings -import '../common/index.mjs'; +import { mustCall, platformTimeout } from '../common/index.mjs'; import * as fixtures from '../common/fixtures.mjs'; import assert from 'node:assert'; +import { once } from 'node:events'; +import { createServer } from 'node:net'; import { test, run } from 'node:test'; const files = [ @@ -10,15 +12,29 @@ const files = [ fixtures.path('test-runner', 'execution-ordered-bypass', 'fast-fail.mjs'), ]; -test('execution-ordered events bypass FileTest declaration-order buffer', async () => { +test('execution-ordered events bypass FileTest declaration-order buffer', { + timeout: platformTimeout(30_000), +}, async (t) => { + const { promise: fastCompleted, resolve: releaseSlow } = Promise.withResolvers(); + const server = createServer(mustCall((socket) => { + t.after(() => socket.destroy()); + fastCompleted.then(mustCall(() => { + socket.end(); + })); + })); + t.after(() => server.close()); + await once(server.listen(0, '127.0.0.1'), 'listening'); + // Concurrency must be a number so the runner does not collapse it to 1 on // single-core CI runners (where `concurrency: true` resolves to // `availableParallelism() - 1`). Without two slots the runner spawns the - // files sequentially and fast-fail never starts while slow is sleeping. + // files sequentially and fast-fail never starts while slow is waiting. const stream = run({ files, isolation: 'process', concurrency: 2, + argv: [String(server.address().port)], + signal: t.signal, }); const events = []; @@ -27,6 +43,9 @@ test('execution-ordered events bypass FileTest declaration-order buffer', async if (data.name === 'slow' || data.name === 'fast-fail') { events.push(`complete:${data.name}`); } + if (data.name === 'fast-fail') { + releaseSlow(); + } }); stream.on('test:fail', (data) => { diff --git a/test/parallel/test-stream-iter-broadcast-from.js b/test/parallel/test-stream-iter-broadcast-from.js index 39d92c2aef49..928d4d472f06 100644 --- a/test/parallel/test-stream-iter-broadcast-from.js +++ b/test/parallel/test-stream-iter-broadcast-from.js @@ -122,8 +122,8 @@ async function testBroadcastFromCancelWhileBlocked() { async function* slowSource() { const enc = new TextEncoder(); yield [enc.encode('chunk1')]; - // Simulate a long delay - the cancel should unblock this - await new Promise((resolve) => setTimeout(resolve, 10000)); + // Simulate a long delay without keeping the cancelled source alive. + await new Promise((resolve) => setTimeout(resolve, 10000).unref()); yield [enc.encode('chunk2')]; sourceFinished = true; } diff --git a/test/pummel/test-crypto-pqc-sign-verify-slh-dsa.mjs b/test/pummel/test-crypto-pqc-sign-verify-slh-dsa.mjs index 772d9bab6f61..52b018e7028d 100644 --- a/test/pummel/test-crypto-pqc-sign-verify-slh-dsa.mjs +++ b/test/pummel/test-crypto-pqc-sign-verify-slh-dsa.mjs @@ -13,6 +13,9 @@ import { promisify } from 'node:util'; import { randomBytes, sign, verify } from 'node:crypto'; import fixtures from '../common/fixtures.js'; +const pSign = promisify(sign); +const pVerify = promisify(verify); + function getKeyFileName(type, suffix) { return `${type.replaceAll('-', '_')}_${suffix}.pem`; } @@ -37,6 +40,8 @@ for (const [asymmetricKeyType, sigLen] of [ }; const data = randomBytes(32); + // Start the async signature before the sync work to overlap the two. + const signaturePromise = pSign(undefined, data, keys.private); // sync { @@ -48,9 +53,7 @@ for (const [asymmetricKeyType, sigLen] of [ // async { - const pSign = promisify(sign); - const pVerify = promisify(verify); - const signature = await pSign(undefined, data, keys.private); + const signature = await signaturePromise; assert.strictEqual(signature.byteLength, sigLen); assert.strictEqual(await pVerify(undefined, randomBytes(32), keys.public, signature), false); assert.strictEqual(await pVerify(undefined, data, keys.public, signature), true); diff --git a/test/pummel/test-dh-regr.js b/test/pummel/test-dh-regr.js index c442fbc3a809..8a2e71745a38 100644 --- a/test/pummel/test-dh-regr.js +++ b/test/pummel/test-dh-regr.js @@ -34,7 +34,6 @@ const assert = require('assert'); const crypto = require('crypto'); const { hasOpenSSL, hasFIPS } = require('../common/crypto'); -let p; let iterations = 2000; if (hasFIPS(3)) { assert.throws(() => crypto.createDiffieHellman(1024), { @@ -42,22 +41,24 @@ if (hasFIPS(3)) { name: 'TypeError', }); - // Use a precomputed approved group instead of generating a 2048-bit prime - // for every test run. Its larger keys also make each pummel iteration more - // expensive, so use enough iterations to exercise the regression without - // making the FIPS job excessively slow. - p = crypto.getDiffieHellman('modp14').getPrime(); + // Keep a lower iteration count for FIPS jobs. iterations = 100; +} + +let createDH; +if (hasOpenSSL(3)) { + // OpenSSL 3 recognizes named groups without validating their primes. + createDH = () => crypto.getDiffieHellman('modp14'); } else { - // FIPS requires length >= 1024, but small parameters keep this pummel test - // from timing out in ordinary CI. - const length = crypto.getFips() === 1 ? 1024 : (hasOpenSSL(3) ? 512 : 256); - p = crypto.createDiffieHellman(length).getPrime(); + // Other backends validate each peer's parameters, so keep them small. + const length = crypto.getFips() === 1 ? 1024 : 256; + const prime = crypto.createDiffieHellman(length).getPrime(); + createDH = () => crypto.createDiffieHellman(prime); } for (let i = 0; i < iterations; i++) { - const a = crypto.createDiffieHellman(p); - const b = crypto.createDiffieHellman(p); + const a = createDH(); + const b = createDH(); a.generateKeys(); b.generateKeys(); diff --git a/test/pummel/test-zlib-zip-slow.js b/test/pummel/test-zlib-zip-slow.js index c3e334c06dec..ab023456890b 100644 --- a/test/pummel/test-zlib-zip-slow.js +++ b/test/pummel/test-zlib-zip-slow.js @@ -20,33 +20,32 @@ const { test } = require('node:test'); tmpdir.refresh(); const GiB = 1024 * 1024 * 1024; -const MEMBER_SIZE = 500 * 1024 * 1024; // Four ~500 MiB stored members... -const STORED_MEMBER_COUNT = 4; -const STREAMED_MEMBER_SIZE = 4.5 * GiB; // ...plus one >4 GiB streamed member: -// the total archive size (~6.5 GiB) pushes offsets over the 4 GiB Zip64 -// threshold, and the streamed member's own sizes exceed 32 bits too, so the -// per-entry Zip64 size fields (central header and data descriptor) are -// exercised as well as the offset promotion. Required free space includes -// generous slack over that total. -const REQUIRED_FREE_BYTES = 12 * GiB; const CHUNK_SIZE = 16 * 1024 * 1024; - -function fillChunk(seed) { - const chunk = Buffer.allocUnsafe(CHUNK_SIZE); - chunk.fill(seed & 0xff); - return chunk; -} +const STREAMED_MEMBER_SIZE = 4 * GiB + CHUNK_SIZE; +const TAIL_MEMBER_SIZE = 64 * 1024; +// The leading member needs Zip64 sizes; the small member after it needs a +// Zip64 offset. Only one member has to be large to exercise both paths. +const REQUIRED_FREE_BYTES = 8 * GiB; +const CENTRAL_FILE_HEADER_SIGNATURE = Buffer.from([0x50, 0x4b, 0x01, 0x02]); async function* repeatingChunks(totalSize, seed) { + const chunk = Buffer.alloc(Math.min(CHUNK_SIZE, totalSize), seed); let remaining = totalSize; while (remaining > 0) { - const size = Math.min(CHUNK_SIZE, remaining); - const chunk = fillChunk(seed); + const size = Math.min(chunk.length, remaining); remaining -= size; yield size === chunk.length ? chunk : chunk.subarray(0, size); } } +function assertZip64Extra(buffer, offset, values) { + assert.strictEqual(buffer.readUInt16LE(offset), 0x0001); + assert.strictEqual(buffer.readUInt16LE(offset + 2), values.length * 8); + for (let i = 0; i < values.length; i++) { + assert.strictEqual(buffer.readBigUInt64LE(offset + 4 + i * 8), BigInt(values[i])); + } +} + test('an archive larger than 4 GiB round-trips and triggers Zip64 via offset', async () => { let free; try { @@ -63,15 +62,14 @@ test('an archive larger than 4 GiB round-trips and triggers Zip64 via offset', a const dir = await fs.mkdtemp(path.join(tmpdir.path, 'zlib-zip-slow-')); const archivePath = path.join(dir, 'large.zip'); try { - const entries = []; - for (let i = 0; i < STORED_MEMBER_COUNT; i++) { - entries.push(zlib.ZipEntry.createStream(`stored-${i}.bin`, repeatingChunks(MEMBER_SIZE, i), { + const entries = [ + zlib.ZipEntry.createStream('streamed.bin', repeatingChunks(STREAMED_MEMBER_SIZE, 0xaa), { method: 'store', - })); - } - entries.push(zlib.ZipEntry.createStream('streamed.bin', repeatingChunks(STREAMED_MEMBER_SIZE, 0xaa), { - method: 'store', - })); + }), + zlib.ZipEntry.createStream('tail.bin', repeatingChunks(TAIL_MEMBER_SIZE, 2), { + method: 'store', + }), + ]; const handle = await fs.open(archivePath, 'w'); try { @@ -85,9 +83,38 @@ test('an archive larger than 4 GiB round-trips and triggers Zip64 via offset', a const stat = await fs.stat(archivePath); assert.ok(stat.size > 4 * GiB, `archive is only ${stat.size} bytes`); + const reader = await fs.open(archivePath, 'r'); + try { + // Read only the leading local header and the archive tail. The two + // central headers and the trailer fit comfortably in these 1024 bytes. + const local = Buffer.alloc(30); + const tail = Buffer.alloc(1024); + await reader.read(local, 0, local.length, 0); + await reader.read(tail, 0, tail.length, stat.size - tail.length); + assert.strictEqual(local.readUInt32LE(0), 0x04034b50); + const tailOffset = local.length + local.readUInt16LE(26) + + local.readUInt16LE(28) + STREAMED_MEMBER_SIZE + 24; // Zip64 data descriptor. + assert.ok(tailOffset > 0xffffffff); + + const bigCentral = tail.indexOf(CENTRAL_FILE_HEADER_SIGNATURE); + assert.notStrictEqual(bigCentral, -1); + assert.strictEqual(tail.readUInt32LE(bigCentral + 20), 0xffffffff); + assert.strictEqual(tail.readUInt32LE(bigCentral + 24), 0xffffffff); + assertZip64Extra(tail, bigCentral + 46 + tail.readUInt16LE(bigCentral + 28), + [STREAMED_MEMBER_SIZE, STREAMED_MEMBER_SIZE]); + + const tailCentral = tail.indexOf(CENTRAL_FILE_HEADER_SIGNATURE, bigCentral + 4); + assert.notStrictEqual(tailCentral, -1); + assert.strictEqual(tail.readUInt32LE(tailCentral + 42), 0xffffffff); + assertZip64Extra(tail, tailCentral + 46 + tail.readUInt16LE(tailCentral + 28), + [tailOffset]); + } finally { + await reader.close(); + } + const zip = await zlib.ZipFile.open(archivePath); try { - assert.strictEqual(zip.size, STORED_MEMBER_COUNT + 1); + assert.strictEqual(zip.size, 2); let seen = 0; for await (const chunk of await zip.stream('streamed.bin')) { @@ -96,12 +123,12 @@ test('an archive larger than 4 GiB round-trips and triggers Zip64 via offset', a } assert.strictEqual(seen, STREAMED_MEMBER_SIZE); - let storedSeen = 0; - for await (const chunk of await zip.stream('stored-2.bin')) { - storedSeen += chunk.length; + let tailSeen = 0; + for await (const chunk of await zip.stream('tail.bin')) { + tailSeen += chunk.length; assert.strictEqual(chunk[0], 2); } - assert.strictEqual(storedSeen, MEMBER_SIZE); + assert.strictEqual(tailSeen, TAIL_MEMBER_SIZE); // The streamed member's sizes genuinely exceed 32 bits (stored, so // compressed === uncompressed), which the reader must have resolved @@ -116,6 +143,13 @@ test('an archive larger than 4 GiB round-trips and triggers Zip64 via offset', a // descriptor) without needing a second copy on disk. let reserialized = 0; for await (const chunk of zlib.createZipArchive([big])) { + if (reserialized === 0) { + assert.strictEqual(chunk.readUInt16LE(6) & 0x08, 0); // No data descriptor. + assert.strictEqual(chunk.readUInt32LE(18), 0xffffffff); + assert.strictEqual(chunk.readUInt32LE(22), 0xffffffff); + assertZip64Extra(chunk, 30 + chunk.readUInt16LE(26), + [STREAMED_MEMBER_SIZE, STREAMED_MEMBER_SIZE]); + } reserialized += chunk.length; } assert.ok(reserialized > STREAMED_MEMBER_SIZE, diff --git a/tools/test.py b/tools/test.py index 2c2a4d78d80a..a20c44e52516 100755 --- a/tools/test.py +++ b/tools/test.py @@ -741,10 +741,11 @@ def RunProcess(context, timeout, args, **rest): timed_out = True else: exit_code = process.poll() - time.sleep(sleep_time) - sleep_time = sleep_time * SLEEP_TIME_FACTOR - if sleep_time > MAX_SLEEP_TIME: - sleep_time = MAX_SLEEP_TIME + if exit_code is None: + time.sleep(sleep_time) + sleep_time = sleep_time * SLEEP_TIME_FACTOR + if sleep_time > MAX_SLEEP_TIME: + sleep_time = MAX_SLEEP_TIME return (process, exit_code, timed_out) @@ -1849,7 +1850,7 @@ def should_keep(case): print() sys.stderr.write("--- Total time: %s ---\n" % FormatTime(duration)) timed_tests = [ t for t in cases_to_run if not t.duration is None ] - timed_tests.sort(key=lambda x: x.duration) + timed_tests.sort(key=lambda x: x.duration, reverse=True) for i, entry in enumerate(timed_tests[:20], start=1): t = FormatTimedelta(entry.duration) sys.stderr.write("%4i (%s) %s\n" % (i, t, entry.GetLabel()))