Files
adolf/test/scripts/local-heavy-check-runtime.test.ts
alvis bedb527145
Some checks failed
ClawSweeper Dispatch / dispatch (push) Has been cancelled
CodeQL / Security High (actions) (push) Has been cancelled
CodeQL / Security High (channel-runtime-boundary) (push) Has been cancelled
CodeQL / Security High (core-auth-secrets) (push) Has been cancelled
CodeQL / Security High (mcp-process-tool-boundary) (push) Has been cancelled
CodeQL / Security High (network-ssrf-boundary) (push) Has been cancelled
CodeQL / Security High (plugin-trust-boundary) (push) Has been cancelled
CodeQL / Security High (process-exec-boundary) (push) Has been cancelled
Docs Sync Publish Repo / sync-publish-repo (push) Has been cancelled
Docs / docs (push) Has been cancelled
OpenClaw Stable Main Closeout / Resolve stable release closeout inputs (push) Has been cancelled
OpenClaw Stable Main Closeout / Verify stable main closeout (push) Has been cancelled
Workflow Sanity / no-tabs (push) Has been cancelled
Workflow Sanity / actionlint (push) Has been cancelled
Workflow Sanity / generated-doc-baselines (push) Has been cancelled
CI / runner-admission (push) Has been cancelled
CI / preflight (push) Has been cancelled
CI / security-fast (push) Has been cancelled
CI / pnpm-store-warmup (push) Has been cancelled
CI / build-artifacts (push) Has been cancelled
CI / native-i18n (push) Has been cancelled
CI / ${{ matrix.check_name }} (push) Has been cancelled
CI / ${{ matrix.checkName }} (push) Has been cancelled
CI / checks-node-compat-node22 (push) Has been cancelled
CI / check-bundled-channel-config-metadata (push) Has been cancelled
CI / check-dependencies (push) Has been cancelled
CI / check-guards (push) Has been cancelled
CI / check-lint (push) Has been cancelled
CI / check-prod-types (push) Has been cancelled
CI / check-shrinkwrap (push) Has been cancelled
CI / check-test-types (push) Has been cancelled
CI / check-additional-boundaries-a (push) Has been cancelled
CI / check-additional-boundaries-bcd (push) Has been cancelled
CI / check-additional-extension-bundled (push) Has been cancelled
CI / check-additional-extension-channels (push) Has been cancelled
CI / check-additional-extension-package-boundary (push) Has been cancelled
CI / check-additional-runtime-topology-architecture (push) Has been cancelled
CI / check-session-accessor-boundary (push) Has been cancelled
CI / check-session-transcript-reader-boundary (push) Has been cancelled
CI / check-docs (push) Has been cancelled
CI / skills-python (push) Has been cancelled
CI / macos-swift (push) Has been cancelled
CI / ios-build (push) Has been cancelled
CI / ci-timings-summary (push) Has been cancelled
Native App Locale Refresh / Refresh native fa (push) Has been cancelled
Native App Locale Refresh / Refresh native fr (push) Has been cancelled
Native App Locale Refresh / Refresh native hi (push) Has been cancelled
Native App Locale Refresh / Refresh native id (push) Has been cancelled
Native App Locale Refresh / Refresh native it (push) Has been cancelled
Native App Locale Refresh / Refresh native ja-JP (push) Has been cancelled
Control UI Locale Refresh / plan (push) Has been cancelled
Control UI Locale Refresh / Refresh ${{ matrix.locale }} (push) Has been cancelled
Control UI Locale Refresh / Commit control UI locale refresh (push) Has been cancelled
Live Media Runner Image / Build live media runner image (push) Has been cancelled
Native App Locale Refresh / Refresh native ar (push) Has been cancelled
Native App Locale Refresh / Refresh native de (push) Has been cancelled
Native App Locale Refresh / Refresh native es (push) Has been cancelled
Native App Locale Refresh / Refresh native ko (push) Has been cancelled
Native App Locale Refresh / Refresh native nl (push) Has been cancelled
Native App Locale Refresh / Refresh native pl (push) Has been cancelled
Native App Locale Refresh / Refresh native pt-BR (push) Has been cancelled
Native App Locale Refresh / Refresh native ru (push) Has been cancelled
Native App Locale Refresh / Refresh native sv (push) Has been cancelled
Native App Locale Refresh / Refresh native th (push) Has been cancelled
Native App Locale Refresh / Refresh native tr (push) Has been cancelled
Native App Locale Refresh / Refresh native uk (push) Has been cancelled
Native App Locale Refresh / Refresh native vi (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-CN (push) Has been cancelled
Native App Locale Refresh / Refresh native zh-TW (push) Has been cancelled
Native App Locale Refresh / Commit native locale refresh (push) Has been cancelled
Plugin Init Scaffold Validation / Validate provider scaffold (push) Has been cancelled
Plugin NPM Release / preview_plugins_npm (push) Has been cancelled
Plugin NPM Release / Validate release publish approval (push) Has been cancelled
Plugin NPM Release / preview_plugin_pack (push) Has been cancelled
Plugin NPM Release / publish_plugins_npm (push) Has been cancelled
Sandbox Common Smoke / sandbox-common-smoke (push) Has been cancelled
Website Installer Sync / static (push) Has been cancelled
Website Installer Sync / linux-docker (push) Has been cancelled
Website Installer Sync / macos-installer (push) Has been cancelled
Website Installer Sync / windows-installer (push) Has been cancelled
Website Installer Sync / sync-website (push) Has been cancelled
Vendor OpenClaw source as Adolf fork baseline
Adolf is a fork/vendored clone of github.com/openclaw/openclaw (v2026.6.11),
free to diverge. Tree copied sans upstream .git; upstream remote added for
future syncs. Node pinned to 24 (.nvmrc); engines already require >=22.19.
Preserves docs/ARCHITECTURE.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
2026-07-05 09:36:54 +00:00

450 lines
14 KiB
TypeScript

// Local Heavy Check Runtime tests cover local heavy check runtime script behavior.
import { execFileSync } from "node:child_process";
import fs from "node:fs";
import path from "node:path";
import { describe, expect, it } from "vitest";
import {
acquireLocalHeavyCheckLockSync,
applyLocalOxlintPolicy,
applyLocalTsgoPolicy,
resolveLocalHeavyCheckEnv,
shouldAcquireLocalHeavyCheckLockForOxlint,
shouldAcquireLocalHeavyCheckLockForTsgo,
} from "../../scripts/lib/local-heavy-check-runtime.mjs";
import { createScriptTestHarness } from "./test-helpers.js";
const { createTempDir } = createScriptTestHarness();
const GIB = 1024 ** 3;
const CONSTRAINED_HOST = {
totalMemoryBytes: 16 * GIB,
logicalCpuCount: 8,
};
const ROOMY_HOST = {
totalMemoryBytes: 128 * GIB,
logicalCpuCount: 16,
};
function makeEnv(overrides: Record<string, string | undefined> = {}) {
const env = {
...process.env,
OPENCLAW_LOCAL_CHECK: "1",
...overrides,
};
if (!Object.hasOwn(overrides, "OPENCLAW_LOCAL_CHECK_MODE")) {
delete env.OPENCLAW_LOCAL_CHECK_MODE;
}
return env;
}
describe("local-heavy-check-runtime", () => {
it("reenables local heavy-check policy for local wrapper entrypoints", () => {
expect(resolveLocalHeavyCheckEnv({ OPENCLAW_LOCAL_CHECK: "0", PATH: "/usr/bin" })).toEqual({
OPENCLAW_LOCAL_CHECK: "1",
PATH: "/usr/bin",
});
expect(resolveLocalHeavyCheckEnv({ OPENCLAW_LOCAL_CHECK: "false", PATH: "/usr/bin" })).toEqual({
OPENCLAW_LOCAL_CHECK: "1",
PATH: "/usr/bin",
});
});
it("preserves local-check disablement in CI", () => {
expect(
resolveLocalHeavyCheckEnv({
CI: "true",
OPENCLAW_LOCAL_CHECK: "0",
PATH: "/usr/bin",
}),
).toEqual({
CI: "true",
OPENCLAW_LOCAL_CHECK: "0",
PATH: "/usr/bin",
});
});
it("tightens local tsgo runs on constrained hosts", () => {
const { args, env } = applyLocalTsgoPolicy([], makeEnv(), CONSTRAINED_HOST);
expect(args).toEqual([
"--declaration",
"false",
"--incremental",
"--tsBuildInfoFile",
".artifacts/tsgo-cache/root.tsbuildinfo",
"--singleThreaded",
"--checkers",
"1",
]);
expect(env.GOGC).toBe("30");
expect(env.GOMEMLIMIT).toBe("3GiB");
});
it("skips declaration transforms for no-emit tsgo checks", () => {
const { args } = applyLocalTsgoPolicy([], makeEnv({ OPENCLAW_LOCAL_CHECK: "0" }), ROOMY_HOST);
expect(args).toEqual(["--declaration", "false"]);
});
it("keeps explicit tsgo flags and Go env overrides intact when throttled", () => {
const { args, env } = applyLocalTsgoPolicy(
["--checkers", "4", "--singleThreaded", "--pprofDir", "/tmp/existing"],
makeEnv({
GOGC: "80",
GOMEMLIMIT: "5GiB",
OPENCLAW_TSGO_PPROF_DIR: "/tmp/profile",
}),
CONSTRAINED_HOST,
);
expect(args).toEqual([
"--checkers",
"4",
"--singleThreaded",
"--pprofDir",
"/tmp/existing",
"--declaration",
"false",
]);
expect(env.GOGC).toBe("80");
expect(env.GOMEMLIMIT).toBe("5GiB");
});
it("keeps explicit tsgo declaration flags intact", () => {
const env = makeEnv({ OPENCLAW_LOCAL_CHECK_MODE: "full" });
const longFlag = applyLocalTsgoPolicy(["--declaration"], env, ROOMY_HOST);
const shortFlag = applyLocalTsgoPolicy(["-d"], env, ROOMY_HOST);
expect(longFlag.args).toEqual(["--declaration"]);
expect(shortFlag.args).toEqual(["-d"]);
});
it("defaults local tsgo to full-speed mode on roomy hosts", () => {
const { args, env } = applyLocalTsgoPolicy([], makeEnv(), ROOMY_HOST);
expect(args).toEqual([
"--declaration",
"false",
"--incremental",
"--tsBuildInfoFile",
".artifacts/tsgo-cache/root.tsbuildinfo",
]);
expect(env.GOGC).toBeUndefined();
expect(env.GOMEMLIMIT).toBeUndefined();
});
it("uses the configured local tsgo build info file", () => {
const { args } = applyLocalTsgoPolicy(
[],
makeEnv({
OPENCLAW_LOCAL_CHECK_MODE: "full",
OPENCLAW_TSGO_BUILD_INFO_FILE: ".artifacts/custom/tsgo.tsbuildinfo",
}),
ROOMY_HOST,
);
expect(args).toEqual([
"--declaration",
"false",
"--incremental",
"--tsBuildInfoFile",
".artifacts/custom/tsgo.tsbuildinfo",
]);
});
it("avoids incremental cache reuse for ad hoc tsgo runs", () => {
const { args } = applyLocalTsgoPolicy(
["--extendedDiagnostics"],
makeEnv({ OPENCLAW_LOCAL_CHECK_MODE: "full" }),
ROOMY_HOST,
);
expect(args).toEqual(["--extendedDiagnostics", "--declaration", "false"]);
});
it("allows forcing the throttled tsgo policy on roomy hosts", () => {
const { args, env } = applyLocalTsgoPolicy(
[],
makeEnv({
OPENCLAW_LOCAL_CHECK_MODE: "throttled",
}),
ROOMY_HOST,
);
expect(args).toEqual([
"--declaration",
"false",
"--incremental",
"--tsBuildInfoFile",
".artifacts/tsgo-cache/root.tsbuildinfo",
"--singleThreaded",
"--checkers",
"1",
]);
expect(env.GOGC).toBe("30");
expect(env.GOMEMLIMIT).toBe("3GiB");
});
it("allows forcing full-speed tsgo runs on roomy hosts", () => {
const { args, env } = applyLocalTsgoPolicy(
[],
makeEnv({
OPENCLAW_LOCAL_CHECK_MODE: "full",
}),
ROOMY_HOST,
);
expect(args).toEqual([
"--declaration",
"false",
"--incremental",
"--tsBuildInfoFile",
".artifacts/tsgo-cache/root.tsbuildinfo",
]);
expect(env.GOGC).toBeUndefined();
expect(env.GOMEMLIMIT).toBeUndefined();
});
it("skips the heavy-check lock for tsgo metadata commands", () => {
expect(shouldAcquireLocalHeavyCheckLockForTsgo(["--help"])).toBe(false);
expect(shouldAcquireLocalHeavyCheckLockForTsgo(["-h"])).toBe(false);
expect(shouldAcquireLocalHeavyCheckLockForTsgo(["--version"])).toBe(false);
expect(shouldAcquireLocalHeavyCheckLockForTsgo(["-v"])).toBe(false);
expect(shouldAcquireLocalHeavyCheckLockForTsgo(["--init"])).toBe(false);
expect(shouldAcquireLocalHeavyCheckLockForTsgo(["--showConfig"])).toBe(false);
});
it("keeps the heavy-check lock for real tsgo runs", () => {
expect(shouldAcquireLocalHeavyCheckLockForTsgo([])).toBe(true);
expect(shouldAcquireLocalHeavyCheckLockForTsgo(["--extendedDiagnostics"])).toBe(true);
});
it("allows forcing the tsgo lock back on", () => {
expect(
shouldAcquireLocalHeavyCheckLockForTsgo(
["--help"],
makeEnv({ OPENCLAW_TSGO_FORCE_LOCK: "1" }),
),
).toBe(true);
});
it("serializes local oxlint runs onto one thread on constrained hosts", () => {
const { args, env } = applyLocalOxlintPolicy([], makeEnv(), CONSTRAINED_HOST);
expect(args).toEqual([
"--type-aware",
"--tsconfig",
"config/tsconfig/oxlint.json",
"--report-unused-disable-directives-severity",
"error",
"--threads=1",
]);
expect(env.GOGC).toBe("30");
expect(env.GOMEMLIMIT).toBe("3GiB");
});
it("defaults local oxlint to one thread on roomy hosts", () => {
const { args, env } = applyLocalOxlintPolicy([], makeEnv(), ROOMY_HOST);
expect(args).toEqual([
"--type-aware",
"--tsconfig",
"config/tsconfig/oxlint.json",
"--report-unused-disable-directives-severity",
"error",
"--threads=1",
]);
expect(env.GOGC).toBe("30");
expect(env.GOMEMLIMIT).toBe("3GiB");
});
it("honors an explicit oxlint thread count", () => {
const { args, env } = applyLocalOxlintPolicy(
["--threads=8"],
makeEnv({ GOGC: "80", GOMEMLIMIT: "5GiB" }),
ROOMY_HOST,
);
expect(args).toEqual([
"--threads=8",
"--type-aware",
"--tsconfig",
"config/tsconfig/oxlint.json",
"--report-unused-disable-directives-severity",
"error",
]);
expect(env.GOGC).toBe("80");
expect(env.GOMEMLIMIT).toBe("5GiB");
});
it("allows forcing full-speed oxlint runs on roomy hosts", () => {
const { args, env } = applyLocalOxlintPolicy(
[],
makeEnv({
OPENCLAW_LOCAL_CHECK_MODE: "full",
}),
ROOMY_HOST,
);
expect(args).toEqual([
"--type-aware",
"--tsconfig",
"config/tsconfig/oxlint.json",
"--report-unused-disable-directives-severity",
"error",
]);
expect(env.GOGC).toBeUndefined();
expect(env.GOMEMLIMIT).toBeUndefined();
});
it("skips the heavy-check lock for explicit oxlint file targets", () => {
const cwd = createTempDir("openclaw-oxlint-lock-skip-");
const target = path.join(cwd, "sample.ts");
fs.writeFileSync(target, "export const ok = true;\n", "utf8");
expect(
shouldAcquireLocalHeavyCheckLockForOxlint(["--type-aware", "--", "sample.ts"], { cwd }),
).toBe(false);
});
it("skips the heavy-check lock for oxlint metadata commands", () => {
expect(shouldAcquireLocalHeavyCheckLockForOxlint(["--help"])).toBe(false);
expect(shouldAcquireLocalHeavyCheckLockForOxlint(["-h"])).toBe(false);
expect(shouldAcquireLocalHeavyCheckLockForOxlint(["--version"])).toBe(false);
expect(shouldAcquireLocalHeavyCheckLockForOxlint(["-V"])).toBe(false);
expect(shouldAcquireLocalHeavyCheckLockForOxlint(["--rules"])).toBe(false);
expect(shouldAcquireLocalHeavyCheckLockForOxlint(["--print-config"])).toBe(false);
expect(shouldAcquireLocalHeavyCheckLockForOxlint(["--init"])).toBe(false);
});
it("keeps the heavy-check lock for directory targets and broad oxlint runs", () => {
const cwd = createTempDir("openclaw-oxlint-lock-keep-");
fs.mkdirSync(path.join(cwd, "src"), { recursive: true });
fs.writeFileSync(path.join(cwd, "src", "sample.ts"), "export const ok = true;\n", "utf8");
expect(shouldAcquireLocalHeavyCheckLockForOxlint(["--type-aware", "--", "src"], { cwd })).toBe(
true,
);
expect(shouldAcquireLocalHeavyCheckLockForOxlint(["--type-aware"], { cwd })).toBe(true);
});
it("allows forcing the oxlint lock back on", () => {
const cwd = createTempDir("openclaw-oxlint-lock-force-");
fs.writeFileSync(path.join(cwd, "sample.ts"), "export const ok = true;\n", "utf8");
expect(
shouldAcquireLocalHeavyCheckLockForOxlint(["--type-aware", "--", "sample.ts"], {
cwd,
env: makeEnv({ OPENCLAW_OXLINT_FORCE_LOCK: "1" }),
}),
).toBe(true);
});
it("reclaims stale local heavy-check locks from dead pids", () => {
const cwd = createTempDir("openclaw-local-heavy-check-");
const commonDir = path.join(cwd, ".git");
const lockDir = path.join(commonDir, "openclaw-local-checks", "heavy-check.lock");
fs.mkdirSync(lockDir, { recursive: true });
fs.writeFileSync(
path.join(lockDir, "owner.json"),
`${JSON.stringify({
pid: 999_999_999,
tool: "tsgo",
cwd,
})}\n`,
"utf8",
);
const release = acquireLocalHeavyCheckLockSync({
cwd,
env: makeEnv(),
toolName: "oxlint",
});
const owner = JSON.parse(fs.readFileSync(path.join(lockDir, "owner.json"), "utf8"));
expect(owner.pid).toBe(process.pid);
expect(owner.tool).toBe("oxlint");
release();
expect(fs.existsSync(lockDir)).toBe(false);
});
it("uses a worktree-local heavy-check lock when explicitly requested", () => {
const repoRoot = createTempDir("openclaw-local-heavy-check-worktree-");
execFileSync("git", ["init"], { cwd: repoRoot, stdio: "ignore" });
const cwd = path.join(repoRoot, "nested", "tooling");
fs.mkdirSync(cwd, { recursive: true });
const commonLockDir = path.join(repoRoot, ".git", "openclaw-local-checks", "heavy-check.lock");
const worktreeLockDir = path.join(
repoRoot,
".artifacts",
"openclaw-local-checks",
"heavy-check.lock",
);
const nestedLockDir = path.join(cwd, ".artifacts", "openclaw-local-checks", "heavy-check.lock");
const release = acquireLocalHeavyCheckLockSync({
cwd,
env: makeEnv({ OPENCLAW_HEAVY_CHECK_LOCK_SCOPE: "worktree" }),
toolName: "check:changed",
});
const owner = JSON.parse(fs.readFileSync(path.join(worktreeLockDir, "owner.json"), "utf8"));
expect(owner.tool).toBe("check:changed");
expect(fs.existsSync(worktreeLockDir)).toBe(true);
expect(fs.existsSync(commonLockDir)).toBe(false);
expect(fs.existsSync(nestedLockDir)).toBe(false);
release();
expect(fs.existsSync(worktreeLockDir)).toBe(false);
});
it("rejects malformed heavy-check lock timing env values", () => {
const cwd = createTempDir("openclaw-local-heavy-check-malformed-env-");
expect(() =>
acquireLocalHeavyCheckLockSync({
cwd,
env: makeEnv({ OPENCLAW_HEAVY_CHECK_LOCK_TIMEOUT_MS: "10ms" }),
toolName: "oxlint",
}),
).toThrow("OPENCLAW_HEAVY_CHECK_LOCK_TIMEOUT_MS must be a positive integer; got: 10ms");
expect(() =>
acquireLocalHeavyCheckLockSync({
cwd,
env: makeEnv({ OPENCLAW_HEAVY_CHECK_LOCK_POLL_MS: "0" }),
toolName: "oxlint",
}),
).toThrow("OPENCLAW_HEAVY_CHECK_LOCK_POLL_MS must be a positive integer; got: 0");
});
it("cleans up stale legacy test locks when acquiring the shared heavy-check lock", () => {
const cwd = createTempDir("openclaw-local-heavy-check-legacy-");
const commonDir = path.join(cwd, ".git");
const locksDir = path.join(commonDir, "openclaw-local-checks");
const legacyLockDir = path.join(locksDir, "test.lock");
const heavyCheckLockDir = path.join(locksDir, "heavy-check.lock");
fs.mkdirSync(legacyLockDir, { recursive: true });
fs.writeFileSync(
path.join(legacyLockDir, "owner.json"),
`${JSON.stringify({
pid: 999_999_999,
tool: "test",
cwd,
})}\n`,
"utf8",
);
const release = acquireLocalHeavyCheckLockSync({
cwd,
env: makeEnv(),
toolName: "oxlint",
});
expect(fs.existsSync(legacyLockDir)).toBe(false);
expect(fs.existsSync(heavyCheckLockDir)).toBe(true);
release();
expect(fs.existsSync(heavyCheckLockDir)).toBe(false);
});
});