From 94349a133e5b45470f3e62d4e33b097247fa2c36 Mon Sep 17 00:00:00 2001 From: "paseo-bot[bot]" <266920839+paseo-bot[bot]@users.noreply.github.com> Date: Thu, 29 Oct 2026 00:31:37 +0000 Subject: [PATCH] test(terminal): capture the Windows record rewrite failure --- .../src/terminal/terminal-worker-process.ts | 7 ++++- .../terminal/worker-terminal-manager.test.ts | 29 +++++++++++++++---- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/packages/server/src/terminal/terminal-worker-process.ts b/packages/server/src/terminal/terminal-worker-process.ts index 6c13ba04d5..8bf306d2e5 100644 --- a/packages/server/src/terminal/terminal-worker-process.ts +++ b/packages/server/src/terminal/terminal-worker-process.ts @@ -223,7 +223,12 @@ function runWorker(argv: string[]): void { ...record, terminals: record.terminals.filter((entry) => sessionsById.has(entry.id)), }; - writeTerminalWorkerRecord(args.paseoHome, record); + try { + writeTerminalWorkerRecord(args.paseoHome, record); + } catch (error) { + console.error("CI terminal record write failed:", (error as NodeJS.ErrnoException).code); + throw error; + } } function removeOwnFiles(): void { diff --git a/packages/server/src/terminal/worker-terminal-manager.test.ts b/packages/server/src/terminal/worker-terminal-manager.test.ts index 21edc39ecd..1758822fce 100644 --- a/packages/server/src/terminal/worker-terminal-manager.test.ts +++ b/packages/server/src/terminal/worker-terminal-manager.test.ts @@ -43,6 +43,7 @@ import { listTerminalWorkerRecords, readTerminalWorkerRecord, terminalWorkerDirectory, + terminalWorkerLogPath, type TerminalWorkerRecord, } from "./terminal-worker-record.js"; import { TERMINAL_WORKER_PROTOCOL_OVERRIDE_ENV } from "./terminal-worker-protocol.js"; @@ -772,13 +773,17 @@ it("never adopts a live worker's terminals after a kill cleanup it could not fin const first = await startRealWorkerManager({ paseoHome }); manager = first; const exitRequestPath = join(cwd, "exit-requested"); + const exitObservedPath = join(cwd, "exit-observed"); const ending = await first.createTerminal({ workspaceId: "ws-unfinished-kill", cwd, ...nodeTerminalCommand(` - const { existsSync } = require("node:fs"); + const { existsSync, writeFileSync } = require("node:fs"); setInterval(() => { - if (existsSync(${JSON.stringify(exitRequestPath)})) process.exit(0); + if (existsSync(${JSON.stringify(exitRequestPath)})) { + writeFileSync(${JSON.stringify(exitObservedPath)}, ""); + process.exit(0); + } }, 25); `), }); @@ -788,6 +793,7 @@ it("never adopts a live worker's terminals after a kill cleanup it could not fin ...nodeTerminalCommand("setInterval(() => {}, 1000);"), }); const pids = await recordedTerminalPids(paseoHome); + const endingPid = pids.get(ending.id)!; const remainingPid = pids.get(remaining.id)!; // A kill cleanup whose process table read fails signals nothing and leaves the worker live. @@ -803,10 +809,21 @@ it("never adopts a live worker's terminals after a kill cleanup it could not fin // One terminal ends on its own: the live worker rewrites its record from memory. writeFileSync(exitRequestPath, ""); - await waitForCondition( - async () => !(await recordedTerminalPids(paseoHome)).has(ending.id), - 10000, - ); + try { + await waitForCondition( + async () => !(await recordedTerminalPids(paseoHome)).has(ending.id), + 10000, + ); + } catch (error) { + const workerLog = readFileSync(terminalWorkerLogPath(paseoHome), "utf8"); + console.error("CI terminal exit diagnostics", { + exitObserved: existsSync(exitObservedPath), + endingAlive: isProcessAlive(endingPid), + remainingAlive: isProcessAlive(remainingPid), + recordWriteErrors: workerLog.match(/CI terminal record write failed: \w+/g) ?? [], + }); + throw error; + } expect((await readUnconfirmedTerminalCleanup(paseoHome)).length).toBeGreaterThan(0); manager = await startRealWorkerManager({ paseoHome });