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
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

This commit is contained in:
Denozordec
2026-06-25 18:24:00 +07:00
parent e5dc483d43
commit 6a1498bf80
35 changed files with 5312 additions and 281 deletions
+124
View File
@@ -0,0 +1,124 @@
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");
});
});