Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
6.0 kB ยท 221 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222import { expect } from "@std/expect";import { afterEach, describe, test } from "@std/testing/bdd";
import { testGrpc, testHttp, testTcp } from "./checker";
const originalFetch = globalThis.fetch;
afterEach(() => { globalThis.fetch = originalFetch;});
/** Stub the checker with one canned JSON body. */function stubChecker(body: unknown) { globalThis.fetch = (() => Promise.resolve( new Response(JSON.stringify(body), { status: 200, headers: { "Content-Type": "application/json" }, }), )) as typeof globalThis.fetch;}
/** Make the checker fetch reject, e.g. with the AbortSignal.timeout error. */function stubCheckerRejects(error: unknown) { globalThis.fetch = (() => Promise.reject(error)) as typeof globalThis.fetch;}
/** Count console.error calls while `fn` runs, then restore. */async function countErrors(fn: () => Promise<unknown>): Promise<number> { const origError = console.error; let count = 0; console.error = () => { count++; }; try { await fn().catch(() => {}); } finally { console.error = origError; } return count;}
const timing = { dnsStart: 1, dnsDone: 2, connectStart: 2, connectDone: 3, tlsHandshakeStart: 3, tlsHandshakeDone: 4, firstByteStart: 4, firstByteDone: 5, transferStart: 5, transferDone: 6,};
describe("testHttp", () => { const input = { url: "https://example.com", method: "GET" as const, region: "ams" as const, assertions: [], };
test("accepts a 2XX response", async () => { stubChecker({ status: 200, latency: 5, headers: {}, timestamp: 1_700_000_000_000, timing, region: "ams", });
const result = await testHttp(input); expect(result.state).toBe("success"); });
test("maps the unreachable shape to its error message without logging", async () => { // `checker.Http` answers 200 with `error` set and status/headers omitted. stubChecker({ error: "Timeout after 45000 ms", latency: 45000, timestamp: 1_700_000_000_000, timing, region: "ams", });
await expect(testHttp(input)).rejects.toThrow("Timeout after 45000 ms"); expect(await countErrors(() => testHttp(input))).toBe(0); });
test("does not log a failed assertion", async () => { stubChecker({ status: 500, latency: 5, headers: {}, timestamp: 1_700_000_000_000, timing, region: "ams", });
await expect(testHttp(input)).rejects.toThrow("Assertion error"); expect(await countErrors(() => testHttp(input))).toBe(0); });
test("maps a checker timeout to BAD_REQUEST without logging", async () => { stubCheckerRejects(new DOMException("timed out", "TimeoutError"));
const error = await testHttp(input).catch((e) => e); expect(error.code).toBe("BAD_REQUEST"); expect(await countErrors(() => testHttp(input))).toBe(0); });
test("still logs an unexpected failure", async () => { stubCheckerRejects(new TypeError("fetch failed"));
const error = await testHttp(input).catch((e) => e); expect(error.code).toBe("INTERNAL_SERVER_ERROR"); expect(await countErrors(() => testHttp(input))).toBe(1); });});
describe("testTcp", () => { const input = { url: "example.com:443", region: "ams" as const };
test("does not log an unreachable target", async () => { stubChecker({ message: "uri not reachable" });
await expect(testTcp(input)).rejects.toThrow("uri not reachable"); expect(await countErrors(() => testTcp(input))).toBe(0); });});
/** * The shape GRPCHandlerRegion returns for a completed RPC. `state` is absent โ * the handler never sends it โ so grpcOutput prefaults it to "success". */function completedResponse( overrides: Record<string, unknown>,): Record<string, unknown> { return { jobType: "grpc", region: "ams", timestamp: 1_700_000_000_000, timing: { dnsStart: 1, dnsDone: 2, connectStart: 2, connectDone: 3, tlsHandshakeStart: 3, tlsHandshakeDone: 4, firstByteStart: 4, firstByteDone: 5, transferStart: 5, transferDone: 6, }, latency: 5, completed: true, ...overrides, };}
describe("testGrpc", () => { test("accepts a SERVING target", async () => { // `error` is omitempty in Go, so a healthy check omits it entirely. stubChecker(completedResponse({ servingStatus: "SERVING" }));
const result = await testGrpc({ url: "api.example.com:443", tls: "tls", region: "ams", }); expect(result.state).toBe("success"); });
test("rejects a completed check that answered NOT_SERVING", async () => { stubChecker( completedResponse({ servingStatus: "NOT_SERVING", error: 1, errorMessage: "service reports NOT_SERVING", }), );
await expect( testGrpc({ url: "api.example.com:443", tls: "tls", region: "ams" }), ).rejects.toThrow("service reports NOT_SERVING"); });
test("rejects a server with no health service", async () => { stubChecker( completedResponse({ error: 1, errorMessage: "server does not implement grpc.health.v1.Health", }), );
await expect( testGrpc({ url: "api.example.com:443", tls: "tls", region: "ams" }), ).rejects.toThrow("does not implement"); });
test("falls back to the serving status when no message is sent", async () => { stubChecker( completedResponse({ servingStatus: "SERVICE_UNKNOWN", error: 1 }), );
await expect( testGrpc({ url: "api.example.com:443", tls: "tls", region: "ams" }), ).rejects.toThrow("SERVICE_UNKNOWN"); });
test("still rejects a transport failure", async () => { // The only shape that carries `state` explicitly. stubChecker({ message: "uri not reachable" });
await expect( testGrpc({ url: "api.example.com:443", tls: "tls", region: "ams" }), ).rejects.toThrow("uri not reachable"); });});