mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 10:16:44 +00:00
fix(qa): reject loose mock OpenAI ports
This commit is contained in:
@@ -1,5 +1,26 @@
|
||||
// Mock OpenAI model config helpers for E2E fixture generation.
|
||||
function formatMockPortValue(value) {
|
||||
return value === undefined ? "<missing>" : JSON.stringify(String(value));
|
||||
}
|
||||
|
||||
export function parseMockOpenAiPort(value, label = "mock OpenAI port") {
|
||||
const text = String(value ?? "").trim();
|
||||
if (!/^[1-9]\d*$/u.test(text)) {
|
||||
throw new Error(
|
||||
`${label} must be a TCP port from 1 to 65535. Got: ${formatMockPortValue(value)}`,
|
||||
);
|
||||
}
|
||||
const port = Number(text);
|
||||
if (!Number.isSafeInteger(port) || port > 65535) {
|
||||
throw new Error(
|
||||
`${label} must be a TCP port from 1 to 65535. Got: ${formatMockPortValue(value)}`,
|
||||
);
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
export function applyMockOpenAiModelConfig(cfg, params) {
|
||||
const mockPort = parseMockOpenAiPort(params.mockPort);
|
||||
const modelRef = params.modelRef ?? "openai/gpt-5.5";
|
||||
const modelId = modelRef.split("/").at(-1) ?? "gpt-5.5";
|
||||
const cost = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
||||
@@ -10,7 +31,7 @@ export function applyMockOpenAiModelConfig(cfg, params) {
|
||||
...cfg.models?.providers,
|
||||
openai: {
|
||||
...cfg.models?.providers?.openai,
|
||||
baseUrl: `http://127.0.0.1:${params.mockPort}/v1`,
|
||||
baseUrl: `http://127.0.0.1:${mockPort}/v1`,
|
||||
apiKey: { source: "env", provider: "default", id: "OPENAI_API_KEY" },
|
||||
api: "openai-responses",
|
||||
agentRuntime: { id: "openclaw" },
|
||||
|
||||
@@ -8,7 +8,10 @@ import {
|
||||
} from "../agent-turn-output.mjs";
|
||||
import { assertOpenAiEnvAuthProfileStore } from "../auth-profile-store-assertions.mjs";
|
||||
import { readPositiveIntEnv } from "../env-limits.mjs";
|
||||
import { applyMockOpenAiModelConfig } from "../fixtures/mock-openai-config.mjs";
|
||||
import {
|
||||
applyMockOpenAiModelConfig,
|
||||
parseMockOpenAiPort,
|
||||
} from "../fixtures/mock-openai-config.mjs";
|
||||
import { readTextFileBounded, readTextFileTail } from "../text-file-utils.mjs";
|
||||
|
||||
const command = process.argv[2];
|
||||
@@ -117,7 +120,7 @@ function assertOnboardState() {
|
||||
}
|
||||
|
||||
function configureMockModel() {
|
||||
const mockPort = Number(process.argv[3]);
|
||||
const mockPort = parseMockOpenAiPort(process.argv[3]);
|
||||
const configPath = path.join(process.env.HOME, ".openclaw", "openclaw.json");
|
||||
const cfg = readJson(configPath);
|
||||
applyMockOpenAiModelConfig(cfg, { mockPort });
|
||||
@@ -125,7 +128,7 @@ function configureMockModel() {
|
||||
}
|
||||
|
||||
function assertMockModelConfig() {
|
||||
const mockPort = Number(process.argv[3]);
|
||||
const mockPort = parseMockOpenAiPort(process.argv[3]);
|
||||
const expectedModelRef = "openai/gpt-5.5";
|
||||
const expectedBaseUrl = `http://127.0.0.1:${mockPort}/v1`;
|
||||
const configPath = path.join(process.env.HOME, ".openclaw", "openclaw.json");
|
||||
|
||||
@@ -7,7 +7,10 @@ import {
|
||||
assertOpenAiRequestLogUsed,
|
||||
} from "../agent-turn-output.mjs";
|
||||
import { assertOpenAiEnvAuthProfileStore } from "../auth-profile-store-assertions.mjs";
|
||||
import { applyMockOpenAiModelConfig } from "../fixtures/mock-openai-config.mjs";
|
||||
import {
|
||||
applyMockOpenAiModelConfig,
|
||||
parseMockOpenAiPort,
|
||||
} from "../fixtures/mock-openai-config.mjs";
|
||||
import { readPluginInstallRecords } from "../plugin-index-sqlite.mjs";
|
||||
import { readTextFileTail } from "../text-file-utils.mjs";
|
||||
|
||||
@@ -145,7 +148,7 @@ function readStateText() {
|
||||
}
|
||||
|
||||
function configureMockOpenAi() {
|
||||
const mockPort = Number(process.argv[3]);
|
||||
const mockPort = parseMockOpenAiPort(process.argv[3]);
|
||||
const cfg = readJson(configPath());
|
||||
applyMockOpenAiModelConfig(cfg, { mockPort, includeImageDefaults: true });
|
||||
writeConfig(cfg);
|
||||
|
||||
@@ -7,7 +7,10 @@ import {
|
||||
assertOpenAiRequestLogUsed,
|
||||
} from "../agent-turn-output.mjs";
|
||||
import { readBoundedResponseText as readBoundedResponseTextWithLimit } from "../bounded-response-text.mjs";
|
||||
import { applyMockOpenAiModelConfig } from "../fixtures/mock-openai-config.mjs";
|
||||
import {
|
||||
applyMockOpenAiModelConfig,
|
||||
parseMockOpenAiPort,
|
||||
} from "../fixtures/mock-openai-config.mjs";
|
||||
import { readPluginInstallRecords } from "../plugin-index-sqlite.mjs";
|
||||
import { readTextFileTail } from "../text-file-utils.mjs";
|
||||
|
||||
@@ -192,7 +195,7 @@ function assertOnboard() {
|
||||
}
|
||||
|
||||
function configureMockModel() {
|
||||
const mockPort = Number(process.argv[3]);
|
||||
const mockPort = parseMockOpenAiPort(process.argv[3]);
|
||||
const cfg = readJson(configPath());
|
||||
applyMockOpenAiModelConfig(cfg, { mockPort });
|
||||
writeConfig(cfg);
|
||||
|
||||
@@ -84,6 +84,17 @@ function runOnboardAssert(home: string) {
|
||||
});
|
||||
}
|
||||
|
||||
function runMockModelAssert(home: string, command: string, port: string) {
|
||||
return spawnSync(process.execPath, [assertionsPath, command, port], {
|
||||
encoding: "utf8",
|
||||
env: {
|
||||
...process.env,
|
||||
HOME: home,
|
||||
NODE_OPTIONS: nodeOptionsWithoutExperimentalWarnings(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function runStatusAssert(
|
||||
channel: string,
|
||||
channelsStatus: unknown,
|
||||
@@ -110,6 +121,22 @@ function runStatusAssert(
|
||||
}
|
||||
|
||||
describe("npm onboard channel agent assertions", () => {
|
||||
it("rejects loose mock OpenAI port args", () => {
|
||||
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-onboard-assertions-"));
|
||||
|
||||
try {
|
||||
for (const command of ["configure-mock-model", "assert-mock-model-config"]) {
|
||||
const result = runMockModelAssert(tempDir, command, "1e3");
|
||||
|
||||
expect(result.status).not.toBe(0);
|
||||
expect(result.stderr).toContain("mock OpenAI port must be a TCP port from 1 to 65535");
|
||||
expect(result.stderr).toContain('"1e3"');
|
||||
}
|
||||
} finally {
|
||||
fs.rmSync(tempDir, { force: true, recursive: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("validates OpenAI env refs from the SQLite auth profile store", () => {
|
||||
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-onboard-assertions-"));
|
||||
const agentDir = path.join(tempDir, ".openclaw", "agents", "main", "agent");
|
||||
|
||||
@@ -55,6 +55,14 @@ function writeAuthProfileStoreSqlite(agentDir: string, store: unknown) {
|
||||
}
|
||||
|
||||
describe("release scenario assertions", () => {
|
||||
it("rejects loose mock OpenAI port args", () => {
|
||||
const result = runAssertion(["configure-mock-openai", "1e3"]);
|
||||
|
||||
expect(result.status).not.toBe(0);
|
||||
expect(result.stderr).toContain("mock OpenAI port must be a TCP port from 1 to 65535");
|
||||
expect(result.stderr).toContain('"1e3"');
|
||||
});
|
||||
|
||||
it("scans large files when checking release scenario output text", () => {
|
||||
const root = mkdtempSync(path.join(tmpdir(), "openclaw-release-scenarios-"));
|
||||
const outputPath = path.join(root, "output.log");
|
||||
|
||||
@@ -88,6 +88,21 @@ async function startTcpFixtureServer(handler: (socket: Socket) => void): Promise
|
||||
}
|
||||
|
||||
describe("release user journey assertions", () => {
|
||||
it("rejects loose mock OpenAI port args", () => {
|
||||
const root = mkdtempSync(path.join(tmpdir(), "openclaw-release-user-assertions-"));
|
||||
const home = path.join(root, "home");
|
||||
|
||||
try {
|
||||
const result = runAssertion(home, ["configure-mock-model", "1e3"]);
|
||||
|
||||
expect(result.status).not.toBe(0);
|
||||
expect(result.stderr).toContain("mock OpenAI port must be a TCP port from 1 to 65535");
|
||||
expect(result.stderr).toContain('"1e3"');
|
||||
} finally {
|
||||
rmSync(root, { force: true, recursive: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("scans large files when checking release user journey output text", () => {
|
||||
const root = mkdtempSync(path.join(tmpdir(), "openclaw-release-user-assertions-"));
|
||||
const home = path.join(root, "home");
|
||||
|
||||
Reference in New Issue
Block a user