#!/usr/bin/env tsx import { CrashLogManager } from '../ts/daemon/crashlogmanager.js'; import type { IProcessLog } from '../ts/shared/protocol/ipc.types.js'; import * as plugins from '../ts/plugins.js'; import * as paths from '../ts/paths.js'; import * as fs from 'fs/promises'; async function testCrashLogManager() { console.log('๐Ÿงช Testing CrashLogManager directly...\n'); const crashLogManager = new CrashLogManager(); const crashLogsDir = plugins.path.join(paths.tspmDir, 'crashlogs'); // Clean up any existing crash logs console.log('๐Ÿ“ Cleaning up existing crash logs...'); try { await fs.rm(crashLogsDir, { recursive: true, force: true }); } catch {} // Create test logs const testLogs: IProcessLog[] = [ { timestamp: Date.now() - 5000, message: '[TEST] Process starting up...', type: 'stdout' }, { timestamp: Date.now() - 4000, message: '[TEST] Initializing components...', type: 'stdout' }, { timestamp: Date.now() - 3000, message: '[TEST] Running main loop...', type: 'stdout' }, { timestamp: Date.now() - 2000, message: '[TEST] Warning: Memory usage high', type: 'stderr' }, { timestamp: Date.now() - 1000, message: '[TEST] Error: Unhandled exception occurred!', type: 'stderr' }, { timestamp: Date.now() - 500, message: '[TEST] Fatal: Process crashing with exit code 42', type: 'stderr' } ]; // Test saving a crash log console.log('๐Ÿ’พ Saving crash log...'); await crashLogManager.saveCrashLog( 1 as any, // ProcessId 'test-process', testLogs, 42, // exit code null, // signal 3, // restart count 1024 * 1024 * 50 // 50MB memory usage ); // 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) { console.error('โŒ No crash logs were created!'); process.exit(1); } // Read and display the crash log const crashLogFile = crashLogFiles[0]; const crashLogPath = plugins.path.join(crashLogsDir, crashLogFile); 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 content const checks = [ { text: 'CRASH REPORT', found: crashLogContent.includes('CRASH REPORT') }, { text: 'Exit Code: 42', found: crashLogContent.includes('Exit Code: 42') }, { text: 'Restart Attempt: 3/10', found: crashLogContent.includes('Restart Attempt: 3/10') }, { text: 'Memory Usage: 50 MB', found: crashLogContent.includes('Memory Usage: 50 MB') }, { text: 'Fatal: Process crashing', found: crashLogContent.includes('Fatal: Process crashing') } ]; console.log('\nโœ… Verification:'); checks.forEach(check => { console.log(` ${check.found ? 'โœ“' : 'โœ—'} Contains "${check.text}"`); }); const allChecksPassed = checks.every(c => c.found); // Test rotation (create 100+ logs to test limit) console.log('\n๐Ÿ”„ Testing rotation (creating 105 crash logs)...'); for (let i = 2; i <= 105; i++) { await crashLogManager.saveCrashLog( i as any, `test-process-${i}`, testLogs, i, null, 1, 1024 * 1024 * 10 ); // Small delay to ensure different timestamps await new Promise(resolve => setTimeout(resolve, 10)); } // Check that we have exactly 100 logs (rotation working) const finalLogFiles = await fs.readdir(crashLogsDir); console.log(` After rotation: ${finalLogFiles.length} crash logs (should be 100)`); if (finalLogFiles.length !== 100) { console.error(`โŒ Rotation failed! Expected 100 logs, got ${finalLogFiles.length}`); process.exit(1); } // Verify oldest logs were deleted (test-process should be gone) const hasOriginal = finalLogFiles.some(f => f.includes('_1_test-process.log')); if (hasOriginal) { console.error('โŒ Rotation failed! Oldest log still exists'); process.exit(1); } if (allChecksPassed) { console.log('\nโœ… All crash log tests passed!'); } else { console.log('\nโŒ Some crash log tests failed!'); process.exit(1); } } // Run the test testCrashLogManager().catch(error => { console.error('โŒ Test failed:', error); process.exit(1); });