From 005a9e308471d802309713cc985319e2ee1c588c Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Fri, 15 Aug 2025 00:24:14 +0200 Subject: [PATCH] test: deflake connection refused proxy tests Previously the tests tries to use UDP ports to fabricate ECONNREFUSED which is incorrect - UDP ports use different namespaces, so the port can have valid TCP listeners. This patch updates the test to fabricate the ECONNREFUSED error by using the port of a recently closed HTTP server. If the ephemeral port happens to be still open, try to get a different one until we succeed. --- ...-http-proxy-request-connection-refused.mjs | 51 +++++++++++-------- ...https-proxy-request-connection-refused.mjs | 51 +++++++++++-------- 2 files changed, 61 insertions(+), 41 deletions(-) diff --git a/test/client-proxy/test-http-proxy-request-connection-refused.mjs b/test/client-proxy/test-http-proxy-request-connection-refused.mjs index 234587dd1dfe0d..d07cf8ce530203 100644 --- a/test/client-proxy/test-http-proxy-request-connection-refused.mjs +++ b/test/client-proxy/test-http-proxy-request-connection-refused.mjs @@ -2,11 +2,10 @@ // handle it correctly. import * as common from '../common/index.mjs'; -import assert from 'node:assert'; import http from 'node:http'; +import assert from 'node:assert'; import { once } from 'events'; import { runProxiedRequest } from '../common/proxy-server.js'; -import dgram from 'node:dgram'; const server = http.createServer(common.mustNotCall()); server.on('error', common.mustNotCall((err) => { console.error('Server error', err); })); @@ -16,24 +15,34 @@ await once(server, 'listening'); const serverHost = `localhost:${server.address().port}`; const requestUrl = `http://${serverHost}/test`; -// Make it fail on connection refused by connecting to a UDP port with TCP. -const udp = dgram.createSocket('udp4'); -udp.bind(0, '127.0.0.1'); -await once(udp, 'listening'); - -const port = udp.address().port; - -const { code, signal, stderr, stdout } = await runProxiedRequest({ - NODE_USE_ENV_PROXY: 1, - REQUEST_URL: requestUrl, - HTTP_PROXY: `http://localhost:${port}`, -}); - -// The proxy client should get a connection refused error. -assert.match(stderr, /Error.*connect ECONNREFUSED/); -assert.strictEqual(stdout.trim(), ''); -assert.strictEqual(code, 0); -assert.strictEqual(signal, null); +let maxRetries = 10; +let foundRefused = false; +while (maxRetries-- > 0) { + // Make it fail on connection refused by connecting to a port of a closed server. + // If it succeeds, get a different port and retry. + const proxy = http.createServer((req, res) => { + res.destroy(); + }); + proxy.listen(0); + await once(proxy, 'listening'); + const port = proxy.address().port; + proxy.close(); + await once(proxy, 'close'); + + console.log(`Trying proxy at port ${port}`); + const { stderr } = await runProxiedRequest({ + NODE_USE_ENV_PROXY: 1, + REQUEST_URL: requestUrl, + HTTP_PROXY: `http://localhost:${port}`, + REQUEST_TIMEOUT: 5000, + }); + + foundRefused = /Error.*connect ECONNREFUSED/.test(stderr); + if (foundRefused) { + // The proxy client should get a connection refused error. + break; + } +} server.close(); -udp.close(); +assert(foundRefused, 'Expected ECONNREFUSED error from proxy request'); diff --git a/test/client-proxy/test-https-proxy-request-connection-refused.mjs b/test/client-proxy/test-https-proxy-request-connection-refused.mjs index de13342c67f2e8..f2a9875a4ef44a 100644 --- a/test/client-proxy/test-https-proxy-request-connection-refused.mjs +++ b/test/client-proxy/test-https-proxy-request-connection-refused.mjs @@ -5,7 +5,7 @@ import fixtures from '../common/fixtures.js'; import assert from 'node:assert'; import { once } from 'events'; import { runProxiedRequest } from '../common/proxy-server.js'; -import dgram from 'node:dgram'; +import http from 'node:http'; if (!common.hasCrypto) common.skip('missing crypto'); @@ -25,24 +25,35 @@ await once(server, 'listening'); const serverHost = `localhost:${server.address().port}`; const requestUrl = `https://${serverHost}/test`; -// Make it fail on connection refused by connecting to a UDP port with TCP. -const udp = dgram.createSocket('udp4'); -udp.bind(0, '127.0.0.1'); -await once(udp, 'listening'); -const port = udp.address().port; - -const { code, signal, stderr, stdout } = await runProxiedRequest({ - NODE_USE_ENV_PROXY: 1, - REQUEST_URL: requestUrl, - HTTPS_PROXY: `http://localhost:${port}`, - NODE_EXTRA_CA_CERTS: fixtures.path('keys', 'fake-startcom-root-cert.pem'), -}); - -// The proxy client should get a connection refused error. -assert.match(stderr, /Error.*connect ECONNREFUSED/); -assert.strictEqual(stdout.trim(), ''); -assert.strictEqual(code, 0); -assert.strictEqual(signal, null); +let maxRetries = 10; +let foundRefused = false; +while (maxRetries-- > 0) { + // Make it fail on connection refused by connecting to a port of a closed server. + // If it succeeds, get a different port and retry. + const proxy = http.createServer((req, res) => { + res.destroy(); + }); + proxy.listen(0); + await once(proxy, 'listening'); + const port = proxy.address().port; + proxy.close(); + await once(proxy, 'close'); + + console.log(`Trying proxy at port ${port}`); + const { stderr } = await runProxiedRequest({ + NODE_USE_ENV_PROXY: 1, + REQUEST_URL: requestUrl, + HTTPS_PROXY: `http://localhost:${port}`, + NODE_EXTRA_CA_CERTS: fixtures.path('keys', 'fake-startcom-root-cert.pem'), + REQUEST_TIMEOUT: 5000, + }); + + foundRefused = /Error.*connect ECONNREFUSED/.test(stderr); + if (foundRefused) { + // The proxy client should get a connection refused error. + break; + } +} server.close(); -udp.close(); +assert(foundRefused, 'Expected ECONNREFUSED error from proxy request');