feat: 新增本机 CPU checker
- 新增 type: cpu checker,基于 os.cpus() 两次快照计算 CPU 使用率 - 配置项:sampleDuration(默认 1s)、includePerCore(默认 false) - expect 字段:usagePercent、idlePercent、maxCoreUsagePercent、minCoreUsagePercent、durationMs - idlePercent 与 usagePercent 互补恒等于 100,百分比范围 0-100 - logicalCoreCount 仅输出到 observation,不作为 expect 字段 - 不暴露 userPercent / systemPercent - 语义校验禁止 sampleDuration >= timeout - 支持 AbortSignal 超时取消 - 完整测试覆盖:schema、validate、normalize、resolve、calculate、execute、expect、config-loader - 新增用户文档 docs/user/checkers/cpu.md - 更新 checker 索引、配置类型列表、示例配置和 schema
This commit is contained in:
@@ -2270,6 +2270,82 @@ targets:
|
||||
);
|
||||
});
|
||||
|
||||
test("解析最简 cpu 配置", async () => {
|
||||
const configPath = join(tempDir, "minimal-cpu.yaml");
|
||||
await writeFile(
|
||||
configPath,
|
||||
`targets:
|
||||
- id: "local-cpu"
|
||||
type: cpu
|
||||
cpu: {}
|
||||
`,
|
||||
);
|
||||
|
||||
const config = await loadConfig(configPath);
|
||||
expect(config.targets).toHaveLength(1);
|
||||
const t = config.targets[0]! as Record<string, unknown>;
|
||||
expect(t["type"]).toBe("cpu");
|
||||
expect((t["cpu"] as Record<string, unknown>)["sampleDurationMs"]).toBe(1000);
|
||||
expect((t["cpu"] as Record<string, unknown>)["includePerCore"]).toBe(false);
|
||||
expect(t["group"]).toBe("default");
|
||||
expect(t["intervalMs"]).toBe(30000);
|
||||
expect(t["timeoutMs"]).toBe(10000);
|
||||
});
|
||||
|
||||
test("解析 cpu expect 配置", async () => {
|
||||
const configPath = join(tempDir, "cpu-expect.yaml");
|
||||
await writeFile(
|
||||
configPath,
|
||||
`targets:
|
||||
- id: "local-cpu"
|
||||
type: cpu
|
||||
cpu:
|
||||
sampleDuration: "2s"
|
||||
includePerCore: true
|
||||
expect:
|
||||
usagePercent: { lte: 85 }
|
||||
idlePercent: { gte: 15 }
|
||||
maxCoreUsagePercent: { lte: 95 }
|
||||
durationMs: { lte: 3000 }
|
||||
`,
|
||||
);
|
||||
|
||||
const config = await loadConfig(configPath);
|
||||
expect(config.targets).toHaveLength(1);
|
||||
const t = config.targets[0]! as Record<string, unknown>;
|
||||
expect((t["cpu"] as Record<string, unknown>)["sampleDurationMs"]).toBe(2000);
|
||||
expect((t["cpu"] as Record<string, unknown>)["includePerCore"]).toBe(true);
|
||||
expect((t["expect"] as Record<string, unknown>)["usagePercent"]).toEqual({ lte: 85 });
|
||||
});
|
||||
|
||||
test("cpu expect 未知字段抛出错误", async () => {
|
||||
await expectConfigError(
|
||||
"cpu-unknown-expect.yaml",
|
||||
`targets:
|
||||
- id: "local-cpu"
|
||||
type: cpu
|
||||
cpu: {}
|
||||
expect:
|
||||
logicalCoreCount: { gte: 4 }
|
||||
`,
|
||||
"expect.logicalCoreCount 是未知字段",
|
||||
);
|
||||
});
|
||||
|
||||
test("cpu sampleDuration >= timeout 抛出错误", async () => {
|
||||
await expectConfigError(
|
||||
"cpu-sample-too-long.yaml",
|
||||
`targets:
|
||||
- id: "local-cpu"
|
||||
type: cpu
|
||||
timeout: "1s"
|
||||
cpu:
|
||||
sampleDuration: "5s"
|
||||
`,
|
||||
"sampleDuration 必须小于 timeout",
|
||||
);
|
||||
});
|
||||
|
||||
describe("logging 配置", () => {
|
||||
test("logging 全部缺省时使用默认值", async () => {
|
||||
const configPath = join(tempDir, "logging-default.yaml");
|
||||
|
||||
Reference in New Issue
Block a user