test(migrator): validate migrator DDL against the latest exported AccountDatabase schema, not a hardcoded version #477

Closed
opened 2026-07-10 04:49:41 +00:00 by JMR-dev · 0 comments
JMR-dev commented 2026-07-10 04:49:41 +00:00 (Migrated from github.com)

Problem

AccountDataMigratorTest.migratorDdlMatchesExportedAccountDatabaseSchema — the guard that keeps the migrator's hardcoded AccountDataMigrator.CREATE_TABLE_SQL byte-for-byte in sync with the exported Room schema — opens a hardcoded schema-version asset:

.open("org.libremail.data.local.AccountDatabase/2.json")

So every AccountDatabase schema bump must also remember to bump this filename. If it isn't bumped, the guard silently validates CREATE_TABLE_SQL against a stale schema version and passes while the entity has already moved on.

That is exactly how PR #472's drift slipped through: the entity gained accounts.authError (v3) but the migrator DDL still described v2. The guard kept comparing v2-DDL against v2-schema (green), while at runtime the migrator created a v2 accounts table that Room — now expecting v3 — rejected with IllegalStateException: Pre-packaged database has an invalid schema: accounts(...). It only surfaced as all E2E jobs red on #472, never in the fast gate.

Fix

Make the guard resolve the schema dynamically instead of hardcoding a version:

  • List the org.libremail.data.local.AccountDatabase androidTest asset directory (AssetManager.list(...)), keep the *.json entries with all-digit stems, and open the highest-numbered one (the current schema).
  • Assert at least one schema file was found, so a mis-wired/relocated schemas/ asset dir (or a renamed DB class) fails loudly rather than NPE-ing or silently passing.

This removes the "remember to bump the filename" footgun entirely: the next AccountDatabase version bump is validated automatically.

Scope

Test-only change to app/src/androidTest/kotlin/org/libremail/data/local/AccountDataMigratorTest.kt. No product-code change. The schemas/ dir is already wired as an androidTest asset source (app/build.gradle.kts: sourceSets.getByName("androidTest").assets.srcDir("$projectDir/schemas")), so the directory is listable at runtime.

Follow-up to #472 (which fixed the immediate drift by pointing the guard at 3.json).

## Problem `AccountDataMigratorTest.migratorDdlMatchesExportedAccountDatabaseSchema` — the guard that keeps the migrator's hardcoded `AccountDataMigrator.CREATE_TABLE_SQL` byte-for-byte in sync with the exported Room schema — opens a **hardcoded** schema-version asset: ```kotlin .open("org.libremail.data.local.AccountDatabase/2.json") ``` So every `AccountDatabase` schema bump must *also* remember to bump this filename. If it isn't bumped, the guard silently validates `CREATE_TABLE_SQL` against a **stale** schema version and passes while the entity has already moved on. That is exactly how PR #472's drift slipped through: the entity gained `accounts.authError` (v3) but the migrator DDL still described v2. The guard kept comparing v2-DDL against v2-schema (green), while at runtime the migrator created a v2 `accounts` table that Room — now expecting v3 — rejected with `IllegalStateException: Pre-packaged database has an invalid schema: accounts(...)`. It only surfaced as **all E2E jobs red** on #472, never in the fast gate. ## Fix Make the guard resolve the schema dynamically instead of hardcoding a version: - List the `org.libremail.data.local.AccountDatabase` androidTest asset directory (`AssetManager.list(...)`), keep the `*.json` entries with all-digit stems, and open the **highest-numbered** one (the current schema). - Assert at least one schema file was found, so a mis-wired/relocated `schemas/` asset dir (or a renamed DB class) fails **loudly** rather than NPE-ing or silently passing. This removes the "remember to bump the filename" footgun entirely: the next `AccountDatabase` version bump is validated automatically. ## Scope Test-only change to `app/src/androidTest/kotlin/org/libremail/data/local/AccountDataMigratorTest.kt`. No product-code change. The `schemas/` dir is already wired as an androidTest asset source (`app/build.gradle.kts`: `sourceSets.getByName("androidTest").assets.srcDir("$projectDir/schemas")`), so the directory is listable at runtime. Follow-up to #472 (which fixed the immediate drift by pointing the guard at `3.json`).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: JMR-dev/LibreMail#477