// QUIC Integration Validation Tests import { QuicClient, QuicServer, QuicConnectionPool } from '../src/transport/quic.js'; import { loadQuicConfig, checkQuicAvailability } from '../src/config/quic.js'; import { logger } from '../src/utils/logger.js'; interface TestResult { name: string; passed: boolean; error?: string; duration?: number; } const results: TestResult[] = []; async function runTest(name: string, fn: () => Promise): Promise { const startTime = Date.now(); try { await fn(); results.push({ name, passed: true, duration: Date.now() - startTime }); console.log(`โœ… ${name} (${Date.now() - startTime}ms)`); } catch (error) { results.push({ name, passed: false, error: (error as Error).message, duration: Date.now() - startTime }); console.error(`โŒ ${name}: ${(error as Error).message}`); } } async function testQuicAvailability(): Promise { const availability = await checkQuicAvailability(); if (availability.available) { logger.info('QUIC is available'); } else { logger.warn('QUIC is not available', { reason: availability.reason }); } } async function testConfigLoading(): Promise { const config = loadQuicConfig({ enabled: true, port: 4433, maxConnections: 50 }); if (config.port !== 4433) { throw new Error('Config port mismatch'); } if (config.maxConnections !== 50) { throw new Error('Config maxConnections mismatch'); } logger.info('Config loaded successfully', { config }); } async function testQuicClientInitialization(): Promise { const client = new QuicClient({ serverHost: 'localhost', serverPort: 4433 }); await client.initialize(); const stats = client.getStats(); if (typeof stats.totalConnections !== 'number') { throw new Error('Stats not properly initialized'); } await client.shutdown(); logger.info('Client initialization successful'); } async function testQuicServerInitialization(): Promise { const server = new QuicServer({ host: '127.0.0.1', port: 14433, // Use non-standard port for testing certPath: './certs/cert.pem', keyPath: './certs/key.pem' }); await server.initialize(); const stats = server.getStats(); if (typeof stats.totalConnections !== 'number') { throw new Error('Server stats not properly initialized'); } logger.info('Server initialization successful'); } async function testConnectionPool(): Promise { const client = new QuicClient(); await client.initialize(); const pool = new QuicConnectionPool(client, 5); // Get connection (should create new) const conn1 = await pool.getConnection('localhost', 4433); // Get same connection (should reuse) const conn2 = await pool.getConnection('localhost', 4433); if (conn1.id !== conn2.id) { throw new Error('Connection pool not reusing connections'); } await pool.clear(); await client.shutdown(); logger.info('Connection pool test successful'); } async function testConfigValidation(): Promise { try { loadQuicConfig({ enabled: true, port: 99999, // Invalid port maxConnections: 100 }); throw new Error('Should have thrown validation error for invalid port'); } catch (error) { if ((error as Error).message.includes('Invalid port')) { logger.info('Config validation working correctly'); } else { throw error; } } } async function testHealthCheck(): Promise { const availability = await checkQuicAvailability(); if (typeof availability.available !== 'boolean') { throw new Error('Health check not returning proper status'); } logger.info('Health check successful', { availability }); } async function testStatsCollection(): Promise { const client = new QuicClient(); await client.initialize(); const stats = client.getStats(); const requiredFields = [ 'totalConnections', 'activeConnections', 'totalStreams', 'activeStreams', 'bytesReceived', 'bytesSent', 'packetsLost', 'rttMs' ]; for (const field of requiredFields) { if (!(field in stats)) { throw new Error(`Missing stats field: ${field}`); } } await client.shutdown(); logger.info('Stats collection successful', { stats }); } async function testEnvironmentVariables(): Promise { const originalValue = process.env.AGENTIC_FLOW_ENABLE_QUIC; // Test with enabled process.env.AGENTIC_FLOW_ENABLE_QUIC = 'true'; let config = loadQuicConfig(); if (!config.enabled) { throw new Error('Environment variable not enabling QUIC'); } // Test with disabled process.env.AGENTIC_FLOW_ENABLE_QUIC = 'false'; config = loadQuicConfig(); if (config.enabled) { throw new Error('Environment variable not disabling QUIC'); } // Restore if (originalValue !== undefined) { process.env.AGENTIC_FLOW_ENABLE_QUIC = originalValue; } else { delete process.env.AGENTIC_FLOW_ENABLE_QUIC; } logger.info('Environment variable handling successful'); } async function main(): Promise { console.log('\n๐Ÿงช QUIC Integration Tests\n'); console.log('='.repeat(50)); await runTest('QUIC Availability Check', testQuicAvailability); await runTest('Configuration Loading', testConfigLoading); await runTest('Configuration Validation', testConfigValidation); await runTest('Client Initialization', testQuicClientInitialization); await runTest('Server Initialization', testQuicServerInitialization); await runTest('Connection Pool', testConnectionPool); await runTest('Health Check', testHealthCheck); await runTest('Stats Collection', testStatsCollection); await runTest('Environment Variables', testEnvironmentVariables); console.log('\n' + '='.repeat(50)); console.log('\n๐Ÿ“Š Test Summary:\n'); const passed = results.filter(r => r.passed).length; const failed = results.filter(r => !r.passed).length; const totalDuration = results.reduce((sum, r) => sum + (r.duration || 0), 0); console.log(`Total: ${results.length}`); console.log(`Passed: ${passed}`); console.log(`Failed: ${failed}`); console.log(`Duration: ${totalDuration}ms`); if (failed > 0) { console.log('\nโŒ Failed Tests:\n'); results.filter(r => !r.passed).forEach(r => { console.log(` โ€ข ${r.name}: ${r.error}`); }); process.exit(1); } else { console.log('\nโœ… All tests passed!\n'); process.exit(0); } } // Run tests main().catch(error => { console.error('Test suite failed:', error); process.exit(1); });