Files
aio-01d4-stu/Last3Mon/77/tlog/tests/test_metrics.py
T

71 lines
3.5 KiB
Python

"""R2 · R3 · R4 · R6 · R7: the definitions of AGENTS.md 3, and the same numbers as my-log-report on the two weeks."""
from tlog import load, metrics
def period(rows, a, b):
return [r for r in rows if load.keep(r, a, b)]
def test_percentile_is_nearest_rank():
values = list(range(1, 11)) # 1..10
assert metrics.pct(values, 0.95) == 10 and metrics.pct(values, 0.5) == 5
assert metrics.pct([], 0.95) == 0
def test_rate_rounds_like_javascript_and_zero_is_zero():
assert metrics.rate(21, 666) == 0.0315 and metrics.rate(0, 0) == 0
assert metrics.js_round(0.00005, 4) == 0.0001 # half up, like Math.round
def test_two_weeks_same_numbers_as_my_log_report(two_weeks):
r = metrics.report(period(two_weeks, "2026-10-19", "2026-10-30"))
assert (r["total"], r["errors"], r["error_rate"], r["p50_ms"], r["p95_ms"]) == (666, 21, 0.0315, 1205, 2537)
assert r["by_route"] == {"자동 답변": 591, "담당자 연결": 34, "잠시 후": 20, "오류": 21}
assert r["by_day"]["2026-10-26"] == {"total": 70, "errors": 16, "error_rate": 0.2286} and "2026-10-24" not in r["by_day"]
assert r["by_release"]["1.2.0"] == {"answers": 8, "repeats": 5, "repeat_rate": 0.625}
def test_weeks_and_one_day(two_weeks):
w2 = metrics.report(period(two_weeks, "2026-10-26", "2026-10-30"))
assert (w2["total"], w2["errors"], w2["error_rate"], w2["p95_ms"]) == (357, 21, 0.0588, 2598)
monday = metrics.report(period(two_weeks, "2026-10-26", "2026-10-26"))
assert (monday["total"], monday["errors"]) == (70, 16)
assert monday["steps"]["faq_ms"]["p95"] == 1000
def test_problems_and_anomalies(two_weeks):
r = metrics.report(period(two_weeks, "2026-10-19", "2026-10-30"))
assert r["failures"][0] == {"node": "Search FAQ", "message": "timeout of 1000ms exceeded", "count": 16}
assert r["failures"][1]["node"] == "Answer" and r["failures"][1]["count"] == 5
assert r["unanswered_topics"] == [{"topic": "와이파이", "count": 34}]
assert [a["hour"] for a in r["anomalies"]] == ["2026-10-26T09", "2026-10-29T15"]
assert r["repeat_topics"][0] == {"topic": "프린터", "answers": 81, "repeats": 8, "repeat_rate": 0.0988}
assert metrics.report(period(two_weeks, "2026-10-19", "2026-10-23"))["anomalies"] == []
def test_steps_and_cost(two_weeks):
r = metrics.report(period(two_weeks, "2026-10-19", "2026-10-30"))
assert r["steps"]["faq_ms"] == {"runs": 646, "p50": 27, "p95": 39}
assert r["steps"]["answer_ms"] == {"runs": 596, "p50": 1179, "p95": 2509}
assert (r["cost_usd"], r["cost_per_run"], r["llm_calls"]) == (0.07836, 0.000118, 596)
def test_slo(two_weeks):
w2 = metrics.report(period(two_weeks, "2026-10-26", "2026-10-30"))
assert w2["unanswered_rate"] == 0.0476 and w2["slo"]["breaches"] == ["error_rate", "unanswered_rate"]
w1 = metrics.report(period(two_weeks, "2026-10-19", "2026-10-23"), {"unanswered_rate": 0.06})
assert w1["slo"]["ok"] is True
def test_empty_period_is_zero_not_null():
r = metrics.report([])
assert (r["total"], r["error_rate"], r["p95_ms"], r["cost_per_run"], r["anomalies"]) == (0, 0, 0, 0, [])
def test_weekly_markdown(two_weeks):
now = metrics.report(period(two_weeks, "2026-10-26", "2026-10-30"))
prev = metrics.report(period(two_weeks, "2026-10-19", "2026-10-23"))
text = metrics.weekly_markdown(now, prev, "2026-10-26", "2026-10-30")
assert "| 요청 | 309 | 357 |" in text and "| 오류율 | 0% | 5.88% |" in text
assert "2026-10-26 09시 · 16/16" in text and "FAQ에 '와이파이' 항목 추가" in text