Skip to content

Commit

Permalink
fix hanging smoke test script
Browse files Browse the repository at this point in the history
  • Loading branch information
0age committed Dec 5, 2024
1 parent a9aee7a commit cf3dd36
Showing 1 changed file with 41 additions and 13 deletions.
54 changes: 41 additions & 13 deletions scripts/smoke-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ function waitForServer(command, args, timeoutMs) {

let serverStarted = false;
let output = '';
let processExited = false;

process.stdout.on('data', (data) => {
const chunk = data.toString();
Expand All @@ -18,35 +19,42 @@ function waitForServer(command, args, timeoutMs) {
// Check if server has started
if (chunk.includes('Server listening')) {
serverStarted = true;
resolve();
resolve(process);
}
});

// Set timeout
const timeout = setTimeout(() => {
if (!serverStarted) {
process.kill('SIGTERM');
reject(new Error('Server failed to start within timeout'));
reject(new Error(`Server failed to start within ${timeoutMs}ms timeout.\nOutput: ${output}`));
}
}, timeoutMs);

process.on('error', (error) => {
clearTimeout(timeout);
reject(error);
reject(new Error(`Server process error: ${error.message}\nOutput: ${output}`));
});

process.on('exit', (code) => {
clearTimeout(timeout);
processExited = true;
if (!serverStarted) {
reject(new Error(`Process exited with code ${code}\nOutput: ${output}`));
reject(new Error(`Process exited with code ${code} before server started\nOutput: ${output}`));
}
});

return process;
// Additional safety timeout - if process exits without starting
setTimeout(() => {
if (!serverStarted && !processExited) {
process.kill('SIGTERM');
reject(new Error(`Server did not start or exit within ${timeoutMs * 2}ms\nOutput: ${output}`));
}
}, timeoutMs * 2);
});
}

// Kill process using port
// Kill process using port with timeout
async function killProcessOnPort(port) {
try {
// Find process using port
Expand All @@ -67,29 +75,47 @@ async function killProcessOnPort(port) {
const kill = spawn('kill', ['-9', pid], { stdio: 'inherit', shell: true });
kill.on('exit', () => resolve());
});
// Wait a bit for the process to die
await new Promise(resolve => setTimeout(resolve, 1000));

// Wait for port to be free with timeout
const maxAttempts = 10;
for (let i = 0; i < maxAttempts; i++) {
await new Promise(resolve => setTimeout(resolve, 500));
const checkPort = spawn('lsof', ['-t', `-i:${port}`], { shell: true });
const stillInUse = await new Promise(resolve => {
checkPort.on('close', code => resolve(code === 0));
});
if (!stillInUse) break;
if (i === maxAttempts - 1) {
throw new Error(`Port ${port} is still in use after ${maxAttempts} attempts to free it`);
}
}
}
} catch (e) {
// Ignore errors from kill commands
console.error(`Error killing process on port ${port}:`, e.message);
}
}

// Get port from environment variable or use default
const PORT = process.env.SMOKE_TEST_PORT || 3000;

async function main() {
let devServer = null;
let prodServer = null;

try {
// Ensure port is free before starting
await killProcessOnPort(PORT);

// Test development mode
console.log(`Testing development mode (pnpm dev) on port ${PORT}...`);
await waitForServer('PORT=' + PORT + ' pnpm', ['dev'], 10000);
devServer = await waitForServer('PORT=' + PORT + ' pnpm', ['dev'], 10000);
console.log('✓ Development server started successfully');

// Kill the development server
await killProcessOnPort(PORT);
if (devServer) {
devServer.kill('SIGTERM');
await killProcessOnPort(PORT);
}

// Test production mode
console.log('\nTesting production mode (pnpm start)...');
Expand All @@ -103,7 +129,7 @@ async function main() {
});
});

await waitForServer('PORT=' + PORT + ' pnpm', ['start'], 10000);
prodServer = await waitForServer('PORT=' + PORT + ' pnpm', ['start'], 10000);
console.log('✓ Production server started successfully');

console.log('\n✅ All smoke tests passed!');
Expand All @@ -112,7 +138,9 @@ async function main() {
console.error('\n❌ Smoke tests failed:', error.message);
process.exit(1);
} finally {
// Cleanup: ensure port is free
// Cleanup: ensure all servers are stopped
if (devServer) devServer.kill('SIGTERM');
if (prodServer) prodServer.kill('SIGTERM');
await killProcessOnPort(PORT);
}
}
Expand Down

0 comments on commit cf3dd36

Please sign in to comment.