mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-21 11:01:14 +00:00
[AZ-357] AC-2 follow-up: populated-duplicates migration test
Closes the partial-coverage gap from batch 10. Adds two integration tests in MigrationTests.cs: - DedupeSqlCollapsesDuplicatesByLatestUpdatedAt_AZ357_AC2: seeds a session-scoped temp table with intentional 4-column duplicates (varying updated_at and id), runs the exact dedupe SQL from migration 012, asserts only the expected rows survive (newest updated_at wins; ties broken by largest id). - NewUniqueConstraintExistsOnFourColumns_AZ357_AC2: queries pg_indexes against the live DB to assert idx_tiles_unique_location is a unique 4-column btree and excludes the version column. Also wires Npgsql 9.0.2 into the integration-tests project, exposes DB_CONNECTION_STRING + postgres healthcheck dependency to the test container in docker-compose.tests.yml, and registers the new tests in both smoke and full suites. Implementation note: first attempt used CREATE TEMP TABLE ON COMMIT DROP, which dropped the table immediately because each Npgsql command runs in its own implicit transaction. Removed ON COMMIT DROP — session-scoped temps are dropped on connection close, which is what we want. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -57,21 +57,24 @@ Single-task batch — DB migration is higher risk and benefits from dedicated re
|
||||
| AC | Evidence |
|
||||
|----|----------|
|
||||
| **AC-1** Cache survives year boundary | Unit test `TreatsCachedTileFromPriorYearAsFresh_AZ357_AC1`: prior-year `Version` row reused; `InsertAsync` not called. |
|
||||
| **AC-2** Migration runs cleanly on populated tile data | (Partial) Migration applied successfully against an integration test DB during container startup. Dedupe SQL is correct by construction (`ROW_NUMBER OVER PARTITION BY ... ORDER BY updated_at DESC, id DESC`). **Not explicitly tested with pre-staged duplicates** — see "Known coverage gap" below. Consistent with how migration 004 (which used the same pattern) was originally verified. |
|
||||
| **AC-2** Migration runs cleanly on populated tile data | New integration tests in `MigrationTests.cs`: `DedupeSqlCollapsesDuplicatesByLatestUpdatedAt_AZ357_AC2` exercises the dedupe DELETE against a temp table with intentional 4-column duplicates (3-way duplicate, updated_at-tie broken by id, plus a unique row); `NewUniqueConstraintExistsOnFourColumns_AZ357_AC2` queries `pg_indexes` to confirm the recreated index has the new shape and excludes `version`. Added in a follow-up commit before batch 11; see "AC-2 follow-up" below. |
|
||||
| **AC-3** Upsert behaves on the new key | New `InsertAsync.ON CONFLICT (latitude, longitude, tile_zoom, tile_size_meters)` clause; integration suite re-runs identical (lat,lon,zoom,size) inserts during the route test (690 tiles processed without unique-violation errors). |
|
||||
| **AC-4** 37 unit + 5 smoke tests stay green | 69 unit + 5 smoke + 3 stub-contract green. |
|
||||
|
||||
### Known coverage gap (AC-2, partial)
|
||||
### AC-2 follow-up (closed)
|
||||
|
||||
The migration's dedupe DELETE has not been exercised against a pre-populated table containing rows that violate the new 4-column constraint. Reasons not addressed in this batch:
|
||||
The original batch left AC-2 partially covered — the migration ran against an empty DB volume on integration startup. Per user direction (option B at batch 10 review pause), a populated-duplicates test was added in a follow-up commit before batch 11:
|
||||
|
||||
- The integration test stack starts with a fresh DB volume, so the migration runs against an empty table.
|
||||
- Inserting test duplicates *after* migration startup is impossible (the new constraint blocks it).
|
||||
- Adding a pre-init SQL injection (docker-compose `command:` or an init script in the postgres image) is out of scope for a 5 SP refactor and would touch CI tooling.
|
||||
- **NEW** `SatelliteProvider.IntegrationTests/MigrationTests.cs` with two tests:
|
||||
1. `DedupeSqlCollapsesDuplicatesByLatestUpdatedAt_AZ357_AC2` — creates a session-scoped `tiles_dedupe_test` temp table, seeds it with intentional 4-column duplicates that have varying `updated_at` and `id`, runs the exact dedupe SQL from migration 012, and asserts only the expected rows survive (newest `updated_at` wins; ties broken by largest `id`; unique rows preserved).
|
||||
2. `NewUniqueConstraintExistsOnFourColumns_AZ357_AC2` — queries `pg_indexes` against the live DB to assert `idx_tiles_unique_location` exists as a unique 4-column btree index and does **not** include the `version` column. Catches the case where a developer skips the migration or rolls back the index recreation.
|
||||
- **NEW dependency** `Npgsql 9.0.2` in `SatelliteProvider.IntegrationTests.csproj` for direct DB connectivity (matches the version used elsewhere in the suite).
|
||||
- **MODIFIED** `docker-compose.tests.yml` — added `DB_CONNECTION_STRING` env var and `postgres: condition: service_healthy` to `integration-tests.depends_on` so the test container can connect directly to the same DB the API uses.
|
||||
- **MODIFIED** `SatelliteProvider.IntegrationTests/Program.cs` — wired `MigrationTests.RunAll()` into both smoke and full suites.
|
||||
|
||||
**Mitigation**: the SQL pattern (`ROW_NUMBER OVER PARTITION BY ... ORDER BY updated_at DESC, id DESC`) is well-understood and matches the established project precedent (migration 004 used a similar `DELETE...USING` pattern with no test). Production rollout should follow the spec's risk mitigation: capture pre-migration row counts, dry-run against a populated copy.
|
||||
**Implementation note (debugging trace)**: first attempt used `CREATE TEMP TABLE ... ON COMMIT DROP`. Each Npgsql command runs in its own implicit transaction by default, so the table was dropped immediately after the `CREATE` committed. Removed the `ON COMMIT DROP` clause — temp tables are automatically dropped when the connection closes (session-scoped), which is exactly what we want.
|
||||
|
||||
This gap is recorded in `_docs/_process_leftovers/` if user wants follow-up tracking; otherwise treat as accepted risk consistent with prior migrations.
|
||||
**Result**: AC-2 now fully covered. Tests run on every integration suite invocation (smoke + full), green.
|
||||
|
||||
## Behavior preservation
|
||||
|
||||
|
||||
Reference in New Issue
Block a user