Commit graph

4 commits

Author SHA1 Message Date
Yuneng Jiang
dc85812971
test(migrations): close the gaps the upgrade assertions left open
Three holes in the new suite, all of which let a test pass without proving
what its name claims:

- A migration recorded twice, once per replica, each with
  applied_steps_count = 1, slipped past both the step-count check and
  migration_names(), which collapses the history into a set. Reject
  duplicate migration_name rows outright.
- auth_traffic only asserted the failures it had seen by the time
  keep_serving hit its target. A request failing after that, or on the
  other replica while the test waited on one stream, was recorded and
  never read. Assert the recorded failures once the thread has joined.
- The rolling test warmed the baseline replica's virtual-key cache before
  the upgrade, and that cache holds for 60 seconds by default
  (UserAPIKeyCacheTTLEnum.in_memory_cache_ttl). The candidate migrates
  well inside that window, so the post-upgrade requests could be served
  from cache without ever repeating the whole-row token lookup that the
  stale prepared statement breaks. Drive the baseline replica with a key
  minted after the schema moved, which it has never seen and must resolve
  from the database.

Re-ran against v1.101.0 -> v1.102.0: 6 passed.
2026-09-21 13:15:46 -07:00
Yuneng Jiang
45d22dc5e1
test(migrations): cover the release-to-release upgrade path
The migration e2e harness only ever used one image: it seeded the database
with the candidate build and then applied synthetic migrations on top. That
proves the migration machinery (locking, crash recovery, legacy baselining,
pooling) but never executes the real schema of release N against the real
migrations of release N+1, which is the path operators actually run.

Adds a baseline image alongside the candidate, so a test can seed with a
published release and upgrade with the build under test.

Suites:

- test_upgrade.py: the candidate applies the pending release migrations,
  keys minted by the baseline release survive, and concurrent replicas
  upgrade a baseline database exactly once.
- test_rolling_upgrade.py: a baseline replica keeps serving virtual-key
  auth while the candidate migrates underneath it, and both releases serve
  and resolve each other's keys during the overlap. This is the reported
  failure: a new column on LiteLLM_VerificationToken invalidates prepared
  plans on pods still running the old release, which the proxy reads
  whole-row, and auth starts failing until those pods leave service.
- test_shaped_database.py: the upgrade completes and preserves rows on a
  populated spend log, rather than on the empty database every other
  migration test starts from.

Every upgrade assertion is gated on the candidate having actually applied
migrations the baseline had not, so a stale pin fails loudly instead of
passing on an empty delta.

CI adds two jobs to the migration_startup workflow. The baseline defaults
to a committed release pin and is overridable per pipeline, matching how
migration_candidate_image already works; only the upgrade jobs pull it.

Verified against a real v1.101.0 -> v1.102.0 upgrade: 6 passed, with the
baseline seeding 165 migrations and the candidate applying the 6 that
landed between the two releases.
2026-09-21 12:50:58 -07:00
Yuneng Jiang
a37f0b4f54
test: isolate migration CI selection and exercise resolver boundaries 2026-09-12 18:49:58 -07:00
Yuneng Jiang
94032014df
fix(proxy): coordinate v2 migration startup and add container regression CI 2026-09-12 18:24:59 -07:00