Skip to content

Commit 1c6135f

Browse files
Trottaddaleax
authored andcommitted
test: fix flaky http(s)-set-server-timeout tests
The tests include a callback that might not be invoked but is wrapped in common.mustCall(). Remove the common.mustCall() wrapper and add a comment explaining that it should not be added. Add a new test case that sets the timeout to 1ms and waits for both the connection handler and the timeout handler to be invoked. This version keeps the common.mustCall() wrapper intact around the connection handler (although it's mostly semantic and not necessary for the test as the test will certainly fail or time out if that handler isn't invoked). PR-URL: #14380 Fixes: #11768 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent de3d73c commit 1c6135f

File tree

2 files changed

+102
-24
lines changed

2 files changed

+102
-24
lines changed

test/parallel/test-http-set-timeout-server.js

+49-10
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,7 @@ function run() {
4242
}
4343

4444
test(function serverTimeout(cb) {
45-
const server = http.createServer((req, res) => {
46-
// Do nothing. We should get a timeout event.
47-
// Might not be invoked. Do not wrap in common.mustCall().
48-
});
45+
const server = http.createServer();
4946
server.listen(common.mustCall(() => {
5047
const s = server.setTimeout(50, common.mustCall((socket) => {
5148
socket.destroy();
@@ -125,11 +122,14 @@ test(function serverResponseTimeoutWithPipeline(cb) {
125122
const server = http.createServer((req, res) => {
126123
if (req.url === '/2')
127124
secReceived = true;
125+
if (req.url === '/1') {
126+
res.end();
127+
return;
128+
}
128129
const s = res.setTimeout(50, () => {
129130
caughtTimeout += req.url;
130131
});
131132
assert.ok(s instanceof http.OutgoingMessage);
132-
if (req.url === '/1') res.end();
133133
});
134134
server.on('timeout', common.mustCall((socket) => {
135135
if (secReceived) {
@@ -152,17 +152,56 @@ test(function serverResponseTimeoutWithPipeline(cb) {
152152
});
153153

154154
test(function idleTimeout(cb) {
155-
const server = http.createServer(common.mustCall((req, res) => {
156-
req.on('timeout', common.mustNotCall());
157-
res.on('timeout', common.mustNotCall());
158-
res.end();
159-
}));
155+
// Test that the an idle connection invokes the timeout callback.
156+
const server = http.createServer();
160157
const s = server.setTimeout(50, common.mustCall((socket) => {
161158
socket.destroy();
162159
server.close();
163160
cb();
164161
}));
165162
assert.ok(s instanceof http.Server);
163+
server.listen(common.mustCall(() => {
164+
const options = {
165+
port: server.address().port,
166+
allowHalfOpen: true,
167+
};
168+
const c = net.connect(options, () => {
169+
// ECONNRESET could happen on a heavily-loaded server.
170+
c.on('error', (e) => {
171+
if (e.message !== 'read ECONNRESET')
172+
throw e;
173+
});
174+
c.write('GET /1 HTTP/1.1\r\nHost: localhost\r\n\r\n');
175+
// Keep-Alive
176+
});
177+
}));
178+
});
179+
180+
test(function fastTimeout(cb) {
181+
let connectionHandlerInvoked = false;
182+
let timeoutHandlerInvoked = false;
183+
let connectionSocket;
184+
185+
function invokeCallbackIfDone() {
186+
if (connectionHandlerInvoked && timeoutHandlerInvoked) {
187+
connectionSocket.destroy();
188+
server.close();
189+
cb();
190+
}
191+
}
192+
193+
const server = http.createServer(common.mustCall((req, res) => {
194+
req.on('timeout', common.mustNotCall());
195+
res.end();
196+
connectionHandlerInvoked = true;
197+
invokeCallbackIfDone();
198+
}));
199+
const s = server.setTimeout(1, common.mustCall((socket) => {
200+
connectionSocket = socket;
201+
timeoutHandlerInvoked = true;
202+
invokeCallbackIfDone();
203+
}));
204+
assert.ok(s instanceof http.Server);
166205
server.listen(common.mustCall(() => {
167206
const options = {
168207
port: server.address().port,

test/parallel/test-https-set-timeout-server.js

+53-14
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,7 @@ function run() {
5252
}
5353

5454
test(function serverTimeout(cb) {
55-
const server = https.createServer(
56-
serverOptions,
57-
(req, res) => {
58-
// Do nothing. We should get a timeout event.
59-
// Might not be invoked. Do not wrap in common.mustCall().
60-
});
55+
const server = https.createServer(serverOptions);
6156
server.listen(common.mustCall(() => {
6257
const s = server.setTimeout(50, common.mustCall((socket) => {
6358
socket.destroy();
@@ -147,11 +142,14 @@ test(function serverResponseTimeoutWithPipeline(cb) {
147142
const server = https.createServer(serverOptions, (req, res) => {
148143
if (req.url === '/2')
149144
secReceived = true;
145+
if (req.url === '/1') {
146+
res.end();
147+
return;
148+
}
150149
const s = res.setTimeout(50, () => {
151150
caughtTimeout += req.url;
152151
});
153152
assert.ok(s instanceof http.OutgoingMessage);
154-
if (req.url === '/1') res.end();
155153
});
156154
server.on('timeout', common.mustCall((socket) => {
157155
if (secReceived) {
@@ -175,19 +173,60 @@ test(function serverResponseTimeoutWithPipeline(cb) {
175173
});
176174

177175
test(function idleTimeout(cb) {
178-
const server = https.createServer(
179-
serverOptions,
180-
common.mustCall((req, res) => {
181-
req.on('timeout', common.mustNotCall());
182-
res.on('timeout', common.mustNotCall());
183-
res.end();
184-
}));
176+
// Test that the an idle connection invokes the timeout callback.
177+
const server = https.createServer(serverOptions);
185178
const s = server.setTimeout(50, common.mustCall((socket) => {
186179
socket.destroy();
187180
server.close();
188181
cb();
189182
}));
190183
assert.ok(s instanceof https.Server);
184+
server.listen(common.mustCall(() => {
185+
const options = {
186+
port: server.address().port,
187+
allowHalfOpen: true,
188+
rejectUnauthorized: false
189+
};
190+
const c = tls.connect(options, () => {
191+
// ECONNRESET could happen on a heavily-loaded server.
192+
c.on('error', (e) => {
193+
if (e.message !== 'read ECONNRESET')
194+
throw e;
195+
});
196+
c.write('GET /1 HTTP/1.1\r\nHost: localhost\r\n\r\n');
197+
// Keep-Alive
198+
});
199+
}));
200+
});
201+
202+
test(function fastTimeout(cb) {
203+
// Test that the socket timeout fires but no timeout fires for the request.
204+
let connectionHandlerInvoked = false;
205+
let timeoutHandlerInvoked = false;
206+
let connectionSocket;
207+
208+
function invokeCallbackIfDone() {
209+
if (connectionHandlerInvoked && timeoutHandlerInvoked) {
210+
connectionSocket.destroy();
211+
server.close();
212+
cb();
213+
}
214+
}
215+
216+
const server = https.createServer(serverOptions, common.mustCall(
217+
(req, res) => {
218+
req.on('timeout', common.mustNotCall());
219+
res.end();
220+
connectionHandlerInvoked = true;
221+
invokeCallbackIfDone();
222+
}
223+
));
224+
const s = server.setTimeout(1, common.mustCall((socket) => {
225+
connectionSocket = socket;
226+
timeoutHandlerInvoked = true;
227+
invokeCallbackIfDone();
228+
}));
229+
assert.ok(s instanceof https.Server);
191230
server.listen(common.mustCall(() => {
192231
const options = {
193232
port: server.address().port,

0 commit comments

Comments
 (0)