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:
@@ -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);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user