mirror of
https://github.com/morluto/rea
synced 2026-10-26 06:16:17 -04:00
test(process): compare progress with retained PTY chunks
This commit is contained in:
@@ -138,3 +138,42 @@ it.each([false, true])(
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
it("retains PTY chunk boundaries when two output messages arrive fragmented", () => {
|
||||
let onData: ((data: string) => void) | undefined;
|
||||
const terminal = {
|
||||
onData: (listener: (data: string) => void) => {
|
||||
onData = listener;
|
||||
return { dispose: () => undefined };
|
||||
},
|
||||
} as unknown as IPty;
|
||||
const scenario = parseProcessScenario({
|
||||
executable: "unused",
|
||||
normalization: { paths: false, pids: false, ports: false },
|
||||
});
|
||||
const frames: TerminalFrame[] = [];
|
||||
const captureRetention = captureTerminalFrames({
|
||||
terminal,
|
||||
scenario,
|
||||
frames,
|
||||
started: 0,
|
||||
onOutput: () => undefined,
|
||||
renderer: { write: () => undefined } as never,
|
||||
normalizeText: createBoundedProcessTextNormalizer(scenario, "/tmp", -1),
|
||||
recordEvent: () => undefined,
|
||||
identifiers: () => [],
|
||||
});
|
||||
// A PTY transports chunks, independently of the child's write boundaries.
|
||||
const chunks = ["SPARSE_CHILD_", "STARTED\r\n", "SPARSE_CHILD_", "DONE\r\n"];
|
||||
for (const chunk of chunks) onData?.(chunk);
|
||||
|
||||
expect(frames.map(({ data }) => data)).toEqual(chunks);
|
||||
expect(frames.map(({ sequence }) => sequence)).toEqual([0, 1, 2, 3]);
|
||||
expect(frames.map(({ data }) => data).join("")).toBe(
|
||||
"SPARSE_CHILD_STARTED\r\nSPARSE_CHILD_DONE\r\n",
|
||||
);
|
||||
expect(captureRetention().raw_terminal).toMatchObject({
|
||||
observed_frames: 4,
|
||||
retained_frames: 4,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -260,9 +260,9 @@ itWithCaptureCapability(
|
||||
operation: "capture_process_scenario",
|
||||
predicate_type: "rea.process-capture",
|
||||
});
|
||||
expect(recorded.frames.map(({ data }) => data).join("")).toContain(
|
||||
"SPARSE_CHILD_STARTED",
|
||||
);
|
||||
const terminalText = recorded.frames.map(({ data }) => data).join("");
|
||||
expect(terminalText).toContain("SPARSE_CHILD_STARTED");
|
||||
expect(terminalText).toContain("SPARSE_CHILD_DONE");
|
||||
expect(capture.stderr).not.toContain("SPARSE_CHILD_STARTED");
|
||||
expect(capture.stderr).not.toContain("SPARSE_CHILD_DONE");
|
||||
const updates = capture.lines.map(({ update }) => update);
|
||||
@@ -273,15 +273,27 @@ itWithCaptureCapability(
|
||||
expect(Math.max(...elapsed) - Math.min(...elapsed)).toBeGreaterThanOrEqual(
|
||||
1_000,
|
||||
);
|
||||
expect(
|
||||
running.every(({ details }) => details.frames <= 2),
|
||||
`running progress details: ${JSON.stringify(running.map(({ details }) => details))}`,
|
||||
).toBe(true);
|
||||
// Frames count retained PTY chunks; child writes may be split or coalesced.
|
||||
for (const [index, update] of running.entries()) {
|
||||
expect(update.details.frames).toBeLessThanOrEqual(recorded.frames.length);
|
||||
const previous = running[index - 1];
|
||||
if (previous !== undefined)
|
||||
expect(update.details.frames).toBeGreaterThanOrEqual(
|
||||
previous.details.frames,
|
||||
);
|
||||
}
|
||||
assertRateBound(
|
||||
updates.filter(({ terminal }) => terminal !== true).length,
|
||||
updates.at(-1)?.details.elapsed_ms ?? 0,
|
||||
);
|
||||
expect(updates.at(-1)).toMatchObject({
|
||||
phase: "cleanup",
|
||||
terminal: true,
|
||||
details: {
|
||||
disposition: "exited",
|
||||
frames: recorded.frames.length,
|
||||
samples: recorded.process_samples.length,
|
||||
interactions: recorded.interaction_events.length,
|
||||
owned_process_group: "cleaned",
|
||||
terminal_renderer: "cleaned",
|
||||
temporary_root: "cleaned",
|
||||
|
||||
Reference in New Issue
Block a user