|
1 | 1 | import { spawnSync } from "node:child_process"; |
| 2 | +import { mkdtempSync, rmSync } from "node:fs"; |
| 3 | +import { tmpdir } from "node:os"; |
2 | 4 | import { describe, expect, it } from "vitest"; |
3 | 5 | import { DEFAULT_RESOURCE_LIMITS } from "../../scripts/lib/docker-e2e-plan.mjs"; |
4 | 6 | import { |
@@ -73,6 +75,51 @@ describe("scripts/test-docker-all scheduler", () => {
|
73 | 75 | expect(result.stderr).not.toContain("at "); |
74 | 76 | }); |
75 | 77 | |
| 78 | +it("rejects loose numeric runner env vars without a stack trace", () => { |
| 79 | +const result = spawnSync(process.execPath, ["scripts/test-docker-all.mjs", "--plan-json"], { |
| 80 | +cwd: process.cwd(), |
| 81 | +encoding: "utf8", |
| 82 | +env: { |
| 83 | + ...process.env, |
| 84 | +OPENCLAW_DOCKER_ALL_PARALLELISM: "1e3", |
| 85 | +}, |
| 86 | +}); |
| 87 | + |
| 88 | +expect(result.status).toBe(1); |
| 89 | +expect(result.stdout).toBe(""); |
| 90 | +expect(result.stderr).toContain( |
| 91 | +"OPENCLAW_DOCKER_ALL_PARALLELISM must be a positive integer", |
| 92 | +); |
| 93 | +expect(result.stderr).not.toContain("at "); |
| 94 | +}); |
| 95 | + |
| 96 | +it("rejects loose numeric resource limit env vars before scheduling lanes", () => { |
| 97 | +const logDir = mkdtempSync(`${tmpdir()}/openclaw-docker-all-`); |
| 98 | +try { |
| 99 | +const result = spawnSync(process.execPath, ["scripts/test-docker-all.mjs"], { |
| 100 | +cwd: process.cwd(), |
| 101 | +encoding: "utf8", |
| 102 | +env: { |
| 103 | + ...process.env, |
| 104 | +OPENCLAW_DOCKER_ALL_BUILD: "0", |
| 105 | +OPENCLAW_DOCKER_ALL_DOCKER_LIMIT: "1e3", |
| 106 | +OPENCLAW_DOCKER_ALL_DRY_RUN: "1", |
| 107 | +OPENCLAW_DOCKER_ALL_LOG_DIR: logDir, |
| 108 | +OPENCLAW_DOCKER_ALL_PREFLIGHT: "0", |
| 109 | +OPENCLAW_DOCKER_ALL_TIMINGS: "0", |
| 110 | +}, |
| 111 | +}); |
| 112 | + |
| 113 | +expect(result.status).toBe(1); |
| 114 | +expect(result.stderr).toContain( |
| 115 | +"OPENCLAW_DOCKER_ALL_DOCKER_LIMIT must be a positive integer", |
| 116 | +); |
| 117 | +expect(result.stderr).not.toContain("at "); |
| 118 | +} finally { |
| 119 | +rmSync(logDir, { force: true, recursive: true }); |
| 120 | +} |
| 121 | +}); |
| 122 | + |
76 | 123 | it("allows an overweight lane to start alone under low parallelism", () => { |
77 | 124 | expect( |
78 | 125 | canStartSchedulerLane( |
|