75 lines
2.4 KiB
TypeScript
75 lines
2.4 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { resolveNativeSandboxLifecycle } from "../services/heartbeat.js";
|
|
|
|
const reusableSandbox = {
|
|
kind: "remote" as const,
|
|
transport: "sandbox",
|
|
reusableLeaseConfigured: true,
|
|
effectiveCapabilities: { reusableLeases: true },
|
|
};
|
|
|
|
describe("paperclip_runner sandbox lifecycle", () => {
|
|
it("keeps a warm reusable sandbox running", () => {
|
|
expect(resolveNativeSandboxLifecycle({
|
|
adapterType: "paperclip_runner",
|
|
lifecyclePolicy: { mode: "warm", idleTimeoutMs: 300_000 },
|
|
target: reusableSandbox,
|
|
})).toEqual({
|
|
runnerProcess: "warm",
|
|
sandboxResource: "keep_running",
|
|
failoverBackup: "verified",
|
|
});
|
|
});
|
|
|
|
it("stops and reuses a per-turn reusable sandbox", () => {
|
|
expect(resolveNativeSandboxLifecycle({
|
|
adapterType: "paperclip_runner",
|
|
lifecyclePolicy: { mode: "per_turn", idleTimeoutMs: null },
|
|
target: reusableSandbox,
|
|
})).toEqual({
|
|
runnerProcess: "per_turn",
|
|
sandboxResource: "stop_and_reuse",
|
|
failoverBackup: "verified",
|
|
});
|
|
});
|
|
|
|
it("destroys a per-turn disposable sandbox", () => {
|
|
expect(resolveNativeSandboxLifecycle({
|
|
adapterType: "paperclip_runner",
|
|
lifecyclePolicy: { mode: "per_turn", idleTimeoutMs: null },
|
|
target: {
|
|
...reusableSandbox,
|
|
reusableLeaseConfigured: false,
|
|
},
|
|
})).toEqual({
|
|
runnerProcess: "per_turn",
|
|
sandboxResource: "destroy_after_turn",
|
|
failoverBackup: "verified",
|
|
});
|
|
});
|
|
|
|
it("rejects warm mode without an effective reusable-lease capability", () => {
|
|
expect(() => resolveNativeSandboxLifecycle({
|
|
adapterType: "paperclip_runner",
|
|
lifecyclePolicy: { mode: "warm", idleTimeoutMs: 300_000 },
|
|
target: {
|
|
...reusableSandbox,
|
|
effectiveCapabilities: { reusableLeases: false },
|
|
},
|
|
})).toThrow("runner_warm_lifecycle_requires_reusable_provider_lease");
|
|
});
|
|
|
|
it("leaves legacy and non-sandbox targets untouched", () => {
|
|
expect(resolveNativeSandboxLifecycle({
|
|
adapterType: "codex_local",
|
|
lifecyclePolicy: { mode: "per_turn", idleTimeoutMs: null },
|
|
target: reusableSandbox,
|
|
})).toBeNull();
|
|
expect(resolveNativeSandboxLifecycle({
|
|
adapterType: "paperclip_runner",
|
|
lifecyclePolicy: { mode: "per_turn", idleTimeoutMs: null },
|
|
target: { kind: "local" },
|
|
})).toBeNull();
|
|
});
|
|
});
|