





















@@ -172,6 +172,22 @@ async function seedContainerRegistry(entries: SandboxRegistryEntry[]) {
172172await fs.writeFile(SANDBOX_REGISTRY_PATH, `${JSON.stringify({ entries }, null, 2)}\n`, "utf-8");
173173}
174174175+async function seedBrowserRegistry(entries: SandboxBrowserRegistryEntry[]) {
176+await fs.writeFile(
177+SANDBOX_BROWSER_REGISTRY_PATH,
178+`${JSON.stringify({ entries }, null, 2)}\n`,
179+"utf-8",
180+);
181+}
182+183+async function seedStaleLock(lockPath: string) {
184+await fs.writeFile(
185+lockPath,
186+`${JSON.stringify({ pid: 999_999_999, createdAt: "2000-01-01T00:00:00.000Z" })}\n`,
187+"utf-8",
188+);
189+}
190+175191describe("registry race safety", () => {
176192it("does not migrate legacy registry files from runtime reads", async () => {
177193await seedContainerRegistry([containerEntry({ containerName: "legacy-container" })]);
@@ -204,6 +220,60 @@ describe("registry race safety", () => {
204220]);
205221});
206222223+it("migrates legacy container and browser registry files after explicit repair", async () => {
224+await seedContainerRegistry([
225+containerEntry({
226+containerName: "legacy-container",
227+sessionKey: "agent:legacy",
228+lastUsedAtMs: 7,
229+configHash: "legacy-container-hash",
230+}),
231+]);
232+await seedBrowserRegistry([
233+browserEntry({
234+containerName: "legacy-browser",
235+sessionKey: "agent:legacy",
236+cdpPort: 9333,
237+noVncPort: 6081,
238+configHash: "legacy-browser-hash",
239+}),
240+]);
241+await seedStaleLock(`${SANDBOX_REGISTRY_PATH}.lock`);
242+await seedStaleLock(`${SANDBOX_BROWSER_REGISTRY_PATH}.lock`);
243+244+await expect(migrateLegacySandboxRegistryFiles()).resolves.toEqual([
245+expect.objectContaining({ kind: "containers", status: "migrated", entries: 1 }),
246+expect.objectContaining({ kind: "browsers", status: "migrated", entries: 1 }),
247+]);
248+249+await expect(fs.access(SANDBOX_REGISTRY_PATH)).rejects.toThrow();
250+await expect(fs.access(SANDBOX_BROWSER_REGISTRY_PATH)).rejects.toThrow();
251+await expect(fs.access(`${SANDBOX_REGISTRY_PATH}.lock`)).rejects.toThrow();
252+await expect(fs.access(`${SANDBOX_BROWSER_REGISTRY_PATH}.lock`)).rejects.toThrow();
253+await expect(readRegistry()).resolves.toEqual({
254+entries: [
255+expect.objectContaining({
256+containerName: "legacy-container",
257+backendId: "docker",
258+runtimeLabel: "legacy-container",
259+sessionKey: "agent:legacy",
260+configHash: "legacy-container-hash",
261+}),
262+],
263+});
264+await expect(readBrowserRegistry()).resolves.toEqual({
265+entries: [
266+expect.objectContaining({
267+containerName: "legacy-browser",
268+sessionKey: "agent:legacy",
269+cdpPort: 9333,
270+noVncPort: 6081,
271+configHash: "legacy-browser-hash",
272+}),
273+],
274+});
275+});
276+207277it("does not overwrite newer sharded entries during legacy migration", async () => {
208278await updateRegistry(
209279containerEntry({
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。