From cdebe0e138604daea57cc0fd1cc8611852aa95b1 Mon Sep 17 00:00:00 2001 From: Yuxin Qiao <104957188+Yuxin-Qiao@users.noreply.github.com> Date: Tue, 4 Aug 2026 17:53:54 +0800 Subject: [PATCH 1/2] fix(test): isolate usage-log fixtures from the real OpenCodex home --- tests/management-api-logs-metrics.test.ts | 24 +++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/management-api-logs-metrics.test.ts b/tests/management-api-logs-metrics.test.ts index b24b9e6d3b..9c94e3073c 100644 --- a/tests/management-api-logs-metrics.test.ts +++ b/tests/management-api-logs-metrics.test.ts @@ -1,4 +1,7 @@ -import { afterEach, describe, expect, test } from "bun:test"; +import { afterEach, beforeEach, describe, expect, test } from "bun:test"; +import { mkdtempSync, rmSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; import { handleManagementAPI } from "../src/server/management-api"; import { addRequestLog, @@ -10,7 +13,24 @@ import type { OcxConfig } from "../src/types"; const config = { providers: [] } as unknown as OcxConfig; -afterEach(() => clearRequestLogsForTests()); +let testDir = ""; +let previousHome: string | undefined; + +beforeEach(() => { + // addRequestLog persists to usage.jsonl; without a scratch OPENCODEX_HOME a bare + // `bun test ` run from outside the repo (no bunfig preload) writes these + // fixture rows into the real ~/.opencodex log and poisons the GUI Usage page. + previousHome = process.env.OPENCODEX_HOME; + testDir = mkdtempSync(join(tmpdir(), "ocx-logs-metrics-")); + process.env.OPENCODEX_HOME = testDir; +}); + +afterEach(() => { + clearRequestLogsForTests(); + if (previousHome === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = previousHome; + if (testDir) rmSync(testDir, { recursive: true, force: true }); +}); async function readLogs(): Promise>> { const url = new URL("http://localhost/api/logs"); From 3304d5c8336e2ade3ac519973663a48b493ca5c1 Mon Sep 17 00:00:00 2001 From: Yuxin Qiao <104957188+Yuxin-Qiao@users.noreply.github.com> Date: Thu, 6 Aug 2026 20:02:30 +0800 Subject: [PATCH 2/2] test: pin usage-log fixture writes to the scratch home --- tests/management-api-logs-metrics.test.ts | 31 ++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/tests/management-api-logs-metrics.test.ts b/tests/management-api-logs-metrics.test.ts index 9c94e3073c..f7077a8951 100644 --- a/tests/management-api-logs-metrics.test.ts +++ b/tests/management-api-logs-metrics.test.ts @@ -1,8 +1,9 @@ import { afterEach, beforeEach, describe, expect, test } from "bun:test"; -import { mkdtempSync, rmSync } from "node:fs"; +import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { handleManagementAPI } from "../src/server/management-api"; +import { usageLogPath } from "../src/usage/log"; import { addRequestLog, clearRequestLogsForTests, @@ -174,5 +175,33 @@ describe("GET /api/logs display metrics", () => { const [dto] = await readLogs(); expect(dto!.displayMetrics.cost).toEqual({ kind: "unavailable", reason: "invalid_cache_breakdown" }); }); + + test("fixture usage rows land in the scratch home, never the default location", () => { + // Pins the safety property this file's isolation exists for: addRequestLog + // persists to usage.jsonl, so if the scratch-home hook is ever dropped (or a + // future test logs before it runs), a bare `bun test ` from outside the + // repo writes fixture rows into the developer's real ~/.opencodex log. + const requestId = "safety-pin-usage-log-target"; + addRequestLog(baseEntry({ requestId })); + + const resolvedTarget = usageLogPath(); + expect(resolvedTarget).toBe(join(testDir, "usage.jsonl")); + expect(readFileSync(resolvedTarget, "utf-8")).toContain(requestId); + + // The default location (what the resolver returns with no OPENCODEX_HOME + // override) must never be the write target for this suite. + const previousHome = process.env.OPENCODEX_HOME; + delete process.env.OPENCODEX_HOME; + try { + const defaultTarget = usageLogPath(); + expect(defaultTarget).not.toBe(resolvedTarget); + if (existsSync(defaultTarget)) { + expect(readFileSync(defaultTarget, "utf-8")).not.toContain(requestId); + } + } finally { + if (previousHome === undefined) delete process.env.OPENCODEX_HOME; + else process.env.OPENCODEX_HOME = previousHome; + } + }); }); import { ManagementRequest as Request } from "./helpers/management-auth";