feat: publish CodexPi contest snapshot
Some checks are pending
Qualité / tests (push) Waiting to run
Some checks are pending
Qualité / tests (push) Waiting to run
This commit is contained in:
67
tests/test_pi_doctor_collector.py
Normal file
67
tests/test_pi_doctor_collector.py
Normal file
@@ -0,0 +1,67 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
SCRIPT = Path(__file__).parents[1] / "scripts" / "pi_doctor_collector.py"
|
||||
SPEC = importlib.util.spec_from_file_location("pi_doctor_collector", SCRIPT)
|
||||
collector = importlib.util.module_from_spec(SPEC)
|
||||
assert SPEC and SPEC.loader
|
||||
SPEC.loader.exec_module(collector)
|
||||
|
||||
|
||||
def snapshot(**overrides):
|
||||
value = {
|
||||
"system": {"timestamp": "2026-10-28T12:00:00+00:00", "cpu_percent": 10, "memory_percent": 20, "temperature_c": 50},
|
||||
"storage": {"root_percent": 30, "mounts": []},
|
||||
"docker": {"available": True, "containers": []},
|
||||
"services": {"codexpi": {"configured": True, "available": True}, "jellyfin": {"configured": False}},
|
||||
}
|
||||
for section, values in overrides.items():
|
||||
value[section].update(values)
|
||||
return value
|
||||
|
||||
|
||||
def test_detects_thresholds_mounts_and_services_without_repairing():
|
||||
value = snapshot(
|
||||
system={"cpu_percent": 99, "temperature_c": 80},
|
||||
storage={"root_percent": 96, "mounts": [{"path": "/mnt/nas", "state": "unavailable", "error": "timeout"}]},
|
||||
services={"codexpi": {"configured": True, "available": False}, "jellyfin": {"configured": False}},
|
||||
)
|
||||
|
||||
incidents = collector.detect_incidents(value)
|
||||
|
||||
assert {item["fingerprint"] for item in incidents} == {
|
||||
"cpu-high", "root-disk-high", "temperature-high", "mount:/mnt/nas", "service:codexpi",
|
||||
}
|
||||
assert next(item for item in incidents if item["fingerprint"] == "cpu-high")["severity"] == "critical"
|
||||
assert not hasattr(collector, "repair")
|
||||
|
||||
|
||||
def test_spool_survives_failure_then_flushes_in_order(tmp_path, monkeypatch):
|
||||
first = collector.enqueue(tmp_path, snapshot())
|
||||
second_value = snapshot(system={"timestamp": "2026-10-28T12:01:00+00:00"})
|
||||
second = collector.enqueue(tmp_path, second_value)
|
||||
delivered = []
|
||||
monkeypatch.setattr(collector, "deliver", lambda url, token, value: delivered.append(value["system"]["timestamp"]))
|
||||
|
||||
assert first.exists() and second.exists()
|
||||
assert collector.flush(tmp_path, "https://codexpi.test", "token") == 2
|
||||
assert delivered == ["2026-10-28T12:00:00+00:00", "2026-10-28T12:01:00+00:00"]
|
||||
assert list(tmp_path.glob("*.json")) == []
|
||||
|
||||
|
||||
def test_delivery_posts_snapshot_then_real_detected_incidents(monkeypatch):
|
||||
requests = []
|
||||
monkeypatch.setattr(collector, "_post", lambda url, token, payload: requests.append((url, token, payload)))
|
||||
value = snapshot(system={"memory_percent": 98})
|
||||
|
||||
collector.deliver("https://codexpi.test/", "secret-token", value)
|
||||
|
||||
assert requests[0][0].endswith("/api/pi-doctor/snapshots/import")
|
||||
assert requests[0][2] == {"snapshot": value}
|
||||
assert requests[1][0].endswith("/api/pi-doctor/incidents/import")
|
||||
assert requests[1][2]["incidents"][0]["fingerprint"] == "memory-high"
|
||||
assert {request[1] for request in requests} == {"secret-token"}
|
||||
Reference in New Issue
Block a user