test: dedupe and optimize test suites

This commit is contained in:
Peter Steinberger
2026-02-19 15:18:50 +00:00
parent b0e55283d5
commit a1cb700a05
80 changed files with 2627 additions and 2962 deletions

View File

@@ -89,11 +89,11 @@ describe("attachChildProcessBridge", () => {
addedSigterm("SIGTERM");
await new Promise<void>((resolve, reject) => {
const timeout = setTimeout(() => reject(new Error("timeout waiting for child exit")), 10_000);
const timeout = setTimeout(() => reject(new Error("timeout waiting for child exit")), 2_000);
child.once("exit", () => {
clearTimeout(timeout);
resolve();
});
});
}, 20_000);
}, 5_000);
});

View File

@@ -38,7 +38,7 @@ describe("runCommandWithTimeout", () => {
it("kills command when no output timeout elapses", async () => {
const result = await runCommandWithTimeout(
[process.execPath, "-e", "setTimeout(() => {}, 1_000)"],
[process.execPath, "-e", "setTimeout(() => {}, 120)"],
{
timeoutMs: 1_000,
noOutputTimeoutMs: 35,
@@ -55,11 +55,11 @@ describe("runCommandWithTimeout", () => {
[
process.execPath,
"-e",
'let i=0; const t=setInterval(() => { process.stdout.write("."); i += 1; if (i >= 2) { clearInterval(t); process.exit(0); } }, 5);',
'process.stdout.write("."); setTimeout(() => process.stdout.write("."), 30); setTimeout(() => process.exit(0), 60);',
],
{
timeoutMs: 1_000,
noOutputTimeoutMs: 120,
noOutputTimeoutMs: 500,
},
);
@@ -72,7 +72,7 @@ describe("runCommandWithTimeout", () => {
it("reports global timeout termination when overall timeout elapses", async () => {
const result = await runCommandWithTimeout(
[process.execPath, "-e", "setTimeout(() => {}, 1_000)"],
[process.execPath, "-e", "setTimeout(() => {}, 120)"],
{
timeoutMs: 15,
},

View File

@@ -1,4 +1,5 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { killProcessTree } from "./kill-tree.js";
const { spawnMock } = vi.hoisted(() => ({
spawnMock: vi.fn(),
@@ -32,7 +33,6 @@ describe("killProcessTree", () => {
afterEach(() => {
killSpy.mockRestore();
vi.useRealTimers();
vi.resetModules();
vi.clearAllMocks();
});
@@ -45,7 +45,6 @@ describe("killProcessTree", () => {
}) as typeof process.kill);
await withPlatform("win32", async () => {
const { killProcessTree } = await import("./kill-tree.js");
killProcessTree(4242, { graceMs: 25 });
expect(spawnMock).toHaveBeenCalledTimes(1);
@@ -70,7 +69,6 @@ describe("killProcessTree", () => {
}) as typeof process.kill);
await withPlatform("win32", async () => {
const { killProcessTree } = await import("./kill-tree.js");
killProcessTree(5252, { graceMs: 10 });
await vi.advanceTimersByTimeAsync(10);
@@ -103,7 +101,6 @@ describe("killProcessTree", () => {
}) as typeof process.kill);
await withPlatform("linux", async () => {
const { killProcessTree } = await import("./kill-tree.js");
killProcessTree(3333, { graceMs: 10 });
await vi.advanceTimersByTimeAsync(10);
@@ -123,7 +120,6 @@ describe("killProcessTree", () => {
}) as typeof process.kill);
await withPlatform("linux", async () => {
const { killProcessTree } = await import("./kill-tree.js");
killProcessTree(4444, { graceMs: 5 });
await vi.advanceTimersByTimeAsync(5);

View File

@@ -1,7 +1,7 @@
import type { ChildProcess } from "node:child_process";
import { EventEmitter } from "node:events";
import { PassThrough } from "node:stream";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const { spawnWithFallbackMock, killProcessTreeMock } = vi.hoisted(() => ({
spawnWithFallbackMock: vi.fn(),
@@ -16,6 +16,8 @@ vi.mock("../../kill-tree.js", () => ({
killProcessTree: (...args: unknown[]) => killProcessTreeMock(...args),
}));
let createChildAdapter: typeof import("./child.js").createChildAdapter;
function createStubChild(pid = 1234) {
const child = new EventEmitter() as ChildProcess;
child.stdin = new PassThrough() as ChildProcess["stdin"];
@@ -33,7 +35,6 @@ async function createAdapterHarness(params?: {
argv?: string[];
env?: NodeJS.ProcessEnv;
}) {
const { createChildAdapter } = await import("./child.js");
const { child, killMock } = createStubChild(params?.pid);
spawnWithFallbackMock.mockResolvedValue({
child,
@@ -48,6 +49,10 @@ async function createAdapterHarness(params?: {
}
describe("createChildAdapter", () => {
beforeAll(async () => {
({ createChildAdapter } = await import("./child.js"));
});
beforeEach(() => {
spawnWithFallbackMock.mockReset();
killProcessTreeMock.mockReset();

View File

@@ -1,4 +1,4 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const { spawnMock, ptyKillMock, killProcessTreeMock } = vi.hoisted(() => ({
spawnMock: vi.fn(),
@@ -32,6 +32,12 @@ function createStubPty(pid = 1234) {
}
describe("createPtyAdapter", () => {
let createPtyAdapter: typeof import("./pty.js").createPtyAdapter;
beforeAll(async () => {
({ createPtyAdapter } = await import("./pty.js"));
});
beforeEach(() => {
spawnMock.mockReset();
ptyKillMock.mockReset();
@@ -41,7 +47,6 @@ describe("createPtyAdapter", () => {
afterEach(() => {
vi.useRealTimers();
vi.resetModules();
vi.clearAllMocks();
});
@@ -50,7 +55,6 @@ describe("createPtyAdapter", () => {
Object.defineProperty(process, "platform", { value: "linux", configurable: true });
try {
spawnMock.mockReturnValue(createStubPty());
const { createPtyAdapter } = await import("./pty.js");
const adapter = await createPtyAdapter({
shell: "bash",
@@ -69,7 +73,6 @@ describe("createPtyAdapter", () => {
it("uses process-tree kill for SIGKILL by default", async () => {
spawnMock.mockReturnValue(createStubPty());
const { createPtyAdapter } = await import("./pty.js");
const adapter = await createPtyAdapter({
shell: "bash",
@@ -84,7 +87,6 @@ describe("createPtyAdapter", () => {
it("wait does not settle immediately on SIGKILL", async () => {
vi.useFakeTimers();
spawnMock.mockReturnValue(createStubPty());
const { createPtyAdapter } = await import("./pty.js");
const adapter = await createPtyAdapter({
shell: "bash",
@@ -111,7 +113,6 @@ describe("createPtyAdapter", () => {
vi.useFakeTimers();
const stub = createStubPty();
spawnMock.mockReturnValue(stub);
const { createPtyAdapter } = await import("./pty.js");
const adapter = await createPtyAdapter({
shell: "bash",
@@ -131,7 +132,6 @@ describe("createPtyAdapter", () => {
it("resolves wait when exit fires before wait is called", async () => {
const stub = createStubPty();
spawnMock.mockReturnValue(stub);
const { createPtyAdapter } = await import("./pty.js");
const adapter = await createPtyAdapter({
shell: "bash",
@@ -146,7 +146,6 @@ describe("createPtyAdapter", () => {
it("keeps inherited env when no override env is provided", async () => {
const stub = createStubPty();
spawnMock.mockReturnValue(stub);
const { createPtyAdapter } = await import("./pty.js");
await createPtyAdapter({
shell: "bash",
@@ -160,7 +159,6 @@ describe("createPtyAdapter", () => {
it("passes explicit env overrides as strings", async () => {
const stub = createStubPty();
spawnMock.mockReturnValue(stub);
const { createPtyAdapter } = await import("./pty.js");
await createPtyAdapter({
shell: "bash",
@@ -177,7 +175,6 @@ describe("createPtyAdapter", () => {
Object.defineProperty(process, "platform", { value: "win32", configurable: true });
try {
spawnMock.mockReturnValue(createStubPty());
const { createPtyAdapter } = await import("./pty.js");
const adapter = await createPtyAdapter({
shell: "powershell.exe",
@@ -199,7 +196,6 @@ describe("createPtyAdapter", () => {
Object.defineProperty(process, "platform", { value: "win32", configurable: true });
try {
spawnMock.mockReturnValue(createStubPty(4567));
const { createPtyAdapter } = await import("./pty.js");
const adapter = await createPtyAdapter({
shell: "powershell.exe",

View File

@@ -1,4 +1,4 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const { createPtyAdapterMock } = vi.hoisted(() => ({
createPtyAdapterMock: vi.fn(),
@@ -33,13 +33,18 @@ function createStubPtyAdapter() {
}
describe("process supervisor PTY command contract", () => {
let createProcessSupervisor: typeof import("./supervisor.js").createProcessSupervisor;
beforeAll(async () => {
({ createProcessSupervisor } = await import("./supervisor.js"));
});
beforeEach(() => {
createPtyAdapterMock.mockReset();
});
it("passes PTY command verbatim to shell args", async () => {
createPtyAdapterMock.mockResolvedValue(createStubPtyAdapter());
const { createProcessSupervisor } = await import("./supervisor.js");
const supervisor = createProcessSupervisor();
const command = `printf '%s\\n' "a b" && printf '%s\\n' '$HOME'`;
@@ -60,7 +65,6 @@ describe("process supervisor PTY command contract", () => {
it("rejects empty PTY command", async () => {
createPtyAdapterMock.mockResolvedValue(createStubPtyAdapter());
const { createProcessSupervisor } = await import("./supervisor.js");
const supervisor = createProcessSupervisor();
await expect(

View File

@@ -24,7 +24,7 @@ describe("process supervisor", () => {
sessionId: "s1",
backendId: "test",
mode: "child",
argv: [process.execPath, "-e", "setTimeout(() => {}, 1_000)"],
argv: [process.execPath, "-e", "setTimeout(() => {}, 120)"],
timeoutMs: 1_000,
noOutputTimeoutMs: 20,
stdinMode: "pipe-closed",
@@ -42,7 +42,7 @@ describe("process supervisor", () => {
backendId: "test",
scopeKey: "scope:a",
mode: "child",
argv: [process.execPath, "-e", "setTimeout(() => {}, 1_000)"],
argv: [process.execPath, "-e", "setTimeout(() => {}, 120)"],
timeoutMs: 1_000,
stdinMode: "pipe-open",
});
@@ -71,7 +71,7 @@ describe("process supervisor", () => {
sessionId: "s-timeout",
backendId: "test",
mode: "child",
argv: [process.execPath, "-e", "setTimeout(() => {}, 1_000)"],
argv: [process.execPath, "-e", "setTimeout(() => {}, 120)"],
timeoutMs: 1,
stdinMode: "pipe-closed",
});