From bf846f98845f5519d1eb246bd10a277541d61b1b Mon Sep 17 00:00:00 2001 From: Yarchik Date: Wed, 21 Oct 2026 13:15:37 +0200 Subject: [PATCH] test_runner: run the longest timer in runAll() PriorityQueue#peekBottom() returned the last slot of the heap, which is not necessarily the largest element, so MockTimers#runAll() could stop before the timer that fires last. Scan the leaves of the heap for the largest element instead. Assisted-by: a closed-source coding agent Signed-off-by: Yarchik --- lib/internal/priority_queue.js | 10 +++++++++- test/parallel/test-runner-mock-timers.js | 13 +++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/internal/priority_queue.js b/lib/internal/priority_queue.js index e6fdb61e9997..717af91eefdf 100644 --- a/lib/internal/priority_queue.js +++ b/lib/internal/priority_queue.js @@ -32,7 +32,15 @@ module.exports = class PriorityQueue { } peekBottom() { - return this.#heap[this.#size]; + const compare = this.#compare; + const heap = this.#heap; + const size = this.#size; + let bottom = heap[size]; + for (let pos = (size >> 1) + 1; pos < size; pos++) { + if (compare(heap[pos], bottom) > 0) + bottom = heap[pos]; + } + return bottom; } percolateDown(pos) { diff --git a/test/parallel/test-runner-mock-timers.js b/test/parallel/test-runner-mock-timers.js index 25510fe023d0..ba1841b4c91e 100644 --- a/test/parallel/test-runner-mock-timers.js +++ b/test/parallel/test-runner-mock-timers.js @@ -195,6 +195,19 @@ describe('Mock Timers Test Suite', () => { assert.strictEqual(Date.now(), 9999); }); + it('should trigger all timers when the longest one is scheduled first', (t) => { + t.mock.timers.enable({ apis: ['setTimeout', 'Date'] }); + const results = []; + + globalThis.setTimeout(() => results.push(1), 9999); + globalThis.setTimeout(() => results.push(3), 8888); + globalThis.setTimeout(() => results.push(2), 8888); + t.mock.timers.runAll(); + + assert.deepStrictEqual(results, [3, 2, 1]); + assert.strictEqual(Date.now(), 9999); + }); + it('should not error if there are not timers to run', (t) => { t.mock.timers.enable(); t.mock.timers.runAll();