From 993950b7733ba9300915955ec6e51e1f21dad806 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Mon, 19 Oct 2026 21:28:54 +0200 Subject: Results tab with build logs; count only real packages sbb-remote 0.4.0: results lists slackrepo's last attempt per package (newest first, with built version and whether a log dir exists), and build-log returns the end of a package's build.log (512 KB) plus its resource.log, accepting only category/pkg paths. Result counts skip the legacy buildresults rows keyed by package file name: the 213 "bad" on the Dashboard matched no package. GUI: a Results tab (chips per result, table sorted by attempt time, detail pane, log viewer window that keeps the failure at the end), opened from the ribbon or by clicking a result in the Dashboard bar or legend, filtered to it. Co-Authored-By: Claude Opus 5.5 --- tests/test_remote.py | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'tests/test_remote.py') diff --git a/tests/test_remote.py b/tests/test_remote.py index 2f273fb..85e642b 100644 --- a/tests/test_remote.py +++ b/tests/test_remote.py @@ -446,14 +446,56 @@ class StatsTest(Base): create table buildresults (itemid text primary key, time text, result text); create table revisions (itemid text, dep text, deplist text, version text, built text, rev text, os text, hintcksum text, primary key (itemid, dep)); - insert into buildresults values ('a', '1', 'ok'), ('b', '1', 'ok'), ('c', '1', 'failed'); + insert into buildresults values ('cat/a', '1', 'ok'), ('cat/b', '1', 'ok'), + ('cat/c', '1', 'failed'), ('ghost', '1', 'bad'), ('c-1.0-x86_64-1_x', '1', 'bad'); insert into revisions values ('cat/a', '/', '/', '1', '1', 'r', 'o', '/'), ('cat/a', 'dep', '/', '1', '1', 'r', 'o', '/'); """) db.close() + # legacy keys without a category/ match no package and are not counted self.assertEqual(sbb.cmd_stats(self.cfg)["slackrepo"], {"results": {"ok": 2, "failed": 1}, "built": 1}) +class ResultsTest(Base): + def setUp(self): + super().setUp() + logdir = os.path.join(self.tmp, "logs") + self.cfg["slackrepo_logdir"] = logdir + db = sqlite3.connect(self.cfg["slackrepo_db"]) + db.executescript(""" + create table buildresults (itemid text primary key, time text, result text); + create table revisions (itemid text, dep text, deplist text, version text, + built text, rev text, os text, hintcksum text, primary key (itemid, dep)); + insert into buildresults values ('cat/a', '100', 'ok'), ('cat/c', '300', 'failed'), + ('ghost', '200', 'bad'); + insert into revisions values ('cat/a', '/', '/', '1.0', '100', 'r', 'o', '/'); + """) + db.close() + os.makedirs(os.path.join(logdir, "cat", "c")) + with open(os.path.join(logdir, "cat", "c", "build.log"), "w") as f: + f.write("x" * 100 + "\nERROR: make failed\n") + with open(os.path.join(logdir, "cat", "c", "resource.log"), "w") as f: + f.write("peak memory 3308M\n") + + def test_rows(self): + self.assertEqual(sbb.cmd_results(self.cfg), {"rows": [ + ["cat/c", "failed", 300, None, True], + ["cat/a", "ok", 100, "1.0", False]]}) + + def test_build_log_tail(self): + with mock.patch.object(sbb, "LOG_TAIL", 20): + log = sbb.cmd_build_log(self.cfg, "cat/c") + self.assertEqual(log["build"], "\nERROR: make failed\n"[-20:]) + self.assertTrue(log["truncated"]) + self.assertEqual(log["resource"], "peak memory 3308M\n") + self.assertIsInstance(log["mtime"], int) + + def test_build_log_rejects(self): + for bad in ("../etc/passwd", "cat/../../x", "cat", "cat/a", "/etc/x"): + with self.subTest(bad=bad), self.assertRaises(sbb.Error): + sbb.cmd_build_log(self.cfg, bad) + + if __name__ == "__main__": unittest.main() -- cgit v1.2.3