import fs from "node:fs" ;
import path from "node:path" ;
import { describe, expect, it } from "vitest" ;
import {
acquireLocalHeavyCheckLockSync,
applyLocalOxlintPolicy,
applyLocalTsgoPolicy,
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> = {}) {
return {
...process.env,
OPENCLAW_LOCAL_CHECK: "1" ,
...overrides,
};
}
describe("local-heavy-check-runtime" , () => {
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 } = applyLocalOxlintPolicy([], makeEnv(), CONSTRAINED_HOST);
expect(args).toEqual([
"--type-aware" ,
"--tsconfig" ,
"tsconfig.oxlint.json" ,
"--report-unused-disable-directives-severity" ,
"error" ,
"--threads=1" ,
]);
});
it("defaults local oxlint to one thread on roomy hosts" , () => {
const { args } = applyLocalOxlintPolicy([], makeEnv(), ROOMY_HOST);
expect(args).toEqual([
"--type-aware" ,
"--tsconfig" ,
"tsconfig.oxlint.json" ,
"--report-unused-disable-directives-severity" ,
"error" ,
"--threads=1" ,
]);
});
it("allows forcing full-speed oxlint runs on roomy hosts" , () => {
const { args } = applyLocalOxlintPolicy(
[],
makeEnv({
OPENCLAW_LOCAL_CHECK_MODE: "full" ,
}),
ROOMY_HOST,
);
expect(args).toEqual([
"--type-aware" ,
"--tsconfig" ,
"tsconfig.oxlint.json" ,
"--report-unused-disable-directives-severity" ,
"error" ,
]);
});
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("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 );
});
});
Messung V0.5 in Prozent C=99 H=98 G=98
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland