diff --git a/scripts/e2e/openwebui-docker.sh b/scripts/e2e/openwebui-docker.sh index 6569e4a4ef29..7389d22c4ab4 100755 --- a/scripts/e2e/openwebui-docker.sh +++ b/scripts/e2e/openwebui-docker.sh @@ -29,6 +29,18 @@ DOCKER_COMMAND_TIMEOUT="${OPENCLAW_OPENWEBUI_DOCKER_COMMAND_TIMEOUT:-$((PROVIDER DOCKER_PULL_TIMEOUT="${OPENCLAW_OPENWEBUI_DOCKER_PULL_TIMEOUT:-600s}" SMOKE_MODE="${OPENWEBUI_SMOKE_MODE:-${OPENCLAW_OPENWEBUI_SMOKE_MODE:-chat}}" +validate_tcp_port() { + local label="$1" + local value="$2" + if [[ ! "$value" =~ ^[0-9]+$ ]] || [ "$value" -lt 1 ] || [ "$value" -gt 65535 ]; then + echo "invalid $label: $value" >&2 + exit 2 + fi +} + +validate_tcp_port OPENCLAW_OPENWEBUI_GATEWAY_PORT "$PORT" +validate_tcp_port OPENCLAW_OPENWEBUI_PORT "$WEBUI_PORT" + case "$SMOKE_MODE" in chat | models) ;; *) diff --git a/test/scripts/docker-build-helper.test.ts b/test/scripts/docker-build-helper.test.ts index 1db7dada04b3..4bdf32bf4a0d 100644 --- a/test/scripts/docker-build-helper.test.ts +++ b/test/scripts/docker-build-helper.test.ts @@ -1,5 +1,5 @@ // Docker Build Helper tests cover docker build helper script behavior. -import { execFileSync, spawn } from "node:child_process"; +import { execFileSync, spawn, spawnSync } from "node:child_process"; import { chmodSync, existsSync, @@ -2687,6 +2687,8 @@ output="$(cat "$sampler_log")" it("keeps Open WebUI Docker E2E resource-guarded", () => { const runner = readFileSync(OPENWEBUI_DOCKER_E2E_PATH, "utf8"); + expect(runner).toContain('validate_tcp_port OPENCLAW_OPENWEBUI_GATEWAY_PORT "$PORT"'); + expect(runner).toContain('validate_tcp_port OPENCLAW_OPENWEBUI_PORT "$WEBUI_PORT"'); expect(runner).toContain("OPENCLAW_OPENWEBUI_MAX_MEMORY_MIB"); expect(runner).toContain("OPENCLAW_OPENWEBUI_MAX_CPU_PERCENT"); expect(runner).toContain('STATS_LOG="$(mktemp'); @@ -2713,6 +2715,23 @@ output="$(cat "$sampler_log")" ); }); + it.each([ + ["gateway", "OPENCLAW_OPENWEBUI_GATEWAY_PORT", "1e3"], + ["webui", "OPENCLAW_OPENWEBUI_PORT", "65536"], + ])("rejects invalid Open WebUI Docker %s ports before Docker setup", (_label, envName, value) => { + const result = spawnSync("bash", [OPENWEBUI_DOCKER_E2E_PATH], { + encoding: "utf8", + env: { + ...process.env, + [envName]: value, + }, + }); + + expect(result.status).toBe(2); + expect(result.stderr).toContain(`invalid ${envName}: ${value}`); + expect(result.stderr).not.toContain("OPENAI_API_KEY is required"); + }); + it("forwards every kitchen-sink RPC runtime env knob into Docker", () => { const runner = readFileSync(KITCHEN_SINK_RPC_DOCKER_E2E_PATH, "utf8"); const walk = readFileSync("scripts/e2e/kitchen-sink-rpc-walk.mjs", "utf8");