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.
This commit is contained in:
@@ -28,6 +28,7 @@ Matrix (docs/plans/FIFA17_PATCHED_CLIENT_CAPABILITY.md):
|
|||||||
O session cleanup / TTL expiry -> capability gone, sentinel
|
O session cleanup / TTL expiry -> capability gone, sentinel
|
||||||
P duplicate registration for a session -> idempotent; no post-freeze change
|
P duplicate registration for a session -> idempotent; no post-freeze change
|
||||||
Q register-before-login (pending consumed) -> clean
|
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`.
|
Standalone unit test in the project style: `python3 test_capability_negotiation.py`.
|
||||||
"""
|
"""
|
||||||
@@ -266,10 +267,33 @@ def main():
|
|||||||
assert mode_of("sidQ") == CLEAN
|
assert mode_of("sidQ") == CLEAN
|
||||||
print("Q register-before-login pending consumed -> clean: OK")
|
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:
|
finally:
|
||||||
us.visible_unopened_packs = _orig_visible
|
us.visible_unopened_packs = _orig_visible
|
||||||
|
|
||||||
print("capability negotiation matrix A-Q: OK")
|
print("capability negotiation matrix A-R: OK")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user