

























@@ -54,7 +54,9 @@ function isProcessAlive(pid: number): boolean {
5454}
55555656async function sleep(ms: number): Promise<void> {
57-await new Promise((resolve) => setTimeout(resolve, ms));
57+await new Promise((resolve) => {
58+setTimeout(resolve, ms);
59+});
5860}
59616062async function waitForFile(filePath: string, timeoutMs: number): Promise<void> {
@@ -247,6 +249,56 @@ describe("resolveTsdownBuildInvocation", () => {
247249expect(result.options.env.NODE_OPTIONS).toBe("--trace-warnings --max-old-space-size=6400");
248250});
249251252+it("honors OPENCLAW_TSDOWN_MAX_OLD_SPACE_MB over platform and memory defaults", () => {
253+const result = resolveTsdownBuildInvocation({
254+nodeExecPath: "/usr/bin/node",
255+npmExecPath: "/tmp/pnpm.cjs",
256+env: { OPENCLAW_TSDOWN_MAX_OLD_SPACE_MB: "3072" },
257+cgroupMemoryLimitBytes: 7 * 1024 * 1024 * 1024,
258+});
259+260+expect(result.options.env.NODE_OPTIONS).toBe("--max-old-space-size=3072");
261+});
262+263+it("keeps memory detection when OPENCLAW_TSDOWN_MAX_OLD_SPACE_MB is blank", () => {
264+const result = resolveTsdownBuildInvocation({
265+nodeExecPath: "/usr/bin/node",
266+npmExecPath: "/tmp/pnpm.cjs",
267+env: { OPENCLAW_TSDOWN_MAX_OLD_SPACE_MB: " " },
268+cgroupMemoryLimitBytes: 7 * 1024 * 1024 * 1024,
269+});
270+271+expect(result.options.env.NODE_OPTIONS).toBe("--max-old-space-size=6400");
272+});
273+274+it("uses OPENCLAW_TSDOWN_MAX_OLD_SPACE_MB to normalize inherited NODE_OPTIONS", () => {
275+const result = resolveTsdownBuildInvocation({
276+platform: "win32",
277+nodeExecPath: "C:\\Program Files\\nodejs\\node.exe",
278+npmExecPath: "C:\\repo\\pnpm.cjs",
279+env: {
280+NODE_OPTIONS: "--trace-warnings --max-old-space-size=12288",
281+OPENCLAW_TSDOWN_MAX_OLD_SPACE_MB: "4096",
282+},
283+ ...NO_MEMORY_LIMIT,
284+});
285+286+expect(result.options.env.NODE_OPTIONS).toBe("--trace-warnings --max-old-space-size=4096");
287+});
288+289+it("rejects malformed OPENCLAW_TSDOWN_MAX_OLD_SPACE_MB values", () => {
290+for (const value of ["0", "-1", "1.5", "1e3", "4096mb", "9007199254740992"]) {
291+expect(() =>
292+resolveTsdownBuildInvocation({
293+nodeExecPath: "/usr/bin/node",
294+npmExecPath: "/tmp/pnpm.cjs",
295+env: { OPENCLAW_TSDOWN_MAX_OLD_SPACE_MB: value },
296+ ...NO_MEMORY_LIMIT,
297+}),
298+).toThrow("OPENCLAW_TSDOWN_MAX_OLD_SPACE_MB must be");
299+}
300+});
301+250302it("falls back to proc meminfo when the cgroup memory limit is unbounded", () => {
251303const fsMock = {
252304readFileSync: vi.fn((filePath: string) => {
@@ -727,7 +779,7 @@ describe("runTsdownBuildInvocation", () => {
727779const rootDir = createTempDir("openclaw-tsdown-timeout-");
728780const childPidPath = path.join(rootDir, "child.pid");
729781const timeoutMs = 1_000;
730-let childPid = 0;
782+let childPid: number | undefined;
731783const childScript = "process.on('SIGTERM', () => {}); setInterval(() => {}, 1000);";
732784const parentScript = [
733785"const { spawn } = require('node:child_process');",
@@ -769,7 +821,7 @@ describe("runTsdownBuildInvocation", () => {
769821expect(result.timedOut).toBe(true);
770822await waitForDead(childPid, 2_000);
771823} finally {
772-if (childPid && isProcessAlive(childPid)) {
824+if (childPid !== undefined && isProcessAlive(childPid)) {
773825process.kill(childPid, "SIGKILL");
774826}
775827}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。