Files
jpmschweitzerandClaude Fable 5 f81622bbf0 test(simulation): Phase-4 hardening — deferred #953/#963 review gaps (T-964)
The verified-still-open coverage list: per-type attractor reachability
fixtures (LakeShore via enclosed depression, PassEntrance via crafted
saddle, PlainCenter via flat terrain, RiverCrossing via confluence) plus
thin_by_spacing behavior (collision, strict-< boundary, equirectangular
column wrap); heightmap 8-bit decode, sea_level passthrough, downsample
identity and zero-target early-return; drainage area_pct bit-for-bit
determinism plus the isolated-basin-fallback divergence comment (Tyre
N1, citing the pre-#953 behavior it deliberately departs from); the
layer1 mountain-branch pairing test (investigated first — the cascade
test supplies a mountain pool but only ever asserted river counts, a
genuine gap); an importer idempotency test covering atlas_city_names
AND atlas_feature_names plus the Sol exemption, wired into
make test-tooling; and the oasis_water dilation radius scaled by
GRID_W/512 (Tyre N2, hash-stable). One stale item dropped per the
refinement trim (test_sim_determinism wiring — already done).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 18:58:53 +02:00

158 lines
6.4 KiB
Python

#!/usr/bin/env python3
"""
Idempotency tests for economy_import.atlas's names-only pool populators
(T-964 — Phase-4 test hardening).
`populate_atlas_city_names` and `populate_atlas_feature_names` both clear
their target table before reinserting (see each function's own docstring:
"there is no UNIQUE(body_id, name[, feature_type]) — without the clear a
re-run would accumulate duplicates"). This test proves that contract holds in
practice: two back-to-back runs against the same DB must yield an IDENTICAL
row count, not a doubled one, and Sol ('GJ 0') must remain permanently
exempt (D-223) on both runs.
Runs against a scratch COPY of the committed `server/data/systems.db` (real
schema + real `bodies`/FK data — not a hand-rolled in-memory schema, which
would drift from the real FK web this populator depends on). Wiki content
(`wiki/star-systems/*/bodies/*/markers.json`) is read directly from the repo
— read-only input, safe to reuse as-is; only the DB connection is scratch.
Deliberately calls the two populator functions directly rather than the full
`import_economics.py` CLI: the CLI's first step shells out to the Rust
`generate_brands` binary and overwrites `generated_brands.toml` on disk
(`brands.regenerate_brands`), a real side effect on shared repo content that
has nothing to do with atlas name-pool idempotency and would make this test
depend on a Rust build.
Stdlib only (unittest) — run directly or via `make test-tooling`:
python3 tooling/economy-db/test_atlas_idempotency.py
"""
import shutil
import sqlite3
import sys
import tempfile
import unittest
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from economy_import import atlas # noqa: E402
from economy_import.paths import DB_PATH # noqa: E402
class AtlasNamePoolIdempotencyTests(unittest.TestCase):
"""Two runs on a scratch DB copy must yield stable, non-doubled counts."""
@classmethod
def setUpClass(cls):
if not DB_PATH.exists():
raise unittest.SkipTest(f"committed systems.db not found at {DB_PATH}")
def setUp(self):
self._tmp = tempfile.TemporaryDirectory()
scratch_path = Path(self._tmp.name) / "systems_scratch.db"
shutil.copyfile(DB_PATH, scratch_path)
self.conn = sqlite3.connect(str(scratch_path))
self.conn.execute("PRAGMA foreign_keys=ON")
def tearDown(self):
self.conn.close()
self._tmp.cleanup()
def test_atlas_city_names_count_stable_across_two_runs(self):
first = atlas.populate_atlas_city_names(self.conn, dry_run=False)
first_count = self.conn.execute(
"SELECT COUNT(*) FROM atlas_city_names"
).fetchone()[0]
self.assertEqual(
first, first_count, "populator return value must match the rows it wrote"
)
second = atlas.populate_atlas_city_names(self.conn, dry_run=False)
second_count = self.conn.execute(
"SELECT COUNT(*) FROM atlas_city_names"
).fetchone()[0]
self.assertEqual(
first_count,
second_count,
"a second run must yield an IDENTICAL atlas_city_names count, not "
"a doubled one — the clear-before-reinsert contract must hold",
)
self.assertEqual(
first, second, "the populator's own return value must also be stable"
)
self.assertGreater(
first_count, 0, "fixture sanity: the committed wiki content must yield rows"
)
def test_atlas_feature_names_count_stable_across_two_runs(self):
# T-1169: atlas_feature_names landed alongside atlas_city_names but
# is a separate table/populator — must be checked independently, not
# assumed to share the city-name populator's idempotency by proximity.
first = atlas.populate_atlas_feature_names(self.conn, dry_run=False)
first_count = self.conn.execute(
"SELECT COUNT(*) FROM atlas_feature_names"
).fetchone()[0]
self.assertEqual(first, first_count)
second = atlas.populate_atlas_feature_names(self.conn, dry_run=False)
second_count = self.conn.execute(
"SELECT COUNT(*) FROM atlas_feature_names"
).fetchone()[0]
self.assertEqual(
first_count,
second_count,
"a second run must yield an IDENTICAL atlas_feature_names count, not "
"a doubled one — the clear-before-reinsert contract must hold",
)
self.assertEqual(first, second)
self.assertGreater(
first_count, 0, "fixture sanity: the committed wiki content must yield rows"
)
def test_sol_system_gj0_gets_zero_rows_in_both_pools_across_two_runs(self):
# D-223 permanent exemption: Sol ('GJ 0') keeps authored,
# geometry-bearing markers.json via sol_import.py — never the names
# pool. Must hold on the FIRST run (not just "never accumulates") and
# remain zero on the second.
for run in (1, 2):
atlas.populate_atlas_city_names(self.conn, dry_run=False)
atlas.populate_atlas_feature_names(self.conn, dry_run=False)
sol_cities = self.conn.execute(
"""SELECT COUNT(*) FROM atlas_city_names
WHERE body_id IN (SELECT body_id FROM bodies WHERE system_id = 'GJ 0')"""
).fetchone()[0]
sol_features = self.conn.execute(
"""SELECT COUNT(*) FROM atlas_feature_names
WHERE body_id IN (SELECT body_id FROM bodies WHERE system_id = 'GJ 0')"""
).fetchone()[0]
self.assertEqual(
sol_cities, 0, f"run {run}: Sol (GJ 0) must have zero atlas_city_names rows"
)
self.assertEqual(
sol_features,
0,
f"run {run}: Sol (GJ 0) must have zero atlas_feature_names rows",
)
# Fixture sanity: GJ 0 must actually have bodies in this DB, or the
# zero-rows assertions above would be vacuously true.
gj0_body_count = self.conn.execute(
"SELECT COUNT(*) FROM bodies WHERE system_id = 'GJ 0'"
).fetchone()[0]
self.assertGreater(
gj0_body_count,
0,
"fixture sanity: GJ 0 (Sol) must have bodies in the committed DB, or "
"the exemption checks above are vacuous",
)
if __name__ == "__main__":
unittest.main(verbosity=2)