fix(readiness): bound DB ping and unset Infisical in test-integration (PMS-685) #466
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/PMS-685-readiness-timeout"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Make the
/api/v1/readyreadiness probe robust and its integration test deterministic: bound the DB ping with a forgiving 3-second timeout, and runjust test-integrationwithINFISICAL_BASE_URLunset so the local harness honors the test's documented "Infisical unconfigured" precondition and faithfully mirrors CI.Why
The spec attributed the intermittent readiness 503 to a hard 1s DB-ping timeout, but there is no DB-ping timeout in the code; the DB ping was unbounded (only the pool's 30s acquire timeout applied). The actual cause of the failing
ready_returns_ok_when_db_reachable_and_infisical_unconfiguredtest is environmental: the dev composeserverservice setsINFISICAL_BASE_URL=http://infisical:8080, but Infisical is an opt-in profile that is not running during tests, soprobe_infisical()times out after ~1s (the observed ~1002ms latency) and/readyreturns 503 withinfisical!= "skipped". CI (integration.yml) runs the suite directly on the runner with noINFISICAL_BASE_URL, so the probe is skipped and the test passes there; only the local dev-container run diverged from CI. Separately, an unbounded readiness DB ping is genuinely the wrong shape for a probe: a hung database would let/readyblock up to 30s rather than returning a prompt 503, so a bounded-but-forgiving 3s timeout is a real robustness improvement in line with the spec's proposed approach.Changes
src/api/router.rs: wrap the readiness DB ping intokio::time::timeout(Duration::from_secs(3), db.health_check()); on elapse, synthesize anAppError::Databaseso the existing 503 / JSON-breakdown /Cache-Control: no-storepath is unchanged. The 3s bound is documented inline on both theready_checkdoc comment and the timeout site.justfile:test-integrationnow runscargo testviaenv -u INFISICAL_BASE_URL, unsetting the dev-container-only var so the suite matches CI and honors readiness.rs's documented precondition. This touches only the test harness, not the production probe: a configured-but-unreachable Infisical still 503s/readyby design.Tests
just pre-commit(mirrors CI check.yml: fmt, clippy --all-targets -D warnings, check --all-targets, unit + doc tests): PASSED, exit 0. Unit tests 293 passed / 0 failed; doc tests 2 passed / 0 failed / 3 ignored.tests/readiness.rsvia the Postgres-backed docker harness withINFISICAL_BASE_URLunset (as the updatedtest-integrationrecipe now does), run 2x at--test-threads=4and 1x at--test-threads=1: all three runs PASSED, 4 passed / 0 failed each, exit 0. Coversready_returns_ok_when_db_reachable_and_infisical_unconfigured(now 200),ready_returns_503_when_db_pool_closed(still 503 when the DB is truly down), plus the cache-control and liveness cases._sqlx_test_*databases owned bypostgreswhile the dev harness connects asmokosh_migrator) had to be cleared first, by reassigning their ownership tomokosh_migratorso sqlx's#[sqlx::test]cleanup could manage them. CI is unaffected (it starts a fresh Postgres and connects as the superuser role).Closing as superseded by #469, which was merged as
6dce6aband ships PMS-685 onmain.Both PRs implement the same issue. Where they overlap, #469's approach is the one that landed:
ready_checkwithtokio::time::timeout(Duration::from_secs(3), db.health_check()). #469 extracts the same 3s bound into aREADY_DB_PING_TIMEOUTconst and abounded_db_ping()helper that takes the ping future rather than the pool, which makes the timeout path unit-testable on tokio's paused clock. It ships three such tests (slow_but_answering_db_ping_is_ok,hung_db_ping_times_out,failing_db_ping_surfaces_the_error) that this PR has no equivalent for.INFISICAL_BASE_URLin thejustfiletest-integrationrecipe. #469 fixes it insidetests/readiness.rswith anunconfigure_infisical()helper each/readycase calls, so the suite's stated precondition holds no matter what the surrounding shell or harness exports, not only under that one recipe.INFISICAL_BASE_URLis read by exactly one test file, so the recipe-level unset adds nothing on top.This branch also never merged past
43587d2(Release v0.9.0), so it predates #469 and now conflicts withmainonsrc/api/router.rs. Rebasing it would resolve to an empty diff.The diagnosis in this PR's description was correct and matches what #469 concluded independently: there was no 1s DB-ping timeout in the code, and the observed ~1002ms latency was the Infisical probe against a host that the opt-in
infisicalcompose profile never started.One thing neither PR addressed, now filed separately as PMS-707:
compose.dev.ymlsetsINFISICAL_BASE_URLunconditionally on theserverservice whileinfisicalis profile-gated, so a plainjust devstack reports/api/v1/ready503 permanently. That is a dev-stack config defect rather than a probe defect, so it is out of scope for PMS-685.The
fix/PMS-685-readiness-timeoutbranch is being deleted alongside this close.Pull request closed