import { mkdir, mkdtemp, readFile, rm } from "node:fs/promises" ;
import os from "node:os" ;
import path from "node:path" ;
import { afterEach, describe, expect, it, vi } from "vitest" ;
const runMatrixQaLive = vi.hoisted(() => vi.fn());
const closeGlobalDispatcher = vi.hoisted(() => vi.fn(async () => {}));
vi.mock("./runners/contract/runtime.js" , () => ({
runMatrixQaLive,
}));
vi.mock("undici" , () => ({
getGlobalDispatcher: () => ({
close: closeGlobalDispatcher,
}),
}));
import { runQaMatrixCommand } from "./cli.runtime.js" ;
const tmpDirs: string[] = [];
describe("matrix qa cli runtime" , () => {
const originalRunNodeOutputLog = process.env.OPENCLAW_RUN_NODE_OUTPUT_LOG;
afterEach(async () => {
vi.clearAllMocks();
if (originalRunNodeOutputLog === undefined) {
delete process.env.OPENCLAW_RUN_NODE_OUTPUT_LOG;
} else {
process.env.OPENCLAW_RUN_NODE_OUTPUT_LOG = originalRunNodeOutputLog;
}
await Promise.all(tmpDirs.splice(0 ).map((dir) => rm(dir, { recursive: true , force: true })));
});
it("rejects non-env credential sources for the disposable Matrix lane" , async () => {
await expect(
runQaMatrixCommand({
credentialSource: "convex" ,
}),
).rejects.toThrow("Matrix QA currently supports only --credential-source env" );
});
it("passes through default env credential source options" , async () => {
const repoRoot = await mkdtemp(path.join(os.tmpdir(), "matrix-qa-cli-" ));
tmpDirs.push(repoRoot);
runMatrixQaLive.mockResolvedValue({
reportPath: "/tmp/matrix-report.md" ,
summaryPath: "/tmp/matrix-summary.json" ,
observedEventsPath: "/tmp/matrix-events.json" ,
});
const originalStdoutWrite = process.stdout.write;
process.stdout.write = (() => true ) as typeof process.stdout.write;
try {
await runQaMatrixCommand({
repoRoot,
outputDir: ".artifacts/qa-e2e/matrix" ,
providerMode: "mock-openai" ,
credentialSource: "env" ,
});
} finally {
process.stdout.write = originalStdoutWrite;
}
expect(runMatrixQaLive).toHaveBeenCalledWith(
expect.objectContaining({
repoRoot,
outputDir: path.join(repoRoot, ".artifacts/qa-e2e/matrix" ),
providerMode: "mock-openai" ,
credentialSource: "env" ,
}),
);
expect(closeGlobalDispatcher).toHaveBeenCalledTimes(1 );
});
it("reuses a run-node output log instead of installing a nested tee" , async () => {
const repoRoot = await mkdtemp(path.join(os.tmpdir(), "matrix-qa-cli-" ));
tmpDirs.push(repoRoot);
const outputPath = path.join(repoRoot, "run-node-output.log" );
process.env.OPENCLAW_RUN_NODE_OUTPUT_LOG = outputPath;
runMatrixQaLive.mockResolvedValue({
reportPath: "/tmp/matrix-report.md" ,
summaryPath: "/tmp/matrix-summary.json" ,
observedEventsPath: "/tmp/matrix-events.json" ,
});
const originalStdoutWrite = process.stdout.write;
process.stdout.write = vi.fn(() => true ) as unknown as typeof process.stdout.write;
try {
await runQaMatrixCommand({
repoRoot,
outputDir: ".artifacts/qa-e2e/matrix" ,
providerMode: "mock-openai" ,
credentialSource: "env" ,
});
} finally {
process.stdout.write = originalStdoutWrite;
}
expect(runMatrixQaLive).toHaveBeenCalledOnce();
await expect(readFile(outputPath, "utf8" )).rejects.toMatchObject({ code: "ENOENT" });
});
it("preserves the Matrix QA failure when output log cleanup also fails" , async () => {
const repoRoot = await mkdtemp(path.join(os.tmpdir(), "matrix-qa-cli-" ));
tmpDirs.push(repoRoot);
const outputDir = path.join(repoRoot, ".artifacts" , "qa-e2e" , "matrix" );
await mkdir(path.join(outputDir, "matrix-qa-output.log" ), { recursive: true });
runMatrixQaLive.mockRejectedValue(new Error("scenario failed" ));
const stderrChunks: string[] = [];
const originalStdoutWrite = process.stdout.write;
const originalStderrWrite = process.stderr.write;
process.stdout.write = (() => true ) as typeof process.stdout.write;
process.stderr.write = ((chunk: string | Buffer) => {
stderrChunks.push(String(chunk));
return true ;
}) as typeof process.stderr.write;
try {
await expect(
runQaMatrixCommand({
repoRoot,
outputDir: ".artifacts/qa-e2e/matrix" ,
providerMode: "mock-openai" ,
credentialSource: "env" ,
}),
).rejects.toThrow("scenario failed" );
} finally {
process.stdout.write = originalStdoutWrite;
process.stderr.write = originalStderrWrite;
}
expect(stderrChunks.join("" )).toContain("Matrix QA output log error" );
});
});
Messung V0.5 in Prozent C=99 H=99 G=98
¤ Dauer der Verarbeitung: 0.3 Sekunden
¤
*© Formatika GbR, Deutschland