






















@@ -1,28 +1,6 @@
11import fs from "node:fs/promises";
22import { afterAll, afterEach, beforeEach, describe, expect, it, vi } from "vitest";
334-const { TEST_STATE_DIR, SANDBOX_REGISTRY_PATH, SANDBOX_BROWSER_REGISTRY_PATH } = vi.hoisted(() => {
5-const path = require("node:path");
6-const { mkdtempSync } = require("node:fs");
7-const { tmpdir } = require("node:os");
8-const baseDir = mkdtempSync(path.join(tmpdir(), "openclaw-sandbox-registry-"));
9-10-return {
11-TEST_STATE_DIR: baseDir,
12-SANDBOX_REGISTRY_PATH: path.join(baseDir, "containers.json"),
13-SANDBOX_BROWSER_REGISTRY_PATH: path.join(baseDir, "browsers.json"),
14-};
15-});
16-17-vi.mock("./constants.js", () => ({
18-SANDBOX_STATE_DIR: TEST_STATE_DIR,
19-SANDBOX_REGISTRY_PATH,
20-SANDBOX_BROWSER_REGISTRY_PATH,
21-}));
22-23-type SandboxBrowserRegistryEntry = import("./registry.js").SandboxBrowserRegistryEntry;
24-type SandboxRegistryEntry = import("./registry.js").SandboxRegistryEntry;
25-264type WriteDelayConfig = {
275targetFile: "containers.json" | "browsers.json";
286containerName: string;
@@ -31,58 +9,67 @@ type WriteDelayConfig = {
319waitForRelease: Promise<void>;
3210};
331134-let activeWriteGate: WriteDelayConfig | null = null;
35-let readBrowserRegistry: typeof import("./registry.js").readBrowserRegistry;
36-let readRegistry: typeof import("./registry.js").readRegistry;
37-let removeBrowserRegistryEntry: typeof import("./registry.js").removeBrowserRegistryEntry;
38-let removeRegistryEntry: typeof import("./registry.js").removeRegistryEntry;
39-let updateBrowserRegistry: typeof import("./registry.js").updateBrowserRegistry;
40-let updateRegistry: typeof import("./registry.js").updateRegistry;
41-42-async function loadFreshRegistryModuleForTest() {
43-vi.resetModules();
44-vi.doMock("./constants.js", () => ({
45-SANDBOX_STATE_DIR: TEST_STATE_DIR,
46-SANDBOX_REGISTRY_PATH,
47-SANDBOX_BROWSER_REGISTRY_PATH,
48-}));
49-vi.doMock("../../infra/json-files.js", async () => {
50-const actual = await vi.importActual<typeof import("../../infra/json-files.js")>(
51-"../../infra/json-files.js",
52-);
12+const { TEST_STATE_DIR, SANDBOX_REGISTRY_PATH, SANDBOX_BROWSER_REGISTRY_PATH, writeGateState } =
13+vi.hoisted(() => {
14+const path = require("node:path");
15+const { mkdtempSync } = require("node:fs");
16+const { tmpdir } = require("node:os");
17+const baseDir = mkdtempSync(path.join(tmpdir(), "openclaw-sandbox-registry-"));
18+5319return {
54- ...actual,
55-writeJsonAtomic: async (
56-filePath: string,
57-value: unknown,
58-options?: Parameters<typeof actual.writeJsonAtomic>[2],
59-) => {
60-const payload = JSON.stringify(value);
61-const gate = activeWriteGate;
62-if (
63-gate &&
64-filePath.includes(gate.targetFile) &&
65-payloadMentionsContainer(payload, gate.containerName)
66-) {
67-if (!gate.started) {
68-gate.started = true;
69-gate.markStarted();
70-}
71-await gate.waitForRelease;
72-}
73-await actual.writeJsonAtomic(filePath, value, options);
74-},
20+TEST_STATE_DIR: baseDir,
21+SANDBOX_REGISTRY_PATH: path.join(baseDir, "containers.json"),
22+SANDBOX_BROWSER_REGISTRY_PATH: path.join(baseDir, "browsers.json"),
23+writeGateState: { active: null as WriteDelayConfig | null },
7524};
7625});
77-({
78- readBrowserRegistry,
79- readRegistry,
80- removeBrowserRegistryEntry,
81- removeRegistryEntry,
82- updateBrowserRegistry,
83- updateRegistry,
84-} = await import("./registry.js"));
85-}
26+27+vi.mock("./constants.js", () => ({
28+SANDBOX_STATE_DIR: TEST_STATE_DIR,
29+SANDBOX_REGISTRY_PATH,
30+SANDBOX_BROWSER_REGISTRY_PATH,
31+}));
32+33+vi.mock("../../infra/json-files.js", async () => {
34+const actual = await vi.importActual<typeof import("../../infra/json-files.js")>(
35+"../../infra/json-files.js",
36+);
37+return {
38+ ...actual,
39+writeJsonAtomic: async (
40+filePath: string,
41+value: unknown,
42+options?: Parameters<typeof actual.writeJsonAtomic>[2],
43+) => {
44+const payload = JSON.stringify(value);
45+const gate = writeGateState.active;
46+if (
47+gate &&
48+filePath.includes(gate.targetFile) &&
49+payloadMentionsContainer(payload, gate.containerName)
50+) {
51+if (!gate.started) {
52+gate.started = true;
53+gate.markStarted();
54+}
55+await gate.waitForRelease;
56+}
57+await actual.writeJsonAtomic(filePath, value, options);
58+},
59+};
60+});
61+62+import {
63+readBrowserRegistry,
64+readRegistry,
65+removeBrowserRegistryEntry,
66+removeRegistryEntry,
67+updateBrowserRegistry,
68+updateRegistry,
69+} from "./registry.js";
70+71+type SandboxBrowserRegistryEntry = import("./registry.js").SandboxBrowserRegistryEntry;
72+type SandboxRegistryEntry = import("./registry.js").SandboxRegistryEntry;
86738774function payloadMentionsContainer(payload: string, containerName: string): boolean {
8875return (
@@ -111,7 +98,7 @@ function installWriteGate(
11198const waitForRelease = new Promise<void>((resolve) => {
11299resolveRelease = resolve;
113100});
114-activeWriteGate = {
101+writeGateState.active = {
115102 targetFile,
116103 containerName,
117104started: false,
@@ -122,18 +109,16 @@ function installWriteGate(
122109 waitForStart,
123110release: () => {
124111resolveRelease();
125-activeWriteGate = null;
112+writeGateState.active = null;
126113},
127114};
128115}
129116130-beforeEach(async () => {
131-activeWriteGate = null;
132-await loadFreshRegistryModuleForTest();
117+beforeEach(() => {
118+writeGateState.active = null;
133119});
134120135121afterEach(async () => {
136-vi.restoreAllMocks();
137122await fs.rm(SANDBOX_REGISTRY_PATH, { force: true });
138123await fs.rm(SANDBOX_BROWSER_REGISTRY_PATH, { force: true });
139124await fs.rm(`${SANDBOX_REGISTRY_PATH}.lock`, { force: true });
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。