mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 16:50:43 +00:00
test: stabilize gateway and TTS tests
This commit is contained in:
@@ -1,13 +1,116 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import type { AnyAgentTool } from "./tools/common.js";
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
textToSpeech: vi.fn(async () => ({
|
||||
success: true,
|
||||
audioPath: "/tmp/openclaw/tts-config-test.opus",
|
||||
provider: "microsoft",
|
||||
voiceCompatible: true,
|
||||
})),
|
||||
const mocks = vi.hoisted(() => {
|
||||
const stubTool = (name: string) =>
|
||||
({
|
||||
name,
|
||||
label: name,
|
||||
displaySummary: name,
|
||||
description: name,
|
||||
parameters: { type: "object", properties: {} },
|
||||
execute: vi.fn(),
|
||||
}) satisfies AnyAgentTool;
|
||||
|
||||
return {
|
||||
stubTool,
|
||||
textToSpeech: vi.fn(async () => ({
|
||||
success: true,
|
||||
audioPath: "/tmp/openclaw/tts-config-test.opus",
|
||||
provider: "microsoft",
|
||||
voiceCompatible: true,
|
||||
})),
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("./openclaw-plugin-tools.js", () => ({
|
||||
resolveOpenClawPluginToolsForOptions: () => [],
|
||||
}));
|
||||
|
||||
vi.mock("./openclaw-tools.nodes-workspace-guard.js", () => ({
|
||||
applyNodesToolWorkspaceGuard: (tool: AnyAgentTool) => tool,
|
||||
}));
|
||||
|
||||
vi.mock("./tools/agents-list-tool.js", () => ({
|
||||
createAgentsListTool: () => mocks.stubTool("agents_list"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/canvas-tool.js", () => ({
|
||||
createCanvasTool: () => mocks.stubTool("canvas"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/cron-tool.js", () => ({
|
||||
createCronTool: () => mocks.stubTool("cron"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/gateway-tool.js", () => ({
|
||||
createGatewayTool: () => mocks.stubTool("gateway"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/image-generate-tool.js", () => ({
|
||||
createImageGenerateTool: () => mocks.stubTool("image_generate"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/image-tool.js", () => ({
|
||||
createImageTool: () => mocks.stubTool("image"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/message-tool.js", () => ({
|
||||
createMessageTool: () => mocks.stubTool("message"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/music-generate-tool.js", () => ({
|
||||
createMusicGenerateTool: () => mocks.stubTool("music_generate"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/nodes-tool.js", () => ({
|
||||
createNodesTool: () => mocks.stubTool("nodes"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/pdf-tool.js", () => ({
|
||||
createPdfTool: () => mocks.stubTool("pdf"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/session-status-tool.js", () => ({
|
||||
createSessionStatusTool: () => mocks.stubTool("session_status"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/sessions-history-tool.js", () => ({
|
||||
createSessionsHistoryTool: () => mocks.stubTool("sessions_history"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/sessions-list-tool.js", () => ({
|
||||
createSessionsListTool: () => mocks.stubTool("sessions_list"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/sessions-send-tool.js", () => ({
|
||||
createSessionsSendTool: () => mocks.stubTool("sessions_send"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/sessions-spawn-tool.js", () => ({
|
||||
createSessionsSpawnTool: () => mocks.stubTool("sessions_spawn"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/sessions-yield-tool.js", () => ({
|
||||
createSessionsYieldTool: () => mocks.stubTool("sessions_yield"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/subagents-tool.js", () => ({
|
||||
createSubagentsTool: () => mocks.stubTool("subagents"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/update-plan-tool.js", () => ({
|
||||
createUpdatePlanTool: () => mocks.stubTool("update_plan"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/video-generate-tool.js", () => ({
|
||||
createVideoGenerateTool: () => mocks.stubTool("video_generate"),
|
||||
}));
|
||||
|
||||
vi.mock("./tools/web-tools.js", () => ({
|
||||
createWebFetchTool: () => mocks.stubTool("web_fetch"),
|
||||
createWebSearchTool: () => mocks.stubTool("web_search"),
|
||||
}));
|
||||
|
||||
vi.mock("../tts/tts.js", () => ({
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import net from "node:net";
|
||||
import { describe, expect, test } from "vitest";
|
||||
import { WebSocket } from "ws";
|
||||
import { writeConfigFile } from "../config/config.js";
|
||||
@@ -23,7 +24,9 @@ const NODE_CLIENT = {
|
||||
};
|
||||
|
||||
async function openLanGatewayWs(params: { host: string; port: number }): Promise<WebSocket> {
|
||||
const ws = new WebSocket(`ws://${params.host}:${params.port}`);
|
||||
const ws = new WebSocket(`ws://${params.host}:${params.port}`, {
|
||||
localAddress: params.host,
|
||||
});
|
||||
trackConnectChallengeNonce(ws);
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const timer = setTimeout(() => reject(new Error("timeout waiting for ws open")), 10_000);
|
||||
@@ -46,10 +49,46 @@ async function openLanGatewayWs(params: { host: string; port: number }): Promise
|
||||
return ws;
|
||||
}
|
||||
|
||||
async function canUseLanSelfConnect(host: string): Promise<boolean> {
|
||||
return await new Promise<boolean>((resolve) => {
|
||||
let settled = false;
|
||||
let client: net.Socket | undefined;
|
||||
const server = net.createServer((socket) => {
|
||||
socket.on("error", () => {});
|
||||
socket.end("ok");
|
||||
});
|
||||
const done = (ok: boolean) => {
|
||||
if (settled) {
|
||||
return;
|
||||
}
|
||||
settled = true;
|
||||
clearTimeout(timer);
|
||||
client?.destroy();
|
||||
server.close(() => resolve(ok));
|
||||
};
|
||||
const timer = setTimeout(() => done(false), 1_000);
|
||||
server.once("error", () => done(false));
|
||||
server.listen(0, "0.0.0.0", () => {
|
||||
const address = server.address();
|
||||
if (!address || typeof address === "string") {
|
||||
done(false);
|
||||
return;
|
||||
}
|
||||
let sawData = false;
|
||||
client = net.connect({ host, port: address.port, localAddress: host });
|
||||
client.on("data", () => {
|
||||
sawData = true;
|
||||
});
|
||||
client.once("error", () => done(false));
|
||||
client.once("close", () => done(sawData));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
describe("gateway trusted CIDR node pairing auto-approve", () => {
|
||||
test("stays disabled by default for a direct non-loopback node", async () => {
|
||||
const lanIp = pickPrimaryLanIPv4();
|
||||
if (!lanIp) {
|
||||
if (!lanIp || !(await canUseLanSelfConnect(lanIp))) {
|
||||
return;
|
||||
}
|
||||
const started = await startServer(TOKEN, { bind: "lan", controlUiEnabled: false });
|
||||
@@ -82,7 +121,7 @@ describe("gateway trusted CIDR node pairing auto-approve", () => {
|
||||
|
||||
test("auto-approves first-time node pairing from a matching direct non-loopback CIDR", async () => {
|
||||
const lanIp = pickPrimaryLanIPv4();
|
||||
if (!lanIp) {
|
||||
if (!lanIp || !(await canUseLanSelfConnect(lanIp))) {
|
||||
return;
|
||||
}
|
||||
await writeConfigFile({
|
||||
|
||||
Reference in New Issue
Block a user