## T-1138 (D-226 T-1124 amendment §4): tests for the client-side ## DistrictWindowLayer LRU cache — keyed on (body_id, center, n), LRU-evict ## only (D-227 determinism means no freshness check is ever needed). class_name TestAtlasWindowCache extends GdUnitTestSuite const AtlasWindowCache := preload("res://ui/implant/apps/atlas/atlas_window_cache.gd") func test_make_key_distinguishes_body_center_and_n() -> void: var k1 := AtlasWindowCache.make_key("GJ1c", Vector2i(10, 20), 32) var k2 := AtlasWindowCache.make_key("GJ1d", Vector2i(10, 20), 32) # different body var k3 := AtlasWindowCache.make_key("GJ1c", Vector2i(11, 20), 32) # different center var k4 := AtlasWindowCache.make_key("GJ1c", Vector2i(10, 20), 64) # different n assert_str(k1).is_not_equal(k2) assert_str(k1).is_not_equal(k3) assert_str(k1).is_not_equal(k4) func test_miss_returns_null_and_has_reports_false() -> void: var cache := AtlasWindowCache.new() assert_that(cache.get_window("GJ1c", Vector2i(0, 0), 32)).is_null() assert_bool(cache.has("GJ1c", Vector2i(0, 0), 32)).is_false() func test_put_then_get_round_trips_exact_window() -> void: var cache := AtlasWindowCache.new() var window := {"center": [10, 20], "n": 32, "morphology": PackedByteArray([1, 2, 3])} cache.put("GJ1c", Vector2i(10, 20), 32, window) assert_bool(cache.has("GJ1c", Vector2i(10, 20), 32)).is_true() assert_that(cache.get_window("GJ1c", Vector2i(10, 20), 32)).is_equal(window) ## D-227: a window fetched once is valid FOREVER for that (body, center, n) — ## no expiry, no invalidation path. Repeated get_window() calls across a ## simulated time gap (just repeated calls here — there is no clock in this ## cache at all) must keep returning the same stored value. func test_cached_window_never_expires() -> void: var cache := AtlasWindowCache.new() var window := {"center": [0, 0], "n": 32} cache.put("GJ1c", Vector2i(0, 0), 32, window) for _i in range(50): assert_that(cache.get_window("GJ1c", Vector2i(0, 0), 32)).is_equal(window) ## Different (body_id, center, n) tuples never collide — this is the whole ## point of the composite key (§4: "cacheable client-side keyed on ## (body_id, center, n)"). func test_different_bodies_same_center_do_not_collide() -> void: var cache := AtlasWindowCache.new() var window_a := {"body": "GJ1c"} var window_b := {"body": "GJ1d"} cache.put("GJ1c", Vector2i(10, 20), 32, window_a) cache.put("GJ1d", Vector2i(10, 20), 32, window_b) assert_that(cache.get_window("GJ1c", Vector2i(10, 20), 32)).is_equal(window_a) assert_that(cache.get_window("GJ1d", Vector2i(10, 20), 32)).is_equal(window_b) ## Overwriting the same key replaces the value (e.g. a re-fetch of an ## already-cached window from a server that somehow returns a different ## payload — should never happen under D-227, but the cache itself must not ## silently keep the stale one on an explicit put()). func test_put_overwrites_existing_key() -> void: var cache := AtlasWindowCache.new() cache.put("GJ1c", Vector2i(0, 0), 32, {"v": 1}) cache.put("GJ1c", Vector2i(0, 0), 32, {"v": 2}) assert_int(cache.size()).is_equal(1) assert_that(cache.get_window("GJ1c", Vector2i(0, 0), 32)).is_equal({"v": 2}) # ============================================================================= # LRU eviction # ============================================================================= func test_eviction_drops_least_recently_used_on_overflow() -> void: var cache := AtlasWindowCache.new(2) # max 2 entries cache.put("GJ1c", Vector2i(0, 0), 32, {"id": "a"}) cache.put("GJ1c", Vector2i(1, 0), 32, {"id": "b"}) cache.put("GJ1c", Vector2i(2, 0), 32, {"id": "c"}) # evicts (0,0) — oldest, untouched assert_int(cache.size()).is_equal(2) assert_bool(cache.has("GJ1c", Vector2i(0, 0), 32)).override_failure_message( "oldest entry should have been evicted" ).is_false() assert_bool(cache.has("GJ1c", Vector2i(1, 0), 32)).is_true() assert_bool(cache.has("GJ1c", Vector2i(2, 0), 32)).is_true() ## get_window() touches an entry (moves it to most-recently-used) — reading an ## entry must protect it from the NEXT eviction, otherwise "LRU" degrades to ## FIFO the moment anything reads from the cache (the common case: Esc-then- ## re-enter and pan-back are exactly "read a recently-cached window", §4). func test_get_touches_entry_and_protects_it_from_eviction() -> void: var cache := AtlasWindowCache.new(2) cache.put("GJ1c", Vector2i(0, 0), 32, {"id": "a"}) cache.put("GJ1c", Vector2i(1, 0), 32, {"id": "b"}) cache.get_window("GJ1c", Vector2i(0, 0), 32) # touch (0,0) — now most-recently-used cache.put("GJ1c", Vector2i(2, 0), 32, {"id": "c"}) # should evict (1,0), not (0,0) assert_bool(cache.has("GJ1c", Vector2i(0, 0), 32)).override_failure_message( "touched entry should survive eviction" ).is_true() assert_bool(cache.has("GJ1c", Vector2i(1, 0), 32)).override_failure_message( "untouched entry should be the one evicted" ).is_false() func test_max_entries_clamped_to_at_least_one() -> void: var cache := AtlasWindowCache.new(0) cache.put("GJ1c", Vector2i(0, 0), 32, {"id": "a"}) cache.put("GJ1c", Vector2i(1, 0), 32, {"id": "b"}) assert_int(cache.size()).is_equal(1) func test_clear_empties_the_cache() -> void: var cache := AtlasWindowCache.new() cache.put("GJ1c", Vector2i(0, 0), 32, {"id": "a"}) cache.clear() assert_int(cache.size()).is_equal(0) assert_bool(cache.has("GJ1c", Vector2i(0, 0), 32)).is_false() # ============================================================================= # granularity / min_wl_m (T-1150, zoom ladder design doc §3 aliasing risk) # ============================================================================= ## **MANDATORY aliasing regression (client half, T-1150):** a granularity-4 ## (quarter) key and a granularity-1 (district) key at the IDENTICAL ## (body_id, center, n) must be DISTINCT cache keys — this is what prevents a ## quarter-spacing request from silently reading (or overwriting) a ## district-spacing window's cache entry, and vice versa. func test_make_key_distinguishes_granularity_at_identical_body_center_n() -> void: var k_district := AtlasWindowCache.make_key( "GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY ) var k_quarter := AtlasWindowCache.make_key("GJ1c", Vector2i(10, 20), 32, 4) assert_str(k_district).is_not_equal(k_quarter) ## Same aliasing risk, the other new axis: two requests identical except for ## `min_wl_m` (the octave cutoff) must not collide either — different cutoffs ## are different derived payloads (T-1149/T-1150). func test_make_key_distinguishes_min_wl_m_at_identical_body_center_n_granularity() -> void: var k_uncut := AtlasWindowCache.make_key( "GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY, 0 ) var k_cut := AtlasWindowCache.make_key( "GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY, 512 ) assert_str(k_uncut).is_not_equal(k_cut) ## Omitting granularity/min_wl_m (every pre-T-1150 call site) must produce the ## SAME key as passing the explicit district/no-cutoff defaults — byte/string ## compatibility for existing callers, not just "doesn't crash". func test_omitted_granularity_and_min_wl_m_match_explicit_district_defaults() -> void: var k_omitted := AtlasWindowCache.make_key("GJ1c", Vector2i(10, 20), 32) var k_explicit := AtlasWindowCache.make_key( "GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY, 0 ) assert_str(k_omitted).is_equal(k_explicit) ## End-to-end through put()/get_window()/has() (not just make_key() in ## isolation): a quarter-granularity window and a district-granularity window ## at the identical (body, center, n) must both be independently retrievable, ## neither one clobbering or masking the other. func test_district_and_quarter_windows_coexist_at_identical_body_center_n() -> void: var cache := AtlasWindowCache.new() var district_window := {"granularity": AtlasWindowCache.DISTRICT_GRANULARITY, "id": "district"} var quarter_window := {"granularity": 4, "id": "quarter"} cache.put("GJ1c", Vector2i(10, 20), 32, district_window, AtlasWindowCache.DISTRICT_GRANULARITY) cache.put("GJ1c", Vector2i(10, 20), 32, quarter_window, 4) assert_int(cache.size()).is_equal(2) assert_that( cache.get_window("GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY) ).is_equal(district_window) assert_that(cache.get_window("GJ1c", Vector2i(10, 20), 32, 4)).is_equal(quarter_window) # ============================================================================= # granularity_v2 (T-1152/T-1153): the string-tag axis — the ONLY thing that # distinguishes Region from District/Quarter, since Region has no legal # legacy-int representation (WindowGranularity::legacy_u32() returns None for # Region — see the server's own doc). This is the SAME mandatory-aliasing # regression class as the granularity/min_wl_m tests above, extended to the # new axis. # ============================================================================= ## **MANDATORY aliasing regression (T-1152/T-1153):** a Region-rung key and a ## District-rung key at the IDENTICAL (body_id, center, n, legacy ## granularity, min_wl_m) must be DISTINCT cache keys — the legacy int slot ## alone (both "District" and default-omitted callers pass ## DISTRICT_GRANULARITY=1) cannot tell them apart; granularity_v2 is what ## does. func test_make_key_distinguishes_granularity_v2_region_from_district() -> void: var k_district := AtlasWindowCache.make_key( "GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY, 0, "District" ) var k_region := AtlasWindowCache.make_key( "GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY, 0, "Region" ) assert_str(k_district).is_not_equal(k_region) ## Omitting granularity_v2 (every pre-T-1152 call site) must produce the SAME ## key as passing the explicit "District" default — byte/string ## compatibility, same contract as the legacy granularity/min_wl_m defaults. func test_omitted_granularity_v2_matches_explicit_district_default() -> void: var k_omitted := AtlasWindowCache.make_key("GJ1c", Vector2i(10, 20), 32) var k_explicit := AtlasWindowCache.make_key( "GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY, 0, "District" ) assert_str(k_omitted).is_equal(k_explicit) ## End-to-end through put()/get_window(): a Region-rung window and a ## District-rung window at the identical (body, center, n) must both be ## independently retrievable — the exact scenario a full-zoom-out-then-back-in ## at the SAME (center, n) would hit if a player oscillates across the ## District/Region boundary. func test_region_and_district_windows_coexist_at_identical_body_center_n() -> void: var cache := AtlasWindowCache.new() var district_window := {"granularity_v2": "District", "id": "district"} var region_window := {"granularity_v2": "Region", "id": "region"} cache.put( "GJ1c", Vector2i(10, 20), 32, district_window, AtlasWindowCache.DISTRICT_GRANULARITY, 0, "District" ) cache.put( "GJ1c", Vector2i(10, 20), 32, region_window, AtlasWindowCache.DISTRICT_GRANULARITY, 0, "Region" ) assert_int(cache.size()).is_equal(2) assert_that( cache.get_window( "GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY, 0, "District" ) ).is_equal(district_window) assert_that( cache.get_window( "GJ1c", Vector2i(10, 20), 32, AtlasWindowCache.DISTRICT_GRANULARITY, 0, "Region" ) ).is_equal(region_window)