fix: 强化 CPU/memory checker 错误处理、timeout 遵守和快照校验
- Memory checker: reader 与 ctx.signal race,abort 返回 memory/timeout,reject 保持 memory/snapshot - CPU checker: 第二次快照异常返回 cpu/snapshot,计算前校验空数组/核心数不一致/非有限值/负 delta - CPU 计算: 零 delta 安全处理,observation 不含 NaN/Infinity - 文档: CPU 互补描述修正,Memory timeout 约束说明 - 测试: +18 覆盖 timeout、异常和边界输入
This commit is contained in:
@@ -153,6 +153,66 @@ describe("MemoryChecker execute", () => {
|
||||
expect(result.observation).toBeNull();
|
||||
});
|
||||
|
||||
test("signal 已 abort 时返回 timeout failure", async () => {
|
||||
const reader = () => Promise.resolve(makeMemData());
|
||||
const checker = new MemoryChecker(reader);
|
||||
|
||||
const target: RawTargetConfig = { id: "mem-test", memory: {}, type: "memory" };
|
||||
const resolved = checker.resolve(target, makeResolveContext());
|
||||
|
||||
const controller = new AbortController();
|
||||
controller.abort();
|
||||
const result = await checker.execute(resolved, { signal: controller.signal });
|
||||
|
||||
expect(result.matched).toBe(false);
|
||||
expect(result.failure?.phase).toBe("memory");
|
||||
expect(result.failure?.path).toBe("timeout");
|
||||
expect(result.observation).toBeNull();
|
||||
});
|
||||
|
||||
test("pending reader 被 signal abort 后返回 timeout failure", async () => {
|
||||
const reader = () =>
|
||||
new Promise<Systeminformation.MemData>(() => {
|
||||
// 故意永不 resolve,模拟悬挂的 reader
|
||||
});
|
||||
const checker = new MemoryChecker(reader);
|
||||
|
||||
const target: RawTargetConfig = { id: "mem-test", memory: {}, type: "memory" };
|
||||
const resolved = checker.resolve(target, makeResolveContext());
|
||||
|
||||
const controller = new AbortController();
|
||||
const executePromise = checker.execute(resolved, { signal: controller.signal });
|
||||
|
||||
controller.abort();
|
||||
|
||||
const result = await executePromise;
|
||||
|
||||
expect(result.matched).toBe(false);
|
||||
expect(result.failure?.phase).toBe("memory");
|
||||
expect(result.failure?.path).toBe("timeout");
|
||||
expect(result.observation).toBeNull();
|
||||
});
|
||||
|
||||
test("reader 在 abort 前 resolve 时返回正常结果", async () => {
|
||||
const data = makeMemData({ active: 4294967296, total: 8589934592 });
|
||||
const reader = () => Promise.resolve(data);
|
||||
const checker = new MemoryChecker(reader);
|
||||
|
||||
const target: RawTargetConfig = { id: "mem-test", memory: {}, type: "memory" };
|
||||
const resolved = checker.resolve(target, makeResolveContext());
|
||||
resolved.expect = { usagePercent: { lte: 85 } };
|
||||
|
||||
const ctx = { signal: new AbortController().signal };
|
||||
const result = await checker.execute(resolved, ctx);
|
||||
|
||||
expect(result.matched).toBe(true);
|
||||
expect(result.failure).toBeNull();
|
||||
expect(result.observation).toMatchObject({
|
||||
totalBytes: 8589934592,
|
||||
usagePercent: 50,
|
||||
});
|
||||
});
|
||||
|
||||
test("detail 格式", async () => {
|
||||
const data = makeMemData({ active: 4294967296, total: 8589934592 });
|
||||
const reader = () => Promise.resolve(data);
|
||||
|
||||
Reference in New Issue
Block a user