From 14ff455a0aaa5cf20f75a0326beb14ff59c9bd98 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Fri, 16 Oct 2026 19:58:24 +0000 Subject: [PATCH] fix(env): make the read/bash differential test deterministic and meaningful The fake tool API lacked retainedOutput, so every bash case threw on both sides and the test only compared the error text. Its stdout+stderr case also depended on the order of two concurrently read pipes and failed intermittently in CI. The API now provides retainedOutput, each bash case writes to one stream, and bash cases must return a result. --- packages/env/test/differential.test.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/env/test/differential.test.ts b/packages/env/test/differential.test.ts index a6b6907b7..96571f151 100644 --- a/packages/env/test/differential.test.ts +++ b/packages/env/test/differential.test.ts @@ -324,6 +324,8 @@ describe("RemoteExecutionEnv against NodeExecutionEnv", () => { env, outputWindow: undefined, output: (chunk: string | Uint8Array) => output.push(String(chunk)), + // As the Harness: the output so far (these outputs stay below the tool's limits). + retainedOutput: () => ({ text: output.join(""), truncated: false }), diagnostic: () => {}, details: async () => {}, }) as unknown as ToolExecutionApi; @@ -348,12 +350,17 @@ describe("RemoteExecutionEnv against NodeExecutionEnv", () => { [createReadTool(), { path: "bom.txt" }], [createReadTool(), { path: "bad.txt" }], [createReadTool(), { path: "missing.txt" }], - [createBashTool(), { command: "cat text.txt; echo err >&2; exit 0" }], + // stdout and stderr are separate pipes, read concurrently: their order relative to each other is not fixed, + // so each case writes to one of them. + [createBashTool(), { command: "cat text.txt; exit 0" }], + [createBashTool(), { command: "echo err >&2; exit 0" }], [createBashTool(), { command: "exit 3" }], [createBashTool(), { command: "printf 'a\\nb'; ls" }], ]; for (const [tool, args] of cases) { const expected = normalize(await run(local, tool, args), roots[0]); + // A bash case returns a result (a nonzero exit is an error result): a throw on both sides would compare equal. + if (tool.name === "bash") expect(expected, JSON.stringify(args)).toHaveProperty("result"); const actual = normalize(await run(remote, tool, args), roots[1]); expect(actual, JSON.stringify(args)).toEqual(expected); }