Files
codex-app-server/cloud/console-react/src/api/chv.closeup.test.ts
T
host 54f20dfe55 feat-chv-closeup:收尾(executor 覆盖到 100%、合并/灰度准备,堆叠于 #264)
- 后端新增 cloud/tests/test_chv_closeup.py 85 项:唤醒失败
  (vm.create/vm.boot/API 超时/guest 就绪超时/host key 不匹配/
  provisioned 缺钉死)、恢复与快照失败、取消与清理(残留
  socket/登记/磁盘/密钥、脏标记)、中途死亡分类、只读
  execute 归类、入口校验、preflight 事后改写、防御性
  except、worker_adapter 剩余分支;executor.py 覆盖 100%。
- 前端新增 src/api/chv.closeup.test.ts 13 项:显式 false、
  undefined、可用性优先级、Workers 旧 bug 文案不复发、
  120 秒边界;控制按钮与新页面仍不做。
- 新增 tools/chv_merge_precheck.py(只读):逐个核 base/head/
  mergeable/CI/链衔接,实测 11 个 PR 全 NOT-READY(CI 全
  FAIL、mergeState 全 UNSTABLE),退出码 1,绝不合并。
- docs/chv-production-readiness.md 新增 §14:审计落盘运维
  runbook(定位/轮转/读取/清理,ADR-14 取舍不变)、mypy
  默认口径 2 错评估(沙箱验证过的标注修法,本轨不改
  其它链文件)、灰度三阶段可执行清单、V-1~V-9 检查表
  (全部未验证)、逐项评分。
- 安全语义不变:egress、key seed 投递、磁盘删除、默认
  provisioned、tap 校验、前端不绕后端白名单均未放宽。
- 只到 PR OPEN,不合并、不部署;CI 账单仍是硬门禁。
2026-10-31 12:15:56 +00:00

77 lines
3.7 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 } from "vitest";
import { chvAttachmentBlocked, chvAvailability, chvAvailabilityText, chvQueueHint, chvVmBadge, chvVmDisplay, chvVmStatusText, countChvWorkers, isWorkerAlive } from "./chv";
// closeup 轨补边角:上一轨 chv.test.ts 已覆主路径后仍缺的
// 显式 false、undefined、优先级与“旧 bug 文案不复发”断言。
// 只测 chv.ts 纯逻辑,不渲染组件、不发请求。
describe("chvVmDisplay 边角(closeup)", () => {
it("字段显式 false 与 absent 同属 not-reported", () => {
const d = chvVmDisplay({ executor: "cloud-hypervisor", chv_vm_dead: false });
expect(d.state).toBe("not-reported");
expect(d.text).toContain("不代表 VM 活着");
});
it("任务 undefined 与 null 同属 unknown", () => {
expect(chvVmDisplay(undefined).state).toBe("unknown");
expect(chvVmDisplay(undefined).text).toContain("无法判断");
});
it("非 CHV 且无 executor 字段时也是 not-applicable", () => {
expect(chvVmDisplay({}).state).toBe("not-applicable");
expect(chvVmDisplay({ executor: undefined }).text).toBe("");
expect(chvVmStatusText({ executor: "cloud-hypervisor", chv_vm_dead: false })).toContain("未报告 VM 死亡");
});
it("列表徽标:显式 false 不出徽标", () => {
expect(chvVmBadge({ executor: "cloud-hypervisor", chv_vm_dead: false })).toBe("");
});
});
describe("chvAvailability 优先级(closeup)", () => {
it("加载失败优先于聚合文案:不把失败写成 aggregate-only", () => {
expect(chvAvailability(null, "完整 worker 清单仅全局管理员可见", "加载失败:x")).toEqual(
{ state: "unknown", reason: "load-failed" },
);
});
it("有清单时忽略错误与聚合文案", () => {
expect(chvAvailability([{ executor: "cloud-hypervisor", alive: false }], "完整 worker 清单仅全局管理员可见", "加载失败:x")).toEqual(
{ state: "known", online: 0, total: 1 },
);
});
it("空清单与空文案是 not-loaded,不是已知 0", () => {
expect(chvAvailability(null, "", "")).toEqual({ state: "unknown", reason: "not-loaded" });
});
it("空 worker 数组是已知 0(与 null 区分)", () => {
expect(chvAvailability([], "", "")).toEqual({ state: "known", online: 0, total: 0 });
expect(countChvWorkers([])).toEqual({ online: 0, total: 0 });
});
});
describe("chvAvailabilityText:Workers 旧 bug 不复发(closeup)", () => {
it("load-failed / not-loaded 绝不写“仅全局管理员可见”", () => {
expect(chvAvailabilityText({ state: "unknown", reason: "load-failed" })).not.toContain("仅全局管理员可见");
expect(chvAvailabilityText({ state: "unknown", reason: "not-loaded" })).not.toContain("仅全局管理员可见");
});
it("known 总数为 0 时仍是已知 0,不写未知", () => {
const text = chvAvailabilityText({ state: "known", online: 0, total: 0 });
expect(text).toContain("在线 0 / 共 0");
expect(text).not.toContain("未知");
});
});
describe("附件拦截与排队提示边角(closeup)", () => {
it("executor 为 undefined/null 时附件不拦", () => {
expect(chvAttachmentBlocked(undefined, true)).toBe(false);
expect(chvAttachmentBlocked(null, true)).toBe(false);
});
it("排队提示:未知三原因一律为空串", () => {
for (const reason of ["aggregate-only", "load-failed", "not-loaded"] as const) {
expect(chvQueueHint("cloud-hypervisor", "queued", { state: "unknown", reason })).toBe("");
}
});
});
describe("isWorkerAlive 边界(closeup)", () => {
it("last_seen 恰好 120 秒算在线(<=120)", () => {
const now = Date.now() / 1000;
expect(isWorkerAlive({ executor: "cloud-hypervisor", last_seen: now - 120 })).toBe(true);
});
});