9d39faabf8
iso_bootstrap_gate.py runs scripts/iso/test/bootstrap-modes.sh in felhom-iso-assistant:trixie (staged copy, read-only mount, --network none), registered fast=False in repo_gates.py so the pre-push hook and CI (both --fast) never run it (decision 147). No docker / no image / docker error -> exit 2 NOT CHECKED. Every green run is followed by a built-in decoy: the harness must FAIL a bootstrap whose pairing banner never paints (R-496 shape), or the gate convicts the instrument as blind. Docker-free decoys in test_iso_bootstrap_gate.py (fake docker on a one-directory PATH), run from test_gate_decoys.py (COVERS). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
148 lines
6.1 KiB
Python
148 lines
6.1 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""Decoys for scripts/iso_bootstrap_gate.py (R-502). DOCKER-FREE — runs on the CI runner (BusyBox +
|
|
python3 + git) and on DooPlex alike, and never reaches the real docker.
|
|
|
|
HOW. The gate finds docker with shutil.which, so every case runs the REAL gate as a subprocess with
|
|
PATH set to ONE temp directory: empty (no docker), or holding a FAKE `docker` written in python with
|
|
an absolute shebang (so it needs nothing else on PATH — /usr/bin, where the real docker lives on
|
|
DooPlex, is never on it). The fake answers `image inspect` and `run` per FAKE_DOCKER_MODE, and for
|
|
`run` reads the STAGED felhom-bootstrap.sh from the `-v <dir>:/src:ro` mount, so it can tell the
|
|
genuine run from the gate's built-in banner decoy.
|
|
|
|
What the fake cannot do is run the harness — that needs root and the image. The harness's power to
|
|
see a broken banner is proven by the gate itself, in the real container, on every full run (its
|
|
built-in decoy). This file proves the gate's verdicts: that a blind harness, a failing harness, a
|
|
harness that checked nothing, and an unrun harness can never read as green.
|
|
|
|
Run: python3 scripts/test_iso_bootstrap_gate.py
|
|
"""
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
ROOT = os.path.dirname(HERE)
|
|
GATE = os.path.join(HERE, "iso_bootstrap_gate.py")
|
|
sys.path.insert(0, HERE)
|
|
import iso_bootstrap_gate as g # noqa: E402
|
|
import repo_gates # noqa: E402
|
|
|
|
FAKE = r'''#!%(py)s
|
|
import os, re, sys
|
|
mode = os.environ.get("FAKE_DOCKER_MODE", "genuine")
|
|
a = sys.argv[1:]
|
|
log = os.environ.get("FAKE_DOCKER_LOG")
|
|
if log:
|
|
open(log, "a").write(" ".join(a) + "\n")
|
|
if a[:2] == ["image", "inspect"]:
|
|
sys.exit(1 if mode == "no-image" else 0)
|
|
if a[:1] == ["rm"]:
|
|
sys.exit(0)
|
|
if a[:1] != ["run"]:
|
|
sys.exit(3)
|
|
if mode == "daemon-error":
|
|
print("docker: Error response from daemon: something broke."); sys.exit(125)
|
|
src = [x for x in a if x.endswith(":/src:ro")][0][:-len(":/src:ro")]
|
|
mutant = "R-502 planted decoy" in open(os.path.join(src, "felhom-bootstrap.sh"), encoding="utf-8").read()
|
|
oks = "".join(" ok: check %%d\n" %% i for i in range(60))
|
|
if mode == "fails" or (mutant and mode != "blind"):
|
|
print(oks + " FAIL: R-496: banner painted to the console seam\nSOME TESTS FAILED"); sys.exit(1)
|
|
if mode == "hollow":
|
|
print("ALL BOOTSTRAP-MODE TESTS PASSED"); sys.exit(0)
|
|
print(oks + "ALL BOOTSTRAP-MODE TESTS PASSED"); sys.exit(0)
|
|
'''
|
|
|
|
|
|
def run_gate(mode=None):
|
|
"""Run the real gate. mode None = no docker on PATH at all."""
|
|
d = tempfile.mkdtemp(prefix="iso-gate-test-")
|
|
try:
|
|
log = os.path.join(d, "calls.log")
|
|
if mode is not None:
|
|
p = os.path.join(d, "docker")
|
|
with open(p, "w") as f:
|
|
f.write(FAKE % {"py": sys.executable})
|
|
os.chmod(p, 0o755)
|
|
env = {"PATH": d, "FAKE_DOCKER_MODE": mode or "", "FAKE_DOCKER_LOG": log,
|
|
"HOME": d, "PYTHONDONTWRITEBYTECODE": "1"}
|
|
r = subprocess.run([sys.executable, GATE], cwd=ROOT, env=env,
|
|
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
|
calls = ""
|
|
if os.path.exists(log):
|
|
with open(log) as f:
|
|
calls = f.read()
|
|
return r.returncode, r.stdout.decode("utf-8", "replace"), calls
|
|
finally:
|
|
shutil.rmtree(d, ignore_errors=True)
|
|
|
|
|
|
class IsoBootstrapGateTest(unittest.TestCase):
|
|
|
|
def test_genuine_passes_and_runs_the_decoy_too(self):
|
|
rc, out, calls = run_gate("genuine")
|
|
self.assertEqual(rc, 0, out)
|
|
self.assertIn("built-in decoy convicted", out)
|
|
self.assertEqual(calls.count("run "), 2, "want the genuine run AND the decoy run:\n" + calls)
|
|
self.assertIn("--network none", calls)
|
|
|
|
def test_blind_harness_convicts(self):
|
|
# The harness passes a bootstrap whose banner never paints: the R-496 shape. Must be 1.
|
|
rc, out, _ = run_gate("blind")
|
|
self.assertEqual(rc, 1, out)
|
|
self.assertIn("instrument is blind", out)
|
|
|
|
def test_failing_harness_convicts(self):
|
|
rc, out, calls = run_gate("fails")
|
|
self.assertEqual(rc, 1, out)
|
|
self.assertIn("FAIL: R-496: banner painted", out)
|
|
self.assertEqual(calls.count("run "), 1)
|
|
|
|
def test_pass_line_without_checks_convicts(self):
|
|
rc, out, _ = run_gate("hollow")
|
|
self.assertEqual(rc, 1, out)
|
|
self.assertIn("proved nothing", out)
|
|
|
|
def test_no_docker_is_not_checked(self):
|
|
rc, out, _ = run_gate(None)
|
|
self.assertEqual(rc, 2, out)
|
|
self.assertIn("NOT CHECKED", out)
|
|
|
|
def test_no_image_is_not_checked(self):
|
|
rc, out, calls = run_gate("no-image")
|
|
self.assertEqual(rc, 2, out)
|
|
self.assertIn("NOT CHECKED", out)
|
|
self.assertNotIn("run ", calls)
|
|
|
|
def test_docker_error_is_not_checked(self):
|
|
rc, out, _ = run_gate("daemon-error")
|
|
self.assertEqual(rc, 2, out)
|
|
|
|
def test_decoy_plants_on_the_real_bootstrap(self):
|
|
# The built-in decoy's anchor must exist ONCE in the real script, and the plant must apply.
|
|
d = tempfile.mkdtemp()
|
|
try:
|
|
self.assertIsNone(g.stage(d, mutate=True))
|
|
with open(os.path.join(d, "felhom-bootstrap.sh"), encoding="utf-8") as f:
|
|
text = f.read()
|
|
self.assertIn("R-502 planted decoy", text)
|
|
for _src, rel in g.INPUTS:
|
|
self.assertTrue(os.path.exists(os.path.join(d, rel)), rel)
|
|
finally:
|
|
shutil.rmtree(d, ignore_errors=True)
|
|
|
|
def test_registered_full_runs_only(self):
|
|
# Decision 147: never in --fast (pre-push hook and CI both run --fast; CI has no docker).
|
|
rows = [r for r in repo_gates.GATES if r[0] == "iso-bootstrap"]
|
|
self.assertEqual(len(rows), 1, "iso-bootstrap must be registered once in repo_gates.GATES")
|
|
self.assertTrue(rows[0][1].endswith("iso_bootstrap_gate.py"))
|
|
self.assertIs(rows[0][3], False, "iso-bootstrap must be fast=False (full runs only)")
|
|
self.assertIs(rows[0][4], False, "iso-bootstrap must not be exemptible")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main(verbosity=2)
|