refactor(channels): dedupe transport and gateway test scaffolds

This commit is contained in:
Peter Steinberger
2026-02-16 14:52:15 +00:00
parent f717a13039
commit 93ca0ed54f
95 changed files with 4068 additions and 5221 deletions

View File

@@ -1,5 +1,7 @@
import { writeFile } from "node:fs/promises";
import { WebSocket } from "ws";
import {
type DeviceIdentity,
loadOrCreateDeviceIdentity,
publicKeyRawBase64UrlFromPem,
signDevicePayload,
@@ -15,6 +17,7 @@ import {
import { GatewayClient } from "./client.js";
import { buildDeviceAuthPayload } from "./device-auth.js";
import { PROTOCOL_VERSION } from "./protocol/index.js";
import { startGatewayServer } from "./server.js";
export async function getFreeGatewayPort(): Promise<number> {
return await getDeterministicFreePortBlock({ offsets: [0, 1, 2, 3, 4] });
@@ -27,6 +30,17 @@ export async function connectGatewayClient(params: {
clientDisplayName?: string;
clientVersion?: string;
mode?: GatewayClientMode;
platform?: string;
role?: "operator" | "node";
scopes?: string[];
caps?: string[];
commands?: string[];
instanceId?: string;
deviceIdentity?: DeviceIdentity;
onEvent?: (evt: { event?: string; payload?: unknown }) => void;
connectDelayMs?: number;
timeoutMs?: number;
timeoutMessage?: string;
}) {
return await new Promise<InstanceType<typeof GatewayClient>>((resolve, reject) => {
let settled = false;
@@ -45,16 +59,28 @@ export async function connectGatewayClient(params: {
const client = new GatewayClient({
url: params.url,
token: params.token,
connectDelayMs: params.connectDelayMs ?? 0,
clientName: params.clientName ?? GATEWAY_CLIENT_NAMES.TEST,
clientDisplayName: params.clientDisplayName ?? "vitest",
clientVersion: params.clientVersion ?? "dev",
platform: params.platform,
mode: params.mode ?? GATEWAY_CLIENT_MODES.TEST,
role: params.role,
scopes: params.scopes,
caps: params.caps,
commands: params.commands,
instanceId: params.instanceId,
deviceIdentity: params.deviceIdentity,
onEvent: params.onEvent,
onHelloOk: () => stop(undefined, client),
onConnectError: (err) => stop(err),
onClose: (code, reason) =>
stop(new Error(`gateway closed during connect (${code}): ${reason}`)),
});
const timer = setTimeout(() => stop(new Error("gateway connect timeout")), 10_000);
const timer = setTimeout(
() => stop(new Error(params.timeoutMessage ?? "gateway connect timeout")),
params.timeoutMs ?? 10_000,
);
timer.unref();
client.start();
});
@@ -136,3 +162,27 @@ export async function connectDeviceAuthReq(params: { url: string; token?: string
ws.close();
return res;
}
export async function startGatewayWithClient(params: {
cfg: unknown;
configPath: string;
token: string;
clientDisplayName?: string;
}) {
await writeFile(params.configPath, `${JSON.stringify(params.cfg, null, 2)}\n`);
process.env.OPENCLAW_CONFIG_PATH = params.configPath;
const port = await getFreeGatewayPort();
const server = await startGatewayServer(port, {
bind: "loopback",
auth: { mode: "token", token: params.token },
controlUiEnabled: false,
});
const client = await connectGatewayClient({
url: `ws://127.0.0.1:${port}`,
token: params.token,
clientDisplayName: params.clientDisplayName,
});
return { port, server, client };
}