Files
felhom.eu/scripts/test_host_swap_rule_gate.py
T

72 lines
2.9 KiB
Python

#!/usr/bin/env python3
"""Decoys for host_swap_rule_gate (R-421). Run: python3 scripts/test_host_swap_rule_gate.py
Each case builds a fake workspace (felhom.eu + a felhom-controller clone) and runs the real gate against it:
1. one row's verdict flipped on the controller side only — drift (the files share every NAME; the fact is a value);
2. identical tables, but no controller test reads the table any more — the label without the fact;
3. no controller clone — INCONCLUSIVE (2), never a pass;
4. the genuine article — must pass.
"""
from __future__ import annotations
import os
import shutil
import subprocess
import sys
import tempfile
HERE = os.path.dirname(os.path.abspath(__file__))
REPO = os.path.dirname(HERE)
GATE = os.path.join(HERE, "host_swap_rule_gate.py")
REAL = os.path.join(REPO, "hub", "internal", "api", "testdata", "host_swap_rule_cases.json")
NAME = "host_swap_rule_cases.json"
def build(tmp, ctrl_table=None, ctrl_test=True, with_ctrl=True):
repo = os.path.join(tmp, "felhom.eu")
hub = os.path.join(repo, "hub", "internal", "api")
os.makedirs(os.path.join(hub, "testdata"))
shutil.copy(REAL, os.path.join(hub, "testdata", NAME))
open(os.path.join(hub, "x_test.go"), "w").write('package api\n// os.ReadFile("testdata/%s")\n' % NAME)
if with_ctrl:
web = os.path.join(tmp, "felhom-controller", "controller", "internal", "web")
os.makedirs(os.path.join(web, "testdata"))
data = open(REAL, encoding="utf-8").read() if ctrl_table is None else ctrl_table
open(os.path.join(web, "testdata", NAME), "w", encoding="utf-8").write(data)
body = 'package web\n// os.ReadFile("testdata/%s")\n' % NAME if ctrl_test else "package web\n"
open(os.path.join(web, "y_test.go"), "w").write(body)
return repo
def run(repo):
env = dict(os.environ, HOST_SWAP_RULE_REPO=repo)
return subprocess.run([sys.executable, GATE], env=env, capture_output=True, text=True).returncode
def main():
real = open(REAL, encoding="utf-8").read()
flipped = real.replace('"guest_swap_mb": 12288, "short": false', '"guest_swap_mb": 12288, "short": true', 1)
assert flipped != real, "the decoy's row is gone from the real table"
cases = [
("one verdict flipped on the controller side", dict(ctrl_table=flipped), 1),
("no controller test reads the table", dict(ctrl_test=False), 1),
("no controller clone", dict(with_ctrl=False), 2),
("the genuine article", dict(), 0),
]
fails = 0
for label, kw, want in cases:
tmp = tempfile.mkdtemp()
try:
got = run(build(tmp, **kw))
finally:
shutil.rmtree(tmp)
ok = got == want
fails += 0 if ok else 1
print(" %s %-45s rc=%d want %d" % ("ok" if ok else "FAIL", label, got, want))
print("host-swap-rule decoys: %d/%d" % (len(cases) - fails, len(cases)))
return 1 if fails else 0
if __name__ == "__main__":
sys.exit(main())