From d38ed0831d7372c8505dc944aea69b5b83da1435 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 24 Apr 2026 10:33:46 +0100 Subject: [PATCH] perf: slim sandbox registry tests --- src/agents/sandbox/registry.test.ts | 137 +++++++++++++--------------- 1 file changed, 61 insertions(+), 76 deletions(-) diff --git a/src/agents/sandbox/registry.test.ts b/src/agents/sandbox/registry.test.ts index a02925e08a1..fd0707849b1 100644 --- a/src/agents/sandbox/registry.test.ts +++ b/src/agents/sandbox/registry.test.ts @@ -1,28 +1,6 @@ import fs from "node:fs/promises"; import { afterAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -const { TEST_STATE_DIR, SANDBOX_REGISTRY_PATH, SANDBOX_BROWSER_REGISTRY_PATH } = vi.hoisted(() => { - const path = require("node:path"); - const { mkdtempSync } = require("node:fs"); - const { tmpdir } = require("node:os"); - const baseDir = mkdtempSync(path.join(tmpdir(), "openclaw-sandbox-registry-")); - - return { - TEST_STATE_DIR: baseDir, - SANDBOX_REGISTRY_PATH: path.join(baseDir, "containers.json"), - SANDBOX_BROWSER_REGISTRY_PATH: path.join(baseDir, "browsers.json"), - }; -}); - -vi.mock("./constants.js", () => ({ - SANDBOX_STATE_DIR: TEST_STATE_DIR, - SANDBOX_REGISTRY_PATH, - SANDBOX_BROWSER_REGISTRY_PATH, -})); - -type SandboxBrowserRegistryEntry = import("./registry.js").SandboxBrowserRegistryEntry; -type SandboxRegistryEntry = import("./registry.js").SandboxRegistryEntry; - type WriteDelayConfig = { targetFile: "containers.json" | "browsers.json"; containerName: string; @@ -31,58 +9,67 @@ type WriteDelayConfig = { waitForRelease: Promise; }; -let activeWriteGate: WriteDelayConfig | null = null; -let readBrowserRegistry: typeof import("./registry.js").readBrowserRegistry; -let readRegistry: typeof import("./registry.js").readRegistry; -let removeBrowserRegistryEntry: typeof import("./registry.js").removeBrowserRegistryEntry; -let removeRegistryEntry: typeof import("./registry.js").removeRegistryEntry; -let updateBrowserRegistry: typeof import("./registry.js").updateBrowserRegistry; -let updateRegistry: typeof import("./registry.js").updateRegistry; +const { TEST_STATE_DIR, SANDBOX_REGISTRY_PATH, SANDBOX_BROWSER_REGISTRY_PATH, writeGateState } = + vi.hoisted(() => { + const path = require("node:path"); + const { mkdtempSync } = require("node:fs"); + const { tmpdir } = require("node:os"); + const baseDir = mkdtempSync(path.join(tmpdir(), "openclaw-sandbox-registry-")); -async function loadFreshRegistryModuleForTest() { - vi.resetModules(); - vi.doMock("./constants.js", () => ({ - SANDBOX_STATE_DIR: TEST_STATE_DIR, - SANDBOX_REGISTRY_PATH, - SANDBOX_BROWSER_REGISTRY_PATH, - })); - vi.doMock("../../infra/json-files.js", async () => { - const actual = await vi.importActual( - "../../infra/json-files.js", - ); return { - ...actual, - writeJsonAtomic: async ( - filePath: string, - value: unknown, - options?: Parameters[2], - ) => { - const payload = JSON.stringify(value); - const gate = activeWriteGate; - if ( - gate && - filePath.includes(gate.targetFile) && - payloadMentionsContainer(payload, gate.containerName) - ) { - if (!gate.started) { - gate.started = true; - gate.markStarted(); - } - await gate.waitForRelease; - } - await actual.writeJsonAtomic(filePath, value, options); - }, + TEST_STATE_DIR: baseDir, + SANDBOX_REGISTRY_PATH: path.join(baseDir, "containers.json"), + SANDBOX_BROWSER_REGISTRY_PATH: path.join(baseDir, "browsers.json"), + writeGateState: { active: null as WriteDelayConfig | null }, }; }); - ({ - readBrowserRegistry, - readRegistry, - removeBrowserRegistryEntry, - removeRegistryEntry, - updateBrowserRegistry, - updateRegistry, - } = await import("./registry.js")); -} + +vi.mock("./constants.js", () => ({ + SANDBOX_STATE_DIR: TEST_STATE_DIR, + SANDBOX_REGISTRY_PATH, + SANDBOX_BROWSER_REGISTRY_PATH, +})); + +vi.mock("../../infra/json-files.js", async () => { + const actual = await vi.importActual( + "../../infra/json-files.js", + ); + return { + ...actual, + writeJsonAtomic: async ( + filePath: string, + value: unknown, + options?: Parameters[2], + ) => { + const payload = JSON.stringify(value); + const gate = writeGateState.active; + if ( + gate && + filePath.includes(gate.targetFile) && + payloadMentionsContainer(payload, gate.containerName) + ) { + if (!gate.started) { + gate.started = true; + gate.markStarted(); + } + await gate.waitForRelease; + } + await actual.writeJsonAtomic(filePath, value, options); + }, + }; +}); + +import { + readBrowserRegistry, + readRegistry, + removeBrowserRegistryEntry, + removeRegistryEntry, + updateBrowserRegistry, + updateRegistry, +} from "./registry.js"; + +type SandboxBrowserRegistryEntry = import("./registry.js").SandboxBrowserRegistryEntry; +type SandboxRegistryEntry = import("./registry.js").SandboxRegistryEntry; function payloadMentionsContainer(payload: string, containerName: string): boolean { return ( @@ -111,7 +98,7 @@ function installWriteGate( const waitForRelease = new Promise((resolve) => { resolveRelease = resolve; }); - activeWriteGate = { + writeGateState.active = { targetFile, containerName, started: false, @@ -122,18 +109,16 @@ function installWriteGate( waitForStart, release: () => { resolveRelease(); - activeWriteGate = null; + writeGateState.active = null; }, }; } -beforeEach(async () => { - activeWriteGate = null; - await loadFreshRegistryModuleForTest(); +beforeEach(() => { + writeGateState.active = null; }); afterEach(async () => { - vi.restoreAllMocks(); await fs.rm(SANDBOX_REGISTRY_PATH, { force: true }); await fs.rm(SANDBOX_BROWSER_REGISTRY_PATH, { force: true }); await fs.rm(`${SANDBOX_REGISTRY_PATH}.lock`, { force: true });