diff --git a/scripts/e2e/mcp-code-mode-gateway-docker.sh b/scripts/e2e/mcp-code-mode-gateway-docker.sh index 487c0a10f381..3002bea0ac4b 100755 --- a/scripts/e2e/mcp-code-mode-gateway-docker.sh +++ b/scripts/e2e/mcp-code-mode-gateway-docker.sh @@ -11,6 +11,19 @@ PORT="${OPENCLAW_MCP_CODE_MODE_GATEWAY_PORT:-18789}" MOCK_PORT="${OPENCLAW_MCP_CODE_MODE_MOCK_PORT:-44082}" TOKEN="mcp-code-mode-e2e-$(date +%s)-$$" CONTAINER_NAME="openclaw-mcp-code-mode-e2e-$$" + +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_MCP_CODE_MODE_GATEWAY_PORT "$PORT" +validate_tcp_port OPENCLAW_MCP_CODE_MODE_MOCK_PORT "$MOCK_PORT" + CLIENT_LOG="$(mktemp -t openclaw-mcp-code-mode-client-log.XXXXXX)" cleanup() { diff --git a/scripts/e2e/mcp-code-mode-gateway-live-docker.sh b/scripts/e2e/mcp-code-mode-gateway-live-docker.sh index 0a30ccf8fc44..4f6edb1e8696 100755 --- a/scripts/e2e/mcp-code-mode-gateway-live-docker.sh +++ b/scripts/e2e/mcp-code-mode-gateway-live-docker.sh @@ -10,9 +10,21 @@ IMAGE_NAME="$(docker_e2e_resolve_image "openclaw-mcp-code-mode-gateway-live-e2e" PORT="${OPENCLAW_MCP_CODE_MODE_LIVE_GATEWAY_PORT:-18789}" TOKEN="mcp-code-mode-live-e2e-$(date +%s)-$$" CONTAINER_NAME="openclaw-mcp-code-mode-live-e2e-$$" -CLIENT_LOG="$(mktemp -t openclaw-mcp-code-mode-live-log.XXXXXX)" PROFILE_FILE="${OPENCLAW_MCP_CODE_MODE_LIVE_PROFILE_FILE:-${OPENCLAW_TESTBOX_PROFILE_FILE:-$HOME/.openclaw-testbox-live.profile}}" +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_MCP_CODE_MODE_LIVE_GATEWAY_PORT "$PORT" + +CLIENT_LOG="$(mktemp -t openclaw-mcp-code-mode-live-log.XXXXXX)" + cleanup() { docker_e2e_docker_cmd rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true rm -f "$CLIENT_LOG" diff --git a/test/scripts/docker-build-helper.test.ts b/test/scripts/docker-build-helper.test.ts index 4bdf32bf4a0d..5cef5a664937 100644 --- a/test/scripts/docker-build-helper.test.ts +++ b/test/scripts/docker-build-helper.test.ts @@ -35,6 +35,7 @@ const ONBOARD_DOCKER_E2E_PATH = "scripts/e2e/onboard-docker.sh"; const KITCHEN_SINK_PLUGIN_DOCKER_E2E_PATH = "scripts/e2e/kitchen-sink-plugin-docker.sh"; const KITCHEN_SINK_RPC_DOCKER_E2E_PATH = "scripts/e2e/kitchen-sink-rpc-docker.sh"; const CODEX_ON_DEMAND_DOCKER_E2E_PATH = "scripts/e2e/codex-on-demand-docker.sh"; +const MCP_CODE_MODE_GATEWAY_DOCKER_E2E_PATH = "scripts/e2e/mcp-code-mode-gateway-docker.sh"; const MCP_CODE_MODE_GATEWAY_LIVE_DOCKER_E2E_PATH = "scripts/e2e/mcp-code-mode-gateway-live-docker.sh"; const CODEX_MEDIA_PATH_SCENARIO_PATH = "scripts/e2e/lib/codex-media-path/scenario.sh"; @@ -2732,6 +2733,27 @@ output="$(cat "$sampler_log")" expect(result.stderr).not.toContain("OPENAI_API_KEY is required"); }); + it.each([ + [MCP_CODE_MODE_GATEWAY_DOCKER_E2E_PATH, "OPENCLAW_MCP_CODE_MODE_GATEWAY_PORT", "1e3"], + [MCP_CODE_MODE_GATEWAY_DOCKER_E2E_PATH, "OPENCLAW_MCP_CODE_MODE_MOCK_PORT", "65536"], + [MCP_CODE_MODE_GATEWAY_LIVE_DOCKER_E2E_PATH, "OPENCLAW_MCP_CODE_MODE_LIVE_GATEWAY_PORT", "0"], + ])( + "rejects invalid MCP code-mode Docker ports before Docker setup", + (scriptPath, envName, value) => { + const result = spawnSync("bash", [scriptPath], { + 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 was not available"); + }, + ); + 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");