diff --git a/scripts/e2e/openai-chat-tools-docker.sh b/scripts/e2e/openai-chat-tools-docker.sh index 57039abc2bff..00fdfcb61100 100644 --- a/scripts/e2e/openai-chat-tools-docker.sh +++ b/scripts/e2e/openai-chat-tools-docker.sh @@ -8,6 +8,9 @@ IMAGE_NAME="$(docker_e2e_resolve_image "openclaw-openai-chat-tools-e2e" OPENCLAW SKIP_BUILD="${OPENCLAW_OPENAI_CHAT_TOOLS_E2E_SKIP_BUILD:-0}" PORT="$(docker_e2e_read_tcp_port_env OPENCLAW_OPENAI_CHAT_TOOLS_PORT 18789)" TIMEOUT_SECONDS="$(docker_e2e_read_positive_int_env OPENCLAW_OPENAI_CHAT_TOOLS_TIMEOUT_SECONDS 180)" +MAX_BODY_BYTES="$( + docker_e2e_read_positive_int_env OPENCLAW_OPENAI_CHAT_TOOLS_MAX_BODY_BYTES 1048576 +)" TOKEN="openai-chat-tools-e2e-$$" PROFILE_FILE="${OPENCLAW_OPENAI_CHAT_TOOLS_PROFILE_FILE:-${OPENCLAW_TESTBOX_PROFILE_FILE:-$HOME/.openclaw-testbox-live.profile}}" if [ ! -f "$PROFILE_FILE" ] && [ -f "$HOME/.profile" ]; then @@ -65,6 +68,7 @@ docker_e2e_run_logged_with_harness openai-chat-tools \ -e "OPENCLAW_GATEWAY_TOKEN=$TOKEN" \ -e "OPENCLAW_OPENAI_CHAT_TOOLS_MODEL=${OPENCLAW_OPENAI_CHAT_TOOLS_MODEL:-openai/gpt-5.4-mini}" \ -e "OPENCLAW_OPENAI_CHAT_TOOLS_TIMEOUT_SECONDS=$TIMEOUT_SECONDS" \ + -e "OPENCLAW_OPENAI_CHAT_TOOLS_MAX_BODY_BYTES=$MAX_BODY_BYTES" \ -e "OPENCLAW_TEST_STATE_SCRIPT_B64=$OPENCLAW_TEST_STATE_SCRIPT_B64" \ -e "PORT=$PORT" \ "${PROFILE_MOUNT[@]}" \ diff --git a/test/scripts/openai-chat-tools-client.test.ts b/test/scripts/openai-chat-tools-client.test.ts index d270f969f90b..1f6b9020e756 100644 --- a/test/scripts/openai-chat-tools-client.test.ts +++ b/test/scripts/openai-chat-tools-client.test.ts @@ -6,6 +6,7 @@ import { tmpdir } from "node:os"; import path from "node:path"; import { beforeAll, describe, expect, it } from "vitest"; import { createBoundedChildOutput } from "../helpers/bounded-child-output.js"; +import { cleanupTempDirs, makeTempDir } from "../helpers/temp-dir.js"; const clientPath = path.resolve("scripts/e2e/lib/openai-chat-tools/client.mjs"); const dockerRunnerPath = path.resolve("scripts/e2e/openai-chat-tools-docker.sh"); @@ -204,6 +205,44 @@ describe("scripts/e2e/lib/openai-chat-tools/client.mjs", () => { rmSync(root, { force: true, recursive: true }); } }); + + it.each([ + ["timeout", "OPENCLAW_OPENAI_CHAT_TOOLS_TIMEOUT_SECONDS", "1e3"], + ["body limit", "OPENCLAW_OPENAI_CHAT_TOOLS_MAX_BODY_BYTES", "64bytes"], + ])( + "rejects invalid Docker runner %s before auth or Docker build work starts", + (_label, envName, value) => { + const tempDirs: string[] = []; + const root = makeTempDir(tempDirs, "openclaw-openai-chat-tools-"); + try { + const result = runDockerRunnerAuthPreflight(root, { [envName]: value }); + const output = `${result.stdout}\n${result.stderr}`; + + expect(result.status).toBe(2); + expect(output).toContain(`invalid ${envName}: ${value}`); + expect(output).not.toContain("OPENAI_API_KEY was not available"); + expect(output).not.toContain("Building Docker image:"); + expect(output).not.toContain("Reusing Docker image:"); + expect(output).not.toContain("Running OpenAI Chat Completions tools Docker E2E"); + } finally { + cleanupTempDirs(tempDirs); + } + }, + ); + + it("passes normalized timeout and body limits into the Docker runner", () => { + const runner = readFileSync(dockerRunnerPath, "utf8"); + + expect(runner).toContain( + "docker_e2e_read_positive_int_env OPENCLAW_OPENAI_CHAT_TOOLS_TIMEOUT_SECONDS 180", + ); + expect(runner).toContain( + "docker_e2e_read_positive_int_env OPENCLAW_OPENAI_CHAT_TOOLS_MAX_BODY_BYTES 1048576", + ); + expect(runner).toContain('-e "OPENCLAW_OPENAI_CHAT_TOOLS_TIMEOUT_SECONDS=$TIMEOUT_SECONDS"'); + expect(runner).toContain('-e "OPENCLAW_OPENAI_CHAT_TOOLS_MAX_BODY_BYTES=$MAX_BODY_BYTES"'); + }); + it("rejects loose timeout env values instead of parsing numeric prefixes", async () => { const result = await runClient(1, { OPENCLAW_OPENAI_CHAT_TOOLS_TIMEOUT_SECONDS: "1e3",