Files
cloudflare-domain-manager/apps/api/test/health-check.test.ts
T
Denozordec 6a1498bf80
Build, Test, and Push CFDM Docker Image / test (push) Successful in 4m0s
Build, Test, and Push CFDM Docker Image / build-and-push (push) Successful in 2m13s
Build, Test, and Push CFDM Docker Image / update-wiki (push) Failing after 6s
Build, Test, and Push CFDM Docker Image / create-release (push) Has been skipped
feat: Implement load balancing and health check features for service groups, including DNS-based load balancing modes and health check configurations, enhancing service reliability and performance monitoring
2026-06-25 18:24:00 +07:00

125 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it, beforeAll, afterAll } from "vitest";
import { createServer, type Server } from "node:net";
import * as healthCheckService from "../src/services/health-check-service.js";
import type { HealthCheckTarget } from "@cfdm/shared";
function startTcpServer(): Promise<{ server: Server; port: number }> {
return new Promise((resolve) => {
const server = createServer();
server.listen(0, "127.0.0.1", () => {
const address = server.address();
const port =
typeof address === "object" && address ? address.port : 0;
resolve({ server, port });
});
});
}
describe("health-check probeTarget", () => {
let server: Server;
let port: number;
beforeAll(async () => {
const started = await startTcpServer();
server = started.server;
port = started.port;
});
afterAll(async () => {
await new Promise<void>((resolve) => server.close(() => resolve()));
});
it("tcp probe succeeds for open port", async () => {
const target: HealthCheckTarget = {
scope: "binding",
ref_id: 1,
ip: "127.0.0.1",
hostname: "test.local",
type: "tcp",
port,
path: null,
expected_status: null,
timeout_ms: 1000,
};
const result = await healthCheckService.probeTarget(target);
expect(result.ok).toBe(true);
expect(result.error).toBeNull();
expect(result.latencyMs).toBeGreaterThanOrEqual(0);
});
it("tcp probe fails for closed port", async () => {
const target: HealthCheckTarget = {
scope: "binding",
ref_id: 1,
ip: "127.0.0.1",
hostname: "test.local",
type: "tcp",
port: 1,
path: null,
expected_status: null,
timeout_ms: 500,
};
const result = await healthCheckService.probeTarget(target);
expect(result.ok).toBe(false);
expect(result.error).not.toBeNull();
});
});
describe("health-check state derivation via runAllChecks", () => {
it("marks ip down after threshold failures and up after recovery", async () => {
const { createMemoryDb, repos, runMigrations } = await import("@cfdm/db");
const { db, sqlite } = createMemoryDb();
runMigrations(sqlite);
const domain = repos.createDomain(db, null, "example.com", "zone-id");
const service = repos.createService(db, "Svc", "svc");
const binding = repos.insertBinding(
db,
domain.id,
service.id,
"@",
null,
);
repos.updateBindingLbConfig(db, binding.id, {
health_check_enabled: true,
health_check_type: "tcp",
health_check_port: 1,
health_check_timeout_ms: 200,
});
repos.replaceBindingIpsWithMeta(db, binding.id, [
{ ip: "127.0.0.1", weight: 1, priority: 1 },
]);
// Запуск с closed port (port 1) — должен зафиксировать down после 2 проверок
await healthCheckService.runAllChecks(db, {
thresholds: {
degradedFailures: 1,
downFailures: 2,
latencyWarnMs: 1000,
},
});
let status = repos.getIpHealthStatusRow(
db,
"binding",
binding.id,
"127.0.0.1",
);
expect(status?.status).toBe("degraded");
await healthCheckService.runAllChecks(db, {
thresholds: {
degradedFailures: 1,
downFailures: 2,
latencyWarnMs: 1000,
},
});
status = repos.getIpHealthStatusRow(
db,
"binding",
binding.id,
"127.0.0.1",
);
expect(status?.status).toBe("down");
});
});