

























@@ -4,6 +4,19 @@ import { discoverGatewayBeacons } from "./bonjour-discovery.js";
4455const WIDE_AREA_DOMAIN = "openclaw.internal.";
667+type BeaconRecord = {
8+domain?: string;
9+instanceName?: string;
10+displayName?: string;
11+host?: string;
12+port?: number;
13+tailnetDns?: string;
14+gatewayPort?: number;
15+sshPort?: number;
16+cliPath?: string;
17+txt?: Record<string, unknown>;
18+};
19+720function collectMatching<T, U>(
821items: readonly T[],
922predicate: (item: T) => boolean,
@@ -18,6 +31,12 @@ function collectMatching<T, U>(
1831return matches;
1932}
203334+function findBeaconByInstance(beacons: readonly BeaconRecord[], instanceName: string) {
35+const beacon = beacons.find((item) => item.instanceName === instanceName);
36+expect(beacon).toBeDefined();
37+return beacon as BeaconRecord;
38+}
39+2140describe("bonjour-discovery", () => {
2241it("discovers beacons on darwin across local + wide-area domains", async () => {
2342const calls: Array<{ argv: string[]; timeoutMs: number }> = [];
@@ -100,22 +119,14 @@ describe("bonjour-discovery", () => {
100119});
101120102121expect(beacons).toHaveLength(3);
103-expect(beacons).toEqual(
104-expect.arrayContaining([
105-expect.objectContaining({
106-instanceName: studioInstance,
107-displayName: "Peter’s Mac Studio",
108-}),
109-]),
110-);
111-expect(beacons.map((b) => b.domain)).toEqual(
112-expect.arrayContaining(["local.", WIDE_AREA_DOMAIN]),
113-);
122+const studioBeacon = findBeaconByInstance(beacons, studioInstance);
123+expect(studioBeacon.displayName).toBe("Peter’s Mac Studio");
124+expect(beacons.map((b) => b.domain)).toContain("local.");
125+expect(beacons.map((b) => b.domain)).toContain(WIDE_AREA_DOMAIN);
114126115127const browseCalls = calls.filter((c) => c.argv[0] === "dns-sd" && c.argv[1] === "-B");
116-expect(browseCalls.map((c) => c.argv[3])).toEqual(
117-expect.arrayContaining(["local.", WIDE_AREA_DOMAIN]),
118-);
128+expect(browseCalls.map((c) => c.argv[3])).toContain("local.");
129+expect(browseCalls.map((c) => c.argv[3])).toContain(WIDE_AREA_DOMAIN);
119130expect([...new Set(browseCalls.map((c) => c.timeoutMs))]).toEqual([1234]);
120131});
121132@@ -166,16 +177,12 @@ describe("bonjour-discovery", () => {
166177run: run as unknown as typeof runCommandWithTimeout,
167178});
168179169-expect(beacons).toEqual([
170-expect.objectContaining({
171-domain: "local.",
172-instanceName: "Studio Gateway",
173-displayName: "Peter’s Mac Studio",
174-txt: expect.objectContaining({
175-displayName: "Peter’s Mac Studio",
176-}),
177-}),
178-]);
180+expect(beacons).toHaveLength(1);
181+const beacon = beacons[0] as BeaconRecord;
182+expect(beacon.domain).toBe("local.");
183+expect(beacon.instanceName).toBe("Studio Gateway");
184+expect(beacon.displayName).toBe("Peter’s Mac Studio");
185+expect(beacon.txt?.displayName).toBe("Peter’s Mac Studio");
179186});
180187181188it("falls back to tailnet DNS probing for wide-area when split DNS is not configured", async () => {
@@ -269,19 +276,17 @@ describe("bonjour-discovery", () => {
269276run: run as unknown as typeof runCommandWithTimeout,
270277});
271278272-expect(beacons).toEqual([
273-expect.objectContaining({
274-domain: WIDE_AREA_DOMAIN,
275-instanceName: "studio-gateway",
276-displayName: "Studio",
277-host: `studio.${zone}`,
278-port: 18789,
279-tailnetDns: "peters-mac-studio-1.sheep-coho.ts.net",
280-gatewayPort: 18789,
281-sshPort: 22,
282-cliPath: "/opt/homebrew/bin/openclaw",
283-}),
284-]);
279+expect(beacons).toHaveLength(1);
280+const beacon = beacons[0] as BeaconRecord;
281+expect(beacon.domain).toBe(WIDE_AREA_DOMAIN);
282+expect(beacon.instanceName).toBe("studio-gateway");
283+expect(beacon.displayName).toBe("Studio");
284+expect(beacon.host).toBe(`studio.${zone}`);
285+expect(beacon.port).toBe(18789);
286+expect(beacon.tailnetDns).toBe("peters-mac-studio-1.sheep-coho.ts.net");
287+expect(beacon.gatewayPort).toBe(18789);
288+expect(beacon.sshPort).toBe(22);
289+expect(beacon.cliPath).toBe("/opt/homebrew/bin/openclaw");
285290286291expect(calls.map((c) => c.argv.slice(0, 2).join(" "))).toContain("tailscale status");
287292expect(calls.map((c) => c.argv[0])).toContain("dig");
@@ -307,13 +312,13 @@ describe("bonjour-discovery", () => {
307312run: run as unknown as typeof runCommandWithTimeout,
308313});
309314310-expect(
311-collectMatching(
312- calls,
313- (c) => c[1] === "-B",
314- (c) => c[3],
315- ),
316-).toEqual(expect.arrayContaining(["local.", "openclaw.internal."]));
315+const browseDomains = collectMatching(
316+calls,
317+(c) => c[1] === "-B",
318+(c) => c[3],
319+);
320+expect(browseDomains).toContain("local.");
321+expect(browseDomains).toContain("openclaw.internal.");
317322318323calls.length = 0;
319324await discoverGatewayBeacons({
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。