test: stabilize sandbox/doctor tests

This commit is contained in:
Peter Steinberger
2026-01-09 15:17:10 +01:00
parent fc7580ab5e
commit 2c5ec94843
3 changed files with 87 additions and 75 deletions

View File

@@ -52,35 +52,39 @@ describe("Agent-specific sandbox config", () => {
spawnCalls.length = 0; spawnCalls.length = 0;
}); });
it("should use global sandbox config when no agent-specific config exists", async () => { it(
const { resolveSandboxContext } = await import("./sandbox.js"); "should use global sandbox config when no agent-specific config exists",
{ timeout: 15_000 },
async () => {
const { resolveSandboxContext } = await import("./sandbox.js");
const cfg: ClawdbotConfig = { const cfg: ClawdbotConfig = {
agents: { agents: {
defaults: { defaults: {
sandbox: { sandbox: {
mode: "all", mode: "all",
scope: "agent", scope: "agent",
},
}, },
list: [
{
id: "main",
workspace: "~/clawd",
},
],
}, },
list: [ };
{
id: "main",
workspace: "~/clawd",
},
],
},
};
const context = await resolveSandboxContext({ const context = await resolveSandboxContext({
config: cfg, config: cfg,
sessionKey: "agent:main:main", sessionKey: "agent:main:main",
workspaceDir: "/tmp/test", workspaceDir: "/tmp/test",
}); });
expect(context).toBeDefined(); expect(context).toBeDefined();
expect(context?.enabled).toBe(true); expect(context?.enabled).toBe(true);
}); },
);
it("should allow agent-specific docker setupCommand overrides", async () => { it("should allow agent-specific docker setupCommand overrides", async () => {
const { resolveSandboxContext } = await import("./sandbox.js"); const { resolveSandboxContext } = await import("./sandbox.js");

View File

@@ -1,16 +1,20 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
describe("sandbox config merges", () => { describe("sandbox config merges", () => {
it("resolves sandbox scope deterministically", async () => { it(
const { resolveSandboxScope } = await import("./sandbox.js"); "resolves sandbox scope deterministically",
{ timeout: 15_000 },
async () => {
const { resolveSandboxScope } = await import("./sandbox.js");
expect(resolveSandboxScope({})).toBe("agent"); expect(resolveSandboxScope({})).toBe("agent");
expect(resolveSandboxScope({ perSession: true })).toBe("session"); expect(resolveSandboxScope({ perSession: true })).toBe("session");
expect(resolveSandboxScope({ perSession: false })).toBe("shared"); expect(resolveSandboxScope({ perSession: false })).toBe("shared");
expect(resolveSandboxScope({ perSession: true, scope: "agent" })).toBe( expect(resolveSandboxScope({ perSession: true, scope: "agent" })).toBe(
"agent", "agent",
); );
}); },
);
it("merges sandbox docker env and ulimits (agent wins)", async () => { it("merges sandbox docker env and ulimits (agent wins)", async () => {
const { resolveSandboxDockerConfig } = await import("./sandbox.js"); const { resolveSandboxDockerConfig } = await import("./sandbox.js");

View File

@@ -244,52 +244,56 @@ vi.mock("./doctor-state-migrations.js", () => ({
})); }));
describe("doctor", () => { describe("doctor", () => {
it("migrates routing.allowFrom to whatsapp.allowFrom", async () => { it(
readConfigFileSnapshot.mockResolvedValue({ "migrates routing.allowFrom to whatsapp.allowFrom",
path: "/tmp/clawdbot.json", { timeout: 15_000 },
exists: true, async () => {
raw: "{}", readConfigFileSnapshot.mockResolvedValue({
parsed: { routing: { allowFrom: ["+15555550123"] } }, path: "/tmp/clawdbot.json",
valid: false, exists: true,
config: {}, raw: "{}",
issues: [ parsed: { routing: { allowFrom: ["+15555550123"] } },
{ valid: false,
path: "routing.allowFrom", config: {},
message: "legacy", issues: [
}, {
], path: "routing.allowFrom",
legacyIssues: [ message: "legacy",
{ },
path: "routing.allowFrom", ],
message: "legacy", legacyIssues: [
}, {
], path: "routing.allowFrom",
}); message: "legacy",
},
],
});
const { doctorCommand } = await import("./doctor.js"); const { doctorCommand } = await import("./doctor.js");
const runtime = { const runtime = {
log: vi.fn(), log: vi.fn(),
error: vi.fn(), error: vi.fn(),
exit: vi.fn(), exit: vi.fn(),
}; };
migrateLegacyConfig.mockReturnValue({ migrateLegacyConfig.mockReturnValue({
config: { whatsapp: { allowFrom: ["+15555550123"] } }, config: { whatsapp: { allowFrom: ["+15555550123"] } },
changes: ["Moved routing.allowFrom → whatsapp.allowFrom."], changes: ["Moved routing.allowFrom → whatsapp.allowFrom."],
}); });
await doctorCommand(runtime, { nonInteractive: true }); await doctorCommand(runtime, { nonInteractive: true });
expect(writeConfigFile).toHaveBeenCalledTimes(1); expect(writeConfigFile).toHaveBeenCalledTimes(1);
const written = writeConfigFile.mock.calls[0]?.[0] as Record< const written = writeConfigFile.mock.calls[0]?.[0] as Record<
string, string,
unknown unknown
>; >;
expect((written.whatsapp as Record<string, unknown>)?.allowFrom).toEqual([ expect((written.whatsapp as Record<string, unknown>)?.allowFrom).toEqual([
"+15555550123", "+15555550123",
]); ]);
expect(written.routing).toBeUndefined(); expect(written.routing).toBeUndefined();
}); },
);
it("migrates legacy Clawdis services", async () => { it("migrates legacy Clawdis services", async () => {
readConfigFileSnapshot.mockResolvedValue({ readConfigFileSnapshot.mockResolvedValue({