mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
fix(e2e): bound image auth mock bodies
This commit is contained in:
@@ -63,6 +63,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Release/CI/E2E: stop tracked gateway and mock service process groups so descendant helpers do not survive E2E cleanup.
|
||||
- Release/CI/E2E: exit Telegram credential proof wrappers promptly after forwarded shutdown signals while keeping the descendant force-kill guard armed.
|
||||
- Release/CI/E2E: reject oversized ClickClack fixture request bodies before release journey smokes can accumulate unbounded payloads.
|
||||
- Release/CI/E2E: reject oversized OpenAI image-auth mock request bodies before Docker proof runs can accumulate unbounded payloads.
|
||||
- Release/CI/E2E: fail secret-provider proof runs when temporary state cleanup still fails after retries instead of hiding the cleanup error.
|
||||
- Release/CI/E2E: fail package-candidate ref proofs when temporary source worktree cleanup fails instead of leaving stale worktrees behind.
|
||||
- Release/CI/E2E: remove package tarball extract directories when tar extraction fails before validation can continue.
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import http from "node:http";
|
||||
import type { AddressInfo } from "node:net";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { isRequestBodyTooLargeError, readBody } from "./lib/mock-openai-http.mjs";
|
||||
|
||||
const DIRECT_IMAGE_BYTES = Buffer.from("docker-direct-image");
|
||||
const CODEX_IMAGE_BYTES = Buffer.from("docker-codex-image");
|
||||
const DIRECT_TOKEN = "sk-openclaw-image-auth-e2e";
|
||||
const CODEX_TOKEN = "docker-codex-oauth-token";
|
||||
|
||||
type RequestRecord = {
|
||||
export type RequestRecord = {
|
||||
method?: string;
|
||||
url?: string;
|
||||
authorization?: string;
|
||||
@@ -21,18 +24,6 @@ function assert(condition: unknown, message: string): asserts condition {
|
||||
}
|
||||
}
|
||||
|
||||
function readBody(req: http.IncomingMessage): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
let body = "";
|
||||
req.setEncoding("utf8");
|
||||
req.on("data", (chunk) => {
|
||||
body += chunk;
|
||||
});
|
||||
req.on("end", () => resolve(body));
|
||||
req.on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
function writeJson(res: http.ServerResponse, status: number, body: unknown): void {
|
||||
res.writeHead(status, { "content-type": "application/json" });
|
||||
res.end(JSON.stringify(body));
|
||||
@@ -63,14 +54,23 @@ function writeCodexSse(res: http.ServerResponse): void {
|
||||
res.end("data: [DONE]\n\n");
|
||||
}
|
||||
|
||||
async function startMockServer(records: RequestRecord[]): Promise<{
|
||||
export async function startMockServer(records: RequestRecord[]): Promise<{
|
||||
baseUrl: string;
|
||||
close: () => Promise<void>;
|
||||
}> {
|
||||
const server = http.createServer((req, res) => {
|
||||
void (async () => {
|
||||
try {
|
||||
const body = await readBody(req);
|
||||
let body: string;
|
||||
try {
|
||||
body = await readBody(req);
|
||||
} catch (error) {
|
||||
if (isRequestBodyTooLargeError(error)) {
|
||||
writeJson(res, 413, { error: { message: error.message } });
|
||||
return;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
records.push({
|
||||
method: req.method,
|
||||
url: req.url,
|
||||
@@ -164,7 +164,7 @@ function createCodexOAuthStore() {
|
||||
} as const;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
export async function main() {
|
||||
assert(
|
||||
process.env.OPENAI_API_KEY === DIRECT_TOKEN,
|
||||
"Docker lane must expose the direct OpenAI API key",
|
||||
@@ -246,4 +246,6 @@ async function main() {
|
||||
}
|
||||
}
|
||||
|
||||
await main();
|
||||
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
||||
await main();
|
||||
}
|
||||
|
||||
33
test/scripts/openai-image-auth-docker-client.test.ts
Normal file
33
test/scripts/openai-image-auth-docker-client.test.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
startMockServer,
|
||||
type RequestRecord,
|
||||
} from "../../scripts/e2e/openai-image-auth-docker-client.ts";
|
||||
|
||||
describe("OpenAI image auth Docker client mock server", () => {
|
||||
it("rejects oversized request bodies before recording them", async () => {
|
||||
const previousLimit = process.env.OPENCLAW_MOCK_OPENAI_REQUEST_MAX_BYTES;
|
||||
process.env.OPENCLAW_MOCK_OPENAI_REQUEST_MAX_BYTES = "4";
|
||||
const records: RequestRecord[] = [];
|
||||
const server = await startMockServer(records);
|
||||
try {
|
||||
const response = await fetch(`${server.baseUrl}/v1/images/generations`, {
|
||||
method: "POST",
|
||||
body: "too large",
|
||||
});
|
||||
|
||||
await expect(response.json()).resolves.toEqual({
|
||||
error: { message: "mock OpenAI request body exceeded 4 bytes" },
|
||||
});
|
||||
expect(response.status).toBe(413);
|
||||
expect(records).toEqual([]);
|
||||
} finally {
|
||||
await server.close();
|
||||
if (previousLimit === undefined) {
|
||||
delete process.env.OPENCLAW_MOCK_OPENAI_REQUEST_MAX_BYTES;
|
||||
} else {
|
||||
process.env.OPENCLAW_MOCK_OPENAI_REQUEST_MAX_BYTES = previousLimit;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user