Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { beforeEach, expect, vi, type Mock } from "vitest";
type ExecDockerRawFn = typeof import("./docker.js").execDockerRaw;
type OpenBoundaryFileFn = typeof import("./fs-bridge-path-safety.runtime.js").openBoundaryFile;
type ExecDockerArgs = Parameters<ExecDockerRawFn>[0];
type ExecDockerRawMock = Mock<ExecDockerRawFn>;
type OpenBoundaryFileMock = Mock<OpenBoundaryFileFn>;
type FsBridgeHoisted = {
execDockerRaw: ExecDockerRawMock;
openBoundaryFile: OpenBoundaryFileMock;
};
let actualOpenBoundaryFile: OpenBoundaryFileFn | undefined;
const hoisted = vi.hoisted(
(): FsBridgeHoisted => ({
execDockerRaw: vi.fn(),
openBoundaryFile: vi.fn(),
}),
);
vi.mock("./docker.js", () => ({
execDockerRaw: (args: ExecDockerArgs, opts?: Parameters<ExecDockerRawFn>[1]) =>
hoisted.execDockerRaw(args, opts),
}));
vi.mock("./fs-bridge-path-safety.runtime.js", async () => {
const actual = await vi.importActual<typeof import("./fs-bridge-path-safety.runtime.js")>(
"./fs-bridge-path-safety.runtime.js",
);
actualOpenBoundaryFile = actual.openBoundaryFile;
return {
...actual,
openBoundaryFile: (params: Parameters<OpenBoundaryFileFn>[0]) =>
hoisted.openBoundaryFile(params),
};
});
import { createSandboxTestContext } from "./test-fixtures.js";
import type { SandboxContext } from "./types.js";
let createSandboxFsBridgeImpl: typeof import("./fs-bridge.js").createSandboxFsBridge;
async function loadFreshFsBridgeModuleForTest() {
vi.resetModules();
vi.doMock("./docker.js", () => ({
execDockerRaw: (args: ExecDockerArgs, opts?: Parameters<ExecDockerRawFn>[1]) =>
hoisted.execDockerRaw(args, opts),
}));
vi.doMock("./fs-bridge-path-safety.runtime.js", async () => {
const actual = await vi.importActual<typeof import("./fs-bridge-path-safety.runtime.js")>(
"./fs-bridge-path-safety.runtime.js",
);
actualOpenBoundaryFile = actual.openBoundaryFile;
return {
...actual,
openBoundaryFile: (params: Parameters<OpenBoundaryFileFn>[0]) =>
hoisted.openBoundaryFile(params),
};
});
({ createSandboxFsBridge: createSandboxFsBridgeImpl } = await import("./fs-bridge.js"));
}
export function createSandboxFsBridge(
...args: Parameters<typeof import("./fs-bridge.js").createSandboxFsBridge>
) {
if (!createSandboxFsBridgeImpl) {
throw new Error("fs-bridge test harness not initialized");
}
return createSandboxFsBridgeImpl(...args);
}
export const mockedExecDockerRaw: ExecDockerRawMock = hoisted.execDockerRaw;
export const mockedOpenBoundaryFile: OpenBoundaryFileMock = hoisted.openBoundaryFile;
const DOCKER_SCRIPT_INDEX = 5;
const DOCKER_FIRST_SCRIPT_ARG_INDEX = 7;
export function getDockerScript(args: string[]): string {
return args[DOCKER_SCRIPT_INDEX] ?? "";
}
export function getDockerArg(args: string[], position: number): string {
return args[DOCKER_FIRST_SCRIPT_ARG_INDEX + position - 1] ?? "";
}
export function getDockerPathArg(args: string[]): string {
return getDockerArg(args, 1);
}
export function getScriptsFromCalls(): string[] {
return mockedExecDockerRaw.mock.calls.map(([args]) => getDockerScript(args));
}
export function findCallByScriptFragment(fragment: string) {
return mockedExecDockerRaw.mock.calls.find(([args]) => getDockerScript(args).includes(fragment));
}
export function findCallByDockerArg(position: number, value: string) {
return mockedExecDockerRaw.mock.calls.find(([args]) => getDockerArg(args, position) === value);
}
export function findCallsByScriptFragment(fragment: string) {
return mockedExecDockerRaw.mock.calls.filter(([args]) =>
getDockerScript(args).includes(fragment),
);
}
export function dockerExecResult(stdout: string) {
return {
stdout: Buffer.from(stdout),
stderr: Buffer.alloc(0),
code: 0,
};
}
export function createSandbox(overrides?: Partial<SandboxContext>): SandboxContext {
return createSandboxTestContext({
overrides: {
containerName: "openclaw-sbx-test",
...overrides,
},
dockerOverrides: {
image: "openclaw-sandbox:bookworm-slim",
containerPrefix: "openclaw-sbx-",
},
});
}
export async function createSeededSandboxFsBridge(
stateDir: string,
params?: {
rootFileName?: string;
rootContents?: string;
nestedFileName?: string;
nestedContents?: string;
},
) {
const workspaceDir = path.join(stateDir, "workspace");
await fs.mkdir(path.join(workspaceDir, "nested"), { recursive: true });
await fs.writeFile(
path.join(workspaceDir, params?.rootFileName ?? "from.txt"),
params?.rootContents ?? "hello",
"utf8",
);
await fs.writeFile(
path.join(workspaceDir, "nested", params?.nestedFileName ?? "file.txt"),
params?.nestedContents ?? "bye",
"utf8",
);
const bridge = createSandboxFsBridge({
sandbox: createSandbox({
workspaceDir,
agentWorkspaceDir: workspaceDir,
}),
});
return { workspaceDir, bridge };
}
export async function withTempDir<T>(
prefix: string,
run: (stateDir: string) => Promise<T>,
): Promise<T> {
const stateDir = await fs.mkdtemp(path.join(os.tmpdir(), prefix));
try {
return await run(stateDir);
} finally {
await fs.rm(stateDir, { recursive: true, force: true });
}
}
export function installDockerReadMock(params?: { canonicalPath?: string }) {
const canonicalPath = params?.canonicalPath;
mockedExecDockerRaw.mockImplementation(async (args) => {
const script = getDockerScript(args);
if (script.includes('readlink -f -- "$cursor"')) {
return dockerExecResult(`${canonicalPath ?? getDockerArg(args, 1)}\n`);
}
if (script.includes('stat -c "%F|%s|%Y"')) {
return dockerExecResult("regular file|1|2");
}
if (script.includes('cat -- "$1"')) {
return dockerExecResult("content");
}
if (script.includes("mktemp")) {
return dockerExecResult("/workspace/.openclaw-write-b.txt.ABC123\n");
}
return dockerExecResult("");
});
}
export async function createHostEscapeFixture(stateDir: string) {
const workspaceDir = path.join(stateDir, "workspace");
const outsideDir = path.join(stateDir, "outside");
const outsideFile = path.join(outsideDir, "secret.txt");
await fs.mkdir(workspaceDir, { recursive: true });
await fs.mkdir(outsideDir, { recursive: true });
await fs.writeFile(outsideFile, "classified");
return { workspaceDir, outsideFile };
}
export async function expectMkdirpAllowsExistingDirectory(params?: {
forceBoundaryIoFallback?: boolean;
}) {
await withTempDir("openclaw-fs-bridge-mkdirp-", async (stateDir) => {
const workspaceDir = path.join(stateDir, "workspace");
const nestedDir = path.join(workspaceDir, "memory", "kemik");
await fs.mkdir(nestedDir, { recursive: true });
if (params?.forceBoundaryIoFallback) {
mockedOpenBoundaryFile.mockImplementationOnce(async () => ({
ok: false,
reason: "io",
error: Object.assign(new Error("EISDIR"), { code: "EISDIR" }),
}));
}
const bridge = createSandboxFsBridge({
sandbox: createSandbox({
workspaceDir,
agentWorkspaceDir: workspaceDir,
}),
});
await expect(bridge.mkdirp({ filePath: "memory/kemik" })).resolves.toBeUndefined();
const mkdirCall = mockedExecDockerRaw.mock.calls.find(
([args]) =>
getDockerScript(args).includes("operation = sys.argv[1]") &&
getDockerArg(args, 1) === "mkdirp",
);
expect(mkdirCall).toBeDefined();
const mountRoot = mkdirCall ? getDockerArg(mkdirCall[0], 2) : "";
const relativePath = mkdirCall ? getDockerArg(mkdirCall[0], 3) : "";
expect(mountRoot).toBe("/workspace");
expect(relativePath).toBe("memory/kemik");
});
}
export function installFsBridgeTestHarness() {
beforeEach(async () => {
await loadFreshFsBridgeModuleForTest();
mockedExecDockerRaw.mockClear();
mockedOpenBoundaryFile.mockClear();
if (actualOpenBoundaryFile) {
mockedOpenBoundaryFile.mockImplementation(actualOpenBoundaryFile);
}
installDockerReadMock();
});
}
¤ Dauer der Verarbeitung: 0.24 Sekunden
(vorverarbeitet am 2026-04-27)
¤
*© Formatika GbR, Deutschland
|
|