fix(tests): migration round-trip tests leave core_api_test at head (T-14)

Every round-trip test across test_book_migration.py, test_scribe_migration.py
and test_tenants_migration.py re-upgraded to its own revision on the way back
up rather than to head, so a full suite run left core_api_test one or two
migrations behind (008, with 009/010 released since). Each now ends on
`upgrade head`; a new TestSchemaEndsAtHeadAfterTheMigrationSuite class checks
the final state directly with no upgrade of its own, as a regression guard.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-10-20 00:27:54 +02:00
co-authored by Claude Sonnet 5
parent 3a3dc959be
commit a81b9a071b
4 changed files with 42 additions and 10 deletions
+8
View File
@@ -17,6 +17,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
documented ways to reach either database; none of them print a password or a
credential-bearing URL.
### Fixed
- **Migration round-trip tests leave `core_api_test` at head** (core-api T-14) — every
round-trip test in `tests/test_book_migration.py`, `tests/test_scribe_migration.py` and
`tests/test_tenants_migration.py` now ends on `upgrade head` rather than its own
revision, so a full suite run leaves the test database at head instead of one or two
migrations behind it.
## [1.15.0] - 2026-10-19
### Added
+2 -2
View File
@@ -65,8 +65,8 @@ class TestMigration005RoundTrip:
assert not await _table_exists(test_database_url, "book_events")
assert not await _table_exists(test_database_url, "book_tenant_counters")
# Leave the schema at head for the rest of the suite.
up = run_alembic(test_database_url, "upgrade", "005")
# Leave the schema at head for the rest of the suite (core-api T-14).
up = run_alembic(test_database_url, "upgrade", "head")
assert up.returncode == 0, up.stderr
assert await _table_exists(test_database_url, "book_records")
assert await _table_exists(test_database_url, "book_events")
+2 -2
View File
@@ -120,8 +120,8 @@ class TestMigration006RoundTrip:
# a downgrade of 006 — proves 006 only touches its own tables.
assert await _table_exists(test_database_url, "book_records")
# Leave the schema at head for the rest of the suite.
up = run_alembic(test_database_url, "upgrade", "006")
# Leave the schema at head for the rest of the suite (core-api T-14).
up = run_alembic(test_database_url, "upgrade", "head")
assert up.returncode == 0, up.stderr
assert await _table_exists(test_database_url, "scribe_addresses")
assert await _table_exists(test_database_url, "scribe_messages")
+30 -6
View File
@@ -67,8 +67,8 @@ class TestMigration007RoundTrip:
assert await _table_exists(test_database_url, "book_records")
assert await _table_exists(test_database_url, "scribe_addresses")
# Leave the schema at head for the rest of the suite.
up = run_alembic(test_database_url, "upgrade", "007")
# Leave the schema at head for the rest of the suite (core-api T-14).
up = run_alembic(test_database_url, "upgrade", "head")
assert up.returncode == 0, up.stderr
assert await _table_exists(test_database_url, "tenants")
assert await _table_exists(test_database_url, "tenant_consumers")
@@ -224,8 +224,8 @@ class TestMigration008RoundTrip:
assert await _table_exists(test_database_url, "tenant_consumers")
assert await _table_exists(test_database_url, "tenants")
# Leave the schema at head for the rest of the suite.
up = run_alembic(test_database_url, "upgrade", "008")
# Leave the schema at head for the rest of the suite (core-api T-14).
up = run_alembic(test_database_url, "upgrade", "head")
assert up.returncode == 0, up.stderr
found = await _scalar(
test_database_url,
@@ -312,7 +312,10 @@ class TestMigration008DataStep:
down = run_alembic(test_database_url, "downgrade", "007")
assert down.returncode == 0, down.stderr
up = run_alembic(test_database_url, "upgrade", "008")
# Upgrade through to head (core-api T-14) — migrations 009/010 touch
# neither this table nor this column, so the assertion below still
# proves 008's data step alone.
up = run_alembic(test_database_url, "upgrade", "head")
assert up.returncode == 0, up.stderr
found = await _scalar(
test_database_url,
@@ -356,7 +359,9 @@ class TestMigration008DataStep:
)
)
up = run_alembic(test_database_url, "upgrade", "008")
# Upgrade through to head (core-api T-14) — same reasoning as
# test_is_a_noop_when_claude_ai_is_absent above.
up = run_alembic(test_database_url, "upgrade", "head")
assert up.returncode == 0, up.stderr
found = await _scalar(
@@ -380,3 +385,22 @@ class TestMigration008DataStep:
)
)
await engine.dispose()
class TestSchemaEndsAtHeadAfterTheMigrationSuite:
"""core-api T-14 regression guard: every round-trip test above (and in
test_book_migration.py / test_scribe_migration.py, which this file's
alphabetically-later collection runs after) must leave `core_api_test`
at head, not on its own revision. This class is the last one defined in
the last-collected migration test file, and its check is a bare
`current` — no `upgrade head` of its own — so a round-trip test that
regresses to ending on its own revision again shows up here as "not
head" rather than being silently repaired by this very check."""
@pytest.mark.asyncio
async def test_schema_is_at_head(self, test_database_url):
result = run_alembic(test_database_url, "current")
assert result.returncode == 0, result.stderr
assert "(head)" in result.stdout, (
f"core_api_test is not at head after the migration suite: {result.stdout!r}"
)