-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test: fix flaky http(s)-set-timeout-server tests #14380
Conversation
/cc @nodejs/testing |
Aren't we excluding an important step in the test? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's discuss
@refack You have a point. Less elegant but more correct fix coming in a bit... |
This solution still fails under load. The connection handler still might never get called, and now without calling |
Moving the Ultimately, may just add a test case: one that solution and one the solution that's here. Then we're getting at everything one way or another (hopefully). |
Stress test showing failures on master (expected to fail): Stress test on this PR (expected to pass): |
@@ -152,11 +152,12 @@ test(function serverResponseTimeoutWithPipeline(cb) { | |||
}); | |||
|
|||
test(function idleTimeout(cb) { | |||
const server = http.createServer(common.mustCall((req, res) => { | |||
// Do not wrap the callback in common.mustCall(). It might not be invoked. | |||
const server = http.createServer((req, res) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: If it "might" not be invoked maybe remove?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it is invoked, we want to make sure timeout
event does not fire on req
and res
(I guess?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But that's what the new test case does.
Superficially this is not wrong or harmful, but might be distracting for future maintainers.
IMHO either remove, or add to the comment that the next test case makes sure this is always true.
Fast timeout makes sense. |
LGTM |
This PR fails in stress test, but much less frequently |
Made some adjustments (PTAL, I did not squash the commits for hopefully easier review). Stress test on this PR: https://ci.nodejs.org/job/node-stress-single-test/1338/ |
|
P.S. const server = http.createServer().on('connection', (req, res) => {
req.on('timeout', common.mustNotCall());
res.on('timeout', common.mustNotCall());
}) Can a |
@refack first need to correct your code. it should be: const print = process._rawDebug;
const server = require('http').createServer();
server.on('request', (req, res) => {
// this will never fire b/c the request is complete before this callback fires.
req.on('timeout', () => print('req timeout'));
// will fire a default 2 mins in the future if the connection isn't closed.
res.on('timeout', () => print('res timeout'));
});
sever.listen(8080); The This is different from const print = process._rawDebug;
const req = require('http').request({ hostname: 'www.reddit.com' }, res => {
print('req callback fired');
});
const t = process.hrtime();
req.setTimeout(10, () => {
const u = process.hrtime(t);
print('timeout:', (u[0] * 1e3 + u[1] / 1e6) >>> 0, 'ms');
});
req.end(); My machine prints
|
@trevnorris wrote: // will fire a default 2 mins in the future if the connection isn't closed.
res.on('timeout', () => print('res timeout')); Ah, of course, but if we're calling Just confirmed running the test locally under heavy load that reducing the timeout to 1ms makes the test far more reliable and increasing it to 5000 makes it reliable under the amount of load I was using. I think the thing to do is remove the test for that timeout to not fire, as clearly it can. Probably won't solve the |
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). Fixes: nodejs#11768
Comments added per nits from @refack. Rebased against master, so running CI again for good measure. CI: https://ci.nodejs.org/job/node-test-pull-request/9332/ EDIT: Windows failure unrelated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Jenkins was restarted so previous CI either didn't run or we lost the results. |
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: nodejs#14380 Fixes: nodejs#11768 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Landed in c5bed4c |
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 <cjihrig@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
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 <cjihrig@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
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 <cjihrig@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
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 <cjihrig@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
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 <cjihrig@gmail.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
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.
Fixes: #11768
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
test http https