





















1-import { spawn } from "node:child_process";
1+import { spawn, spawnSync } from "node:child_process";
2+import { mkdtempSync, readFileSync, rmSync } from "node:fs";
23import { createServer, type Server } from "node:http";
4+import { tmpdir } from "node:os";
35import path from "node:path";
46import { describe, expect, it } from "vitest";
5768const clientPath = path.resolve("scripts/e2e/lib/openai-chat-tools/client.mjs");
9+const writeConfigPath = path.resolve("scripts/e2e/lib/openai-chat-tools/write-config.mjs");
710811interface ClientResult {
912error?: Error;
@@ -77,6 +80,22 @@ function runClient(
7780});
7881}
798283+function runWriteConfig(root: string, env: Record<string, string> = {}) {
84+return spawnSync(process.execPath, [writeConfigPath], {
85+encoding: "utf8",
86+env: {
87+ ...process.env,
88+OPENCLAW_CONFIG_PATH: path.join(root, "openclaw.json"),
89+OPENCLAW_GATEWAY_TOKEN: "test-token",
90+OPENCLAW_OPENAI_CHAT_TOOLS_MODEL: "openai/gpt-5.5",
91+OPENCLAW_STATE_DIR: path.join(root, "state"),
92+OPENCLAW_TEST_WORKSPACE_DIR: path.join(root, "workspace"),
93+PORT: "18789",
94+ ...env,
95+},
96+});
97+}
98+8099function toolCallResponse() {
81100return {
82101choices: [
@@ -99,6 +118,56 @@ function toolCallResponse() {
99118}
100119101120describe("scripts/e2e/lib/openai-chat-tools/client.mjs", () => {
121+it("rejects loose timeout env values instead of parsing numeric prefixes", async () => {
122+const result = await runClient(1, {
123+OPENCLAW_OPENAI_CHAT_TOOLS_TIMEOUT_SECONDS: "1e3",
124+});
125+126+expect(result.status).not.toBe(0);
127+expect(result.stderr).toContain("invalid OPENCLAW_OPENAI_CHAT_TOOLS_TIMEOUT_SECONDS: 1e3");
128+});
129+130+it("rejects loose body limit env values instead of parsing numeric prefixes", async () => {
131+const result = await runClient(1, {
132+OPENCLAW_OPENAI_CHAT_TOOLS_MAX_BODY_BYTES: "64bytes",
133+});
134+135+expect(result.status).not.toBe(0);
136+expect(result.stderr).toContain("invalid OPENCLAW_OPENAI_CHAT_TOOLS_MAX_BODY_BYTES: 64bytes");
137+});
138+139+it("rejects loose write-config timeout env values", () => {
140+const root = mkdtempSync(path.join(tmpdir(), "openclaw-openai-chat-tools-"));
141+try {
142+const result = runWriteConfig(root, {
143+OPENCLAW_OPENAI_CHAT_TOOLS_TIMEOUT_SECONDS: "1e3",
144+});
145+146+expect(result.status).not.toBe(0);
147+expect(result.stderr).toContain("invalid OPENCLAW_OPENAI_CHAT_TOOLS_TIMEOUT_SECONDS: 1e3");
148+} finally {
149+rmSync(root, { force: true, recursive: true });
150+}
151+});
152+153+it("writes strict positive timeout and port values into generated config", () => {
154+const root = mkdtempSync(path.join(tmpdir(), "openclaw-openai-chat-tools-"));
155+try {
156+const result = runWriteConfig(root, {
157+OPENCLAW_OPENAI_CHAT_TOOLS_TIMEOUT_SECONDS: "240",
158+PORT: "19001",
159+});
160+161+expect(result.status).toBe(0);
162+const config = JSON.parse(readFileSync(path.join(root, "openclaw.json"), "utf8"));
163+expect(config.gateway.port).toBe(19001);
164+expect(config.models.providers.openai.timeoutSeconds).toBe(240);
165+expect(config.agents.defaults.timeoutSeconds).toBe(240);
166+} finally {
167+rmSync(root, { force: true, recursive: true });
168+}
169+});
170+102171it("accepts a matching chat completions tool call response", async () => {
103172const server = createServer((request, response) => {
104173expect(request.method).toBe("POST");
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。