chore: refactoring and tests (#12629)
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { checkServerHealth } from "./server-health"
|
||||
|
||||
function abortFromInput(input: RequestInfo | URL, init?: RequestInit) {
|
||||
if (init?.signal) return init.signal
|
||||
if (input instanceof Request) return input.signal
|
||||
return undefined
|
||||
}
|
||||
|
||||
describe("checkServerHealth", () => {
|
||||
test("returns healthy response with version", async () => {
|
||||
const fetch = (async () =>
|
||||
@@ -24,10 +30,40 @@ describe("checkServerHealth", () => {
|
||||
expect(result).toEqual({ healthy: false })
|
||||
})
|
||||
|
||||
test("uses timeout fallback when AbortSignal.timeout is unavailable", async () => {
|
||||
const timeout = Object.getOwnPropertyDescriptor(AbortSignal, "timeout")
|
||||
Object.defineProperty(AbortSignal, "timeout", {
|
||||
configurable: true,
|
||||
value: undefined,
|
||||
})
|
||||
|
||||
let aborted = false
|
||||
const fetch = ((input: RequestInfo | URL, init?: RequestInit) =>
|
||||
new Promise<Response>((_resolve, reject) => {
|
||||
const signal = abortFromInput(input, init)
|
||||
signal?.addEventListener(
|
||||
"abort",
|
||||
() => {
|
||||
aborted = true
|
||||
reject(new DOMException("Aborted", "AbortError"))
|
||||
},
|
||||
{ once: true },
|
||||
)
|
||||
})) as unknown as typeof globalThis.fetch
|
||||
|
||||
const result = await checkServerHealth("http://localhost:4096", fetch, { timeoutMs: 10 }).finally(() => {
|
||||
if (timeout) Object.defineProperty(AbortSignal, "timeout", timeout)
|
||||
if (!timeout) Reflect.deleteProperty(AbortSignal, "timeout")
|
||||
})
|
||||
|
||||
expect(aborted).toBe(true)
|
||||
expect(result).toEqual({ healthy: false })
|
||||
})
|
||||
|
||||
test("uses provided abort signal", async () => {
|
||||
let signal: AbortSignal | undefined
|
||||
const fetch = (async (input: RequestInfo | URL, init?: RequestInit) => {
|
||||
signal = init?.signal ?? (input instanceof Request ? input.signal : undefined)
|
||||
signal = abortFromInput(input, init)
|
||||
return new Response(JSON.stringify({ healthy: true, version: "1.2.3" }), {
|
||||
status: 200,
|
||||
headers: { "content-type": "application/json" },
|
||||
@@ -39,4 +75,40 @@ describe("checkServerHealth", () => {
|
||||
|
||||
expect(signal).toBe(abort.signal)
|
||||
})
|
||||
|
||||
test("retries transient failures and eventually succeeds", async () => {
|
||||
let count = 0
|
||||
const fetch = (async () => {
|
||||
count += 1
|
||||
if (count < 3) throw new TypeError("network")
|
||||
return new Response(JSON.stringify({ healthy: true, version: "1.2.3" }), {
|
||||
status: 200,
|
||||
headers: { "content-type": "application/json" },
|
||||
})
|
||||
}) as unknown as typeof globalThis.fetch
|
||||
|
||||
const result = await checkServerHealth("http://localhost:4096", fetch, {
|
||||
retryCount: 2,
|
||||
retryDelayMs: 1,
|
||||
})
|
||||
|
||||
expect(count).toBe(3)
|
||||
expect(result).toEqual({ healthy: true, version: "1.2.3" })
|
||||
})
|
||||
|
||||
test("returns unhealthy when retries are exhausted", async () => {
|
||||
let count = 0
|
||||
const fetch = (async () => {
|
||||
count += 1
|
||||
throw new TypeError("network")
|
||||
}) as unknown as typeof globalThis.fetch
|
||||
|
||||
const result = await checkServerHealth("http://localhost:4096", fetch, {
|
||||
retryCount: 2,
|
||||
retryDelayMs: 1,
|
||||
})
|
||||
|
||||
expect(count).toBe(3)
|
||||
expect(result).toEqual({ healthy: false })
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user