104 lines
3.2 KiB
TypeScript
104 lines
3.2 KiB
TypeScript
import { rm, stat } from "node:fs/promises";
|
|
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
|
|
import { runBenchmark } from "../experiment/benchmark-runner.js";
|
|
|
|
describe("runBenchmark", () => {
|
|
const tempFiles: string[] = [];
|
|
|
|
afterEach(async () => {
|
|
await Promise.all(
|
|
tempFiles.map(async (file) => {
|
|
try {
|
|
await rm(file, { force: true, recursive: true });
|
|
} catch {
|
|
// ignore cleanup failures
|
|
}
|
|
}),
|
|
);
|
|
tempFiles.length = 0;
|
|
});
|
|
|
|
it("runs command successfully", async () => {
|
|
const result = await runBenchmark({
|
|
command: `${process.execPath} -e \"console.log('METRIC accuracy=0.91')\"`,
|
|
cwd: process.cwd(),
|
|
});
|
|
|
|
expect(result.exitCode).toBe(0);
|
|
expect(result.stdout).toContain("METRIC accuracy=0.91");
|
|
expect(result.durationMs).toBeGreaterThanOrEqual(0);
|
|
expect(result.timedOut).toBe(false);
|
|
});
|
|
|
|
it("times out long-running process", async () => {
|
|
const result = await runBenchmark({
|
|
command: `${process.execPath} -e \"setTimeout(() => console.log('done'), 2000)\"`,
|
|
cwd: process.cwd(),
|
|
timeoutMs: 100,
|
|
});
|
|
|
|
expect(result.timedOut).toBe(true);
|
|
expect(result.exitCode).not.toBe(0);
|
|
});
|
|
|
|
it("truncates oversized stdout and writes full output to temp file", async () => {
|
|
const result = await runBenchmark({
|
|
command: `${process.execPath} -e \"process.stdout.write('x'.repeat(2048))\"`,
|
|
cwd: process.cwd(),
|
|
maxBufferBytes: 256,
|
|
sessionId: "EXP-1",
|
|
});
|
|
|
|
expect(result.truncated).toBe(true);
|
|
expect(result.truncatedTempFile).toBeTruthy();
|
|
if (result.truncatedTempFile) {
|
|
tempFiles.push(result.truncatedTempFile);
|
|
const stats = await stat(result.truncatedTempFile);
|
|
expect(stats.size).toBeGreaterThan(256);
|
|
}
|
|
expect(result.stdout.length).toBeLessThanOrEqual(64 * 1024);
|
|
});
|
|
|
|
it("supports abort signal", async () => {
|
|
const controller = new AbortController();
|
|
const runPromise = runBenchmark({
|
|
command: `${process.execPath} -e \"setInterval(() => process.stdout.write('tick\\n'), 50)\"`,
|
|
cwd: process.cwd(),
|
|
abortSignal: controller.signal,
|
|
});
|
|
|
|
setTimeout(() => controller.abort(), 120);
|
|
|
|
const result = await runPromise;
|
|
expect(result.exitCode).not.toBe(0);
|
|
expect(result.timedOut).toBe(false);
|
|
});
|
|
|
|
it("throttles progress callbacks and stops after completion", async () => {
|
|
vi.useFakeTimers();
|
|
const onProgress = vi.fn();
|
|
|
|
const promise = runBenchmark({
|
|
command: `${process.execPath} -e \"let i=0; const t=setInterval(()=>{console.log(i++); if(i===5){clearInterval(t); process.exit(0);} }, 50)\"`,
|
|
cwd: process.cwd(),
|
|
onProgress,
|
|
});
|
|
|
|
await vi.advanceTimersByTimeAsync(1500);
|
|
const result = await promise;
|
|
const callsAtFinish = onProgress.mock.calls.length;
|
|
await vi.advanceTimersByTimeAsync(1000);
|
|
|
|
expect(result.exitCode).toBe(0);
|
|
expect(callsAtFinish).toBeGreaterThan(0);
|
|
expect(onProgress.mock.calls.length).toBe(callsAtFinish);
|
|
for (const call of onProgress.mock.calls) {
|
|
expect(call[0].elapsedMs).toBeGreaterThanOrEqual(0);
|
|
}
|
|
|
|
vi.useRealTimers();
|
|
});
|
|
});
|