# -*- coding: utf-8 -*- """Seam test for scripts/agent_gates.py. Run from the repo root: python3 scripts/test_agent_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 the 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. The second test is the one that matters here: this repo's only gate lives in a SIBLING clone, so "the sibling is missing" must be a FAILURE and not a quiet skip. """ import os import shutil import subprocess import sys import tempfile import unittest ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) ENTRY = os.path.join(ROOT, "scripts", "agent_gates.py") class AgentGatesTest(unittest.TestCase): @classmethod def setUpClass(cls): p = subprocess.run([sys.executable, ENTRY, "--fast"], cwd=ROOT, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) cls.rc = p.returncode cls.out = p.stdout.decode("utf-8", "replace") def test_exit_code_is_zero(self): self.assertEqual(self.rc, 0, self.out) def test_member_gate_actually_ran(self): self.assertIn("cited paths — exact", self.out, "the reuse-refs gate is listed but its own output never appeared — an inert " "runner prints the summary without calling anything:\n%s" % self.out) def test_missing_shared_checker_is_a_failure_not_a_skip(self): """Fail-closed. Copy the entry point into a lone directory with no felhom.eu sibling and confirm it CONVICTS rather than reporting green with nothing run.""" tmp = tempfile.mkdtemp(prefix="agent-gates-") try: lone = os.path.join(tmp, "felhom-agent", "scripts") os.makedirs(lone) shutil.copy(ENTRY, os.path.join(lone, "agent_gates.py")) p = subprocess.run([sys.executable, os.path.join(lone, "agent_gates.py"), "--fast"], cwd=os.path.dirname(lone), stdout=subprocess.PIPE, stderr=subprocess.STDOUT) out = p.stdout.decode("utf-8", "replace") self.assertNotEqual(p.returncode, 0, out) self.assertIn("is MISSING — tried", out) finally: shutil.rmtree(tmp, ignore_errors=True) 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)