R-885: script-tests gate runs every scripts/**/test_*.py on every push (decoys, red-proofs); closed (336 -> 335)
gates / gates (push) Failing after 1m17s
gates / gates (push) Failing after 1m17s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Decoys for scripts/script_tests_gate.py (R-885, R-421). Run: python3 scripts/test_script_tests_gate.py
|
||||
|
||||
Each decoy is a fake repo with a scripts/ tree. The gate must REFUSE: a suite that prints "OK" but exits 1 (the label
|
||||
without the fact); a failing suite three directories deep (scope is a walk, not a list); an empty scripts/ (a gate that
|
||||
checked nothing). It must PASS the genuine article, and step aside when nested.
|
||||
"""
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
GATE = os.path.join(HERE, "script_tests_gate.py")
|
||||
|
||||
COVERS = {
|
||||
"script-tests": ("a suite that PRINTS OK and exits 1; a failing suite three levels deep; an empty scripts/ "
|
||||
"tree; plus the genuine article (must pass) and the nested-run mark (must step aside)"),
|
||||
}
|
||||
|
||||
|
||||
def fake_repo(files):
|
||||
root = tempfile.mkdtemp()
|
||||
os.makedirs(os.path.join(root, "scripts"))
|
||||
for rel, body in files.items():
|
||||
p = os.path.join(root, "scripts", rel)
|
||||
os.makedirs(os.path.dirname(p), exist_ok=True)
|
||||
open(p, "w").write(body)
|
||||
return root
|
||||
|
||||
|
||||
def gate(root, nested=False):
|
||||
env = {k: v for k, v in os.environ.items() if k != "FELHOM_SCRIPT_TESTS_GATE"}
|
||||
if nested:
|
||||
env["FELHOM_SCRIPT_TESTS_GATE"] = "1"
|
||||
return subprocess.run([sys.executable, GATE, root], env=env, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT).returncode
|
||||
|
||||
|
||||
CASES = [
|
||||
("prints OK, exits 1", {"test_a.py": "print('OK')\nraise SystemExit(1)\n"}, False, 1),
|
||||
("failing suite 3 levels deep", {"test_ok.py": "pass\n", "x/y/z/test_deep.py": "raise SystemExit(2)\n"}, False, 1),
|
||||
("empty scripts/", {"README": "no tests here\n"}, False, 1),
|
||||
("genuine: two passing suites", {"test_a.py": "pass\n", "sub/test_b.py": "print('fine')\n"}, False, 0),
|
||||
("nested run steps aside", {"test_a.py": "raise SystemExit(1)\n"}, True, 0),
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
bad = 0
|
||||
for name, files, nested, want in CASES:
|
||||
got = gate(fake_repo(files), nested)
|
||||
ok = got == want
|
||||
bad += not ok
|
||||
print("%s %-32s want rc=%d got rc=%d" % ("ok " if ok else "FAIL", name, want, got))
|
||||
print("script-tests decoys: %d/%d" % (len(CASES) - bad, len(CASES)))
|
||||
return 1 if bad else 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user