import { describe, expect, it } from "vitest"; import { chvAttachmentBlocked, chvAvailability, chvAvailabilityText, chvQueueHint, chvVmBadge, chvVmDisplay, chvVmStatusText, countChvWorkers, isChvExecutor, isWorkerAlive } from "./chv"; // 纯逻辑测试:只测 chv.ts,不渲染组件、不发请求、不读 localStorage。 // alive 规则与 WorkersSection 现有口径一致:alive 字段优先, // 缺失时用 last_seen 距今 <= 120 秒判定在线。 describe("isWorkerAlive", () => { it("alive 字段优先", () => { expect(isWorkerAlive({ executor: "cloud-hypervisor", alive: true })).toBe(true); expect(isWorkerAlive({ executor: "cloud-hypervisor", alive: false, last_seen: Date.now() / 1000 })).toBe(false); }); it("无 alive 时用 last_seen 120 秒门槛", () => { const now = Date.now() / 1000; expect(isWorkerAlive({ executor: "cloud-hypervisor", last_seen: now - 10 })).toBe(true); expect(isWorkerAlive({ executor: "cloud-hypervisor", last_seen: now - 121 })).toBe(false); expect(isWorkerAlive({ executor: "cloud-hypervisor" })).toBe(false); }); }); describe("countChvWorkers", () => { it("只数 cloud-hypervisor,不数 docker/local", () => { const now = Date.now() / 1000; expect(countChvWorkers([ { executor: "cloud-hypervisor", alive: true }, { executor: "cloud-hypervisor", last_seen: now - 9999 }, { executor: "docker", alive: true }, ])).toEqual({ online: 1, total: 2 }); }); }); describe("chvAvailability", () => { it("有清单时按清单数", () => { expect(chvAvailability([{ executor: "cloud-hypervisor", alive: true }], "", "")).toEqual( { state: "known", online: 1, total: 1 }, ); }); it("无清单但聚合文案时是未知,不是 0", () => { expect(chvAvailability(null, "在线 2 / 离线 1(共 3;完整 worker 清单仅全局管理员可见)", "")).toEqual( { state: "unknown", reason: "aggregate-only" }, ); }); it("无 worker 注册时是已知 0", () => { expect(chvAvailability(null, "无 worker 注册", "")).toEqual({ state: "known", online: 0, total: 0 }); }); it("加载失败时是未知", () => { expect(chvAvailability(null, "", "加载失败:x")).toEqual({ state: "unknown", reason: "load-failed" }); }); it("尚未加载时是未知", () => { expect(chvAvailability(null, "未加载", "")).toEqual({ state: "unknown", reason: "not-loaded" }); }); }); describe("isChvExecutor", () => { it("精确值才算 CHV,不做大小写/前缀宽松匹配", () => { expect(isChvExecutor("cloud-hypervisor")).toBe(true); expect(isChvExecutor("Cloud-Hypervisor")).toBe(false); expect(isChvExecutor("cloud-hypervisor-x")).toBe(false); expect(isChvExecutor("docker")).toBe(false); expect(isChvExecutor(undefined)).toBe(false); expect(isChvExecutor(null)).toBe(false); }); }); describe("chvAttachmentBlocked", () => { it("仅 CHV + 带附件时拦(后端 400 的前端提示口径)", () => { expect(chvAttachmentBlocked("cloud-hypervisor", true)).toBe(true); expect(chvAttachmentBlocked("cloud-hypervisor", false)).toBe(false); expect(chvAttachmentBlocked("docker", true)).toBe(false); expect(chvAttachmentBlocked("cloud", true)).toBe(false); }); }); describe("chvVmStatusText", () => { it("已报告死亡时给死亡文案", () => { expect(chvVmStatusText({ executor: "cloud-hypervisor", chv_vm_dead: true })).toContain("VM 中途死亡"); }); it("CHV 无字段时给未报告文案,绝不写成活着", () => { const text = chvVmStatusText({ executor: "cloud-hypervisor" }); expect(text).toContain("未报告 VM 死亡"); expect(text).toContain("不代表 VM 活着"); }); it("非 CHV 任务不显示 VM 行", () => { expect(chvVmStatusText({ executor: "docker" })).toBe(""); expect(chvVmStatusText({ executor: "docker", chv_vm_dead: true })).toBe(""); }); }); describe("chvVmBadge", () => { it("只有 CHV + 已报告死亡时才出徽标", () => { expect(chvVmBadge({ executor: "cloud-hypervisor", chv_vm_dead: true })).toBe("VM 已报告死亡"); expect(chvVmBadge({ executor: "cloud-hypervisor" })).toBe(""); expect(chvVmBadge({ executor: "docker", chv_vm_dead: true })).toBe(""); }); }); describe("chvQueueHint", () => { it("仅 CHV + 排队 + 已知零在线时给提示", () => { const knownZero = { state: "known" as const, online: 0, total: 0 }; expect(chvQueueHint("cloud-hypervisor", "queued", knownZero)).toContain("可能原因"); expect(chvQueueHint("docker", "queued", knownZero)).toBe(""); expect(chvQueueHint("cloud-hypervisor", "running", knownZero)).toBe(""); expect(chvQueueHint("cloud-hypervisor", "queued", { state: "unknown" as const, reason: "aggregate-only" })).toBe(""); expect(chvQueueHint("cloud-hypervisor", "queued", { state: "known" as const, online: 1, total: 1 })).toBe(""); }); }); describe("chvVmDisplay(to10 四态)", () => { it("字段 present=true → dead", () => { const d = chvVmDisplay({ executor: "cloud-hypervisor", chv_vm_dead: true }); expect(d.state).toBe("dead"); expect(d.text).toContain("VM 中途死亡"); }); it("字段 absent → not-reported,不猜 live", () => { const d = chvVmDisplay({ executor: "cloud-hypervisor" }); expect(d.state).toBe("not-reported"); expect(d.text).toContain("不代表 VM 活着"); }); it("任务未加载 → unknown", () => { const d = chvVmDisplay(null); expect(d.state).toBe("unknown"); expect(d.text).toContain("无法判断"); }); it("非 CHV → not-applicable,text 为空", () => { const d = chvVmDisplay({ executor: "docker", chv_vm_dead: true }); expect(d.state).toBe("not-applicable"); expect(d.text).toBe(""); }); it("旧入口仍是 display 的 text(unknown/not-applicable 回空)", () => { expect(chvVmStatusText({ executor: "cloud-hypervisor", chv_vm_dead: true })).toContain("VM 中途死亡"); expect(chvVmStatusText(null)).toBe(""); expect(chvVmStatusText({ executor: "docker" })).toBe(""); }); }); describe("chvAvailabilityText(to10 四处统一文案)", () => { it("known 零在线:不拦提交、后端是最终权威", () => { const text = chvAvailabilityText({ state: "known", online: 0, total: 2 }); expect(text).toContain("在线 0 / 共 2"); expect(text).toContain("不拦提交"); expect(text).toContain("最终权威"); }); it("known 非零:只有在线数,无排队警告", () => { const text = chvAvailabilityText({ state: "known", online: 1, total: 1 }); expect(text).toContain("在线 1 / 共 1"); expect(text).not.toContain("排队"); }); it("未知三原因各有不同文案,绝不写成 0", () => { expect(chvAvailabilityText({ state: "unknown", reason: "aggregate-only" })).toContain("仅全局管理员可见"); expect(chvAvailabilityText({ state: "unknown", reason: "load-failed" })).toContain("加载失败"); expect(chvAvailabilityText({ state: "unknown", reason: "not-loaded" })).toContain("尚未加载"); for (const reason of ["aggregate-only", "load-failed", "not-loaded"] as const) { expect(chvAvailabilityText({ state: "unknown", reason })).not.toContain("在线 0"); } }); });