import { tap, expect } from '@git.zone/tstest/tapbundle'; 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'; tap.test('CrashLogManager should save and read crash logs', async () => { const crashLogManager = new CrashLogManager(); const crashLogsDir = plugins.path.join(paths.tspmDir, 'crashlogs'); // Clean up any 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 await crashLogManager.saveCrashLog( 1 as any, 'test-process', testLogs, 42, null, 3, 1024 * 1024 * 50 ); // Check if crash log was created const crashLogFiles = await fs.readdir(crashLogsDir).catch(() => []); expect(crashLogFiles.length).toBeGreaterThan(0); // Read and verify content const crashLogFile = crashLogFiles[0]; const crashLogPath = plugins.path.join(crashLogsDir, crashLogFile); const crashLogContent = await fs.readFile(crashLogPath, 'utf-8'); expect(crashLogContent).toInclude('CRASH REPORT'); expect(crashLogContent).toInclude('Exit Code: 42'); expect(crashLogContent).toInclude('Restart Attempt: 3/10'); expect(crashLogContent).toInclude('Memory Usage: 50 MB'); expect(crashLogContent).toInclude('Fatal: Process crashing'); }); tap.test('CrashLogManager should rotate old logs at 100 limit', async () => { const crashLogManager = new CrashLogManager(); const crashLogsDir = plugins.path.join(paths.tspmDir, 'crashlogs'); // Clean up try { await fs.rm(crashLogsDir, { recursive: true, force: true }); } catch {} const testLogs: IProcessLog[] = [ { timestamp: Date.now(), message: '[TEST] Test log', type: 'stdout' } ]; // Create 105 crash logs to test rotation for (let i = 1; i <= 105; i++) { await crashLogManager.saveCrashLog( i as any, `test-process-${i}`, testLogs, i, null, 1, 1024 * 1024 * 10 ); await new Promise(resolve => setTimeout(resolve, 10)); } // Check that we have exactly 100 logs (rotation working) const finalLogFiles = await fs.readdir(crashLogsDir); expect(finalLogFiles.length).toEqual(100); // Verify oldest logs were deleted const hasFirstLog = finalLogFiles.some(f => f.includes('_1_test-process-1.log')); expect(hasFirstLog).toBeFalse(); }); export default tap.start();