import { describe, it, expect } from 'vitest'; import { spawn } from 'child_process'; import path from 'path'; function runNode(script: string, timeoutMs = 120_000) { return new Promise<{ code: number; stdout: string; stderr: string }>( (resolve, reject) => { const p = spawn('pnpm', ['-s', 'tsx', script], { stdio: ['ignore', 'pipe', 'pipe'], env: { ...process.env }, }); let stdout = ''; let stderr = ''; p.stdout.on('data', (d) => (stdout += d.toString())); p.stderr.on('data', (d) => (stderr += d.toString())); const t = setTimeout(() => { p.kill('SIGKILL'); reject(new Error('timeout')); }, timeoutMs); p.on('close', (code) => { clearTimeout(t); resolve({ code: code ?? -1, stdout, stderr }); }); }, ); } describe('redis kill/reconnect end-to-end (both handlers)', () => { it('survives redis restart without Socket already opened', async () => { const script = path.join(__dirname, 'scripts', 'redis-kill-reconnect.ts'); const res = await runNode(script, 180_000); expect(res.code).toBe(0); expect(res.stdout).toContain('OK'); expect(res.stderr).not.toContain('Socket already opened'); }, 180_000); });