mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-12 14:40:44 +00:00
test: tighten sandbox registry assertions
This commit is contained in:
@@ -82,6 +82,7 @@ import {
|
||||
|
||||
type SandboxBrowserRegistryEntry = import("./registry.js").SandboxBrowserRegistryEntry;
|
||||
type SandboxRegistryEntry = import("./registry.js").SandboxRegistryEntry;
|
||||
type MigrationResult = Awaited<ReturnType<typeof migrateLegacySandboxRegistryFiles>>[number];
|
||||
|
||||
function payloadMentionsContainer(payload: string, containerName: string): boolean {
|
||||
return (
|
||||
@@ -189,7 +190,24 @@ async function seedStaleLock(lockPath: string) {
|
||||
}
|
||||
|
||||
async function expectPathMissing(targetPath: string): Promise<void> {
|
||||
await expect(fs.access(targetPath)).rejects.toMatchObject({ code: "ENOENT" });
|
||||
try {
|
||||
await fs.access(targetPath);
|
||||
throw new Error(`expected ${targetPath} to be missing`);
|
||||
} catch (error) {
|
||||
const code = error && typeof error === "object" && "code" in error ? error.code : undefined;
|
||||
expect(code).toBe("ENOENT");
|
||||
}
|
||||
}
|
||||
|
||||
function requireMigrationResult(
|
||||
results: readonly MigrationResult[],
|
||||
kind: MigrationResult["kind"],
|
||||
): MigrationResult {
|
||||
const result = results.find((candidate) => candidate.kind === kind);
|
||||
if (!result) {
|
||||
throw new Error(`expected migration result for ${kind}`);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
describe("registry race safety", () => {
|
||||
@@ -214,14 +232,12 @@ describe("registry race safety", () => {
|
||||
|
||||
await migrateLegacySandboxRegistryFiles();
|
||||
const registry = await readRegistry();
|
||||
expect(registry.entries).toEqual([
|
||||
expect.objectContaining({
|
||||
containerName: "legacy-container",
|
||||
backendId: "docker",
|
||||
runtimeLabel: "legacy-container",
|
||||
configLabelKind: "Image",
|
||||
}),
|
||||
]);
|
||||
expect(registry.entries).toHaveLength(1);
|
||||
const [entry] = registry.entries;
|
||||
expect(entry?.containerName).toBe("legacy-container");
|
||||
expect(entry?.backendId).toBe("docker");
|
||||
expect(entry?.runtimeLabel).toBe("legacy-container");
|
||||
expect(entry?.configLabelKind).toBe("Image");
|
||||
});
|
||||
|
||||
it("migrates legacy container and browser registry files after explicit repair", async () => {
|
||||
@@ -245,37 +261,34 @@ describe("registry race safety", () => {
|
||||
await seedStaleLock(`${SANDBOX_REGISTRY_PATH}.lock`);
|
||||
await seedStaleLock(`${SANDBOX_BROWSER_REGISTRY_PATH}.lock`);
|
||||
|
||||
await expect(migrateLegacySandboxRegistryFiles()).resolves.toEqual([
|
||||
expect.objectContaining({ kind: "containers", status: "migrated", entries: 1 }),
|
||||
expect.objectContaining({ kind: "browsers", status: "migrated", entries: 1 }),
|
||||
]);
|
||||
const migrationResults = await migrateLegacySandboxRegistryFiles();
|
||||
const containerMigration = requireMigrationResult(migrationResults, "containers");
|
||||
const browserMigration = requireMigrationResult(migrationResults, "browsers");
|
||||
expect(containerMigration.status).toBe("migrated");
|
||||
expect(containerMigration.entries).toBe(1);
|
||||
expect(browserMigration.status).toBe("migrated");
|
||||
expect(browserMigration.entries).toBe(1);
|
||||
|
||||
await expectPathMissing(SANDBOX_REGISTRY_PATH);
|
||||
await expectPathMissing(SANDBOX_BROWSER_REGISTRY_PATH);
|
||||
await expectPathMissing(`${SANDBOX_REGISTRY_PATH}.lock`);
|
||||
await expectPathMissing(`${SANDBOX_BROWSER_REGISTRY_PATH}.lock`);
|
||||
await expect(readRegistry()).resolves.toEqual({
|
||||
entries: [
|
||||
expect.objectContaining({
|
||||
containerName: "legacy-container",
|
||||
backendId: "docker",
|
||||
runtimeLabel: "legacy-container",
|
||||
sessionKey: "agent:legacy",
|
||||
configHash: "legacy-container-hash",
|
||||
}),
|
||||
],
|
||||
});
|
||||
await expect(readBrowserRegistry()).resolves.toEqual({
|
||||
entries: [
|
||||
expect.objectContaining({
|
||||
containerName: "legacy-browser",
|
||||
sessionKey: "agent:legacy",
|
||||
cdpPort: 9333,
|
||||
noVncPort: 6081,
|
||||
configHash: "legacy-browser-hash",
|
||||
}),
|
||||
],
|
||||
});
|
||||
const containerRegistry = await readRegistry();
|
||||
expect(containerRegistry.entries).toHaveLength(1);
|
||||
const [container] = containerRegistry.entries;
|
||||
expect(container?.containerName).toBe("legacy-container");
|
||||
expect(container?.backendId).toBe("docker");
|
||||
expect(container?.runtimeLabel).toBe("legacy-container");
|
||||
expect(container?.sessionKey).toBe("agent:legacy");
|
||||
expect(container?.configHash).toBe("legacy-container-hash");
|
||||
const browserRegistry = await readBrowserRegistry();
|
||||
expect(browserRegistry.entries).toHaveLength(1);
|
||||
const [browser] = browserRegistry.entries;
|
||||
expect(browser?.containerName).toBe("legacy-browser");
|
||||
expect(browser?.sessionKey).toBe("agent:legacy");
|
||||
expect(browser?.cdpPort).toBe(9333);
|
||||
expect(browser?.noVncPort).toBe(6081);
|
||||
expect(browser?.configHash).toBe("legacy-browser-hash");
|
||||
});
|
||||
|
||||
it("does not overwrite newer sharded entries during legacy migration", async () => {
|
||||
@@ -297,12 +310,8 @@ describe("registry race safety", () => {
|
||||
await migrateLegacySandboxRegistryFiles();
|
||||
|
||||
const entry = await readRegistryEntry("container-a");
|
||||
expect(entry).toEqual(
|
||||
expect.objectContaining({
|
||||
sessionKey: "new-session",
|
||||
lastUsedAtMs: 10,
|
||||
}),
|
||||
);
|
||||
expect(entry?.sessionKey).toBe("new-session");
|
||||
expect(entry?.lastUsedAtMs).toBe(10);
|
||||
});
|
||||
|
||||
it("reads a single sharded entry without scanning the full registry", async () => {
|
||||
@@ -310,12 +319,8 @@ describe("registry race safety", () => {
|
||||
await updateRegistry(containerEntry({ containerName: "container-y", sessionKey: "sess:y" }));
|
||||
|
||||
const entry = await readRegistryEntry("container-x");
|
||||
expect(entry).toEqual(
|
||||
expect.objectContaining({
|
||||
containerName: "container-x",
|
||||
sessionKey: "sess:x",
|
||||
}),
|
||||
);
|
||||
expect(entry?.containerName).toBe("container-x");
|
||||
expect(entry?.sessionKey).toBe("sess:x");
|
||||
await expect(readRegistryEntry("missing-container")).resolves.toBeNull();
|
||||
});
|
||||
|
||||
@@ -424,9 +429,10 @@ describe("registry race safety", () => {
|
||||
const invalidEntries = `{"entries":[{"sessionKey":"agent:main"}]}`;
|
||||
await seedMalformedContainerRegistry(invalidEntries);
|
||||
await seedMalformedBrowserRegistry(invalidEntries);
|
||||
await expect(migrateLegacySandboxRegistryFiles()).resolves.toEqual([
|
||||
expect.objectContaining({ kind: "containers", status: "quarantined-invalid" }),
|
||||
expect.objectContaining({ kind: "browsers", status: "quarantined-invalid" }),
|
||||
]);
|
||||
const migrationResults = await migrateLegacySandboxRegistryFiles();
|
||||
expect(requireMigrationResult(migrationResults, "containers").status).toBe(
|
||||
"quarantined-invalid",
|
||||
);
|
||||
expect(requireMigrationResult(migrationResults, "browsers").status).toBe("quarantined-invalid");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user