diff --git a/data/nodes.db b/data/nodes.db index 89194de..234e439 100644 Binary files a/data/nodes.db and b/data/nodes.db differ diff --git a/tests/integration/database/connection-management.test.ts b/tests/integration/database/connection-management.test.ts index 10b6547..7b52ae7 100644 --- a/tests/integration/database/connection-management.test.ts +++ b/tests/integration/database/connection-management.test.ts @@ -138,9 +138,13 @@ describe('Database Connection Management', () => { // Test concurrent reads const promises = connections.map((conn, index) => { - return new Promise((resolve) => { - const result = conn.prepare('SELECT ? as id').get(index); - resolve(result); + return new Promise((resolve, reject) => { + try { + const result = conn.prepare('SELECT ? as id').get(index); + resolve(result); + } catch (error) { + reject(error); + } }); }); @@ -148,12 +152,32 @@ describe('Database Connection Management', () => { expect(results).toHaveLength(connectionCount); } finally { - // Cleanup connections - connections.forEach(conn => conn.close()); - if (fs.existsSync(dbPath)) { - fs.unlinkSync(dbPath); - fs.unlinkSync(`${dbPath}-wal`); - fs.unlinkSync(`${dbPath}-shm`); + // Cleanup connections - ensure all are closed even if some fail + await Promise.all( + connections.map(async (conn) => { + try { + if (conn.open) { + conn.close(); + } + } catch (error) { + // Ignore close errors + } + }) + ); + + // Clean up files with error handling + try { + if (fs.existsSync(dbPath)) { + fs.unlinkSync(dbPath); + } + if (fs.existsSync(`${dbPath}-wal`)) { + fs.unlinkSync(`${dbPath}-wal`); + } + if (fs.existsSync(`${dbPath}-shm`)) { + fs.unlinkSync(`${dbPath}-shm`); + } + } catch (error) { + // Ignore cleanup errors } } }); @@ -285,7 +309,7 @@ describe('Database Connection Management', () => { db.exec('ROLLBACK'); conn2.close(); } - }); + }, { timeout: 5000 }); // Add explicit timeout }); describe('Database Configuration', () => { diff --git a/tests/integration/msw-setup.test.ts b/tests/integration/msw-setup.test.ts index 397f2c0..27796f5 100644 --- a/tests/integration/msw-setup.test.ts +++ b/tests/integration/msw-setup.test.ts @@ -50,13 +50,21 @@ describe('MSW Setup Verification', () => { }); describe('Integration Test Server', () => { + let serverStarted = false; + beforeAll(() => { - // Start a separate MSW instance for more control - mswTestServer.start({ onUnhandledRequest: 'error' }); + // Only start if not already running + if (!serverStarted) { + mswTestServer.start({ onUnhandledRequest: 'error' }); + serverStarted = true; + } }); afterAll(() => { - mswTestServer.stop(); + if (serverStarted) { + mswTestServer.stop(); + serverStarted = false; + } }); it('should handle workflow creation with custom response', async () => { @@ -163,7 +171,7 @@ describe('MSW Setup Verification', () => { expect(requests).toHaveLength(2); expect(requests[0].url).toContain('/api/v1/workflows'); expect(requests[1].url).toContain('/api/v1/executions'); - }); + }, { timeout: 10000 }); // Increase timeout for this specific test it('should work with scoped handlers', async () => { const result = await mswTestServer.withScope( diff --git a/tests/integration/setup/msw-test-server.ts b/tests/integration/setup/msw-test-server.ts index 7e9f023..10dde0d 100644 --- a/tests/integration/setup/msw-test-server.ts +++ b/tests/integration/setup/msw-test-server.ts @@ -66,17 +66,34 @@ export const mswTestServer = { waitForRequests: (count: number, timeout = 5000): Promise => { return new Promise((resolve, reject) => { const requests: Request[] = []; - const timeoutId = setTimeout(() => { - reject(new Error(`Timeout waiting for ${count} requests. Got ${requests.length}`)); - }, timeout); - - integrationTestServer.events.on('request:match', ({ request }) => { + let timeoutId: NodeJS.Timeout | null = null; + + // Event handler function to allow cleanup + const handleRequest = ({ request }: { request: Request }) => { requests.push(request); if (requests.length === count) { - clearTimeout(timeoutId); + cleanup(); resolve(requests); } - }); + }; + + // Cleanup function to remove listener and clear timeout + const cleanup = () => { + if (timeoutId) { + clearTimeout(timeoutId); + timeoutId = null; + } + integrationTestServer.events.removeListener('request:match', handleRequest); + }; + + // Set timeout + timeoutId = setTimeout(() => { + cleanup(); + reject(new Error(`Timeout waiting for ${count} requests. Got ${requests.length}`)); + }, timeout); + + // Add event listener + integrationTestServer.events.on('request:match', handleRequest); }); }, @@ -86,14 +103,28 @@ export const mswTestServer = { verifyNoUnhandledRequests: (): Promise => { return new Promise((resolve, reject) => { let hasUnhandled = false; + let timeoutId: NodeJS.Timeout | null = null; - integrationTestServer.events.on('request:unhandled', ({ request }) => { + const handleUnhandled = ({ request }: { request: Request }) => { hasUnhandled = true; + cleanup(); reject(new Error(`Unhandled request: ${request.method} ${request.url}`)); - }); + }; + + const cleanup = () => { + if (timeoutId) { + clearTimeout(timeoutId); + timeoutId = null; + } + integrationTestServer.events.removeListener('request:unhandled', handleUnhandled); + }; + + // Add event listener + integrationTestServer.events.on('request:unhandled', handleUnhandled); // Give a small delay to allow any pending requests - setTimeout(() => { + timeoutId = setTimeout(() => { + cleanup(); if (!hasUnhandled) { resolve(); } diff --git a/tests/setup/test-env.ts b/tests/setup/test-env.ts index 30be463..629ccbe 100644 --- a/tests/setup/test-env.ts +++ b/tests/setup/test-env.ts @@ -77,7 +77,7 @@ function setTestDefaults(): void { TEST_TIMEOUT_UNIT: '5000', TEST_TIMEOUT_INTEGRATION: '15000', TEST_TIMEOUT_E2E: '30000', - TEST_TIMEOUT_GLOBAL: '60000', + TEST_TIMEOUT_GLOBAL: '30000', // Reduced from 60s to 30s to catch hangs faster // Test execution TEST_RETRY_ATTEMPTS: '2',