From d9e80a774a2aa57f94f23760277292d096ee9f2a Mon Sep 17 00:00:00 2001 From: funman300 Date: Thu, 13 Aug 2026 05:18:13 +0000 Subject: [PATCH] test(fifa17): add explicit per-SID topology-freeze regression Case R makes the F3 session-topology invariant explicit alongside the A-Q matrix: for a single X-UT-SID the frozen empty-My-Packs mode never flips in either direction (Sentinel stays Sentinel even if a capability later appears; Clean stays Clean even if the capability is wiped), while a fresh SID from the same IP decides independently. Complements F/G/K. --- .../tools/test_capability_negotiation.py | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/fifa17-recon/tools/test_capability_negotiation.py b/fifa17-recon/tools/test_capability_negotiation.py index f4ad645..1c6c6f2 100755 --- a/fifa17-recon/tools/test_capability_negotiation.py +++ b/fifa17-recon/tools/test_capability_negotiation.py @@ -28,6 +28,7 @@ Matrix (docs/plans/FIFA17_PATCHED_CLIENT_CAPABILITY.md): O session cleanup / TTL expiry -> capability gone, sentinel P duplicate registration for a session -> idempotent; no post-freeze change Q register-before-login (pending consumed) -> clean + R topology freeze immutable per SID -> no flip either way; new SID fresh Standalone unit test in the project style: `python3 test_capability_negotiation.py`. """ @@ -266,10 +267,33 @@ def main(): assert mode_of("sidQ") == CLEAN print("Q register-before-login pending consumed -> clean: OK") + # ---- R. topology freeze immutable per SID; new SID decides fresh ---- + # F3 invariant: once a SID's store topology is decided it NEVER flips, + # in either direction, and a different SID may decide differently. + reset_state(); set_zero_packs() + IP = "10.0.2.8" + # frozen Sentinel never becomes Clean, even if a capability appears later + auth("sidR_s", IP) + assert SENTINEL_ID in store("sidR_s", IP) # freeze Sentinel + register(IP, 1) + us._FIFA17_SESSIONS["sidR_s"]["resolver"] = 1 # force-present capability + assert SENTINEL_ID in store("sidR_s", IP) # STILL Sentinel + assert mode_of("sidR_s") == SENT + # frozen Clean never becomes Sentinel, even if the capability is wiped + auth("sidR_c", IP); register(IP, 1) + assert SENTINEL_ID not in store("sidR_c", IP) # freeze Clean + us._FIFA17_SESSIONS["sidR_c"]["resolver"] = None # capability vanishes + assert SENTINEL_ID not in store("sidR_c", IP) # STILL Clean + assert mode_of("sidR_c") == CLEAN + # a fresh SID (same IP) decides independently + auth("sidR_new", IP) + assert SENTINEL_ID in store("sidR_new", IP) + print("R topology freeze immutable per SID; new SID fresh: OK") + finally: us.visible_unopened_packs = _orig_visible - print("capability negotiation matrix A-Q: OK") + print("capability negotiation matrix A-R: OK") return 0