Skip to content

test: fill coverage completeness gaps (seed E2E, seed_custom, Django mode)#87

Merged
croc100 merged 7 commits into
mainfrom
test/coverage-completeness-gaps
Jun 13, 2026
Merged

test: fill coverage completeness gaps (seed E2E, seed_custom, Django mode)#87
croc100 merged 7 commits into
mainfrom
test/coverage-completeness-gaps

Conversation

@croc100

@croc100 croc100 commented Jun 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • seed() now has an E2E test that verifies seeded data survives a safe rollback via assert_data_intact()
  • seed_custom() has full unit tests: insert, verify, delete detection, warn on failure, auto-PK retrieval
  • Django mode seed() crash (caused by self._runner being None) is regression-tested via MRTFixture in Django mode
  • mrt drift CLI edge cases (missing alembic.ini, no-drift, drift detected) are covered
  • assert_schema_matches() happy path and failure paths covered
  • One pre-existing test fixed: test_drift_missing_alembic_ini_exits_1 was failing because metadata load error fires before the alembic.ini check

Test plan

  • All 493 tests pass, 17 skipped
  • Coverage: 81% → CI will report exact codecov score

croc100 added 6 commits June 11, 2026 08:28
- seed() used self._runner.engine which is None in Django mode;
  switch to self._seeder.engine which is always set
- replace bare except/pass in SmartSeeder.seed_table() with
  warnings.warn so failures are visible instead of swallowed silently

Closes #83, #84
…t custom-seed failures

Three root causes fixed:

1. seed() was calling seed_table() (auto-generates rows) instead of
   inserting the caller-supplied rows. Add SmartSeeder.seed_custom()
   and wire seed() through it so the rows parameter is actually used.

2. SmartSeeder.seed_table() used a deterministic hash for generated
   values, causing UNIQUE constraint violations when check_all() seeded
   the same table across consecutive revision checks (prior rows survive
   downgrade and remain in the DB). Add a per-instance random offset so
   each SmartSeeder produces distinct values.

3. Custom-seed insertion in verifier._build_seeder() silently swallowed
   all exceptions. Replace bare except/pass with warnings.warn so
   failures are visible.
…mn type

String columns used a fixed-width row_index format that truncates to the
same prefix when the instance offset is large (e.g. offset=500000 →
"mrt_title_500000"[:10] == "mrt_title_" for all rows). Switch to
uuid4().hex[:limit] which is unique regardless of column length.

Datetime/date/time types had a narrow modulo range (28 days, 24 hours)
causing cross-instance collisions. Spread values over a 10-year window
using the full hash seed instead.
Three new static analysis checks for lock-heavy PostgreSQL operations:

MRT211 — create_foreign_key() without postgresql_not_valid=True
  Acquires ShareRowExclusiveLock and scans the referencing table.
  Safe path: add with NOT VALID, then VALIDATE CONSTRAINT separately.

MRT212 — create_check_constraint() without postgresql_not_valid=True
  Full table scan under AccessShareLock. Same two-step approach applies.

MRT213 — alter_column(nullable=False) on an existing column
  SET NOT NULL triggers a full table scan under AccessExclusiveLock.
  Safe path on PG 12+: validated CHECK constraint first, then SET NOT NULL.

Closes #85
MRT211 (FK without NOT VALID) and MRT212 (CHECK without NOT VALID) warn
about PostgreSQL lock duration — a performance/availability concern, not
a data survival or rollback safety concern. That's django-migration-linter
territory.

MRT213 (SET NOT NULL on existing column) stays: it's about existing NULL
data causing migration failure, consistent with MRT401/MRT403.
@codecov-commenter

codecov-commenter commented Jun 11, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 94.44444% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pytest_mrt/core/seeder.py 91.66% 2 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

A failed custom-seed INSERT was caught and warned, but the row had
already been appended to the seeder's tracked rows. verify() then
reported it as 'lost after rollback', blaming the migration for data
the seed never inserted. Track rows only after a successful insert.

Also applies ruff format to verifier.py (fixes CI lint failure).
@croc100
croc100 merged commit 0aa3e89 into main Jun 13, 2026
15 checks passed
@croc100
croc100 deleted the test/coverage-completeness-gaps branch June 13, 2026 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants