fix(test): clamp qa otel child timer

This commit is contained in:
Vincent Koc 2026-06-22 03:12:25 +02:00
parent b99812b3b1
commit 29eba5aaef
No known key found for this signature in database
2 changed files with 15 additions and 2 deletions

View file

@ -10,6 +10,7 @@ import { tmpdir } from "node:os";
import path from "node:path";
import { pathToFileURL } from "node:url";
import { gunzipSync } from "node:zlib";
import { resolveTimerTimeoutMs } from "@openclaw/normalization-core/number-coercion";
import { stripLeadingPackageManagerSeparator } from "../../../../scripts/lib/arg-utils.mjs";
import { resolveWindowsTaskkillPath } from "../../../../scripts/lib/windows-taskkill.mjs";
@ -1275,12 +1276,13 @@ async function waitForChild(
timeoutMs = QA_SUITE_TIMEOUT_MS,
killGraceMs = QA_SUITE_KILL_GRACE_MS,
): Promise<number> {
const resolvedTimeoutMs = resolveTimerTimeoutMs(timeoutMs, QA_SUITE_TIMEOUT_MS);
const childExit = new Promise<number>((resolve) => {
child.once("close", (code) => resolve(code ?? 1));
});
let timeoutHandle: NodeJS.Timeout | undefined;
const timeout = new Promise<"timeout">((resolve) => {
timeoutHandle = setTimeout(() => resolve("timeout"), timeoutMs);
timeoutHandle = setTimeout(() => resolve("timeout"), resolvedTimeoutMs);
timeoutHandle.unref();
});
const result = await Promise.race([childExit, timeout]).finally(() => {
@ -1298,7 +1300,7 @@ async function waitForChild(
terminateChildTree(child, "SIGKILL", cleanupPids);
await waitForProcessTreeExit(child, 1000, cleanupPids);
}
throw new Error(`openclaw qa suite timed out after ${timeoutMs}ms`);
throw new Error(`openclaw qa suite timed out after ${resolvedTimeoutMs}ms`);
}
function collectChildProcessTreePids(child: ChildProcess): number[] {

View file

@ -7,6 +7,7 @@ import os from "node:os";
import path from "node:path";
import { setTimeout as delay } from "node:timers/promises";
import { gzipSync } from "node:zlib";
import { MAX_TIMER_TIMEOUT_MS } from "@openclaw/normalization-core/number-coercion";
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
import { resolveWindowsTaskkillPath } from "../../../../scripts/lib/windows-taskkill.mjs";
import { testing } from "./qa-otel-smoke-runtime.js";
@ -662,6 +663,16 @@ describe("qa-otel-smoke receiver bounds", () => {
}
});
it("clamps oversized QA suite child timers before scheduling", async () => {
const child = spawn(
process.execPath,
["--input-type=module", "--eval", "setTimeout(() => process.exit(0), 25);"],
{ stdio: "ignore" },
);
await expect(testing.waitForChild(child, MAX_TIMER_TIMEOUT_MS + 1, 100)).resolves.toBe(0);
});
it("uses taskkill for Windows QA suite timeout cleanup", () => {
const kill = vi.fn();
const runTaskkill = vi.fn(() => ({ status: 0 }));