155 lines
4.7 KiB
TypeScript
155 lines
4.7 KiB
TypeScript
import { describe, it, beforeEach, afterEach } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
const originalFetch = globalThis.fetch;
|
|
|
|
afterEach(() => {
|
|
globalThis.fetch = originalFetch;
|
|
});
|
|
|
|
describe("healthMonitor", () => {
|
|
let mod;
|
|
beforeEach(async () => {
|
|
try {
|
|
const prev = await import("../../src/lib/versionManager/healthMonitor.ts");
|
|
prev.stopMonitoring("test-tool");
|
|
prev.stopMonitoring("tool-a");
|
|
prev.stopMonitoring("tool-b");
|
|
} catch {}
|
|
mod = await import("../../src/lib/versionManager/healthMonitor.ts");
|
|
});
|
|
|
|
afterEach(() => {
|
|
try {
|
|
mod.stopMonitoring("test-tool");
|
|
} catch {}
|
|
try {
|
|
mod.stopMonitoring("tool-a");
|
|
} catch {}
|
|
try {
|
|
mod.stopMonitoring("tool-b");
|
|
} catch {}
|
|
});
|
|
|
|
describe("checkHealth", () => {
|
|
it("should return healthy for 200 with models", async () => {
|
|
globalThis.fetch = async () => ({
|
|
ok: true,
|
|
status: 200,
|
|
json: async () => ({ data: [{ id: "m1" }, { id: "m2" }] }),
|
|
});
|
|
const r = await mod.checkHealth("http://127.0.0.1:8317");
|
|
assert.equal(r.healthy, true);
|
|
assert.equal(r.modelCount, 2);
|
|
assert.equal(r.error, null);
|
|
assert.ok(r.latency >= 0);
|
|
});
|
|
|
|
it("should return unhealthy for non-200", async () => {
|
|
globalThis.fetch = async () => ({
|
|
ok: false,
|
|
status: 503,
|
|
json: async () => ({}),
|
|
});
|
|
const r = await mod.checkHealth("http://127.0.0.1:8317");
|
|
assert.equal(r.healthy, false);
|
|
assert.equal(r.modelCount, 0);
|
|
assert.equal(r.error, "HTTP 503");
|
|
});
|
|
|
|
it("should return unhealthy on network error", async () => {
|
|
globalThis.fetch = async () => {
|
|
throw new Error("ECONNREFUSED");
|
|
};
|
|
const r = await mod.checkHealth("http://127.0.0.1:8317");
|
|
assert.equal(r.healthy, false);
|
|
assert.ok(r.error.includes("ECONNREFUSED"));
|
|
});
|
|
|
|
it("should handle non-array data.data", async () => {
|
|
globalThis.fetch = async () => ({
|
|
ok: true,
|
|
status: 200,
|
|
json: async () => ({ data: "not-array" }),
|
|
});
|
|
const r = await mod.checkHealth("http://127.0.0.1:8317");
|
|
assert.equal(r.healthy, true);
|
|
assert.equal(r.modelCount, 0);
|
|
});
|
|
|
|
it("should use custom health path", async () => {
|
|
let capturedUrl;
|
|
globalThis.fetch = async (url) => {
|
|
capturedUrl = url;
|
|
return { ok: true, status: 200, json: async () => ({ data: [] }) };
|
|
};
|
|
await mod.checkHealth("http://127.0.0.1:8317", "/health");
|
|
assert.ok(capturedUrl.includes("/health"));
|
|
});
|
|
|
|
it("should default to /v1/models", async () => {
|
|
let capturedUrl;
|
|
globalThis.fetch = async (url) => {
|
|
capturedUrl = url;
|
|
return { ok: true, status: 200, json: async () => ({ data: [] }) };
|
|
};
|
|
await mod.checkHealth("http://127.0.0.1:8317");
|
|
assert.ok(capturedUrl.includes("/v1/models"));
|
|
});
|
|
|
|
it("should handle non-Error throws", async () => {
|
|
globalThis.fetch = async () => {
|
|
throw "string error";
|
|
};
|
|
const r = await mod.checkHealth("http://127.0.0.1:8317");
|
|
assert.equal(r.healthy, false);
|
|
assert.equal(r.error, "string error");
|
|
});
|
|
|
|
it("should return unhealthy for 500", async () => {
|
|
globalThis.fetch = async () => ({
|
|
ok: false,
|
|
status: 500,
|
|
json: async () => ({}),
|
|
});
|
|
const r = await mod.checkHealth("http://127.0.0.1:8317");
|
|
assert.equal(r.healthy, false);
|
|
assert.equal(r.error, "HTTP 500");
|
|
});
|
|
});
|
|
|
|
describe("startMonitoring / stopMonitoring / isMonitoring", () => {
|
|
it("should start and stop monitoring", () => {
|
|
globalThis.fetch = async () => ({
|
|
ok: true,
|
|
status: 200,
|
|
json: async () => ({ data: [] }),
|
|
});
|
|
mod.startMonitoring("tool-a", "http://127.0.0.1:8317", 60_000);
|
|
assert.equal(mod.isMonitoring("tool-a"), true);
|
|
mod.stopMonitoring("tool-a");
|
|
assert.equal(mod.isMonitoring("tool-a"), false);
|
|
});
|
|
|
|
it("should replace previous monitoring on re-start", () => {
|
|
globalThis.fetch = async () => ({
|
|
ok: true,
|
|
status: 200,
|
|
json: async () => ({ data: [] }),
|
|
});
|
|
mod.startMonitoring("tool-b", "http://127.0.0.1:8317", 60_000);
|
|
mod.startMonitoring("tool-b", "http://127.0.0.1:8317", 30_000);
|
|
assert.equal(mod.isMonitoring("tool-b"), true);
|
|
mod.stopMonitoring("tool-b");
|
|
});
|
|
|
|
it("should return false for non-monitored tool", () => {
|
|
assert.equal(mod.isMonitoring("nonexistent"), false);
|
|
});
|
|
|
|
it("should handle stopMonitoring for non-existent tool", () => {
|
|
assert.doesNotThrow(() => mod.stopMonitoring("ghost"));
|
|
});
|
|
});
|
|
});
|