|
|
import { describe, expect, it } from "vitest";
|
|
|
import { METRIC_COUNTER } from "@/lib/constants/metrics";
|
|
|
import {
|
|
|
computeP95,
|
|
|
computeRate,
|
|
|
computeRates,
|
|
|
type MetricsCounters,
|
|
|
} from "@/modules/metrics/collector";
|
|
|
|
|
|
function emptyCounters(): MetricsCounters {
|
|
|
return {
|
|
|
[METRIC_COUNTER.POST_TOTAL]: 0,
|
|
|
[METRIC_COUNTER.POST_DONE]: 0,
|
|
|
[METRIC_COUNTER.CACHE_HIT_L1]: 0,
|
|
|
[METRIC_COUNTER.CACHE_HIT_L2]: 0,
|
|
|
[METRIC_COUNTER.RPA_TRIGGERED]: 0,
|
|
|
[METRIC_COUNTER.RPA_DONE]: 0,
|
|
|
[METRIC_COUNTER.DONE_TOTAL]: 0,
|
|
|
[METRIC_COUNTER.DONE_REALTIME]: 0,
|
|
|
};
|
|
|
}
|
|
|
|
|
|
describe("computeRates (GD-4)", () => {
|
|
|
it("100 次 mock:80 done / 100 post → api 80%", () => {
|
|
|
const counters: MetricsCounters = {
|
|
|
...emptyCounters(),
|
|
|
[METRIC_COUNTER.POST_TOTAL]: 100,
|
|
|
[METRIC_COUNTER.POST_DONE]: 80,
|
|
|
};
|
|
|
expect(computeRates(counters).api_success_rate).toBe(80);
|
|
|
});
|
|
|
|
|
|
it("RPA 85/100 → rpa_success_rate 85%", () => {
|
|
|
const counters: MetricsCounters = {
|
|
|
...emptyCounters(),
|
|
|
[METRIC_COUNTER.RPA_TRIGGERED]: 100,
|
|
|
[METRIC_COUNTER.RPA_DONE]: 85,
|
|
|
};
|
|
|
expect(computeRates(counters).rpa_success_rate).toBe(85);
|
|
|
});
|
|
|
|
|
|
it("realtime 90/100 done → realtime_rate 90%", () => {
|
|
|
const counters: MetricsCounters = {
|
|
|
...emptyCounters(),
|
|
|
[METRIC_COUNTER.DONE_TOTAL]: 100,
|
|
|
[METRIC_COUNTER.DONE_REALTIME]: 90,
|
|
|
};
|
|
|
expect(computeRates(counters).realtime_rate).toBe(90);
|
|
|
});
|
|
|
|
|
|
it("cache (L1+L2) 90/100 post → cache_hit_rate 90%", () => {
|
|
|
const counters: MetricsCounters = {
|
|
|
...emptyCounters(),
|
|
|
[METRIC_COUNTER.POST_TOTAL]: 100,
|
|
|
[METRIC_COUNTER.CACHE_HIT_L1]: 40,
|
|
|
[METRIC_COUNTER.CACHE_HIT_L2]: 50,
|
|
|
};
|
|
|
expect(computeRates(counters).cache_hit_rate).toBe(90);
|
|
|
});
|
|
|
|
|
|
it("分母为 0 → 返回 0", () => {
|
|
|
expect(computeRate(10, 0)).toBe(0);
|
|
|
expect(computeRates(emptyCounters()).api_success_rate).toBe(0);
|
|
|
});
|
|
|
});
|
|
|
|
|
|
describe("computeP95", () => {
|
|
|
it("100 样本 P95 取第 95 百分位", () => {
|
|
|
const samples = Array.from({ length: 100 }, (_, index) => index + 1);
|
|
|
expect(computeP95(samples)).toBe(95);
|
|
|
});
|
|
|
|
|
|
it("空样本 → 0", () => {
|
|
|
expect(computeP95([])).toBe(0);
|
|
|
});
|
|
|
});
|