Skip to content

Commit a080b73

Browse files
committed
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.
1 parent af5d1c9 commit a080b73

File tree

2 files changed

+60
-41
lines changed

2 files changed

+60
-41
lines changed

test/client-proxy/test-http-proxy-request-connection-refused.mjs

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22
// handle it correctly.
33

44
import * as common from '../common/index.mjs';
5-
import assert from 'node:assert';
65
import http from 'node:http';
76
import { once } from 'events';
87
import { runProxiedRequest } from '../common/proxy-server.js';
9-
import dgram from 'node:dgram';
108

119
const server = http.createServer(common.mustNotCall());
1210
server.on('error', common.mustNotCall((err) => { console.error('Server error', err); }));
@@ -16,24 +14,34 @@ await once(server, 'listening');
1614
const serverHost = `localhost:${server.address().port}`;
1715
const requestUrl = `http://${serverHost}/test`;
1816

19-
// Make it fail on connection refused by connecting to a UDP port with TCP.
20-
const udp = dgram.createSocket('udp4');
21-
udp.bind(0, '127.0.0.1');
22-
await once(udp, 'listening');
23-
24-
const port = udp.address().port;
25-
26-
const { code, signal, stderr, stdout } = await runProxiedRequest({
27-
NODE_USE_ENV_PROXY: 1,
28-
REQUEST_URL: requestUrl,
29-
HTTP_PROXY: `http://localhost:${port}`,
30-
});
31-
32-
// The proxy client should get a connection refused error.
33-
assert.match(stderr, /Error.*connect ECONNREFUSED/);
34-
assert.strictEqual(stdout.trim(), '');
35-
assert.strictEqual(code, 0);
36-
assert.strictEqual(signal, null);
17+
let maxRetries = 10;
18+
let foundRefused = false;
19+
while (maxRetries-- > 0) {
20+
// Make it fail on connection refused by connecting to a port of a closed server.
21+
// If it succeeds, get a different port and retry.
22+
const proxy = http.createServer((req, res) => {
23+
res.destroy();
24+
});
25+
proxy.listen(0);
26+
await once(proxy, 'listening');
27+
const port = proxy.address().port;
28+
proxy.close();
29+
await once(proxy, 'close');
30+
31+
console.log(`Trying proxy at port ${port}`);
32+
const { stderr } = await runProxiedRequest({
33+
NODE_USE_ENV_PROXY: 1,
34+
REQUEST_URL: requestUrl,
35+
HTTP_PROXY: `http://localhost:${port}`,
36+
REQUEST_TIMEOUT: 5000,
37+
});
38+
39+
foundRefused = /Error.*connect ECONNREFUSED/.test(stderr);
40+
if (foundRefused) {
41+
// The proxy client should get a connection refused error.
42+
break;
43+
}
44+
}
3745

3846
server.close();
39-
udp.close();
47+
assert(foundRefused, 'Expected ECONNREFUSED error from proxy request');

test/client-proxy/test-https-proxy-request-connection-refused.mjs

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import fixtures from '../common/fixtures.js';
55
import assert from 'node:assert';
66
import { once } from 'events';
77
import { runProxiedRequest } from '../common/proxy-server.js';
8-
import dgram from 'node:dgram';
8+
import http from 'node:http';
99

1010
if (!common.hasCrypto)
1111
common.skip('missing crypto');
@@ -25,24 +25,35 @@ await once(server, 'listening');
2525
const serverHost = `localhost:${server.address().port}`;
2626
const requestUrl = `https://${serverHost}/test`;
2727

28-
// Make it fail on connection refused by connecting to a UDP port with TCP.
29-
const udp = dgram.createSocket('udp4');
30-
udp.bind(0, '127.0.0.1');
31-
await once(udp, 'listening');
32-
const port = udp.address().port;
33-
34-
const { code, signal, stderr, stdout } = await runProxiedRequest({
35-
NODE_USE_ENV_PROXY: 1,
36-
REQUEST_URL: requestUrl,
37-
HTTPS_PROXY: `http://localhost:${port}`,
38-
NODE_EXTRA_CA_CERTS: fixtures.path('keys', 'fake-startcom-root-cert.pem'),
39-
});
40-
41-
// The proxy client should get a connection refused error.
42-
assert.match(stderr, /Error.*connect ECONNREFUSED/);
43-
assert.strictEqual(stdout.trim(), '');
44-
assert.strictEqual(code, 0);
45-
assert.strictEqual(signal, null);
28+
let maxRetries = 10;
29+
let foundRefused = false;
30+
while (maxRetries-- > 0) {
31+
// Make it fail on connection refused by connecting to a port of a closed server.
32+
// If it succeeds, get a different port and retry.
33+
const proxy = http.createServer((req, res) => {
34+
res.destroy();
35+
});
36+
proxy.listen(0);
37+
await once(proxy, 'listening');
38+
const port = proxy.address().port;
39+
proxy.close();
40+
await once(proxy, 'close');
41+
42+
console.log(`Trying proxy at port ${port}`);
43+
const { stderr } = await runProxiedRequest({
44+
NODE_USE_ENV_PROXY: 1,
45+
REQUEST_URL: requestUrl,
46+
HTTPS_PROXY: `http://localhost:${port}`,
47+
NODE_EXTRA_CA_CERTS: fixtures.path('keys', 'fake-startcom-root-cert.pem'),
48+
REQUEST_TIMEOUT: 5000,
49+
});
50+
51+
foundRefused = /Error.*connect ECONNREFUSED/.test(stderr);
52+
if (foundRefused) {
53+
// The proxy client should get a connection refused error.
54+
break;
55+
}
56+
}
4657

4758
server.close();
48-
udp.close();
59+
assert(foundRefused, 'Expected ECONNREFUSED error from proxy request');

0 commit comments

Comments
 (0)