test: fill coverage completeness gaps (seed E2E, seed_custom, Django mode)#87
Merged
Conversation
…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 Report❌ Patch coverage is
📢 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).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
seed()now has an E2E test that verifies seeded data survives a safe rollback viaassert_data_intact()seed_custom()has full unit tests: insert, verify, delete detection, warn on failure, auto-PK retrievalseed()crash (caused byself._runnerbeingNone) is regression-tested viaMRTFixturein Django modemrt driftCLI edge cases (missing alembic.ini, no-drift, drift detected) are coveredassert_schema_matches()happy path and failure paths coveredtest_drift_missing_alembic_ini_exits_1was failing because metadata load error fires before the alembic.ini checkTest plan