test(fifa17): smoke-test the apply probe and prove the gate fails closed
Unit tests cover classification and body parsing; they do not prove the running
host behaves. These three scripts exercise the real service, and they found
nothing broken but make the two load-bearing claims checkable:
fifa17-apply-snapshot.py Core truth around an apply: coins, owned rows, kind
histogram, the source stack's copy count, and the
target's mutable fields (contract/fitness/playStyle/
training/injury). Coins and ownership come from the
staging DB, not the wire, so the check cannot be
satisfied by a projection bug.
fifa17-apply-probe-smoke.py Replays the EXACT captured request plus the edges,
against the live host, no client needed:
1. {"apply":[{"id":100000003}]} -> 200 {"itemData":[]}
source=Consumable subtype=201 copies=1,
target=fifa17_200389 rating=87
2. two targets -> 400 apply_batch_unsupported
3. unknown target wire id -> 200 UNRESOLVED_WIRE_ID
4. unowned source -> 200 NOT_OWNED
then re-snapshots: Core identical after all four.
fifa17-apply-gate-off.py The production-safety claim. With APPLY_PROBE unset
the same request must produce the pre-probe
behaviour, and does: no apply-probe line, three
passthrough lines, 502 into the dead upstream, Core
unchanged. Verified by restarting staging without the
flag -- an assertion about failing closed is worth
nothing unless the closed path is executed.
Nothing here writes to production; snapshot reads the staging DB read-only.
This commit is contained in:
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python3
|
||||
"""With OPENFUT_FIFA17_APPLY_PROBE unset the apply MUST fall through to the
|
||||
Python passthrough -- i.e. exactly the behaviour that existed before the probe.
|
||||
That is the production-safety claim, so prove it rather than assert it."""
|
||||
import subprocess
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
|
||||
LOG = "/home/alex/openfut-sold-staging/logs/utas-host.log"
|
||||
mark = sum(1 for _ in open(LOG))
|
||||
before = subprocess.run(["python3", "/home/alex/OpenFUT/scripts/fifa17-apply-snapshot.py"],
|
||||
capture_output=True, text=True).stdout
|
||||
|
||||
req = urllib.request.Request(
|
||||
"http://127.0.0.1:8299/ut/game/fifa17/item/resource/5001004",
|
||||
data=b'{"apply":[{"id":100000003}]}',
|
||||
headers={"X-OpenFUT-Game": "fifa17", "Content-Type": "application/json"},
|
||||
method="POST")
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=30) as r:
|
||||
st, body = r.status, r.read().decode()
|
||||
except urllib.error.HTTPError as e:
|
||||
st, body = e.code, e.read().decode()
|
||||
print(" status=%s body=%s" % (st, body))
|
||||
|
||||
print("--- log with the gate OFF ---")
|
||||
lines = list(open(LOG))[mark:]
|
||||
for line in lines:
|
||||
if any(k in line for k in ("apply-probe", "passthrough", "PYTHON")):
|
||||
print(" " + line.rstrip()[:150])
|
||||
|
||||
probe_served = any("apply-probe" in line for line in lines)
|
||||
went_python = any("owner=PYTHON" in line for line in lines)
|
||||
after = subprocess.run(["python3", "/home/alex/OpenFUT/scripts/fifa17-apply-snapshot.py"],
|
||||
capture_output=True, text=True).stdout
|
||||
print("\n probe served (must be False): %s" % probe_served)
|
||||
print(" proxied to Python (must be True): %s" % went_python)
|
||||
print(" Core unchanged: %s" % (before == after))
|
||||
print("\nRESULT: %s" % ("OK -- gate fails closed"
|
||||
if (not probe_served and went_python and before == after)
|
||||
else "FAILED"))
|
||||
Reference in New Issue
Block a user