test(codex): clean goal fixtures after setup failures

This commit is contained in:
paseo-bot[bot]
2026-10-13 11:03:17 +02:00
parent da5e8fbce3
commit 060d521340
2 changed files with 90 additions and 69 deletions
@@ -5,7 +5,7 @@ import path from "node:path";
import { expect, test } from "vitest";
import { createTestLogger } from "../../../test-utils/test-logger.js";
import { CodexAppServerAgentClient } from "./codex-app-server-agent.js";
import type { AgentStreamEvent } from "../agent-sdk-types.js";
import type { AgentSession, AgentStreamEvent } from "../agent-sdk-types.js";
// Native Codex owns goals; the fixture supplies inference responses only.
test("records all four /goal commands as user edits in the next model request", async () => {
@@ -45,6 +45,8 @@ test("records all four /goal commands as user edits in the next model request",
});
}
const server = createServer(handleRequest);
let session: AgentSession | null = null;
try {
server.listen(0, "127.0.0.1");
await once(server, "listening");
const address = server.address();
@@ -70,7 +72,7 @@ stream_max_retries = 0
`,
);
const client = new CodexAppServerAgentClient(createTestLogger(), { env: { CODEX_HOME: root } });
const session = await client.createSession({
session = await client.createSession({
provider: "codex",
cwd: root,
model: "gpt-6.1-sol",
@@ -82,7 +84,9 @@ stream_max_retries = 0
if (["turn_completed", "turn_canceled", "turn_failed"].includes(event.type)) active = false;
});
try {
expect((await session.listCommands?.())?.some((command) => command.name === "goal")).toBe(true);
expect((await session.listCommands?.())?.some((command) => command.name === "goal")).toBe(
true,
);
for (const command of [
"/goal AUDIT_GOAL: summarize local evidence",
"/goal pause",
@@ -104,7 +108,9 @@ stream_max_retries = 0
);
}
await expect.poll(() => active, { timeout: 30_000 }).toBe(false);
expect((await session.run("PROBE_AFTER_GOAL_CLEAR")).finalText).toBe("LOCAL_FIXTURE_RESPONSE");
expect((await session.run("PROBE_AFTER_GOAL_CLEAR")).finalText).toBe(
"LOCAL_FIXTURE_RESPONSE",
);
const body = JSON.parse(requests.at(-1)!);
const goalContext = body.input
.filter((item: { role: string }) => item.role === "user")
@@ -119,10 +125,20 @@ stream_max_retries = 0
expect(goalContext).toContain("User cleared the goal.");
} finally {
unsubscribe();
await session.close();
}
} finally {
try {
await session?.close();
} finally {
try {
server.closeAllConnections();
if (server.listening) {
server.close();
await once(server, "close");
}
} finally {
rmSync(root, { recursive: true, force: true });
}
}
}
}, 60_000);
@@ -4,6 +4,7 @@ import { expect, test } from "vitest";
import { createTestLogger } from "../../../test-utils/test-logger.js";
import { CodexAppServerAgentClient } from "./codex-app-server-agent.js";
import type { AgentSession } from "../agent-sdk-types.js";
// A protocol peer exercises the public session interface without a Codex install.
test("marks set, pause, resume and clear as user goal mutations", async () => {
@@ -35,13 +36,14 @@ readline.createInterface({ input: process.stdin }).on("line", (line) => {
command: { mode: "replace", argv: [process.execPath, script] },
env: { CODEX_HOME: root, CAPTURE: capture },
});
const session = await client.createSession({
let session: AgentSession | null = null;
try {
session = await client.createSession({
provider: "codex",
cwd: root,
model: "test-model",
thinkingOptionId: "low",
});
try {
for (const command of ["/goal ship feature", "/goal pause", "/goal resume", "/goal clear"]) {
const handler = session.tryHandleOutOfBand?.(command);
if (!handler) throw new Error(`Missing handler for ${command}`);
@@ -73,7 +75,10 @@ readline.createInterface({ input: process.stdin }).on("line", (line) => {
{ method: "thread/goal/clear", params: { threadId: "goal-thread", origin: "user" } },
]);
} finally {
await session.close();
try {
await session?.close();
} finally {
rmSync(root, { recursive: true, force: true });
}
}
});