diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-19 21:20:00 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-19 21:20:00 +0200 |
| commit | 3865fd7d10d76cd265800fd8d5915a5792be4619 (patch) | |
| tree | 28c4c160ad0668699d4a5d43a01bcc198369e6a0 /tests | |
| parent | 57df6adb767e1691599f894e1e3925870b1b3b3f (diff) | |
| download | sb-builder-3865fd7d10d76cd265800fd8d5915a5792be4619.tar.gz sb-builder-3865fd7d10d76cd265800fd8d5915a5792be4619.zip | |
Dashboard: VM meters and sparklines, slackpkg tile
sbb-remote 0.3.0 adds CPU busy % (two /proc/stat samples), RAM total
and available, disk / total and free, and the last slackpkg update
(LASTUPDATE) and package change (/var/log/packages), replacing
disk_free. The Dashboard shows a VM card with meters for CPU, RAM and
disk / (accent, warning from 80%, critical from 90%, value always
printed) and CPU/RAM sparklines from this session's polls, and a
slackpkg tile in place of VM load.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_gui.py | 35 | ||||
| -rw-r--r-- | tests/test_remote.py | 27 |
2 files changed, 59 insertions, 3 deletions
diff --git a/tests/test_gui.py b/tests/test_gui.py index b99aebf..a597c01 100644 --- a/tests/test_gui.py +++ b/tests/test_gui.py @@ -30,6 +30,7 @@ ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") sys.path.insert(0, ROOT) from PyQt6.QtCore import QCoreApplication, QEvent, QObject, QProcess, pyqtSignal # noqa: E402 +from PyQt6.QtGui import QColor # noqa: E402 from PyQt6.QtWidgets import QApplication # noqa: E402 from sb_builder import VERSION, config # noqa: E402 @@ -120,8 +121,10 @@ class FakeNotifier(QObject): self.sent.append((title, body, jid)) -STATS = {"load": [0.5, 0.4, 0.3], "uptime": 3600.0, - "disk_free": {"repo": 10 * 2**30, "state": None}, +STATS = {"load": [0.5, 0.4, 0.3], "uptime": 3600.0, "cpu": 85.0, + "mem": {"total": 16 * 2**30, "available": 12 * 2**30}, + "disk": {"total": 100 * 2**30, "free": 10 * 2**30}, + "slackpkg": {"update": 1791760212, "upgrade": None}, "packages": {"total": 10, "personal": 2, "pentesting": 1, "shadowed": 1}, "sync": {"personal": None, "pentesting": 1792351223}, "slackrepo": None} JOB = {"id": "20260101-000000-sbshadow", "kind": "sbshadow", "args": ["--no"], "argv": [], @@ -249,6 +252,25 @@ class FilterTest(unittest.TestCase): self.assertEqual(self.names("cat:misc", statuses={"ok"}), []) +class MeterTest(unittest.TestCase): + def test_color_thresholds(self): + from sb_builder.dashboard import STATUS, meter_color + accent = QColor("#123456") + self.assertEqual(meter_color(79.9, accent), accent) + self.assertEqual(meter_color(80, accent), QColor(STATUS["aborted"])) + self.assertEqual(meter_color(95, accent), QColor(STATUS["failed"])) + + def test_sparkline_cap_and_nulls(self): + from sb_builder.dashboard import Meter + m = Meter("CPU", spark=True) + for i in range(100): + m.set(float(i), "") + self.assertEqual(len(m.spark.points), m.spark.points.maxlen) + self.assertEqual(m.spark.points[-1], 99.0) + m.set(None, "") + self.assertEqual(m.value.text(), "n/a") + + class SmokeTest(unittest.TestCase): def window(self, **answers): remote = FakeRemote({"version": ({"version": VERSION, "overlays": ["personal"]}, None), @@ -269,7 +291,14 @@ class SmokeTest(unittest.TestCase): self.assertEqual(tiles["Packages"].value.text(), "10") self.assertEqual(tiles["Packages"].detail.text(), "2\u00a0personal · 1\u00a0pentesting · 1\u00a0shadowed") self.assertEqual(tiles["Built"].value.text(), "n/a") - self.assertIn("10.0 GiB free", tiles["VM load"].detail.text()) + d = w.dashboard + self.assertEqual((d.cpu.value.text(), d.ram.value.text(), d.disk.value.text()), + ("85%", "25%", "90%")) + self.assertIn("load 0.50", d.cpu.detail.text()) + self.assertEqual(d.disk.detail.text(), "10.0 GiB free of 100.0 GiB") + self.assertEqual(tiles["slackpkg"].value.text(), "n/a") + self.assertIn("lists updated", tiles["slackpkg"].detail.text()) + self.assertEqual(len(d.cpu.spark.points), 1) self.assertEqual(w.dashboard.legend.text(), "n/a") jobs = w.open_jobs() self.assertIs(w.open_jobs(), jobs) diff --git a/tests/test_remote.py b/tests/test_remote.py index c2b9857..2f273fb 100644 --- a/tests/test_remote.py +++ b/tests/test_remote.py @@ -391,11 +391,38 @@ class StatsTest(Base): def test_missing_sources_are_null(self): s = sbb.cmd_stats(self.cfg) self.assertIsNotNone(s["load"]) + self.assertEqual(set(s["disk"]), {"total", "free"}) + self.assertIn("slackpkg", s) self.assertIsNone(s["packages"]) self.assertIsNone(s["slackrepo"]) self.assertEqual(s["sync"], {"personal": None, "pentesting": None}) json.dumps(s) + def test_vm_figures(self): + meminfo = os.path.join(self.tmp, "meminfo") + with open(meminfo, "w") as f: + f.write("MemTotal: 16000 kB\nMemFree: 9000 kB\nMemAvailable: 12000 kB\n") + self.assertEqual(sbb._meminfo(meminfo), {"total": 16000 * 1024, "available": 12000 * 1024}) + with mock.patch.object(sbb, "_cpu_times", side_effect=[(100, 1000), (150, 1100)]), \ + mock.patch.object(sbb.time, "sleep"): + self.assertEqual(sbb._cpu(), 50.0) + stat = os.path.join(self.tmp, "stat") + with open(stat, "w") as f: + f.write("cpu 10 0 10 70 10 0 0 0 0 0\ncpu0 1 2 3 4\n") + self.assertEqual(sbb._cpu_times(stat), (20, 100)) # idle + iowait count as not busy + + def test_slackpkg_times(self): + last = os.path.join(self.tmp, "LASTUPDATE") + with open(last, "w") as f: + f.write("1791760212\n") + pkgs = os.path.join(self.tmp, "packages") + os.mkdir(pkgs) + for name, t in (("a-1-x86_64-1", 1000), ("b-2-x86_64-1", 3000)): + open(os.path.join(pkgs, name), "w").close() + os.utime(os.path.join(pkgs, name), (t, t)) + self.assertEqual(sbb._slackpkg(last, pkgs), {"update": 1791760212, "upgrade": 3000}) + self.assertEqual(sbb._slackpkg("/nonexistent", "/nonexistent"), {"update": None, "upgrade": None}) + def test_counts(self): r = self.cfg["repo_dir"] for p in ("cat/foo", "cat/bar", "personal/foo", "personal/baz", "pentesting/nmap"): |
