From 8bb09abad06dd908142a951e58be2de83e74f55c Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Wed, 22 Jul 2026 21:15:47 +0200 Subject: [PATCH] test(ui): wrong-body Pending must not touch retry state (PR #193 Hoshe finding 1) Pins on_response()'s guard ordering: body_id check BEFORE the status branch, so another body's cold Pending can never burn one of our 30 retries or reschedule our timer (multi-body browsing / shared-broadcast tile fan-out). Revert-verified: reordering the guards makes this test fail; final own-body Ready assertion proves the request is genuinely untouched, not just un-retried. 44/44 in the file. Tickets: T-1163 Co-Authored-By: Claude Fable 5 --- client/tests/test_atlas_window_request.gd | 35 +++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/client/tests/test_atlas_window_request.gd b/client/tests/test_atlas_window_request.gd index 791429d21..7cb4d27fb 100644 --- a/client/tests/test_atlas_window_request.gd +++ b/client/tests/test_atlas_window_request.gd @@ -562,6 +562,41 @@ func test_cold_request_error_gives_up_immediately_without_retry() -> void: assert_int(req._retries).is_equal(0) +## PR #193 review (Hoshe): a whole-response Pending for a DIFFERENT body +## must not touch this request's retry state — the body_id guard runs +## BEFORE the status branch in on_response(), so someone else's cold-body +## pending can never burn one of OUR 30 retries (or reschedule our timer). +## Structurally guaranteed by guard ordering today; this test pins the +## ordering, because a refactor that moves the status branch first would +## silently cross-wire every concurrent cold descent (multi-body Atlas +## browsing, or the orbital tile fan-out where all requests share one +## broadcast signal). The final Ready-for-OUR-body assertion proves the +## request is genuinely unaffected, not just un-retried. +func test_pending_for_a_different_body_does_not_touch_retry_state() -> void: + var req = _make_request() + req.request_now("GJ380c", Vector2i(2, 2), 2) + assert_bool(req.is_pending()).is_true() + + req.on_response(_pending_response("OtherBody")) + + assert_int(req._retries).override_failure_message( + "a Pending for a DIFFERENT body must not increment OUR retry counter" + + " — the body_id guard must run before the status branch" + ).is_equal(0) + assert_bool(req.is_pending()).override_failure_message( + "a wrong-body Pending must leave the request still pending its own" + + " response, neither given up nor retried" + ).is_true() + + var window: Dictionary = _mock_window(Vector2i(2, 2), 2) + req.on_response(_mock_response("GJ380c", window)) + assert_bool(req.is_pending()).override_failure_message( + "after ignoring a wrong-body Pending, our OWN Ready must still be" + + " accepted normally — the request state must be genuinely untouched" + ).is_false() + assert_int(req._retries).is_equal(0) + + # ============================================================================= # _retry_delay_for() — deterministic exponential backoff + per-tile stagger # (PR #192 cold-start round 3 hardening: 6 tiles retrying in perfect