mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-03 09:39:25 +00:00
Tests must not race real timers (docs/help/testing/writing-tests.md, Cost budget and Flake triage), yet withTestTimeout and raceWithTimeoutResult call sites grew from 123 (2026-09-01) to 478 (2026-09-26). #161691 audited them, fixed the worst files, and added the timer-free replacements awaitGateBeforeSettlement and withinTest. This stops new uses. check:test-timeout-race-ratchet keeps per-file counts in config/test-timeout-race-baseline.txt (172 files, 403 sites) and only lets them shrink. It parses every repository code file that mentions either helper and counts each identifier reference except import specifiers: plain and generic calls, namespace calls, aliases, re-exports, and local copies such as the private raceWithTimeoutResult in fetch-guard.ssrf.test.ts. Comments and strings do not count; test/helpers/promise.ts owns the helpers and is excluded. Failures point authors at awaitGateBeforeSettlement, withinTest, or fake timers through the owner's clock seam; removed sites require --prune. The per-file count lifecycle (merge-base comparison, verified renames, base drift allowance, prune, shrink demand) moves from the assertion-safety ratchet into scripts/lib/shrink-ratchet.mts so both ratchets share one owner. The assertion-safety output and exit codes are unchanged. Wiring: scripts/check.mts preflight, check:changed routing for any code file or the baseline, and one added line each in the existing PR baseline-ratchet step and the main-push ratchet step (ci.yml +164 bytes, no new steps). Proof (Linux Testbox, pre-rebase tree; baseline refreshed after rebase): new ratchet passes in under 1 s; injecting a call into a baselined file and a new test file fails with the guidance; assertion-safety reports its unchanged totals; tsgo:scripts, tsgo:test:root, and check:changed --base origin/main pass; the affected test/scripts files pass. New test file: 4 s with --maxWorkers=1. Release note context: maintainer tooling only; no user-visible change. CI: run 36812237216 green except checks-windows-node-test-3, which fails the same package-update-swap.windows.test.ts assertion on main (scheduled run 36807764485); fix owned by #162361. Related: #161691
77 lines
2.6 KiB
TypeScript
77 lines
2.6 KiB
TypeScript
// Check tests cover check script behavior.
|
|
import { spawnSync } from "node:child_process";
|
|
import { describe, expect, it } from "vitest";
|
|
import { PREFLIGHT_CHECKS, runCommand } from "../../scripts/check.mts";
|
|
|
|
describe("scripts/check", () => {
|
|
function runCheck(...args: string[]) {
|
|
return spawnSync(process.execPath, ["--import", "tsx", "scripts/check.mts", ...args], {
|
|
cwd: process.cwd(),
|
|
encoding: "utf8",
|
|
});
|
|
}
|
|
|
|
it("prints help without running check stages", () => {
|
|
const result = runCheck("--help");
|
|
|
|
expect(result.status).toBe(0);
|
|
expect(result.stderr).toBe("");
|
|
expect(result.stdout).toContain("Usage: node --import tsx scripts/check.mts");
|
|
expect(result.stdout).not.toContain("[check]");
|
|
});
|
|
|
|
it("rejects unknown args before running check stages", () => {
|
|
for (const args of [["--bogus"], ["bogus", "--help"]]) {
|
|
const result = runCheck(...args);
|
|
|
|
expect(result.status).toBe(2);
|
|
expect(result.stdout).toBe("");
|
|
expect(result.stderr).toContain(`unknown argument: ${args[0]}`);
|
|
expect(result.stderr).toContain("Usage: node --import tsx scripts/check.mts");
|
|
expect(result.stderr).not.toContain("[check]");
|
|
}
|
|
});
|
|
|
|
it("runs pnpm commands through the managed child runner", async () => {
|
|
const calls: Array<{ args: string[]; bin: string }> = [];
|
|
const result = await runCommand(
|
|
{ args: ["lint"], name: "lint" },
|
|
async (options: { args: string[]; bin: string }) => {
|
|
calls.push(options);
|
|
return 0;
|
|
},
|
|
);
|
|
|
|
expect(calls).toEqual([{ args: ["lint"], bin: "pnpm" }]);
|
|
expect(result).toMatchObject({ name: "lint", status: 0 });
|
|
expect(result.durationMs).toBeGreaterThanOrEqual(0);
|
|
});
|
|
|
|
it("keeps script policy guards in the aggregate preflight", () => {
|
|
expect(PREFLIGHT_CHECKS).not.toContainEqual({
|
|
name: "environment variable count ratchet",
|
|
args: ["check:env-var-count"],
|
|
});
|
|
expect(PREFLIGHT_CHECKS).toContainEqual(
|
|
expect.objectContaining({
|
|
name: "max-lines suppression ratchet",
|
|
args: ["check:max-lines-ratchet"],
|
|
}),
|
|
);
|
|
expect(PREFLIGHT_CHECKS).toContainEqual(
|
|
expect.objectContaining({
|
|
name: "assertion SAFETY comment ratchet",
|
|
args: ["check:assertion-safety"],
|
|
}),
|
|
);
|
|
expect(PREFLIGHT_CHECKS).toContainEqual({
|
|
name: "test timeout race ratchet",
|
|
args: ["check:test-timeout-race-ratchet"],
|
|
usesBase: true,
|
|
});
|
|
expect(PREFLIGHT_CHECKS).toContainEqual({
|
|
name: "script TypeScript erasability",
|
|
args: ["check:script-erasability"],
|
|
});
|
|
});
|
|
});
|