8cb2a0f9c6
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.
67 lines
2.5 KiB
Python
Executable File
67 lines
2.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Smoke-test the consumable-apply probe against the RUNNING staging host.
|
|
|
|
Replays the exact request the client sent, plus the batch and unknown-target
|
|
edges, then proves Core is byte-identical afterwards. No client needed.
|
|
"""
|
|
import json
|
|
import subprocess
|
|
import urllib.error
|
|
import urllib.request
|
|
|
|
BASE = "http://127.0.0.1:8299"
|
|
PATH = "/ut/game/fifa17/item/resource/5001004"
|
|
H = {"X-OpenFUT-Game": "fifa17", "Content-Type": "application/json"}
|
|
LOG = "/home/alex/openfut-sold-staging/logs/utas-host.log"
|
|
|
|
|
|
def post(path, payload):
|
|
req = urllib.request.Request(
|
|
BASE + path, data=payload, headers=H, method="POST")
|
|
try:
|
|
with urllib.request.urlopen(req, timeout=30) as r:
|
|
return r.status, r.read().decode()
|
|
except urllib.error.HTTPError as e:
|
|
return e.code, e.read().decode()
|
|
|
|
|
|
before = subprocess.run(["python3", "/home/alex/OpenFUT/scripts/fifa17-apply-snapshot.py"],
|
|
capture_output=True, text=True).stdout
|
|
mark = sum(1 for _ in open(LOG))
|
|
|
|
print("=== 1. the EXACT request captured from the client ===")
|
|
st, body = post(PATH, b'{"apply":[{"id":100000003}]}')
|
|
print(" status=%s body=%s" % (st, body))
|
|
ok1 = st == 200 and json.loads(body) == {"itemData": []}
|
|
|
|
print("\n=== 2. batch: semantics unproven, must be REFUSED not guessed ===")
|
|
st2, body2 = post(PATH, b'{"apply":[{"id":100000003},{"id":100000004}]}')
|
|
print(" status=%s body=%s" % (st2, body2[:90]))
|
|
ok2 = st2 == 400 and "apply_batch_unsupported" in body2
|
|
|
|
print("\n=== 3. unknown target: observed, never invented ===")
|
|
st3, body3 = post(PATH, b'{"apply":[{"id":999999999}]}')
|
|
print(" status=%s body=%s" % (st3, body3))
|
|
ok3 = st3 == 200
|
|
|
|
print("\n=== 4. unowned source resource ===")
|
|
st4, body4 = post("/ut/game/fifa17/item/resource/1234567", b'{"apply":[{"id":100000003}]}')
|
|
print(" status=%s body=%s" % (st4, body4))
|
|
ok4 = st4 == 200
|
|
|
|
print("\n=== host log ===")
|
|
for line in list(open(LOG))[mark:]:
|
|
if "apply-probe" in line:
|
|
print(" " + line.rstrip()[:190])
|
|
|
|
after = subprocess.run(["python3", "/home/alex/OpenFUT/scripts/fifa17-apply-snapshot.py"],
|
|
capture_output=True, text=True).stdout
|
|
same = before == after
|
|
print("\n=== 5. Core unchanged by all four requests: %s ===" % ("YES" if same else "NO"))
|
|
if not same:
|
|
for b, a in zip(before.splitlines(), after.splitlines()):
|
|
if b != a:
|
|
print(" BEFORE %s\n AFTER %s" % (b.strip(), a.strip()))
|
|
|
|
print("\nRESULT: %s" % ("OK" if all([ok1, ok2, ok3, ok4, same]) else "FAILED"))
|