From c51ea8e18c2a8bbabbd9374741d9e6817e99a559 Mon Sep 17 00:00:00 2001 From: Carlos Santos <4a.santos@gmail.com> Date: Wed, 4 Jun 2025 13:49:28 +0200 Subject: [PATCH] test: update recording test for avoiding garbage recordings --- backend/tests/helpers/test-scenarios.ts | 8 ++++---- .../api/recordings/race-conditions.test.ts | 20 ++++++++++++++----- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/backend/tests/helpers/test-scenarios.ts b/backend/tests/helpers/test-scenarios.ts index 97859f0..574203c 100644 --- a/backend/tests/helpers/test-scenarios.ts +++ b/backend/tests/helpers/test-scenarios.ts @@ -36,9 +36,9 @@ export interface TestContext { * @param withParticipant Whether to join a fake participant in the room. * @returns Room data including secrets and cookies. */ -export const setupSingleRoom = async (withParticipant = false): Promise => { +export const setupSingleRoom = async (roomPrefix: string, withParticipant = false): Promise => { const room = await createRoom({ - roomIdPrefix: 'TEST_ROOM' + roomIdPrefix: roomPrefix }); // Extract the room secrets and generate participant tokens, saved as cookies @@ -70,7 +70,7 @@ export const setupMultiRoomTestContext = async (numRooms: number, withParticipan const rooms: RoomData[] = []; for (let i = 0; i < numRooms; i++) { - const roomData = await setupSingleRoom(withParticipants); + const roomData = await setupSingleRoom('TEST_ROOM', withParticipants); rooms.push(roomData); } @@ -98,7 +98,7 @@ export const setupSingleRoomWithRecording = async ( stopRecordingCond = false, stopDelay?: StringValue ): Promise => { - const roomData = await setupSingleRoom(true); + const roomData = await setupSingleRoom('TEST_ROOM', true); const response = await startRecording(roomData.room.roomId, roomData.moderatorCookie); expectValidStartRecordingResponse(response, roomData.room.roomId); roomData.recordingId = response.body.recordingId; diff --git a/backend/tests/integration/api/recordings/race-conditions.test.ts b/backend/tests/integration/api/recordings/race-conditions.test.ts index 693d451..25e03f0 100644 --- a/backend/tests/integration/api/recordings/race-conditions.test.ts +++ b/backend/tests/integration/api/recordings/race-conditions.test.ts @@ -79,6 +79,7 @@ describe('Recording API Race Conditions Tests', () => { expect(startRoomCompositeSpy).toHaveBeenCalled(); console.log('Recording start response:', result.body); expect(result.status).toBe(500); // Service Unavailable due to failure + expect(result.body.error).toContain('Internal Server Error'); } finally { // Cleanup startRoomCompositeSpy.mockRestore(); @@ -95,13 +96,21 @@ describe('Recording API Race Conditions Tests', () => { context = await setupMultiRoomTestContext(1, true); const roomData = context.getRoomByIndex(0)!; + // Track active mock promises to ensure we can handle timeouts correctly + const activeMockPromises: Promise[] = []; + // Mock the startRoomComposite method to simulate a delay // const originalStartRoomComposite = recordingService['livekitService'].startRoomComposite; const startRoomCompositeSpy = jest .spyOn(recordingService['livekitService'], 'startRoomComposite') .mockImplementation(async (...args) => { - await sleep('6s'); // Longer than 3s timeout - throw new Error('Request failed with status 503: Service Unavailable'); + const mockPromise = (async () => { + await sleep('4s'); // Longer than 1s timeout + throw new Error('Request failed with status 503: Service Unavailable'); + })(); + + activeMockPromises.push(mockPromise); + return mockPromise; }); // Mock the handleRecordingLockTimeout method to prevent actual timeout handling @@ -121,13 +130,14 @@ describe('Recording API Race Conditions Tests', () => { roomData.room.roomId ); expect(releaseLockSpy).toHaveBeenCalled(); - expect(startRoomCompositeSpy).toHaveBeenCalled(); + expect(startRoomCompositeSpy).toHaveBeenCalledTimes(1); console.log('Recording start response:', result.body); expect(result.body.message).toContain('timed out while starting'); expect(result.status).toBe(503); // Service Unavailable due to timeout + await Promise.allSettled(activeMockPromises); } finally { - // Cleanup + // Cleanup after mock finishes startRoomCompositeSpy.mockRestore(); handleTimeoutSpy.mockRestore(); releaseLockSpy.mockRestore(); @@ -159,7 +169,7 @@ describe('Recording API Race Conditions Tests', () => { if (callCount === 1) { // First call (room1) - timeout await sleep('5s'); - return originalStartRoomComposite.apply(recordingService['livekitService'], args); + throw new Error('Request failed with status 503: Service Unavailable'); } else { // Subsequent calls - work normally return originalStartRoomComposite.apply(recordingService['livekitService'], args);