Skip to content

SCRUM-229 — Patch publish/rollback integration test

Plan ref: PAT-D2 (docs/11-admin-plane-plan.md).

What exists

services/patch/integration/publish_rollback_test.go (build tag integration, so go test ./... never runs it; skips without PATCH_TEST_DATABASE_URL):

  1. builds the real config and patch binaries and runs them as processes on free loopback ports, sharing one DB and one blob directory; an in-test Ed25519 JWKS stands in for admin-auth;
  2. takes the config_test:dev advisory lock Config's tests use and restores the dev head afterwards;
  3. through Config's HTTP API only: new namespace, schema, two versions;
  4. publish v1 → Patch's dev manifest changes within 5 s, names the namespace at v1; If-None-Match → 304 with an empty body;
  5. publish v2 → manifest shows v2;
  6. rollback → Patch serves a manifest byte-identical to the v1 one, same ETag;
  7. the namespace blob is fetchable from /patch/v1/blob/{sha256} and hashes right.

CI: ci/services/otomo-patch/unit_test.sh integration runs services/patch/integration/run.sh in the compose go container.

Bug fixed on the way: patch serve ignored PATCH_POLL_INTERVAL (a hard-coded 60 s constant was passed to the watcher although the config parsed the variable).

How to verify

cd services/patch
gofmt -l . && go vet ./... && go vet -tags integration ./integration/...
go test -race -count=1 ./...
PATCH_TEST_DATABASE_URL=postgres://auth_rw:pw@127.0.0.1:5433/config_test?sslmode=disable \
  bash integration/run.sh

Results at time of writing

  • Unit suite (6 packages) and the integration test (≈4 s): pass.

How it was built

DeepSeek run scoped (Landlock) to services/patch (177 s, ~29k output tokens, reasoning effort low); it found the poll-interval bug. Claude review: checked the lock/restore and bounded waits, ran it, wired the CI level.