test: speed up isolated-agent and pty test suites

This commit is contained in:
Peter Steinberger 2026-02-16 03:58:39 +00:00
parent 3fe22ea2fd
commit 25dc4293bf
3 changed files with 29 additions and 40 deletions

View File

@ -1,9 +1,17 @@
import { afterEach, expect, test, vi } from "vitest";
import { resetProcessRegistryForTests } from "./bash-process-registry";
import { createExecTool } from "./bash-tools.exec";
const { ptySpawnMock } = vi.hoisted(() => ({
ptySpawnMock: vi.fn(),
}));
vi.mock("@lydell/node-pty", () => ({
spawn: (...args: unknown[]) => ptySpawnMock(...args),
}));
afterEach(() => {
resetProcessRegistryForTests();
vi.resetModules();
vi.clearAllMocks();
});
@ -11,25 +19,20 @@ test("exec disposes PTY listeners after normal exit", async () => {
const disposeData = vi.fn();
const disposeExit = vi.fn();
vi.doMock("@lydell/node-pty", () => ({
spawn: () => {
return {
pid: 0,
write: vi.fn(),
onData: (listener: (value: string) => void) => {
setTimeout(() => listener("ok"), 0);
return { dispose: disposeData };
},
onExit: (listener: (event: { exitCode: number; signal?: number }) => void) => {
setTimeout(() => listener({ exitCode: 0 }), 0);
return { dispose: disposeExit };
},
kill: vi.fn(),
};
ptySpawnMock.mockImplementation(() => ({
pid: 0,
write: vi.fn(),
onData: (listener: (value: string) => void) => {
listener("ok");
return { dispose: disposeData };
},
onExit: (listener: (event: { exitCode: number; signal?: number }) => void) => {
listener({ exitCode: 0 });
return { dispose: disposeExit };
},
kill: vi.fn(),
}));
const { createExecTool } = await import("./bash-tools.exec");
const tool = createExecTool({ allowBackground: false });
const result = await tool.execute("toolcall", {
command: "echo ok",
@ -46,19 +49,14 @@ test("exec tears down PTY resources on timeout", async () => {
const disposeExit = vi.fn();
const kill = vi.fn();
vi.doMock("@lydell/node-pty", () => ({
spawn: () => {
return {
pid: 0,
write: vi.fn(),
onData: () => ({ dispose: disposeData }),
onExit: () => ({ dispose: disposeExit }),
kill,
};
},
ptySpawnMock.mockImplementation(() => ({
pid: 0,
write: vi.fn(),
onData: () => ({ dispose: disposeData }),
onExit: () => ({ dispose: disposeExit }),
kill,
}));
const { createExecTool } = await import("./bash-tools.exec");
const tool = createExecTool({ allowBackground: false });
await expect(
tool.execute("toolcall", {

View File

@ -1,5 +1,6 @@
import { afterEach, expect, test, vi } from "vitest";
import { listRunningSessions, resetProcessRegistryForTests } from "./bash-process-registry";
import { createExecTool } from "./bash-tools.exec";
const { supervisorSpawnMock } = vi.hoisted(() => ({
supervisorSpawnMock: vi.fn(),
@ -17,7 +18,6 @@ vi.mock("../process/supervisor/index.js", () => ({
afterEach(() => {
resetProcessRegistryForTests();
vi.resetModules();
vi.clearAllMocks();
});
@ -26,7 +26,6 @@ test("exec cleans session state when PTY fallback spawn also fails", async () =>
.mockRejectedValueOnce(new Error("pty spawn failed"))
.mockRejectedValueOnce(new Error("child fallback failed"));
const { createExecTool } = await import("./bash-tools.exec");
const tool = createExecTool({ allowBackground: false });
await expect(

View File

@ -166,6 +166,8 @@ vi.mock("../../agents/defaults.js", () => ({
DEFAULT_PROVIDER: "openai",
}));
const { runCronIsolatedAgentTurn } = await import("./run.js");
// ---------- helpers ----------
function makeJob(overrides?: Record<string, unknown>) {
@ -230,8 +232,6 @@ describe("runCronIsolatedAgentTurn — skill filter", () => {
it("passes agent-level skillFilter to buildWorkspaceSkillSnapshot", async () => {
resolveAgentSkillsFilterMock.mockReturnValue(["meme-factory", "weather"]);
const { runCronIsolatedAgentTurn } = await import("./run.js");
const result = await runCronIsolatedAgentTurn(
makeParams({
cfg: { agents: { list: [{ id: "scout", skills: ["meme-factory", "weather"] }] } },
@ -250,8 +250,6 @@ describe("runCronIsolatedAgentTurn — skill filter", () => {
it("omits skillFilter when agent has no skills config", async () => {
resolveAgentSkillsFilterMock.mockReturnValue(undefined);
const { runCronIsolatedAgentTurn } = await import("./run.js");
const result = await runCronIsolatedAgentTurn(
makeParams({
cfg: { agents: { list: [{ id: "general" }] } },
@ -268,8 +266,6 @@ describe("runCronIsolatedAgentTurn — skill filter", () => {
it("passes empty skillFilter when agent explicitly disables all skills", async () => {
resolveAgentSkillsFilterMock.mockReturnValue([]);
const { runCronIsolatedAgentTurn } = await import("./run.js");
const result = await runCronIsolatedAgentTurn(
makeParams({
cfg: { agents: { list: [{ id: "silent", skills: [] }] } },
@ -302,8 +298,6 @@ describe("runCronIsolatedAgentTurn — skill filter", () => {
isNewSession: true,
});
const { runCronIsolatedAgentTurn } = await import("./run.js");
const result = await runCronIsolatedAgentTurn(
makeParams({
cfg: { agents: { list: [{ id: "weather-bot", skills: ["weather"] }] } },
@ -338,8 +332,6 @@ describe("runCronIsolatedAgentTurn — skill filter", () => {
isNewSession: true,
});
const { runCronIsolatedAgentTurn } = await import("./run.js");
const result = await runCronIsolatedAgentTurn(
makeParams({
cfg: { agents: { list: [{ id: "weather-bot", skills: ["weather", "meme-factory"] }] } },