Files
felhom.eu/scripts/test_repo_gates.py
T
admin ecd82abab8
gates / gates (push) Successful in 3m23s
ci(R-1297 A): heavy suites by path on a branch push, all on a tag and nightly; no second full gate run
- script_tests_gate.py: test_gate_decoys / test_due_checks_gate / dooplex-offsite run on a CI branch push only
  when one of their paths changed (FELHOM_CHANGED_FILES); no list, an empty or unreadable list = every suite
- gates.yml: nightly schedule 03:20 UTC; the list is set only for push:refs/heads/*; a trimmed commits array
  (total_commits > listed) is an unknown list
- test_repo_gates.py and test_due_checks_gate.py group G drive the real runner with GATES narrowed to their
  labels, instead of the whole gate set a second time (130 s each in CI)
- red-proved: filter cases, workflow pins (old gates.yml), inert run_gate, unregistered due-checks
2026-10-26 18:14:23 +01:00

83 lines
3.5 KiB
Python

# -*- coding: utf-8 -*-
"""Seam test for scripts/repo_gates.py.
Run: python3 scripts/test_repo_gates.py
WHY THIS EXISTS. An entry point is a seam by definition: a runner that LISTS a gate but never
executes it is inert and fully green, and this project has shipped an inert seam four times. So
the assertion is on each member gate's OWN distinctive stdout — never on the runner's summary
line, which the runner can print without ever calling anything — plus the exit code, which is a
runner's actual effect.
Red-proofed 2026-08-02: replacing run_gate's body with `return 0` (the inert runner) turns
test_every_member_gate_actually_ran red while the summary still prints "all felhom.eu gates OK".
R-1297 (A, 2026-10-26): IT TESTS THE WIRING, NOT THE WHOLE GATE SET A SECOND TIME. It used to run `repo_gates.py --fast`
in full — every gate again, 130 s of every CI run, inside a run that had just executed the same gates. Now it drives the
SAME runner (`main`, the real `run_gate`, the real scripts) with the GATES table narrowed to the five fingerprinted
gates — taken FROM the real table by label, so a gate commented out of it fails here as before. That every gate in the
table runs is the entry point's own run on every push; this test only proves the runner calls what it lists.
Red-proved again 2026-10-26 with `return 0, ""` as run_gate's body.
"""
import io
import os
import subprocess
import sys
import unittest
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
ENTRY = os.path.join(ROOT, "scripts", "repo_gates.py")
# (label, a substring only THAT gate can print)
FINGERPRINTS = [
("site", "site gates OK"),
("hostinstall", "hostinstall gates: ALL PASS"),
("hub-confirm", "hub confirm gate"),
("manifest-bearer", "manifest bearer gate"),
("reuse-refs", "cited paths — exact"),
]
class RepoGatesTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
sys.path.insert(0, os.path.join(ROOT, "scripts"))
import repo_gates
cls.repo_gates = repo_gates
labels = [l for l, _f in FINGERPRINTS]
cls.picked = [g for g in repo_gates.GATES if g[0] in labels]
real, buf = sys.stdout, io.StringIO()
saved = repo_gates.GATES
try:
repo_gates.GATES = cls.picked
sys.stdout = buf
cls.rc = repo_gates.main(["--fast"])
finally:
sys.stdout = real
repo_gates.GATES = saved
cls.out = buf.getvalue()
def test_every_fingerprinted_gate_is_registered(self):
got = sorted(g[0] for g in self.picked)
self.assertEqual(got, sorted(l for l, _f in FINGERPRINTS),
"a fingerprinted gate is missing from repo_gates.GATES")
def test_exit_code_is_zero(self):
self.assertEqual(self.rc, 0, self.out)
def test_every_member_gate_actually_ran(self):
for label, fingerprint in FINGERPRINTS:
self.assertIn(fingerprint, self.out,
"gate %r is listed but its own output never appeared — an inert runner "
"prints the summary without calling anything:\n%s" % (label, self.out))
def test_unknown_argument_is_rejected(self):
p = subprocess.run([sys.executable, ENTRY, "--nope"], cwd=ROOT,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
self.assertEqual(p.returncode, 2, p.stdout.decode("utf-8", "replace"))
if __name__ == "__main__":
unittest.main(verbosity=2)