test(FN-4636): complete Step 5 — add sandbox wiring integration coverage
Fusion-Task-Id: FN-4636 Fusion-Task-Lineage: 38ff2f48-4cb1-42c2-8f64-eb3b8d3d7f2c
This commit is contained in:
122
packages/engine/src/__tests__/sandbox-wiring.test.ts
Normal file
122
packages/engine/src/__tests__/sandbox-wiring.test.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import { __runConfiguredCommandForTests } from "../executor.js";
|
||||
import { __executePostMergeScriptStepForTests } from "../merger.js";
|
||||
import { RoutineRunner } from "../routine-runner.js";
|
||||
import { defaultShell } from "../shell-utils.js";
|
||||
import {
|
||||
__resetSandboxBackendForTests,
|
||||
__setSandboxBackendForTests,
|
||||
type SandboxBackend,
|
||||
} from "../sandbox/index.js";
|
||||
|
||||
describe("sandbox wiring", () => {
|
||||
afterEach(() => {
|
||||
__resetSandboxBackendForTests();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("routes executor runConfiguredCommand through sandbox backend", async () => {
|
||||
const run = vi.fn().mockResolvedValue({
|
||||
stdout: "out",
|
||||
stderr: "err",
|
||||
exitCode: 23,
|
||||
signal: "SIGTERM",
|
||||
timedOut: true,
|
||||
bufferExceeded: true,
|
||||
spawnError: new Error("spawn"),
|
||||
});
|
||||
const stub: SandboxBackend = {
|
||||
capabilities: () => ({ id: "native", supportsNetworkPolicy: false, supportsFilesystemPolicy: false, platform: "any" }),
|
||||
prepare: async () => {},
|
||||
run,
|
||||
dispose: async () => {},
|
||||
};
|
||||
__setSandboxBackendForTests(stub);
|
||||
|
||||
const result = await __runConfiguredCommandForTests("echo hi", "/tmp", 1200, { A: "1" });
|
||||
|
||||
expect(run).toHaveBeenCalledTimes(1);
|
||||
expect(run).toHaveBeenCalledWith("echo hi", {
|
||||
cwd: "/tmp",
|
||||
timeoutMs: 1200,
|
||||
maxBuffer: 10 * 1024 * 1024,
|
||||
encoding: "utf-8",
|
||||
env: { A: "1" },
|
||||
});
|
||||
expect(result).toMatchObject({
|
||||
stdout: "out",
|
||||
stderr: "err",
|
||||
exitCode: 23,
|
||||
signal: "SIGTERM",
|
||||
timedOut: true,
|
||||
bufferExceeded: true,
|
||||
});
|
||||
expect(result.spawnError).toBeInstanceOf(Error);
|
||||
});
|
||||
|
||||
it("routes merger executePostMergeScriptStep through sandbox backend", async () => {
|
||||
const run = vi.fn().mockResolvedValue({
|
||||
stdout: "",
|
||||
stderr: "",
|
||||
exitCode: 0,
|
||||
signal: null,
|
||||
timedOut: false,
|
||||
bufferExceeded: false,
|
||||
});
|
||||
__setSandboxBackendForTests({
|
||||
capabilities: () => ({ id: "native", supportsNetworkPolicy: false, supportsFilesystemPolicy: false, platform: "any" }),
|
||||
prepare: async () => {},
|
||||
run,
|
||||
dispose: async () => {},
|
||||
});
|
||||
|
||||
const result = await __executePostMergeScriptStepForTests(
|
||||
{ updateTask: vi.fn() } as any,
|
||||
"FN-1",
|
||||
{ scriptName: "post" } as any,
|
||||
"/tmp/worktree",
|
||||
{ scripts: { post: "echo post" } } as any,
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(run).toHaveBeenCalledWith("echo post", {
|
||||
cwd: "/tmp/worktree",
|
||||
encoding: "utf-8",
|
||||
timeoutMs: 120_000,
|
||||
maxBuffer: 10 * 1024 * 1024,
|
||||
});
|
||||
});
|
||||
|
||||
it("routes routine runner command branch through sandbox backend", async () => {
|
||||
const run = vi.fn().mockResolvedValue({
|
||||
stdout: "routine",
|
||||
stderr: "",
|
||||
exitCode: 0,
|
||||
signal: null,
|
||||
timedOut: false,
|
||||
bufferExceeded: false,
|
||||
});
|
||||
__setSandboxBackendForTests({
|
||||
capabilities: () => ({ id: "native", supportsNetworkPolicy: false, supportsFilesystemPolicy: false, platform: "any" }),
|
||||
prepare: async () => {},
|
||||
run,
|
||||
dispose: async () => {},
|
||||
});
|
||||
|
||||
const runner = new RoutineRunner({
|
||||
routineStore: {} as any,
|
||||
heartbeatMonitor: {} as any,
|
||||
rootDir: "/tmp/root",
|
||||
});
|
||||
|
||||
const result = await (runner as any).executeCommand("echo routine", 5000, new Date().toISOString());
|
||||
expect(result.success).toBe(true);
|
||||
expect(run).toHaveBeenCalledWith("echo routine", {
|
||||
cwd: "/tmp/root",
|
||||
timeoutMs: 5000,
|
||||
maxBuffer: 1024 * 1024,
|
||||
shell: defaultShell,
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -365,11 +365,8 @@ function configuredCommandErrorMessage(result: RunCommandResult): string {
|
||||
return parts.length ? parts.join("\n") : "Command failed";
|
||||
}
|
||||
|
||||
let configuredCommandSandboxBackend: SandboxBackend | null = null;
|
||||
|
||||
function getConfiguredCommandSandboxBackend(): SandboxBackend {
|
||||
configuredCommandSandboxBackend ??= resolveSandboxBackend();
|
||||
return configuredCommandSandboxBackend;
|
||||
return resolveSandboxBackend();
|
||||
}
|
||||
|
||||
async function runConfiguredCommand(
|
||||
|
||||
@@ -8938,11 +8938,8 @@ async function runPostMergeWorkflowSteps(
|
||||
}
|
||||
}
|
||||
|
||||
let postMergeScriptSandboxBackend: SandboxBackend | null = null;
|
||||
|
||||
function getPostMergeScriptSandboxBackend(): SandboxBackend {
|
||||
postMergeScriptSandboxBackend ??= resolveSandboxBackend();
|
||||
return postMergeScriptSandboxBackend;
|
||||
return resolveSandboxBackend();
|
||||
}
|
||||
|
||||
/** Execute a script-mode post-merge workflow step in the provided execution directory. */
|
||||
|
||||
@@ -32,11 +32,8 @@ const DEFAULT_TIMEOUT_MS = 5 * 60 * 1000;
|
||||
const MAX_BUFFER = 1024 * 1024;
|
||||
const MAX_OUTPUT_LENGTH = 10 * 1024;
|
||||
|
||||
let routineCommandSandboxBackend: SandboxBackend | null = null;
|
||||
|
||||
function getRoutineCommandSandboxBackend(): SandboxBackend {
|
||||
routineCommandSandboxBackend ??= resolveSandboxBackend();
|
||||
return routineCommandSandboxBackend;
|
||||
return resolveSandboxBackend();
|
||||
}
|
||||
|
||||
/** Options for RoutineRunner constructor */
|
||||
|
||||
Reference in New Issue
Block a user