Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 87 additions & 17 deletions test/parallel/test-http-client-immediate-error.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,106 @@
const net = require('net');
const http = require('http');
const { internalBinding } = require('internal/test/binding');
const { UV_ENETUNREACH } = internalBinding('uv');
const { UV_ENETUNREACH, UV_EADDRINUSE } = internalBinding('uv');
const {
newAsyncId,
symbols: { async_id_symbol }
} = require('internal/async_hooks');

const agent = new http.Agent();
agent.createConnection = common.mustCall((cfg) => {
const sock = new net.Socket();
const config = {
host: 'http://example.com',
// We need to specify 'family' in both items of the array so 'internalConnectMultiple' is invoked
connectMultiple: [{ address: '192.4.4.4', family: 4 }, { address: '200::1', family: 6 }],
connectSolo: { address: '192.4.4.4', family: 4 },
};

// Fake the handle so we can enforce returning an immediate error
sock._handle = {
connect: common.mustCall((req, addr, port) => {
return UV_ENETUNREACH;
}),
readStart() {},
close() {}
};
function agentFactory(handle, count) {
const agent = new http.Agent();
agent.createConnection = common.mustCall((...cfg) => {
const normalized = net._normalizeArgs(cfg);
const sock = new net.Socket();

// Simulate just enough socket handle initialization
sock[async_id_symbol] = newAsyncId();
// Fake the handle so we can enforce returning an immediate error
sock._handle = handle;

sock.connect(cfg);
return sock;
// Simulate just enough socket handle initialization
sock[async_id_symbol] = newAsyncId();

sock.connect(normalized);
return sock;
}, count);

return agent;
};

const handleWithoutBind = (callCount) => ({
connect: common.mustCall((req, addr, port) => {

Check failure on line 45 in test/parallel/test-http-client-immediate-error.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Assertions must be wrapped into `common.mustSucceed`, `common.mustCall` or `common.mustCallAtLeast`
return UV_ENETUNREACH;
}, callCount),
readStart() { },
close() { },
});

const handleWithBind = (callCount) => ({
readStart() { },
close() { },
bind: common.mustCall(() => UV_EADDRINUSE, callCount),

Check failure on line 55 in test/parallel/test-http-client-immediate-error.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Assertions must be wrapped into `common.mustSucceed`, `common.mustCall` or `common.mustCallAtLeast`
});

const agentWithoutBind = agentFactory(handleWithoutBind(3), 3); // Because three tests will use this
const agentWithBind = agentFactory(handleWithBind(2), 2); // Because two tests will use this handle

console.log('test initiated: test-1', Date.now());
http.get({
host: '127.0.0.1',
port: 1,
agent
agent: agentWithoutBind,
}).on('error', common.mustCall((err) => {
assert.strictEqual(err.code, 'ENETUNREACH');
console.log('test completed: test-1', Date.now());
}));

console.log('test initiated: test-2', Date.now());
http.request(config.host, {
agent: agentWithoutBind,
lookup(_0, _1, cb) {
cb(null, config.connectMultiple);
},
}).on('error', common.mustCall((err) => {
assert.strictEqual(err.code, 'ENETUNREACH');
console.log('test completed: test-2', Date.now());
}));

console.log('test initiated: test-3', Date.now());
http.request(config.host, {
agent: agentWithoutBind,
lookup(_0, _1, cb) {
cb(null, config.connectSolo.address, config.connectSolo.family);
},
family: 4,
}).on('error', common.mustCall((err) => {
assert.strictEqual(err.code, 'ENETUNREACH');
console.log('test completed: test-3', Date.now());
}));

console.log('test initiated: test-4', Date.now());
http.request(config.host, {
agent: agentWithBind,
family: 4, // We specify 'family' so 'internalConnect' is invoked
localPort: 2222 // Required to trigger _handle.bind()
}).on('error', common.mustCall((err) => {
assert.strictEqual(err.code, 'EADDRINUSE');
console.log('test completed: test-4', Date.now());
}));

console.log('test initiated: test-5', Date.now());
http.request(config.host, {
agent: agentWithBind,
lookup(_0, _1, cb) {
cb(null, config.connectMultiple);
},
localPort: 2222, // Required to trigger _handle.bind()
}).on('error', common.mustCall((err) => {
assert.strictEqual(err.code, 'EADDRINUSE');
console.log('test completed: test-5', Date.now());
}));
Loading