fix(e2e): preflight openai chat tools auth

This commit is contained in:
Vincent Koc
2026-05-31 05:20:33 +02:00
parent 4dad7bd93b
commit e1a9817141
2 changed files with 92 additions and 2 deletions

View File

@@ -13,11 +13,39 @@ if [ ! -f "$PROFILE_FILE" ] && [ -f "$HOME/.profile" ]; then
PROFILE_FILE="$HOME/.profile"
fi
read_profile_openai_api_key() {
local profile_file="$1"
(
set +u
set -a
# shellcheck disable=SC1090
source "$profile_file" >/dev/null
set +a
printf '%s' "${OPENAI_API_KEY:-}"
)
}
PROFILE_STATUS="none"
if [ -f "$PROFILE_FILE" ] && [ -r "$PROFILE_FILE" ]; then
PROFILE_STATUS="$PROFILE_FILE"
fi
OPENAI_API_KEY_VALUE="${OPENAI_API_KEY:-}"
if [ "$PROFILE_STATUS" != "none" ]; then
OPENAI_API_KEY_VALUE="$(read_profile_openai_api_key "$PROFILE_FILE")"
fi
if [[ "$OPENAI_API_KEY_VALUE" == "undefined" || "$OPENAI_API_KEY_VALUE" == "null" ]]; then
OPENAI_API_KEY_VALUE=""
fi
if [ -z "$OPENAI_API_KEY_VALUE" ]; then
echo "ERROR: OPENAI_API_KEY was not available after sourcing $PROFILE_STATUS." >&2
exit 1
fi
docker_e2e_build_or_reuse "$IMAGE_NAME" openai-chat-tools "$ROOT_DIR/scripts/e2e/Dockerfile" "$ROOT_DIR" "" "$SKIP_BUILD"
OPENCLAW_TEST_STATE_SCRIPT_B64="$(docker_e2e_test_state_shell_b64 openai-chat-tools empty)"
PROFILE_MOUNT=()
PROFILE_STATUS="none"
if [ -f "$PROFILE_FILE" ] && [ -r "$PROFILE_FILE" ]; then
set -a
# shellcheck disable=SC1090

View File

@@ -1,11 +1,12 @@
import { spawn, spawnSync } from "node:child_process";
import { mkdtempSync, readFileSync, rmSync } from "node:fs";
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { createServer, type Server } from "node:http";
import { tmpdir } from "node:os";
import path from "node:path";
import { describe, expect, it } from "vitest";
const clientPath = path.resolve("scripts/e2e/lib/openai-chat-tools/client.mjs");
const dockerRunnerPath = path.resolve("scripts/e2e/openai-chat-tools-docker.sh");
const writeConfigPath = path.resolve("scripts/e2e/lib/openai-chat-tools/write-config.mjs");
interface ClientResult {
@@ -96,6 +97,20 @@ function runWriteConfig(root: string, env: Record<string, string> = {}) {
});
}
function runDockerRunnerAuthPreflight(root: string, env: Record<string, string> = {}) {
return spawnSync("bash", [dockerRunnerPath], {
encoding: "utf8",
env: {
...process.env,
HOME: root,
OPENAI_API_KEY: "",
OPENAI_BASE_URL: "",
OPENCLAW_OPENAI_CHAT_TOOLS_PROFILE_FILE: path.join(root, "missing.profile"),
...env,
},
});
}
function toolCallResponse() {
return {
choices: [
@@ -118,6 +133,53 @@ function toolCallResponse() {
}
describe("scripts/e2e/lib/openai-chat-tools/client.mjs", () => {
it("keeps full profile exports out of the Docker build phase", () => {
const runner = readFileSync(dockerRunnerPath, "utf8");
const preflightSourceIndex = runner.indexOf('source "$profile_file"');
const buildIndex = runner.indexOf("docker_e2e_build_or_reuse");
const fullProfileSourceIndex = runner.indexOf('source "$PROFILE_FILE"', buildIndex);
expect(preflightSourceIndex).toBeGreaterThanOrEqual(0);
expect(buildIndex).toBeGreaterThan(preflightSourceIndex);
expect(fullProfileSourceIndex).toBeGreaterThan(buildIndex);
});
it("fails auth preflight before Docker build work starts", () => {
const root = mkdtempSync(path.join(tmpdir(), "openclaw-openai-chat-tools-"));
try {
const result = runDockerRunnerAuthPreflight(root);
const output = `${result.stdout}\n${result.stderr}`;
expect(result.status).toBe(1);
expect(output).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 {
rmSync(root, { force: true, recursive: true });
}
});
it("treats placeholder profile auth as missing before Docker build work starts", () => {
const root = mkdtempSync(path.join(tmpdir(), "openclaw-openai-chat-tools-"));
try {
const profile = path.join(root, "profile");
writeFileSync(profile, "OPENAI_API_KEY=undefined\n");
const result = runDockerRunnerAuthPreflight(root, {
OPENCLAW_OPENAI_CHAT_TOOLS_PROFILE_FILE: profile,
});
const output = `${result.stdout}\n${result.stderr}`;
expect(result.status).toBe(1);
expect(output).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 {
rmSync(root, { force: true, recursive: true });
}
});
it("rejects loose timeout env values instead of parsing numeric prefixes", async () => {
const result = await runClient(1, {
OPENCLAW_OPENAI_CHAT_TOOLS_TIMEOUT_SECONDS: "1e3",