mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 22:07:03 +01:00
Verified by the 100%-coverage tests from the previous commit, written before this seam existed. _cpu_table/_dedupe_ram/_ram_table/_gpu_table move to _usage_report_tables.py with the two constants they own. _md_escape and _fmt_h move to _usage_report_format.py: both the tables module and the render module need them, so a third module is what avoids a cycle. Import sites name the owning module; no re-export barrel. usage_report.py needed no edit - it imports _fmt_h and _render_report from the render module, and both names still resolve there. Evidence the move was verbatim: an AST comparison of all 10 functions against HEAD reports 10 identical, 0 mismatches. That matters because I retyped rather than cut-and-pasted, and did briefly introduce a literal × where the original had × - ruff's RUF001 caught it. Coverage stays 100% line+branch on all three (15/55/54 stmts, 4/10/14 branches, 0 missed). Test count 43 before and after, summed across the five files it now lives in - the check that matters for a test split, since a file outside the runner's glob is silently never collected. Directory total 143 passed, unchanged. Ran the real program: a full report from today's atop + pmon logs, every section rendering through the new boundaries including the RAM sibling dedupe and its (+20 more) truncation. Over-cap 41 -> 39. No suppressions; a shared test-helper module was tried and abandoned because name-tests-test would have needed an exclusion. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
57 lines
1.9 KiB
Python
57 lines
1.9 KiB
Python
"""Tests for usage_report's GPU Markdown table."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import _usage_report_tables as tables
|
|
from _usage_report_types import GpuAgg
|
|
|
|
|
|
def _cells(row: str) -> list[str]:
|
|
"""Split a Markdown table row into stripped cell values."""
|
|
return [c.strip() for c in row.strip().strip("|").split("|")]
|
|
|
|
|
|
def test_gpu_table_sorts_by_gpu_seconds_and_honours_top() -> None:
|
|
"""Rows are ordered by SM-seconds descending and truncated to *top*."""
|
|
aggs = {
|
|
"low": GpuAgg("low", sm_pct_sum=10.0, samples=1),
|
|
"high": GpuAgg("high", sm_pct_sum=900.0, samples=1),
|
|
"mid": GpuAgg("mid", sm_pct_sum=100.0, samples=1),
|
|
}
|
|
|
|
rows = tables._gpu_table(aggs, total_samples=10, top=2)
|
|
|
|
assert len(rows) == 4
|
|
assert _cells(rows[2])[1] == "high"
|
|
assert _cells(rows[3])[1] == "mid"
|
|
|
|
|
|
def test_gpu_table_reports_sample_presence_percentage() -> None:
|
|
"""The Samples column shows the share of total samples the process was in."""
|
|
aggs = {"g": GpuAgg("g", sm_pct_sum=50.0, samples=5)}
|
|
|
|
cells = _cells(tables._gpu_table(aggs, total_samples=20, top=1)[2])
|
|
|
|
assert cells[6] == "5 (25%)"
|
|
|
|
|
|
def test_gpu_table_zero_total_samples_yields_zero_presence() -> None:
|
|
"""A zero sample total cannot be divided by, so presence renders as 0%."""
|
|
aggs = {"g": GpuAgg("g", sm_pct_sum=50.0, samples=5)}
|
|
|
|
cells = _cells(tables._gpu_table(aggs, total_samples=0, top=1)[2])
|
|
|
|
assert cells[6] == "5 (0%)"
|
|
|
|
|
|
def test_gpu_table_escapes_program_names() -> None:
|
|
"""A pipe in a GPU process name cannot break out of its cell."""
|
|
aggs = {"a|b": GpuAgg("a|b", sm_pct_sum=1.0, samples=1)}
|
|
|
|
assert r"a\|b" in tables._gpu_table(aggs, total_samples=1, top=1)[2]
|
|
|
|
|
|
def test_gpu_table_empty_input_is_header_only() -> None:
|
|
"""No GPU aggregates means header and separator only."""
|
|
assert len(tables._gpu_table({}, total_samples=0, top=5)) == 2
|