test(terminal): verify cleanup by process identity (#8389)

* test(terminal): capture recurring worker publication failures

* test(terminal): diagnose the remaining process cleanup wait

* test(terminal): verify cleanup by process identity

* test(terminal): retain native liveness proof during cleanup checks

---------

Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
This commit is contained in:
paseo-bot[bot]
2026-10-31 18:38:48 +00:00
committed by GitHub
parent 2dd931c8bd
commit 85354fcb6a
2 changed files with 19 additions and 2 deletions
@@ -5,6 +5,7 @@ import { tmpdir } from "node:os";
import path from "node:path";
import { Worker } from "node:worker_threads";
import { isPlatform } from "../test-utils/platform.js";
import { classifyTerminalProgramProcess } from "./terminal-worker-ownership.js";
import { currentBootId } from "../server/pid-lock.js";
import {
createTerminalWorkerProcessInspector,
@@ -260,15 +261,19 @@ describe.skipIf(isPlatform("win32"))("terminal worker reaper", () => {
it("leaves a program alive when its pid now belongs to a process with another birth time", async () => {
const home = makeHome();
const unrelated = spawnIdle();
const original = { id: "t1", pid: unrelated.pid!, startedAt: "Thu Jan 1 00:00:00 1970" };
const recordPath = writeRecord(home, {
pid: await goneProcessPid(),
terminals: [{ id: "t1", pid: unrelated.pid!, startedAt: "Thu Jan 1 00:00:00 1970" }],
terminals: [original],
});
await reapTerminalWorkers({ paseoHome: home, inspector, gracefulMs: 0 });
expect(isAlive(unrelated.pid!)).toBe(true);
expect(existsSync(recordPath)).toBe(false);
expect(
classifyTerminalProgramProcess(original, await inspector.inspect(original.pid)),
).toMatchObject({ status: "unrelated" });
});
it("retires a record from an earlier boot without signaling anything it names", async () => {
@@ -50,6 +50,7 @@ import type {
WorkerTerminalState,
TerminalWorkerToParentMessage,
} from "./terminal-worker-protocol.js";
import { classifyTerminalProgramProcess } from "./terminal-worker-ownership.js";
import { createTerminalWorkerProcessInspector } from "./terminal-worker-processes.js";
import {
readUnconfirmedTerminalCleanup,
@@ -881,8 +882,19 @@ it.each([false, true])(
expect(manager.getTerminal(remaining.id)).toBeUndefined();
expect(await manager.getTerminals(cwd)).toEqual([]);
await waitForCondition(() => !isProcessAlive(remainingPid), 10000);
expect(await readUnconfirmedTerminalCleanup(paseoHome)).toEqual([]);
const original = record!.terminals.find((entry) => entry.id === remaining.id)!;
// Startup can launch a new worker after cleanup and Windows can reuse the old PID.
// Require the original process to be gone, not the numeric PID to remain unused.
await expect
.poll(
async () =>
!isProcessAlive(remainingPid) ||
classifyTerminalProgramProcess(original, await inspector.inspect(remainingPid)).status ===
"unrelated",
{ timeout: 10000 },
)
.toBe(true);
},
);