mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 14:28:27 +00:00
Merged via /review-pr -> /prepare-pr -> /merge-pr.
Prepared head SHA: 795ec6aa2f
Co-authored-by: davidbors-snyk <240482518+davidbors-snyk@users.noreply.github.com>
Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
Reviewed-by: @steipete
89 lines
2.6 KiB
TypeScript
89 lines
2.6 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
vi.mock("./docker.js", () => ({
|
|
execDockerRaw: vi.fn(),
|
|
}));
|
|
|
|
import type { SandboxContext } from "./types.js";
|
|
import { execDockerRaw } from "./docker.js";
|
|
import { createSandboxFsBridge } from "./fs-bridge.js";
|
|
|
|
const mockedExecDockerRaw = vi.mocked(execDockerRaw);
|
|
|
|
const sandbox: SandboxContext = {
|
|
enabled: true,
|
|
sessionKey: "sandbox:test",
|
|
workspaceDir: "/tmp/workspace",
|
|
agentWorkspaceDir: "/tmp/workspace",
|
|
workspaceAccess: "rw",
|
|
containerName: "moltbot-sbx-test",
|
|
containerWorkdir: "/workspace",
|
|
docker: {
|
|
image: "moltbot-sandbox:bookworm-slim",
|
|
containerPrefix: "moltbot-sbx-",
|
|
network: "none",
|
|
user: "1000:1000",
|
|
workdir: "/workspace",
|
|
readOnlyRoot: false,
|
|
tmpfs: [],
|
|
capDrop: [],
|
|
seccompProfile: "",
|
|
apparmorProfile: "",
|
|
setupCommand: "",
|
|
binds: [],
|
|
dns: [],
|
|
extraHosts: [],
|
|
pidsLimit: 0,
|
|
},
|
|
tools: { allow: ["*"], deny: [] },
|
|
browserAllowHostControl: false,
|
|
};
|
|
|
|
describe("sandbox fs bridge shell compatibility", () => {
|
|
beforeEach(() => {
|
|
mockedExecDockerRaw.mockReset();
|
|
mockedExecDockerRaw.mockImplementation(async (args) => {
|
|
const script = args[5] ?? "";
|
|
if (script.includes('stat -c "%F|%s|%Y"')) {
|
|
return {
|
|
stdout: Buffer.from("regular file|1|2"),
|
|
stderr: Buffer.alloc(0),
|
|
code: 0,
|
|
};
|
|
}
|
|
if (script.includes('cat -- "$1"')) {
|
|
return {
|
|
stdout: Buffer.from("content"),
|
|
stderr: Buffer.alloc(0),
|
|
code: 0,
|
|
};
|
|
}
|
|
return {
|
|
stdout: Buffer.alloc(0),
|
|
stderr: Buffer.alloc(0),
|
|
code: 0,
|
|
};
|
|
});
|
|
});
|
|
|
|
it("uses POSIX-safe shell prologue in all bridge commands", async () => {
|
|
const bridge = createSandboxFsBridge({ sandbox });
|
|
|
|
await bridge.readFile({ filePath: "a.txt" });
|
|
await bridge.writeFile({ filePath: "b.txt", data: "hello" });
|
|
await bridge.mkdirp({ filePath: "nested" });
|
|
await bridge.remove({ filePath: "b.txt" });
|
|
await bridge.rename({ from: "a.txt", to: "c.txt" });
|
|
await bridge.stat({ filePath: "c.txt" });
|
|
|
|
expect(mockedExecDockerRaw).toHaveBeenCalled();
|
|
|
|
const scripts = mockedExecDockerRaw.mock.calls.map(([args]) => args[5] ?? "");
|
|
const executables = mockedExecDockerRaw.mock.calls.map(([args]) => args[3] ?? "");
|
|
|
|
expect(executables.every((shell) => shell === "sh")).toBe(true);
|
|
expect(scripts.every((script) => script.includes("set -eu;"))).toBe(true);
|
|
expect(scripts.some((script) => script.includes("pipefail"))).toBe(false);
|
|
});
|
|
});
|