Fix flaky createBarrier test by using fake timers

The 'abandons a wait after the timeout expires' test relied on real
setTimeout calls with tight margins (~50ms) between barrier timeouts
and tick delays. On loaded CI machines, timer coalescing could cause
both to fire in the same event loop turn, making the test flaky.

Switched all createBarrier tests to jest.useFakeTimers() with
advanceTimersByTime() for deterministic timer control, removing
the real-timer tick helper entirely.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
This commit is contained in:
Fredrik Adelöw
2026-03-09 14:11:25 +01:00
parent a6d1c15f75
commit 71da72d1a6
@@ -121,8 +121,13 @@ describe('startTaskPipeline', () => {
});
describe('createBarrier', () => {
const tick = (millis: number) =>
new Promise(resolve => setTimeout(resolve, millis));
beforeEach(() => {
jest.useFakeTimers();
});
afterEach(() => {
jest.useRealTimers();
});
it('abandons a wait after the timeout expires', async () => {
const abortController = new AbortController();
@@ -132,10 +137,11 @@ describe('createBarrier', () => {
const fn1 = jest.fn();
barrier.wait().then(fn1);
await tick(0);
await Promise.resolve();
expect(fn1).not.toHaveBeenCalled();
await tick(50);
jest.advanceTimersByTime(50);
await Promise.resolve();
expect(fn1).not.toHaveBeenCalled();
// start a new wait mid-way through the timeout
@@ -143,14 +149,16 @@ describe('createBarrier', () => {
const fn2 = jest.fn();
barrier.wait().then(fn2);
await tick(0);
await Promise.resolve();
expect(fn2).not.toHaveBeenCalled();
await tick(50);
jest.advanceTimersByTime(50);
await Promise.resolve();
expect(fn1).toHaveBeenCalledTimes(1);
expect(fn2).not.toHaveBeenCalled();
await tick(50);
jest.advanceTimersByTime(50);
await Promise.resolve();
expect(fn1).toHaveBeenCalledTimes(1);
expect(fn2).toHaveBeenCalledTimes(1);
});
@@ -164,16 +172,16 @@ describe('createBarrier', () => {
barrier.wait().then(fn1);
// should resolve immediately, not after timeout
await tick(0);
await Promise.resolve();
expect(fn1).not.toHaveBeenCalled();
abortController.abort();
await tick(0);
await Promise.resolve();
expect(fn1).toHaveBeenCalledTimes(1);
// subsequent waits should be immediate no matter what
const fn2 = jest.fn();
barrier.wait().then(fn2);
await tick(0);
await Promise.resolve();
expect(fn2).toHaveBeenCalledTimes(1);
});
@@ -185,7 +193,8 @@ describe('createBarrier', () => {
const fn1 = jest.fn();
barrier.wait().then(fn1);
await tick(50);
jest.advanceTimersByTime(50);
await Promise.resolve();
expect(fn1).not.toHaveBeenCalled();
// start a new wait mid-way through the timeout
@@ -193,13 +202,13 @@ describe('createBarrier', () => {
const fn2 = jest.fn();
barrier.wait().then(fn2);
await tick(0);
await Promise.resolve();
expect(fn1).not.toHaveBeenCalled();
expect(fn2).not.toHaveBeenCalled();
barrier.release();
await tick(0);
await Promise.resolve();
expect(fn1).toHaveBeenCalledTimes(1);
expect(fn2).toHaveBeenCalledTimes(1);
});