test_runner: preserve run duration when using test-rerun · nodejs/node@904bdf5 · GitHub
Skip to content

Commit 904bdf5

Browse files
MoLowsxa
authored andcommitted
test_runner: preserve run duration when using test-rerun
Signed-off-by: Moshe Atlow <moshe@atlow.co.il> PR-URL: #63429 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: Aviv Keller <me@aviv.sh>
1 parent 3f54c8b commit 904bdf5

4 files changed

Lines changed: 43 additions & 1 deletion

File tree

lib/internal/test_runner/reporter/rerun.js

Lines changed: 1 addition & 0 deletions

lib/internal/test_runner/test.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ const {
99
ArrayPrototypeSplice,
1010
ArrayPrototypeUnshift,
1111
ArrayPrototypeUnshiftApply,
12+
BigInt,
1213
Error,
1314
FunctionPrototype,
1415
MathFloor,
1516
MathMax,
17+
MathRound,
1618
Number,
1719
NumberPrototypeToFixed,
1820
ObjectKeys,
@@ -769,14 +771,25 @@ class Test extends AsyncResource {
769771
const previousAttempt = this.root.harness.previousRuns[this.attempt - 1]?.[testIdentifier];
770772
if (previousAttempt != null) {
771773
this.passedAttempt = previousAttempt.passed_on_attempt;
774+
if (previousAttempt.duration_ms !== undefined) {
775+
this.replayedDurationNs = BigInt(MathRound(previousAttempt.duration_ms * 1_000_000));
776+
}
772777
this.fn = () => {
778+
// Restore the original duration on the synthetic replay. Suites are
779+
// skipped here because Suite.run() unconditionally reassigns
780+
// startTime later; only non-suite tests benefit from setting it.
781+
if (this.reportedType !== 'suite') {
782+
this.startTime = hrtime();
783+
this.endTime = this.startTime + (this.replayedDurationNs ?? 0n);
784+
}
773785
for (let i = 0; i < (previousAttempt.children?.length ?? 0); i++) {
774786
const child = previousAttempt.children[i];
775787
const t = this.createSubtest(Test, child.name, { __proto__: null }, noop, {
776788
__proto__: null,
777789
loc: [child.line, child.column, child.file],
778790
}, noop);
779-
t.endTime = t.startTime = hrtime();
791+
t.startTime = hrtime();
792+
t.endTime = t.startTime + (t.replayedDurationNs ?? 0n);
780793
// For suites, Suite.run() starts the subtests via SafePromiseAll.
781794
// Starting them here as well would run them twice, re-invoking the
782795
// synthetic children-creator against a now-incremented disambiguator
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
'use strict';
2+
// A passing test with a measurable duration alongside a failing test. The
3+
// failing test forces the rerun feature to retry on a second invocation,
4+
// causing the passing test to be replayed via the synthetic noop stub.
5+
const { test } = require('node:test');
6+
7+
test('passing slow test', async () => {
8+
await new Promise((resolve) => setTimeout(resolve, 25));
9+
});
10+
11+
test('always failing', () => {
12+
throw new Error('boom');
13+
});

test/parallel/test-runner-test-rerun-failures.js

Lines changed: 15 additions & 0 deletions

0 commit comments

Comments
 (0)