forked from anomalyco/opencode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhttpapi-mdns.test.ts
More file actions
82 lines (73 loc) · 3.21 KB
/
httpapi-mdns.test.ts
File metadata and controls
82 lines (73 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import { afterEach, describe, expect, mock, test } from "bun:test"
import { Flag } from "@opencode-ai/core/flag/flag"
import * as Log from "@opencode-ai/core/util/log"
import { withTimeout } from "../../src/util/timeout"
import { resetDatabase } from "../fixture/db"
import { disposeAllInstances } from "../fixture/fixture"
void Log.init({ print: false })
type Event = { kind: "publish"; port: number; name: string } | { kind: "unpublishAll" } | { kind: "destroy" }
const events: Event[] = []
void mock.module("bonjour-service", () => ({
Bonjour: class {
publish(opts: { port: number; name: string }) {
events.push({ kind: "publish", port: opts.port, name: opts.name })
return { on: () => {} }
}
unpublishAll() {
events.push({ kind: "unpublishAll" })
}
destroy() {
events.push({ kind: "destroy" })
}
},
}))
// Import Server AFTER the mock so the MDNS module picks up the stub.
const { Server } = await import("../../src/server/server")
const original = {
OPENCODE_SERVER_PASSWORD: Flag.OPENCODE_SERVER_PASSWORD,
OPENCODE_SERVER_USERNAME: Flag.OPENCODE_SERVER_USERNAME,
}
afterEach(async () => {
events.length = 0
Flag.OPENCODE_SERVER_PASSWORD = original.OPENCODE_SERVER_PASSWORD
Flag.OPENCODE_SERVER_USERNAME = original.OPENCODE_SERVER_USERNAME
await disposeAllInstances()
await resetDatabase()
})
describe("HttpApi Server.listen mDNS", () => {
test("skips publish for loopback hostnames", async () => {
Flag.OPENCODE_SERVER_PASSWORD = "mdns-secret"
Flag.OPENCODE_SERVER_USERNAME = "opencode"
const listener = await Server.listen({ hostname: "127.0.0.1", port: 0, mdns: true })
try {
expect(events.filter((e) => e.kind === "publish")).toEqual([])
} finally {
await withTimeout(listener.stop(true), 10_000, "timed out stopping loopback mdns listener")
}
expect(events.filter((e) => e.kind === "publish")).toEqual([])
})
test("publishes for non-loopback hostnames and unpublishes on stop", async () => {
Flag.OPENCODE_SERVER_PASSWORD = "mdns-secret"
Flag.OPENCODE_SERVER_USERNAME = "opencode"
const listener = await Server.listen({ hostname: "0.0.0.0", port: 0, mdns: true })
try {
const published = events.filter((e) => e.kind === "publish")
expect(published.length).toBe(1)
expect(published[0]!.port).toBe(listener.port)
expect(published[0]!.name).toBe(`opencode-${listener.port}`)
} finally {
await withTimeout(listener.stop(true), 10_000, "timed out stopping mdns listener")
}
expect(events.some((e) => e.kind === "unpublishAll")).toBe(true)
expect(events.some((e) => e.kind === "destroy")).toBe(true)
})
test("scope finalizer unpublishes even if stop() is not called for force-close", async () => {
Flag.OPENCODE_SERVER_PASSWORD = "mdns-secret"
Flag.OPENCODE_SERVER_USERNAME = "opencode"
const listener = await Server.listen({ hostname: "0.0.0.0", port: 0, mdns: true })
expect(events.filter((e) => e.kind === "publish").length).toBe(1)
// Plain (graceful) stop without close=true should still unpublish.
await withTimeout(listener.stop(), 10_000, "timed out stopping graceful mdns listener")
expect(events.some((e) => e.kind === "unpublishAll")).toBe(true)
})
})