108 lines
3.3 KiB
TypeScript
108 lines
3.3 KiB
TypeScript
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
|
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);
|
|
`;
|
|
|
|
tap.test('manual crash log test via CLI', async (tools) => {
|
|
const crashScriptPath = plugins.path.join(paths.tspmDir, 'test-crash-script.js');
|
|
const crashLogsDir = plugins.path.join(paths.tspmDir, 'crashlogs');
|
|
|
|
// Clean up any existing crash logs
|
|
try {
|
|
await fs.rm(crashLogsDir, { recursive: true, force: true });
|
|
} catch {}
|
|
|
|
// Write the crash script
|
|
await fs.writeFile(crashScriptPath, CRASH_SCRIPT);
|
|
|
|
// Stop any existing daemon
|
|
try {
|
|
execSync('tsx ts/cli.ts daemon stop', { stdio: 'pipe' });
|
|
} catch {}
|
|
await tools.delayFor(1000);
|
|
|
|
// Start the daemon
|
|
console.log('Starting daemon...');
|
|
try {
|
|
execSync('tsx ts/cli.ts daemon start', { stdio: 'pipe' });
|
|
} catch {}
|
|
await tools.delayFor(2000);
|
|
|
|
// Add a process that will crash
|
|
console.log('Adding crash test process...');
|
|
let addOutput: string;
|
|
try {
|
|
addOutput = execSync(`tsx ts/cli.ts add "node ${crashScriptPath}" --name crash-test`, { encoding: 'utf-8', stdio: 'pipe' });
|
|
} catch (e: any) {
|
|
addOutput = e.stdout || '';
|
|
}
|
|
console.log(addOutput);
|
|
|
|
// Extract process ID from output
|
|
const idMatch = addOutput.match(/Assigned ID: (\d+)/i)
|
|
|| addOutput.match(/id[:\s]+(\d+)/i);
|
|
|
|
if (!idMatch) {
|
|
console.log('Could not extract process ID, skipping rest of test');
|
|
// Clean up
|
|
try { execSync('tsx ts/cli.ts daemon stop', { stdio: 'pipe' }); } catch {}
|
|
await fs.unlink(crashScriptPath).catch(() => {});
|
|
return;
|
|
}
|
|
|
|
const processId = parseInt(idMatch[1]);
|
|
console.log(`Process ID: ${processId}`);
|
|
|
|
// Start the process
|
|
console.log('Starting process that will crash...');
|
|
try {
|
|
execSync(`tsx ts/cli.ts start ${processId}`, { stdio: 'pipe' });
|
|
} catch {}
|
|
|
|
// Wait for the process to crash (it crashes after 3 seconds)
|
|
console.log('Waiting for process to crash...');
|
|
await tools.delayFor(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}`));
|
|
|
|
expect(crashLogFiles.length).toBeGreaterThan(0);
|
|
|
|
// Find and verify crash log
|
|
const testCrashLog = crashLogFiles.find(file => file.includes('crash-test'));
|
|
if (testCrashLog) {
|
|
const crashLogPath = plugins.path.join(crashLogsDir, testCrashLog);
|
|
const crashLogContent = await fs.readFile(crashLogPath, 'utf-8');
|
|
|
|
console.log('\nCrash log content:');
|
|
console.log(crashLogContent);
|
|
|
|
expect(crashLogContent).toInclude('CRASH REPORT');
|
|
expect(crashLogContent).toInclude('Exit Code');
|
|
}
|
|
|
|
// Clean up
|
|
console.log('Cleaning up...');
|
|
try { execSync(`tsx ts/cli.ts delete ${processId}`, { stdio: 'pipe' }); } catch {}
|
|
try { execSync('tsx ts/cli.ts daemon stop', { stdio: 'pipe' }); } catch {}
|
|
await fs.unlink(crashScriptPath).catch(() => {});
|
|
});
|
|
|
|
export default tap.start();
|