test: deflake long timer WPTs - #63106
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #63106 +/- ##
=======================================
Coverage 90.29% 90.29%
=======================================
Files 790 790
Lines 271882 271882
Branches 51899 51906 +7
=======================================
+ Hits 245485 245502 +17
+ Misses 16888 16881 -7
+ Partials 9509 9499 -10 🚀 New features to boost your workflow:
|
731ede1 to
f3f975a
Compare
|
You might want to update |
Can you elaborate? Is this rooted in the WPT runner browsers run, generally more context for review would be great. |
f3f975a to
f7e0a1a
Compare
It's actually WPT semantic. In I think WPT is mirroring the browser's beaviour where the uncaugth exceptions after Editing the description and the comment. |
Maybe I am missing something, but I don't think this change covers it. It seems |
|
This pull request has been marked as stale due to 90 days of inactivity. |
c6751d8 to
d094730
Compare
panva
left a comment
There was a problem hiding this comment.
I'd prefer to scope this workaround to test/wpt/test-timers.js. This changes error handling for every WPT suite, including swallowing unhandled rejections reported after completion, and removeAllListeners('uncaughtException') also removes unrelated handlers.
Can we use setScriptModifier() like in test-user-timing.js, limited to the two affected fixtures? For example:
'use strict';
const assert = require('assert');
const { basename } = require('path');
const { WPTRunner } = require('../common/wpt');
const runner = new WPTRunner('html/webappapis/timers', { concurrency: 1 });
runner.setScriptModifier((script) => {
if (!['type-long-settimeout.any.js', 'type-long-setinterval.any.js']
.includes(basename(script.filename))) return;
// Cancel the failure timer when the test completes so it cannot throw
// while the runner is still processing the completion message.
const failureTimer = 'setTimeout(assert_unreached, 100);';
assert(script.code.includes(failureTimer), `Unexpected contents of ${script.filename}`);
script.code = script.code.replace(failureTimer,
'const failureTimer = setTimeout(assert_unreached, 100);\n' +
'add_completion_callback(() => clearTimeout(failureTimer));');
});
runner.runJsTests();The failure timer would still catch missing completion, but couldn't throw after the test has finished.
|
@marcopiraccini please squash, rebase, and update the first commit to reflect the changes and the current PR title. |
type-long-settimeout.any.js and type-long-setinterval.any.js arm setTimeout(assert_unreached, 100) as a guard. Under load it can fire after done(), and the resulting uncaught exception can reach the WPT runner before the completion message, failing the spec. Use a script modifier to clear the guard timer from a completion callback, for these two fixtures only. The guard still fails the test when done() is never called. Signed-off-by: marcopiraccini <marco.piraccini@gmail.com>
3318fb1 to
e5f48b4
Compare
This comment was marked as outdated.
This comment was marked as outdated.
|
Landed in c90c3dd |
type-long-settimeout.any.jsandtype-long-setinterval.any.jsinwpt/test-timersare flaky. Both armsetTimeout(assert_unreached, 100)as a guard and calldone()from a timer whose delay overflows to 1 ms. Under load the guard can still fire afterdone(). testharness.js ignores exceptions once a test has a result, but in Node.js the throw becomes anuncaughtException, and the resultingWorker'error'event can reach the runner before the completion message and fail the spec.