Files
rea/tests/boundary/process/providerProcessOutput.test.ts
T
morluto ba056e08a4 fix(providers): bound launcher diagnostics without losing byte counts
Give Ghidra and Hopper an 8 MiB aggregate retained-output budget while continuing to drain their process pipes. Expose total observed bytes at the supervisor boundary and retained bytes plus explicit truncation in provider diagnostics.

Redact known transport tokens even when the retained prefix ends inside one, preserving adjacent caller path/query evidence. Existing partial-launch and cleanup ownership remain intact.

Validation: 285 tests across 34 focused suites passed; the final cutoff-fixture refinement passed all 31 Ghidra/Hopper diagnostic tests. check:fast and architecture guards passed. Provider fixtures use real child processes; real Ghidra/Hopper applications were not verified.
2026-10-11 02:50:06 +08:00

49 lines
1.6 KiB
TypeScript

import { expect, it } from "vitest";
import {
ProviderProcessSupervisor,
type ProviderProcessDiagnostic,
} from "../../../src/process/ProviderProcess.js";
import {
spawnProviderProcessFixture,
stopProviderProcessFixture,
} from "../../fixtures/providerProcess.js";
it("bounds capture before diagnostic callbacks while draining both output streams", async () => {
const child = spawnProviderProcessFixture("burst", 70_000);
const diagnostics: ProviderProcessDiagnostic[] = [];
const supervisor = new ProviderProcessSupervisor(
{ process: child, ownsProcessLifetime: true },
{
maxDiagnosticBytes: 1024,
onDiagnostic: (event) => {
const snapshot = supervisor.snapshot();
expect(
snapshot.stdout.bytes + snapshot.stderr.bytes,
).toBeLessThanOrEqual(1024);
diagnostics.push(event);
},
},
);
try {
expect(await supervisor.waitForOutputClose(2_000)).toBe(true);
expect(
diagnostics.some((event) => event.type === "output" && event.truncated),
).toBe(true);
const snapshot = supervisor.snapshot();
expect(snapshot.stdout.observedBytes).toBe(70_000);
expect(snapshot.stderr.observedBytes).toBe(70_000);
expect(snapshot.stdout.bytes + snapshot.stderr.bytes).toBeLessThanOrEqual(
1024,
);
for (const stream of ["stdout", "stderr"])
expect(
diagnostics
.filter((event) => event.type === "output" && event.stream === stream)
.at(-1),
).toMatchObject({ totalBytes: 70_000 });
} finally {
await supervisor.stop();
await stopProviderProcessFixture(child);
}
});