mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-12 00:53:42 +00:00
refactor(test): share gateway server start helper
This commit is contained in:
@@ -13,13 +13,12 @@ import { createRegistry } from "./server.e2e-registry-helpers.js";
|
|||||||
import {
|
import {
|
||||||
agentCommand,
|
agentCommand,
|
||||||
connectOk,
|
connectOk,
|
||||||
getFreePort,
|
|
||||||
installGatewayTestHooks,
|
installGatewayTestHooks,
|
||||||
onceMessage,
|
onceMessage,
|
||||||
rpcReq,
|
rpcReq,
|
||||||
startGatewayServer,
|
|
||||||
startServerWithClient,
|
startServerWithClient,
|
||||||
testState,
|
testState,
|
||||||
|
withGatewayServer,
|
||||||
writeSessionStore,
|
writeSessionStore,
|
||||||
} from "./test-helpers.js";
|
} from "./test-helpers.js";
|
||||||
|
|
||||||
@@ -326,9 +325,7 @@ describe("gateway server agent", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("agent dedupe survives reconnect", { timeout: 60_000 }, async () => {
|
test("agent dedupe survives reconnect", { timeout: 60_000 }, async () => {
|
||||||
const port = await getFreePort();
|
await withGatewayServer(async ({ port }) => {
|
||||||
const server = await startGatewayServer(port);
|
|
||||||
|
|
||||||
const dial = async () => {
|
const dial = async () => {
|
||||||
const ws = new WebSocket(`ws://127.0.0.1:${port}`);
|
const ws = new WebSocket(`ws://127.0.0.1:${port}`);
|
||||||
await new Promise<void>((resolve) => ws.once("open", resolve));
|
await new Promise<void>((resolve) => ws.once("open", resolve));
|
||||||
@@ -371,7 +368,7 @@ describe("gateway server agent", () => {
|
|||||||
const res = await final2P;
|
const res = await final2P;
|
||||||
expect(res.payload).toEqual(final1.payload);
|
expect(res.payload).toEqual(final1.payload);
|
||||||
ws2.close();
|
ws2.close();
|
||||||
await server.close();
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test("agent events stream to webchat clients when run context is registered", async () => {
|
test("agent events stream to webchat clients when run context is registered", async () => {
|
||||||
|
|||||||
@@ -3,10 +3,9 @@ import { resolveMainSessionKeyFromConfig } from "../config/sessions.js";
|
|||||||
import { drainSystemEvents, peekSystemEvents } from "../infra/system-events.js";
|
import { drainSystemEvents, peekSystemEvents } from "../infra/system-events.js";
|
||||||
import {
|
import {
|
||||||
cronIsolatedRun,
|
cronIsolatedRun,
|
||||||
getFreePort,
|
|
||||||
installGatewayTestHooks,
|
installGatewayTestHooks,
|
||||||
startGatewayServer,
|
|
||||||
testState,
|
testState,
|
||||||
|
withGatewayServer,
|
||||||
waitForSystemEvent,
|
waitForSystemEvent,
|
||||||
} from "./test-helpers.js";
|
} from "./test-helpers.js";
|
||||||
|
|
||||||
@@ -14,16 +13,6 @@ installGatewayTestHooks({ scope: "suite" });
|
|||||||
|
|
||||||
const resolveMainKey = () => resolveMainSessionKeyFromConfig();
|
const resolveMainKey = () => resolveMainSessionKeyFromConfig();
|
||||||
|
|
||||||
async function withGatewayServer<T>(fn: (ctx: { port: number }) => Promise<T>): Promise<T> {
|
|
||||||
const port = await getFreePort();
|
|
||||||
const server = await startGatewayServer(port);
|
|
||||||
try {
|
|
||||||
return await fn({ port });
|
|
||||||
} finally {
|
|
||||||
await server.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("gateway server hooks", () => {
|
describe("gateway server hooks", () => {
|
||||||
test("handles auth, wake, and agent flows", async () => {
|
test("handles auth, wake, and agent flows", async () => {
|
||||||
testState.hooksConfig = { enabled: true, token: "hook-secret" };
|
testState.hooksConfig = { enabled: true, token: "hook-secret" };
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
import {
|
import {
|
||||||
connectOk,
|
connectOk,
|
||||||
getFreePort,
|
|
||||||
installGatewayTestHooks,
|
installGatewayTestHooks,
|
||||||
rpcReq,
|
rpcReq,
|
||||||
startGatewayServer,
|
|
||||||
startServerWithClient,
|
startServerWithClient,
|
||||||
|
withGatewayServer,
|
||||||
} from "./test-helpers.js";
|
} from "./test-helpers.js";
|
||||||
|
|
||||||
const hoisted = vi.hoisted(() => {
|
const hoisted = vi.hoisted(() => {
|
||||||
@@ -200,9 +199,7 @@ describe("gateway hot reload", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("applies hot reload actions and emits restart signal", async () => {
|
it("applies hot reload actions and emits restart signal", async () => {
|
||||||
const port = await getFreePort();
|
await withGatewayServer(async () => {
|
||||||
const server = await startGatewayServer(port);
|
|
||||||
|
|
||||||
const onHotReload = hoisted.getOnHotReload();
|
const onHotReload = hoisted.getOnHotReload();
|
||||||
expect(onHotReload).toBeTypeOf("function");
|
expect(onHotReload).toBeTypeOf("function");
|
||||||
|
|
||||||
@@ -302,8 +299,7 @@ describe("gateway hot reload", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
expect(signalSpy).toHaveBeenCalledTimes(1);
|
expect(signalSpy).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
await server.close();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -331,6 +331,43 @@ export async function startGatewayServer(port: number, opts?: GatewayServerOptio
|
|||||||
return await mod.startGatewayServer(port, resolvedOpts);
|
return await mod.startGatewayServer(port, resolvedOpts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function startGatewayServerWithRetries(params: {
|
||||||
|
port: number;
|
||||||
|
opts?: GatewayServerOptions;
|
||||||
|
}): Promise<{ port: number; server: Awaited<ReturnType<typeof startGatewayServer>> }> {
|
||||||
|
let port = params.port;
|
||||||
|
for (let attempt = 0; attempt < 10; attempt++) {
|
||||||
|
try {
|
||||||
|
return {
|
||||||
|
port,
|
||||||
|
server: await startGatewayServer(port, params.opts),
|
||||||
|
};
|
||||||
|
} catch (err) {
|
||||||
|
const code = (err as { cause?: { code?: string } }).cause?.code;
|
||||||
|
if (code !== "EADDRINUSE") {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
port = await getFreePort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error("failed to start gateway server after retries");
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function withGatewayServer<T>(
|
||||||
|
fn: (ctx: { port: number; server: Awaited<ReturnType<typeof startGatewayServer>> }) => Promise<T>,
|
||||||
|
opts?: { port?: number; serverOptions?: GatewayServerOptions },
|
||||||
|
): Promise<T> {
|
||||||
|
const started = await startGatewayServerWithRetries({
|
||||||
|
port: opts?.port ?? (await getFreePort()),
|
||||||
|
opts: opts?.serverOptions,
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
return await fn({ port: started.port, server: started.server });
|
||||||
|
} finally {
|
||||||
|
await started.server.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function startServerWithClient(
|
export async function startServerWithClient(
|
||||||
token?: string,
|
token?: string,
|
||||||
opts?: GatewayServerOptions & { wsHeaders?: Record<string, string> },
|
opts?: GatewayServerOptions & { wsHeaders?: Record<string, string> },
|
||||||
@@ -352,22 +389,9 @@ export async function startServerWithClient(
|
|||||||
process.env.OPENCLAW_GATEWAY_TOKEN = fallbackToken;
|
process.env.OPENCLAW_GATEWAY_TOKEN = fallbackToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
let server: Awaited<ReturnType<typeof startGatewayServer>> | null = null;
|
const started = await startGatewayServerWithRetries({ port, opts: gatewayOpts });
|
||||||
for (let attempt = 0; attempt < 10; attempt++) {
|
port = started.port;
|
||||||
try {
|
const server = started.server;
|
||||||
server = await startGatewayServer(port, gatewayOpts);
|
|
||||||
break;
|
|
||||||
} catch (err) {
|
|
||||||
const code = (err as { cause?: { code?: string } }).cause?.code;
|
|
||||||
if (code !== "EADDRINUSE") {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
port = await getFreePort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!server) {
|
|
||||||
throw new Error("failed to start gateway server after retries");
|
|
||||||
}
|
|
||||||
|
|
||||||
const ws = new WebSocket(
|
const ws = new WebSocket(
|
||||||
`ws://127.0.0.1:${port}`,
|
`ws://127.0.0.1:${port}`,
|
||||||
|
|||||||
Reference in New Issue
Block a user