Files
NetMesh/infrastructure/ai/harness/terminalMonitorGuard.test.ts

76 lines
3.8 KiB
TypeScript
Raw Permalink Normal View History

import assert from 'node:assert/strict';
import test from 'node:test';
import { isStreamingMonitorCommand, TerminalMonitorGuard } from './terminalMonitorGuard';
import { applyMonitorStopResult } from './capabilityTools';
test('TerminalMonitorGuard bounds lines and batches', () => {
const guard = new TerminalMonitorGuard();
const result = guard.process('chat:job', `${'x'.repeat(800)}\n${'line\n'.repeat(1_000)}`);
assert.equal(result.action, 'deliver');
assert.ok((result.content?.length ?? Infinity) <= 3_000);
assert.ok((result.content?.split('\n')[0].length ?? Infinity) <= 500);
});
test('TerminalMonitorGuard suppresses bursts and stops a sustained overload', () => {
let now = 0;
const guard = new TerminalMonitorGuard({ now: () => now });
for (let index = 0; index < 10; index += 1) {
assert.equal(guard.process('chat:job', `line ${index}`).action, 'deliver');
}
assert.equal(guard.process('chat:job', 'burst').action, 'suppress');
let action = guard.process('chat:job', 'still flooding').action;
for (now = 1_000; now <= 31_000 && action !== 'stop'; now += 1_000) {
action = guard.process('chat:job', 'still flooding').action;
}
assert.equal(action, 'stop');
});
test('monitor stop result does not claim success when the backend stop failed', () => {
const failed = applyMonitorStopResult(
{ jobId: 'job-1', status: 'running' },
{ ok: false, error: 'lost worker' },
12,
);
assert.equal(failed.status, 'running');
assert.match(String(failed.output), /stop failed/);
assert.match(String(failed.output), /may still be running/);
const accepted = applyMonitorStopResult(
{ jobId: 'job-1', status: 'running' },
{ ok: true },
12,
);
assert.equal(accepted.status, 'stopping');
assert.match(String(accepted.output), /stop requested/);
});
test('isStreamingMonitorCommand requires an actual follow option', () => {
assert.equal(isStreamingMonitorCommand('tail app-file.log'), false);
assert.equal(isStreamingMonitorCommand('tail -n 10 foo.log'), false);
assert.equal(isStreamingMonitorCommand('journalctl --since 5m foo'), false);
assert.equal(isStreamingMonitorCommand('tail -f app.log'), true);
assert.equal(isStreamingMonitorCommand('tail -n0F app.log'), true);
assert.equal(isStreamingMonitorCommand('journalctl --follow -u nginx'), true);
assert.equal(isStreamingMonitorCommand('docker logs -f api'), true);
assert.equal(isStreamingMonitorCommand('kubectl logs --follow pod/api'), true);
assert.equal(isStreamingMonitorCommand('cd /srv && watch npm test'), true);
});
test('isStreamingMonitorCommand recognizes common wrappers and compose logs', () => {
assert.equal(isStreamingMonitorCommand('sudo journalctl -f -u nginx'), true);
assert.equal(isStreamingMonitorCommand('sudo -u root tail -f /var/log/syslog'), true);
assert.equal(isStreamingMonitorCommand('env LANG=C tail --follow app.log'), true);
assert.equal(isStreamingMonitorCommand('stdbuf -oL kubectl logs -f pod/api'), true);
assert.equal(isStreamingMonitorCommand('timeout 60s tail -f app.log'), true);
assert.equal(isStreamingMonitorCommand('docker compose logs -f api'), true);
assert.equal(isStreamingMonitorCommand('sudo -H journalctl -f -u nginx'), true);
assert.equal(isStreamingMonitorCommand('kubectl -n production logs -f pod/api'), true);
assert.equal(isStreamingMonitorCommand('kubectl --context prod logs --follow pod/api'), true);
assert.equal(isStreamingMonitorCommand('docker --context prod logs -f api'), true);
assert.equal(isStreamingMonitorCommand('docker compose -f compose.prod.yml logs -f api'), true);
assert.equal(isStreamingMonitorCommand('docker compose -p demo logs -f api'), true);
assert.equal(isStreamingMonitorCommand('sudo tail -n 10 app.log'), false);
assert.equal(isStreamingMonitorCommand('timeout 60s journalctl --since 5m'), false);
});