improve: speed up CLI spawn tests (#122891)

* test(agents): trim cli spawn test imports

* test(agents): distinguish prerelease policies

---------

Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Peter Steinberger
2026-08-12 19:07:19 -07:00
committed by GitHub
parent 326501fce3
commit 239087d448
2 changed files with 83 additions and 129 deletions
+83 -112
View File
@@ -23,14 +23,6 @@ import {
} from "../logging/diagnostic-run-activity.js";
import type { getProcessSupervisor } from "../process/supervisor/index.js";
import { createTestAdmittedRunContext } from "./admitted-run-context.test-support.js";
import {
registerExecApprovalRequestForHostOrThrow,
resolveRegisteredExecApprovalDecision,
} from "./bash-tools.exec-approval-request.js";
import {
makeBootstrapWarn as realMakeBootstrapWarn,
resolveBootstrapContextForRun as realResolveBootstrapContextForRun,
} from "./bootstrap-files.js";
import {
buildClaudeLiveRunContext,
buildPreparedCliRunContext,
@@ -45,12 +37,6 @@ import {
requireRecord,
requireRegexMatch,
} from "./cli-runner.test-helpers.js";
import {
createManagedRun,
mockSuccessfulCliRun,
restoreCliRunnerPrepareTestDeps,
supervisorSpawnMock,
} from "./cli-runner.test-support.js";
import { resetClaudeLiveSessionsForTest } from "./cli-runner/claude-live-session.test-support.js";
import {
attachCliMessagingDeliveryEvidence,
@@ -60,13 +46,20 @@ import { executePreparedCliRun } from "./cli-runner/execute.js";
import {
buildCliEnvAuthLog,
buildCliExecLogLine,
createManagedRun,
setCliRunnerExecuteTestDeps,
supervisorSpawnMock,
} from "./cli-runner/execute.test-support.js";
import { buildCliAgentSystemPrompt, writeCliSystemPromptFile } from "./cli-runner/helpers.js";
import { cliBackendLog, formatCliBackendOutputDigest } from "./cli-runner/log.js";
import { setCliRunnerPrepareTestDeps } from "./cli-runner/prepare.test-support.js";
import type { PreparedCliRunContext } from "./cli-runner/types.js";
// Approval behavior is injected below; loading its gateway/tool graph here is incidental.
vi.mock("./bash-tools.exec-approval-request.js", () => ({
registerExecApprovalRequestForHostOrThrow: vi.fn(),
resolveRegisteredExecApprovalDecision: vi.fn(),
}));
// Gateway unit coverage owns quiet-admission timing. These spawn cases only
// need to drain calls already in flight, so skip the repeated 250 ms quiet window.
vi.mock("../gateway/mcp-http.loopback-runtime.js", async (importOriginal) => {
@@ -97,12 +90,15 @@ beforeEach(() => {
resetDiagnosticRunActivityForTest();
startDiagnosticRunActivityTracking();
resetClaudeLiveSessionsForTest();
restoreCliRunnerPrepareTestDeps();
setCliRunnerExecuteTestDeps({
writeCliSystemPromptFile,
invokeNodeClaudeCliRun,
registerExecApprovalRequestForHostOrThrow,
resolveRegisteredExecApprovalDecision,
registerExecApprovalRequestForHostOrThrow: async () => {
throw new Error("unexpected exec approval registration");
},
resolveRegisteredExecApprovalDecision: async () => {
throw new Error("unexpected exec approval resolution");
},
});
supervisorSpawnMock.mockClear();
});
@@ -121,6 +117,21 @@ const GEMINI_OK_JSONL = `${[
].join("\n")}\n`;
const tempDirs = useAutoCleanupTempDirTracker(afterEach);
function mockSuccessfulCliRun(stdout = "ok") {
supervisorSpawnMock.mockResolvedValueOnce(
createManagedRun({
reason: "exit",
exitCode: 0,
exitSignal: null,
durationMs: 50,
stdout,
stderr: "",
timedOut: false,
noOutputTimedOut: false,
}),
);
}
async function createCliPackageFixture(version: string): Promise<{
root: string;
entrypoint: string;
@@ -1316,47 +1327,63 @@ describe("runCliAgent spawn path", () => {
});
it.each([
{ version: "0.40.0-preview.2", admitted: false },
{ version: "0.40.0-preview.3", admitted: true },
{ version: "0.41.0-nightly.20260423.gd1c91f526", admitted: false },
{ version: "0.41.0-nightly.20260427.g42587de73", admitted: true },
{ version: "0.53.0-beta.0", admitted: false },
])("applies the exact tool-availability policy to $version", async ({ version, admitted }) => {
const fixture = await createCliPackageFixture(version);
const run = () =>
executePreparedCliRun(
buildPreparedCliRunContext({
provider: "google-gemini-cli",
model: "gemini-3.1-pro-preview",
backend: { command: fixture.entrypoint },
cliToolAvailability: { native: [], openClaw: [] },
runtimeArtifact: {
kind: "bundled-package-tree",
packageName: "@fixture/versioned-cli",
entrypoint: "command",
exactToolAvailabilityVersionPolicy: {
stableMinimum: "0.39.1",
prereleaseMinimums: {
preview: "0.40.0-preview.3",
nightly: "0.41.0-nightly.20260427.g42587de73",
{
version: "0.40.0-preview.2",
admitted: false,
expectedError: "requires >=0.40.0-preview.3; found 0.40.0-preview.2",
},
{
version: "0.41.0-nightly.20260427.g42587de73",
admitted: true,
stableMinimum: "99.0.0",
expectedError: undefined,
},
{
version: "0.53.0-beta.0",
admitted: false,
expectedError: "unsupported release line; found 0.53.0-beta.0",
},
])(
"applies the exact tool-availability policy to $version",
async ({ version, admitted, stableMinimum = "0.39.1", expectedError }) => {
const fixture = await createCliPackageFixture(version);
const run = () =>
executePreparedCliRun(
buildPreparedCliRunContext({
provider: "google-gemini-cli",
model: "gemini-3.1-pro-preview",
backend: { command: fixture.entrypoint },
cliToolAvailability: { native: [], openClaw: [] },
runtimeArtifact: {
kind: "bundled-package-tree",
packageName: "@fixture/versioned-cli",
entrypoint: "command",
exactToolAvailabilityVersionPolicy: {
stableMinimum,
prereleaseMinimums: {
preview: "0.40.0-preview.3",
nightly: "0.41.0-nightly.20260427.g42587de73",
},
},
},
},
}),
);
try {
if (admitted) {
mockSuccessfulCliRun(GEMINI_OK_JSONL);
await expect(run()).resolves.toBeDefined();
expect(supervisorSpawnMock).toHaveBeenCalledOnce();
} else {
await expect(run()).rejects.toThrow("requires a supported package version");
expect(supervisorSpawnMock).not.toHaveBeenCalled();
}),
);
try {
if (admitted) {
mockSuccessfulCliRun(GEMINI_OK_JSONL);
await expect(run()).resolves.toBeDefined();
expect(supervisorSpawnMock).toHaveBeenCalledOnce();
} else {
await expect(run()).rejects.toThrow(
expectDefined(expectedError, "rejected version error"),
);
expect(supervisorSpawnMock).not.toHaveBeenCalled();
}
} finally {
await fs.rm(fixture.root, { recursive: true, force: true });
}
} finally {
await fs.rm(fixture.root, { recursive: true, force: true });
}
});
},
);
it("does not apply the exact tool-availability version floor to normal agent turns", async () => {
const fixture = await createCliPackageFixture("0.39.0");
@@ -2627,61 +2654,5 @@ describe("runCliAgent spawn path", () => {
expect(promptCarrier).toContain("- AGENTS.md: 200 raw -> 20 injected");
expect(promptCarrier).toContain("hi");
});
it("loads workspace bootstrap files into the Claude CLI system prompt", async () => {
const workspaceDir = await fs.mkdtemp(
path.join(os.tmpdir(), "openclaw-cli-bootstrap-context-"),
);
await fs.writeFile(
path.join(workspaceDir, "AGENTS.md"),
[
"# AGENTS.md",
"",
"Read SOUL.md and IDENTITY.md before replying.",
"Use the injected workspace bootstrap files as standing instructions.",
].join("\n"),
"utf-8",
);
await fs.writeFile(path.join(workspaceDir, "SOUL.md"), "SOUL-SECRET\n", "utf-8");
await fs.writeFile(path.join(workspaceDir, "IDENTITY.md"), "IDENTITY-SECRET\n", "utf-8");
await fs.writeFile(path.join(workspaceDir, "USER.md"), "USER-SECRET\n", "utf-8");
setCliRunnerPrepareTestDeps({
makeBootstrapWarn: realMakeBootstrapWarn,
resolveBootstrapContextForRun: realResolveBootstrapContextForRun,
});
try {
const { contextFiles } = await realResolveBootstrapContextForRun({
workspaceDir,
});
const allArgs = buildCliAgentSystemPrompt({
workspaceDir,
modelDisplay: "claude-cli/sonnet",
contextFiles,
tools: [],
});
const agentsPath = path.join(workspaceDir, "AGENTS.md");
const soulPath = path.join(workspaceDir, "SOUL.md");
const identityPath = path.join(workspaceDir, "IDENTITY.md");
const userPath = path.join(workspaceDir, "USER.md");
expect(allArgs).toContain("# Project Context");
expect(allArgs).toContain(`## ${agentsPath}`);
expect(allArgs).toContain("Read SOUL.md and IDENTITY.md before replying.");
expect(allArgs).toContain(`## ${soulPath}`);
expect(allArgs).toContain("SOUL-SECRET");
expect(allArgs).toContain(
"SOUL.md: persona/tone. Follow it unless higher-priority instructions override.",
);
expect(allArgs).toContain(`## ${identityPath}`);
expect(allArgs).toContain("IDENTITY-SECRET");
expect(allArgs).toContain(`## ${userPath}`);
expect(allArgs).toContain("USER-SECRET");
} finally {
await fs.rm(workspaceDir, { recursive: true, force: true });
restoreCliRunnerPrepareTestDeps();
}
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
-17
View File
@@ -2,7 +2,6 @@
import type { Mock } from "vitest";
import { beforeEach, vi } from "vitest";
import { getClaudeGeneration } from "./cli-runner/claude-live-registry.js";
import { createManagedRun, supervisorSpawnMock } from "./cli-runner/execute.test-support.js";
import { setCliRunnerPrepareTestDeps } from "./cli-runner/prepare.test-support.js";
import type { EmbeddedContextFile } from "./embedded-agent-helpers.js";
import type { WorkspaceBootstrapFile } from "./workspace.js";
@@ -41,22 +40,6 @@ setCliRunnerPrepareTestDeps({
resolveOpenClawReferencePaths: async () => ({ docsPath: null, sourcePath: null }),
});
/** Queue one successful CLI supervisor run. */
export function mockSuccessfulCliRun(stdout = "ok") {
supervisorSpawnMock.mockResolvedValueOnce(
createManagedRun({
reason: "exit",
exitCode: 0,
exitSignal: null,
durationMs: 50,
stdout,
stderr: "",
timedOut: false,
noOutputTimedOut: false,
}),
);
}
/** Restore prepare-time CLI runner test dependencies after a test overrides them. */
export function restoreCliRunnerPrepareTestDeps() {
setCliRunnerPrepareTestDeps({