2e6a981120
release / release (push) Successful in 13s
M4 — health report (the 0.0.4 CHANGELOG entry, folded into this release):
- core/health.py: scan journalctl (Xid/panic/OOM/MCE/AER/thermal), SMART,
NVIDIA driver mismatch, journald persistence, live temps -> findings
- CLI `rigdoctor report` (text/JSON); GUI Health tab; scanner tests
M9 — installer (first cut):
- core/{catalog,sysenv,installer}.py; `rigdoctor install [--check] [-y]`
- GUI Setup tab: detect distro/GPU, show optional components, one-click
install of missing apt packages via pkexec/sudo
M13 — update check (check half):
- core/updates.py; sidebar shows up-to-date / "Update to v…" / unavailable
Plus tests, version bump to 0.0.5, CHANGELOG, and doc status updates.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
47 lines
1.9 KiB
Python
47 lines
1.9 KiB
Python
"""Tests for the M4 health report's log scanner (synthetic input)."""
|
||
|
||
import unittest
|
||
|
||
from rigdoctor.core.health import CRITICAL, WARNING, run_health_checks, scan_journal_text
|
||
|
||
|
||
class HealthScanTests(unittest.TestCase):
|
||
def test_xid_79_is_critical(self):
|
||
text = "NVRM: Xid (PCI:0000:01:00): 79, pid=1234, GPU has fallen off the bus."
|
||
findings = scan_journal_text(text)
|
||
gpu = [f for f in findings if f.category == "GPU"]
|
||
self.assertEqual(len(gpu), 1)
|
||
self.assertIn("79", gpu[0].title)
|
||
self.assertEqual(gpu[0].severity, CRITICAL)
|
||
|
||
def test_xid_count_aggregates(self):
|
||
text = "\n".join(["NVRM: Xid (PCI:0000:01:00): 79, foo"] * 3)
|
||
gpu = [f for f in scan_journal_text(text) if f.category == "GPU"][0]
|
||
self.assertIn("×3", gpu.title)
|
||
|
||
def test_oom_and_panic_detected(self):
|
||
text = "Out of memory: Killed process 999 (game)\nKernel panic - not syncing: x"
|
||
cats = {f.category for f in scan_journal_text(text)}
|
||
self.assertIn("Memory", cats)
|
||
self.assertIn("Kernel", cats)
|
||
|
||
def test_mce_critical(self):
|
||
findings = scan_journal_text("mce: [Hardware Error]: Machine check events logged")
|
||
self.assertTrue(any(f.severity == CRITICAL and f.category == "Hardware" for f in findings))
|
||
|
||
def test_clean_text_yields_no_findings(self):
|
||
self.assertEqual(scan_journal_text("usb 1-1: new high-speed USB device\nbluetooth: ok"), [])
|
||
|
||
def test_run_health_checks_returns_findings(self):
|
||
# Runs against the real system; just assert it returns a sorted list of Findings.
|
||
findings = run_health_checks()
|
||
self.assertIsInstance(findings, list)
|
||
severities = [f.severity for f in findings]
|
||
order = {"critical": 0, "warning": 1, "info": 2, "ok": 3}
|
||
ranks = [order.get(s, 9) for s in severities]
|
||
self.assertEqual(ranks, sorted(ranks))
|
||
|
||
|
||
if __name__ == "__main__":
|
||
unittest.main()
|