#!/usr/bin/env tsx import * as plugins from '../ts/plugins.js'; import * as paths from '../ts/paths.js'; import * as fs from 'fs/promises'; import { execSync } from 'child_process'; // Test process that will crash const CRASH_SCRIPT = ` setInterval(() => { console.log('[test] Process is running...'); }, 1000); setTimeout(() => { console.error('[test] About to crash with non-zero exit code!'); process.exit(42); }, 3000); `; async function testCrashLog() { console.log('๐Ÿงช Testing crash log functionality...\n'); const crashScriptPath = plugins.path.join(paths.tspmDir, 'test-crash-script.js'); const crashLogsDir = plugins.path.join(paths.tspmDir, 'crashlogs'); try { // Clean up any existing crash logs console.log('๐Ÿ“ Cleaning up existing crash logs...'); try { await fs.rm(crashLogsDir, { recursive: true, force: true }); } catch {} // Write the crash script console.log('๐Ÿ“ Writing test crash script...'); await fs.writeFile(crashScriptPath, CRASH_SCRIPT); // Stop any existing daemon console.log('๐Ÿ›‘ Stopping any existing daemon...'); try { execSync('tsx ts/cli.ts daemon stop', { stdio: 'inherit' }); } catch {} await new Promise(resolve => setTimeout(resolve, 1000)); // Start the daemon console.log('๐Ÿš€ Starting daemon...'); execSync('tsx ts/cli.ts daemon start', { stdio: 'inherit' }); await new Promise(resolve => setTimeout(resolve, 2000)); // Add a process that will crash console.log('โž• Adding crash test process...'); const addOutput = execSync(`tsx ts/cli.ts add "node ${crashScriptPath}" --name crash-test`, { encoding: 'utf-8' }); console.log(addOutput); // Extract process ID from output const idMatch = addOutput.match(/Process added with ID: (\d+)/); if (!idMatch) { throw new Error('Could not extract process ID from output'); } const processId = parseInt(idMatch[1]); console.log(` Process ID: ${processId}`); // Start the process console.log('โ–ถ๏ธ Starting process that will crash...'); execSync(`tsx ts/cli.ts start ${processId}`, { stdio: 'inherit' }); // Wait for the process to crash (it crashes after 3 seconds) console.log('โณ Waiting for process to crash...'); await new Promise(resolve => setTimeout(resolve, 5000)); // Check if crash log was created console.log('๐Ÿ” Checking for crash log...'); const crashLogFiles = await fs.readdir(crashLogsDir).catch(() => []); console.log(` Found ${crashLogFiles.length} crash log files:`); crashLogFiles.forEach(file => console.log(` - ${file}`)); if (crashLogFiles.length === 0) { throw new Error('No crash logs were created!'); } // Find the crash log for our test process const testCrashLog = crashLogFiles.find(file => file.includes('crash-test')); if (!testCrashLog) { throw new Error('Could not find crash log for test process'); } // Read and display crash log content const crashLogPath = plugins.path.join(crashLogsDir, testCrashLog); const crashLogContent = await fs.readFile(crashLogPath, 'utf-8'); console.log('\n๐Ÿ“‹ Crash log content:'); console.log('โ”€'.repeat(60)); console.log(crashLogContent); console.log('โ”€'.repeat(60)); // Verify crash log contains expected information const checks = [ { text: 'CRASH REPORT', found: crashLogContent.includes('CRASH REPORT') }, { text: 'Exit Code: 42', found: crashLogContent.includes('Exit Code: 42') }, { text: 'About to crash', found: crashLogContent.includes('About to crash') }, { text: 'Process is running', found: crashLogContent.includes('Process is running') } ]; console.log('\nโœ… Verification:'); checks.forEach(check => { console.log(` ${check.found ? 'โœ“' : 'โœ—'} Contains "${check.text}"`); }); const allChecksPassed = checks.every(c => c.found); // Clean up console.log('\n๐Ÿงน Cleaning up...'); execSync(`tsx ts/cli.ts delete ${processId}`, { stdio: 'inherit' }); execSync('tsx ts/cli.ts daemon stop', { stdio: 'inherit' }); await fs.unlink(crashScriptPath).catch(() => {}); if (allChecksPassed) { console.log('\nโœ… All crash log tests passed!'); } else { console.log('\nโŒ Some crash log tests failed!'); process.exit(1); } } catch (error) { console.error('\nโŒ Test failed:', error); // Clean up on error try { execSync('tsx ts/cli.ts daemon stop', { stdio: 'inherit' }); await fs.unlink(crashScriptPath).catch(() => {}); } catch {} process.exit(1); } } // Run the test testCrashLog();