test(host_agent): pure-function tests for metric expansion
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,98 @@
|
|||||||
|
"""Pure-function tests for host_agent metric expansion."""
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
|
from plugins.host_agent.routes import _expand_sample_to_metrics
|
||||||
|
|
||||||
|
|
||||||
|
NOW = datetime(2026, 4, 14, 12, 0, 0, tzinfo=timezone.utc)
|
||||||
|
|
||||||
|
|
||||||
|
def _sample() -> dict:
|
||||||
|
return {
|
||||||
|
"ts": NOW.isoformat(),
|
||||||
|
"cpu_pct": 12.5,
|
||||||
|
"mem": {
|
||||||
|
"total_bytes": 16_000_000_000,
|
||||||
|
"used_bytes": 8_000_000_000,
|
||||||
|
"available_bytes": 8_000_000_000,
|
||||||
|
"swap_used_bytes": 0,
|
||||||
|
},
|
||||||
|
"load": {"1m": 0.1, "5m": 0.2, "15m": 0.3},
|
||||||
|
"uptime_secs": 1234,
|
||||||
|
"storage": [
|
||||||
|
{"mount": "/", "total_bytes": 1000, "used_bytes": 400},
|
||||||
|
{"mount": "/mnt/data", "total_bytes": 2000, "used_bytes": 1800},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _by_metric(rows, name):
|
||||||
|
return [r for r in rows if r.metric_name == name]
|
||||||
|
|
||||||
|
|
||||||
|
def test_expand_emits_cpu_mem_load_uptime():
|
||||||
|
rows = _expand_sample_to_metrics(_sample(), "testhost", NOW)
|
||||||
|
names = {r.metric_name for r in rows}
|
||||||
|
assert "cpu_pct" in names
|
||||||
|
assert "mem_used_pct" in names
|
||||||
|
assert "mem_available_bytes" in names
|
||||||
|
assert "swap_used_bytes" in names
|
||||||
|
assert "load_1m" in names and "load_5m" in names and "load_15m" in names
|
||||||
|
assert "uptime_secs" in names
|
||||||
|
|
||||||
|
|
||||||
|
def test_expand_source_module_and_recorded_at():
|
||||||
|
rows = _expand_sample_to_metrics(_sample(), "testhost", NOW)
|
||||||
|
assert rows, "expected non-empty rows"
|
||||||
|
for r in rows:
|
||||||
|
assert r.source_module == "host_agent"
|
||||||
|
assert r.recorded_at == NOW
|
||||||
|
|
||||||
|
|
||||||
|
def test_expand_cpu_value_and_resource():
|
||||||
|
cpu = _by_metric(_expand_sample_to_metrics(_sample(), "testhost", NOW), "cpu_pct")
|
||||||
|
assert len(cpu) == 1
|
||||||
|
assert cpu[0].value == 12.5
|
||||||
|
assert cpu[0].resource_name == "testhost"
|
||||||
|
|
||||||
|
|
||||||
|
def test_expand_mem_used_pct_math():
|
||||||
|
# used = total - available = 50%
|
||||||
|
used = _by_metric(_expand_sample_to_metrics(_sample(), "testhost", NOW), "mem_used_pct")
|
||||||
|
assert len(used) == 1
|
||||||
|
assert abs(used[0].value - 50.0) < 0.01
|
||||||
|
|
||||||
|
|
||||||
|
def test_expand_per_mount_disk_metrics():
|
||||||
|
rows = _expand_sample_to_metrics(_sample(), "testhost", NOW)
|
||||||
|
per_mount = _by_metric(rows, "disk_used_pct")
|
||||||
|
assert {r.resource_name for r in per_mount} == {"testhost:/", "testhost:/mnt/data"}
|
||||||
|
# Values: / is 40%, /mnt/data is 90%
|
||||||
|
by_res = {r.resource_name: r.value for r in per_mount}
|
||||||
|
assert abs(by_res["testhost:/"] - 40.0) < 0.01
|
||||||
|
assert abs(by_res["testhost:/mnt/data"] - 90.0) < 0.01
|
||||||
|
|
||||||
|
|
||||||
|
def test_expand_disk_worst_is_max():
|
||||||
|
worst = _by_metric(_expand_sample_to_metrics(_sample(), "testhost", NOW), "disk_used_pct_worst")
|
||||||
|
assert len(worst) == 1
|
||||||
|
assert worst[0].resource_name == "testhost"
|
||||||
|
assert abs(worst[0].value - 90.0) < 0.01
|
||||||
|
|
||||||
|
|
||||||
|
def test_expand_skips_missing_cpu_and_load():
|
||||||
|
sample = {"mem": {"total_bytes": 100, "available_bytes": 50}}
|
||||||
|
rows = _expand_sample_to_metrics(sample, "h", NOW)
|
||||||
|
names = {r.metric_name for r in rows}
|
||||||
|
assert "cpu_pct" not in names
|
||||||
|
assert "load_1m" not in names
|
||||||
|
assert "uptime_secs" not in names
|
||||||
|
assert "mem_used_pct" in names
|
||||||
|
|
||||||
|
|
||||||
|
def test_expand_empty_storage_emits_no_disk_worst():
|
||||||
|
sample = {"cpu_pct": 1.0, "storage": []}
|
||||||
|
rows = _expand_sample_to_metrics(sample, "h", NOW)
|
||||||
|
names = {r.metric_name for r in rows}
|
||||||
|
assert "disk_used_pct_worst" not in names
|
||||||
|
assert "cpu_pct" in names
|
||||||
Reference in New Issue
Block a user