import * as net from 'net'; /** * Finds `count` free ports by binding to port 0 and reading the OS-assigned port. * All servers are opened simultaneously to guarantee uniqueness. * Returns an array of guaranteed-free ports. */ export async function findFreePorts(count: number): Promise { const servers: net.Server[] = []; const ports: number[] = []; // Open all servers simultaneously on port 0 await Promise.all( Array.from({ length: count }, () => new Promise((resolve, reject) => { const server = net.createServer(); server.listen(0, '127.0.0.1', () => { const addr = server.address() as net.AddressInfo; ports.push(addr.port); servers.push(server); resolve(); }); server.on('error', reject); }) ) ); // Close all servers await Promise.all( servers.map( (server) => new Promise((resolve) => server.close(() => resolve())) ) ); return ports; } /** * Verifies that all given ports are free (not listening). * Useful as a cleanup assertion at the end of tests. * Throws if any port is still in use. */ export async function assertPortsFree(ports: number[]): Promise { const results = await Promise.all( ports.map( (port) => new Promise<{ port: number; free: boolean }>((resolve) => { const client = net.connect({ port, host: '127.0.0.1' }); client.on('connect', () => { client.destroy(); resolve({ port, free: false }); }); client.on('error', () => { resolve({ port, free: true }); }); client.setTimeout(1000, () => { client.destroy(); resolve({ port, free: true }); }); }) ) ); const occupied = results.filter((r) => !r.free); if (occupied.length > 0) { throw new Error( `Ports still in use after cleanup: ${occupied.map((r) => r.port).join(', ')}` ); } }