From 508639982deab02e9421afd828317d6c4881e397 Mon Sep 17 00:00:00 2001 From: Sinity Date: Mon, 27 Jul 2026 15:04:07 +0200 Subject: [PATCH] test(storage): stop lifecycle report tests drifting with new declarations Problem: three tests in test_index_fast_forward_lifecycle.py monkeypatched by appending a synthetic declaration onto the REAL module-level INDEX_DELTA_DECLARATIONS tuple, then asserted an exact literal invalid_versions/missing_versions result. index_delta_declaration_report() flags any declaration whose version exceeds the version under test, and accumulates missing_versions across the whole expected range -- so every schema version declared after these tests were written (38, 39, 41, 42, 43) silently widened the actual result past the hardcoded literal, or (for the missing_versions case) would have let any future undeclared gap leak into an unrelated assertion. What changed: all three tests now build an isolated declarations tuple (filtered to only the versions each test actually needs, e.g. <=36 or <=INDEX_SCHEMA_VERSION) before monkeypatching lifecycle.INDEX_DELTA_DECLARATIONS, instead of splicing onto the live tuple. This matches the isolation convention already used by other tests in this file (e.g. test_semantic_delta_routes_a_plan_away_from_sql_fast_forward, test_plan_orders_declarations_before_validating_contiguity), so the asserted literals are stable regardless of how many future schema versions get declared. Verification: - devtools test tests/unit/storage/test_index_fast_forward_lifecycle.py -> 9 passed - mypy --strict tests/unit/storage/test_index_fast_forward_lifecycle.py -> Success - ruff check / ruff format --check on the touched file -> clean - Future-proofing proof: temporarily added a throwaway v44 IndexDeltaDeclaration to the real module-level INDEX_DELTA_DECLARATIONS tuple in lifecycle.py and reran the suite. All 3 previously-fixed tests still passed unchanged (their isolated fixtures ignore versions beyond what each test needs). Only test_current_index_schema_has_a_complete_delta_declaration failed, which is expected/correct: a declaration beyond the current INDEX_SCHEMA_VERSION is itself an invalid state per the report's own semantics, not a test bug. Reverted the throwaway declaration afterward (lifecycle.py has zero diff). Ref polylogue-z2fj Co-Authored-By: Claude --- .../test_index_fast_forward_lifecycle.py | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/tests/unit/storage/test_index_fast_forward_lifecycle.py b/tests/unit/storage/test_index_fast_forward_lifecycle.py index 7f1e90ebf5..54d068a76d 100644 --- a/tests/unit/storage/test_index_fast_forward_lifecycle.py +++ b/tests/unit/storage/test_index_fast_forward_lifecycle.py @@ -102,10 +102,18 @@ def test_nonsemantic_delta_without_operations_is_rejected(monkeypatch: pytest.Mo version=37, classes=(DerivedDeltaClass.INDEX_ONLY,), ) + # Isolate to declarations at or below 36 (the versions this plan actually + # needs) rather than the live module tuple: the live tuple keeps growing + # past 37 as later schema versions get declared, and every one of those + # would otherwise leak into invalid_versions via the + # `declaration.version > current_version` check below. + base_declarations = tuple( + declaration for declaration in lifecycle.INDEX_DELTA_DECLARATIONS if declaration.version <= 36 + ) monkeypatch.setattr( lifecycle, "INDEX_DELTA_DECLARATIONS", - (*lifecycle.INDEX_DELTA_DECLARATIONS, empty_declaration), + (*base_declarations, empty_declaration), ) report = lifecycle.index_delta_declaration_report(37) @@ -128,10 +136,14 @@ def test_delta_without_a_declared_class_is_rejected(monkeypatch: pytest.MonkeyPa ), ), ) + # Same isolation rationale as test_nonsemantic_delta_without_operations_is_rejected above. + base_declarations = tuple( + declaration for declaration in lifecycle.INDEX_DELTA_DECLARATIONS if declaration.version <= 36 + ) monkeypatch.setattr( lifecycle, "INDEX_DELTA_DECLARATIONS", - (*lifecycle.INDEX_DELTA_DECLARATIONS, unclassified_declaration), + (*base_declarations, unclassified_declaration), ) assert lifecycle.index_delta_declaration_report(37)["invalid_versions"] == (37,) @@ -143,6 +155,15 @@ def test_schema_policy_rejects_an_index_bump_without_a_delta_declaration( monkeypatch: pytest.MonkeyPatch, ) -> None: """The real lab command must fail before an undeclared bump reaches CI.""" + # Isolate to declarations at or below the current (pre-bump) schema + # version: index_delta_declaration_report's missing_versions accumulates + # over the whole expected range, so any future currently-undeclared gap + # elsewhere in the live tuple would otherwise leak into this assertion + # alongside the version this test deliberately leaves undeclared. + complete_declarations = tuple( + declaration for declaration in lifecycle.INDEX_DELTA_DECLARATIONS if declaration.version <= INDEX_SCHEMA_VERSION + ) + monkeypatch.setattr(lifecycle, "INDEX_DELTA_DECLARATIONS", complete_declarations) monkeypatch.setattr(schema_policy, "INDEX_SCHEMA_VERSION", INDEX_SCHEMA_VERSION + 1) exit_code = schema_policy.main(["--json"])