Skip to content

Commit 0930c21

Browse files
joyeecheungtargos
authored andcommitted
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. PR-URL: #59476 Refs: nodejs/reliability#1287 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
1 parent b3af17c commit 0930c21

File tree

2 files changed

+61
-41
lines changed

2 files changed

+61
-41
lines changed

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

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
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';
6+
import assert from 'node:assert';
77
import { once } from 'events';
88
import { runProxiedRequest } from '../common/proxy-server.js';
9-
import dgram from 'node:dgram';
109

1110
const server = http.createServer(common.mustNotCall());
1211
server.on('error', common.mustNotCall((err) => { console.error('Server error', err); }));
@@ -16,24 +15,34 @@ await once(server, 'listening');
1615
const serverHost = `localhost:${server.address().port}`;
1716
const requestUrl = `http://${serverHost}/test`;
1817

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

3847
server.close();
39-
udp.close();
48+
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)