diff --git a/scripts/check_buildbot_system.py b/scripts/check_buildbot_system.py index d25acadf3..f81f47c2f 100644 --- a/scripts/check_buildbot_system.py +++ b/scripts/check_buildbot_system.py @@ -213,10 +213,12 @@ def main() -> None: sys.exit(1) # Unreachable upstream means the freshness question was not answered, and - # a zero exit says it was answered "fresh". A new asset nobody tracks, or - # a tracked one the buildbot dropped, is a change to act on: a zero exit - # there let the online pipeline call the system directory current. - if report.get("error") or pending(report): + # a zero exit says it was answered "fresh". An asset whose HEAD went + # unanswered is the same question left open, as check_freshness counts + # UNKNOWN. A new asset nobody tracks, or a tracked one the buildbot + # dropped, is a change to act on: a zero exit there let the online + # pipeline call the system directory current. + if report.get("error") or pending(report) or unanswered(report): raise SystemExit(1) @@ -225,6 +227,11 @@ def pending(report: dict) -> list[dict]: return [e for e in report.get("entries", []) if e["status"] in ("NEW", "STALE")] +def unanswered(report: dict) -> list[dict]: + """Tracked entries whose remote version could not be read.""" + return [e for e in report.get("entries", []) if e["status"] == "UNKNOWN"] + + if __name__ == "__main__": from common import run_cli diff --git a/tests/test_audit_regressions.py b/tests/test_audit_regressions.py index b1e24bdf8..600cdf19b 100644 --- a/tests/test_audit_regressions.py +++ b/tests/test_audit_regressions.py @@ -2826,14 +2826,29 @@ class ACheckThatCannotAnswerDoesNotPass(unittest.TestCase): self.assertEqual(unsatisfied, ["bios/absent.bin"]) def test_an_unreachable_buildbot_is_not_a_fresh_verdict(self): - source = (ROOT / "scripts" / "check_buildbot_system.py").read_text( - encoding="utf-8" - ) - self.assertIn( - 'if report.get("error") or pending(report):', - source.split("def main(")[-1], - "main() ignores the error the report carries", - ) + """Every HEAD unanswered printed "16 unknown" and exited 0, so the + online pipeline printed check_buildbot OK.""" + sys.path.insert(0, str(ROOT / "scripts")) + import check_buildbot_system as cbs # noqa: PLC0415 + + registry = str(ROOT / "platforms" / "_data_dirs.yml") + tracked = cbs.load_tracked_entries(registry) + self.assertTrue(tracked) + cases = { + "index unreachable": mock.patch.object( + cbs, "fetch_index", side_effect=OSError("down")), + "every HEAD unanswered": mock.patch.object( + cbs, "fetch_index", return_value=set(tracked)), + } + for label, index in cases.items(): + with self.subTest(label), index, \ + mock.patch.object(cbs, "get_remote_etag", return_value=None), \ + mock.patch.object(sys, "argv", ["check_buildbot_system.py", + "--registry", registry]), \ + contextlib.redirect_stdout(io.StringIO()), \ + self.assertRaises(SystemExit) as stop: + cbs.main() + self.assertEqual(stop.exception.code, 1) def test_a_missing_profile_directory_says_so(self): from scripts import common as _common