From f22fe9663c0c8b9931702b9eca7ce8ffa0c2143e Mon Sep 17 00:00:00 2001 From: Aliou Diallo Date: Wed, 5 Aug 2026 13:35:46 +0200 Subject: [PATCH] test(e2e): assert one process_ended per self-exiting process A duplicate emit would reach the notification service twice and deliver the same lifecycle notification to the agent twice. The test waits past one liveness tick so a re-classification of an already-finalized record would be caught. --- tests/e2e/process-end-once.e2e.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tests/e2e/process-end-once.e2e.ts diff --git a/tests/e2e/process-end-once.e2e.ts b/tests/e2e/process-end-once.e2e.ts new file mode 100644 index 0000000..e75f052 --- /dev/null +++ b/tests/e2e/process-end-once.e2e.ts @@ -0,0 +1,29 @@ +import { expect } from "vitest"; +import { getManager } from "../../src/get-manager"; +import { test } from "./fixtures"; +import { collectEvents, waitForEnd } from "./utils"; + +/** + * A process that exits on its own must emit exactly one `process_ended`. + * A duplicate emit reaches the notification service twice and the agent + * receives the same lifecycle notification twice. + */ +test("emits process_ended once for a process that exits on its own", async ({ + cwd, +}) => { + using manager = getManager(); + const events = collectEvents(manager); + + const info = manager.start("short-lived", "sleep 0.2; echo done", cwd); + + await waitForEnd(manager, info.id); + // The liveness tick runs every 5s; give it a chance to re-classify a + // record that the close handler already finalized. + await new Promise((resolve) => setTimeout(resolve, 6000)); + + const ended = events.filter( + (event) => event.type === "process_ended" && event.info.id === info.id, + ); + + expect(ended).toHaveLength(1); +}, 15000); -- 2.51.2