Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
test_runner: add tests for various mock timer issues
  • Loading branch information
mika-fischer committed Oct 25, 2023
commit 1a23be5a49a84d3aed7e580dc79aaca5ad421954
85 changes: 85 additions & 0 deletions test/parallel/test-runner-mock-timers.js
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,59 @@ describe('Mock Timers Test Suite', () => {
code: 'ERR_INVALID_ARG_TYPE',
});
});

// Test for https://github.com/nodejs/node/issues/50365
it('should not affect other timers when aborting', async (t) => {
const f1 = t.mock.fn();
const f2 = t.mock.fn();
t.mock.timers.enable({ apis: ['setTimeout'] });
const ac = new AbortController();

// id 1 & pos 1 in priority queue
nodeTimersPromises.setTimeout(100, undefined, { signal: ac.signal }).then(f1, f1);
// id 2 & pos 1 in priority queue (id 1 is moved to pos 2)
nodeTimersPromises.setTimeout(50).then(f2, f2);

ac.abort(); // BUG: will remove timer at pos 1 not timer with id 1!

t.mock.timers.runAll();
await nodeTimersPromises.setImmediate(); // let promises settle

// First setTimeout is aborted
assert.strictEqual(f1.mock.callCount(), 1);
assert.strictEqual(f1.mock.calls[0].arguments[0].code, 'ABORT_ERR');

// Second setTimeout should resolve, but never settles, because it was eronously removed by ac.abort()
assert.strictEqual(f2.mock.callCount(), 1);
});

// Test for https://github.com/nodejs/node/issues/50365
it('should not affect other timers when aborted after triggering', async (t) => {
const f1 = t.mock.fn();
const f2 = t.mock.fn();
t.mock.timers.enable({ apis: ['setTimeout'] });
const ac = new AbortController();

// id 1 & pos 1 in priority queue
nodeTimersPromises.setTimeout(50, true, { signal: ac.signal }).then(f1, f1);
// id 2 & pos 2 in priority queue
nodeTimersPromises.setTimeout(100).then(f2, f2);

// First setTimeout resolves
t.mock.timers.tick(50);
Comment thread
anonrig marked this conversation as resolved.
Resolved
await nodeTimersPromises.setImmediate(); // let promises settle
assert.strictEqual(f1.mock.callCount(), 1);
assert.strictEqual(f1.mock.calls[0].arguments.length, 1);
assert.strictEqual(f1.mock.calls[0].arguments[0], true);

// Now timer with id 2 will be at pos 1 in priority queue
ac.abort(); // BUG: will remove timer at pos 1 not timer with id 1!

// Second setTimeout should resolve, but never settles, because it was eronously removed by ac.abort()
t.mock.timers.runAll();
await nodeTimersPromises.setImmediate(); // let promises settle
assert.strictEqual(f2.mock.callCount(), 1);
});
});

describe('setInterval Suite', () => {
Expand Down Expand Up @@ -626,6 +679,38 @@ describe('Mock Timers Test Suite', () => {
});
assert.strictEqual(numIterations, expectedIterations);
});

// Test for https://github.com/nodejs/node/issues/50381
it('should use the correct interval', (t) => {
Comment thread
mika-fischer marked this conversation as resolved.
Resolved
t.mock.timers.enable({ apis: ['setInterval'] });
const fn = t.mock.fn();
setInterval(fn, 1000);
assert.strictEqual(fn.mock.callCount(), 0);
t.mock.timers.tick(1000);
assert.strictEqual(fn.mock.callCount(), 1);
t.mock.timers.tick(1);
t.mock.timers.tick(1);
t.mock.timers.tick(1);
assert.strictEqual(fn.mock.callCount(), 1);
});

// Test for https://github.com/nodejs/node/issues/50382
it('should not prevent due timers to be processed', async (t) => {
t.mock.timers.enable({ apis: ['setInterval', 'setTimeout'] });
const f1 = t.mock.fn();
const f2 = t.mock.fn();

setInterval(f1, 1000);
setTimeout(f2, 1001);

assert.strictEqual(f1.mock.callCount(), 0);
assert.strictEqual(f2.mock.callCount(), 0);

t.mock.timers.tick(1001);

assert.strictEqual(f1.mock.callCount(), 1);
assert.strictEqual(f2.mock.callCount(), 1);
});
});
});
});
Expand Down