fix(qa): stop Matrix phases after run timeout

This commit is contained in:
Vincent Koc
2026-05-27 13:12:55 +02:00
parent 66965f5008
commit f4b9d24621
2 changed files with 46 additions and 3 deletions

View File

@@ -4,6 +4,7 @@ import { renderQaMarkdownReport } from "../../report.js";
import { testing as liveTesting } from "./runtime.js";
afterEach(() => {
vi.restoreAllMocks();
vi.useRealTimers();
});
@@ -106,6 +107,37 @@ describe("matrix live qa runtime", () => {
}
});
it("does not start Matrix QA work after the hard run deadline expires", async () => {
const task = vi.fn(async () => "started");
vi.spyOn(Date, "now").mockReturnValue(1_001);
await expect(
liveTesting.withMatrixQaRunDeadline(
{
deadlineMs: 1_000,
timeoutMs: 30_000,
},
"Matrix scenario late",
task,
),
).rejects.toThrow(/Matrix scenario late not started because Matrix QA run timed out/u);
expect(task).not.toHaveBeenCalled();
});
it("passes the remaining Matrix QA run budget to the phase timeout", async () => {
vi.spyOn(Date, "now").mockReturnValue(1_000);
expect(
liveTesting.remainingMatrixQaRunMs(
{
deadlineMs: 1_250,
timeoutMs: 30_000,
},
"Matrix canary",
),
).toBe(250);
});
it("normalizes the Matrix QA canary timeout env", () => {
const previous = process.env.OPENCLAW_QA_MATRIX_CANARY_TIMEOUT_MS;
try {

View File

@@ -201,8 +201,17 @@ function resolveMatrixQaCanaryTimeoutMs() {
);
}
function remainingMatrixQaRunMs(deadline: { deadlineMs: number }) {
return Math.max(1, deadline.deadlineMs - Date.now());
function remainingMatrixQaRunMs(
deadline: { deadlineMs: number; timeoutMs: number },
label: string,
) {
const remainingMs = Math.floor(deadline.deadlineMs - Date.now());
if (!Number.isFinite(deadline.deadlineMs) || remainingMs <= 0) {
throw new Error(
`${label} not started because Matrix QA run timed out after ${formatMatrixQaDurationMs(deadline.timeoutMs)}`,
);
}
return remainingMs;
}
async function withMatrixQaTimeout<T>(
@@ -232,7 +241,7 @@ async function withMatrixQaRunDeadline<T>(
label: string,
task: () => Promise<T>,
) {
return await withMatrixQaTimeout(label, remainingMatrixQaRunMs(deadline), task);
return await withMatrixQaTimeout(label, remainingMatrixQaRunMs(deadline, label), task);
}
async function cleanupMatrixQaResource(params: {
@@ -1137,10 +1146,12 @@ export const testing = {
findMatrixQaScenarios,
isMatrixAccountReady,
patchMatrixQaGatewayConfig,
remainingMatrixQaRunMs,
resolveMatrixQaCanaryTimeoutMs,
resolveMatrixQaModels,
shouldWriteMatrixQaProgress,
summarizeMatrixQaConfigSnapshot,
waitForMatrixChannelReady,
withMatrixQaRunDeadline,
};
export { testing as __testing };