mirror of
https://github.com/rajnandan1/kener.git
synced 2026-08-07 07:14:56 +00:00
test: cover tool.ts uptime math (ParseUptime, formulas, UptimeCalculator)
This commit is contained in:
@@ -9,7 +9,13 @@ import {
|
||||
GetMinuteStartTimestampUTC,
|
||||
GetNowTimestampUTC,
|
||||
GetNowTimestampUTCInMs,
|
||||
IsValidUptimeFormula,
|
||||
ParsePercentage,
|
||||
ParseUptime,
|
||||
UnparsePercentage,
|
||||
UptimeCalculator,
|
||||
} from "./tool";
|
||||
import type { TimestampStatusCount } from "./types/db";
|
||||
|
||||
// All fixed timestamps are at 12:00 UTC so that local-date-based functions
|
||||
// (GetDayStartTimestampUTC mixes local date parts with Date.UTC) produce the
|
||||
@@ -79,3 +85,122 @@ describe("timestamp helpers", () => {
|
||||
expect(BeginningOfMinute({ date, timeZone: "UTC" })).toBe(NOON_UTC);
|
||||
});
|
||||
});
|
||||
|
||||
describe("ParseUptime", () => {
|
||||
it("returns '-' when there is no data", () => {
|
||||
expect(ParseUptime(0, 0)).toBe("-");
|
||||
});
|
||||
|
||||
it("returns '0' when nothing is up", () => {
|
||||
expect(ParseUptime(0, 10)).toBe("0");
|
||||
});
|
||||
|
||||
it("returns whole numbers without decimals", () => {
|
||||
expect(ParseUptime(10, 10)).toBe("100");
|
||||
expect(ParseUptime(5, 10)).toBe("50");
|
||||
});
|
||||
|
||||
it("keeps 4 decimal places and strips trailing zeros", () => {
|
||||
expect(ParseUptime(1, 3)).toBe("33.3333");
|
||||
expect(ParseUptime(2, 3)).toBe("66.6667");
|
||||
expect(ParseUptime(1, 8)).toBe("12.5");
|
||||
expect(ParseUptime(999, 1000)).toBe("99.9");
|
||||
});
|
||||
});
|
||||
|
||||
describe("ParsePercentage / UnparsePercentage", () => {
|
||||
it("formats numbers as percentage strings", () => {
|
||||
expect(ParsePercentage(NaN)).toBe("-");
|
||||
expect(ParsePercentage(0)).toBe("0");
|
||||
expect(ParsePercentage(100)).toBe("100");
|
||||
expect(ParsePercentage(99.9)).toBe("99.9000");
|
||||
});
|
||||
|
||||
it("parses percentage strings back to numbers", () => {
|
||||
expect(UnparsePercentage("99.9")).toBe(99.9);
|
||||
expect(UnparsePercentage("0")).toBe(0);
|
||||
expect(Number.isNaN(UnparsePercentage("-"))).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("IsValidUptimeFormula", () => {
|
||||
it("accepts single variables and operator chains", () => {
|
||||
expect(IsValidUptimeFormula("up")).toBe(true);
|
||||
expect(IsValidUptimeFormula("up + down")).toBe(true);
|
||||
expect(IsValidUptimeFormula("up+down+degraded+maintenance")).toBe(true);
|
||||
expect(IsValidUptimeFormula("up - down * maintenance / degraded")).toBe(true);
|
||||
});
|
||||
|
||||
it("is case-insensitive", () => {
|
||||
expect(IsValidUptimeFormula("UP + Maintenance")).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects malformed formulas", () => {
|
||||
expect(IsValidUptimeFormula("")).toBe(false);
|
||||
expect(IsValidUptimeFormula(" ")).toBe(false);
|
||||
expect(IsValidUptimeFormula("up +")).toBe(false);
|
||||
expect(IsValidUptimeFormula("+ up")).toBe(false);
|
||||
expect(IsValidUptimeFormula("banana + up")).toBe(false);
|
||||
expect(IsValidUptimeFormula("up ** down")).toBe(false);
|
||||
expect(IsValidUptimeFormula("up down")).toBe(false);
|
||||
expect(IsValidUptimeFormula("42")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("UptimeCalculator", () => {
|
||||
const day = (overrides: Partial<TimestampStatusCount>): TimestampStatusCount => ({
|
||||
ts: 0,
|
||||
countOfUp: 0,
|
||||
countOfDown: 0,
|
||||
countOfDegraded: 0,
|
||||
countOfMaintenance: 0,
|
||||
avgLatency: 0,
|
||||
maxLatency: 0,
|
||||
minLatency: 0,
|
||||
...overrides,
|
||||
});
|
||||
|
||||
it("computes uptime and latency aggregates with the default formulas", () => {
|
||||
// Defaults (global-constants): numerator "up + maintenance + degraded",
|
||||
// denominator "up + down + degraded + maintenance"
|
||||
const data = [
|
||||
day({ countOfUp: 30, countOfDown: 10, avgLatency: 100, maxLatency: 150, minLatency: 50 }),
|
||||
day({ countOfUp: 50, countOfDegraded: 10, avgLatency: 200, maxLatency: 300, minLatency: 80 }),
|
||||
];
|
||||
expect(UptimeCalculator(data)).toEqual({
|
||||
uptime: "90", // (80 up + 0 maintenance + 10 degraded) / 100 total
|
||||
avgLatency: "150ms", // (100 + 200) / 2
|
||||
maxLatency: "300ms",
|
||||
minLatency: "50ms",
|
||||
});
|
||||
});
|
||||
|
||||
it("supports a custom numerator formula", () => {
|
||||
const data = [day({ countOfUp: 30, countOfDown: 10 }), day({ countOfUp: 50, countOfDegraded: 10 })];
|
||||
expect(UptimeCalculator(data, "up").uptime).toBe("80");
|
||||
});
|
||||
|
||||
it("falls back to the default formula when the custom one is invalid", () => {
|
||||
const data = [day({ countOfUp: 30, countOfDown: 10 }), day({ countOfUp: 50, countOfDegraded: 10 })];
|
||||
expect(UptimeCalculator(data, "banana + up").uptime).toBe("90");
|
||||
});
|
||||
|
||||
it("returns '-' uptime and empty latencies for no data", () => {
|
||||
expect(UptimeCalculator([])).toEqual({
|
||||
uptime: "-",
|
||||
avgLatency: "",
|
||||
maxLatency: "",
|
||||
minLatency: "",
|
||||
});
|
||||
});
|
||||
|
||||
it("only counts entries with a positive avgLatency toward the average", () => {
|
||||
const data = [
|
||||
day({ countOfUp: 10, avgLatency: 0 }),
|
||||
day({ countOfUp: 10, avgLatency: 100, maxLatency: 100, minLatency: 100 }),
|
||||
];
|
||||
const result = UptimeCalculator(data);
|
||||
expect(result.uptime).toBe("100");
|
||||
expect(result.avgLatency).toBe("100ms"); // (0 + 100) / 1 entry with latency > 0
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user