Skip to content

Commit

Permalink
test_runner: fix incorrect cleanup of timers
Browse files Browse the repository at this point in the history
Removal of mocket timers from the priority queue was broken. It used the
timerId instead of the position in the queue as index. This lead to
removal of incorrect timers from the queue causing timers not to be
scheduled at all.

Also, aborts caused removal from the queue even when the timer was
already triggered, and thus no longer present in the queue.

Fixes: nodejs#50365
  • Loading branch information
mika-fischer committed Oct 25, 2023
1 parent 73ec104 commit 22fbdd3
Showing 1 changed file with 14 additions and 10 deletions.
24 changes: 14 additions & 10 deletions lib/internal/test_runner/mock/mock_timers.js
Original file line number Diff line number Diff line change
Expand Up @@ -260,20 +260,23 @@ class MockTimers {

#createTimer(isInterval, callback, delay, ...args) {
const timerId = this.#currentTimer++;
this.#executionQueue.insert({
const timer = {
__proto__: null,
id: timerId,
callback,
runAt: this.#now + delay,
interval: isInterval ? delay : undefined,
args,
});

return timerId;
};
this.#executionQueue.insert(timer);
return timer;
}

#clearTimer(position) {
this.#executionQueue.removeAt(position);
#clearTimer(timer) {
if (timer.priorityQueuePosition !== undefined) {
this.#executionQueue.removeAt(timer.priorityQueuePosition);
timer.priorityQueuePosition = undefined;
}
}

#createDate() {
Expand Down Expand Up @@ -397,10 +400,10 @@ class MockTimers {
emitter.emit('data', result);
};

const timerId = this.#createTimer(true, callback, interval, options);
const timer = this.#createTimer(true, callback, interval, options);
const clearListeners = () => {
emitter.removeAllListeners();
context.#clearTimer(timerId);
context.#clearTimer(timer);
};
const iterator = {
__proto__: null,
Expand Down Expand Up @@ -453,11 +456,11 @@ class MockTimers {
}

const onabort = () => {
clearFn(id);
clearFn(timer);
return reject(abortIt(options.signal));
};

const id = timerFn(() => {
const timer = timerFn(() => {
return resolve(result);
}, ms);

Expand Down Expand Up @@ -620,6 +623,7 @@ class MockTimers {
FunctionPrototypeApply(timer.callback, undefined, timer.args);

this.#executionQueue.shift();
timer.priorityQueuePosition = undefined;

if (timer.interval !== undefined) {
timer.runAt += timer.interval;
Expand Down

0 comments on commit 22fbdd3

Please sign in to comment.