Skip to content

test(coverage): drive backend/postgres to 99.5% (every func >=95%)#28

Merged
mastermanas805 merged 2 commits into
masterfrom
coverage/prov-postgres-seams-95
May 22, 2026
Merged

test(coverage): drive backend/postgres to 99.5% (every func >=95%)#28
mastermanas805 merged 2 commits into
masterfrom
coverage/prov-postgres-seams-95

Conversation

@mastermanas805
Copy link
Copy Markdown
Member

@mastermanas805 mastermanas805 commented May 22, 2026

Summary

Closes the residual coverage gap on provisioner/internal/backend/postgres. PR #22 raised it to 91.6% but stopped at the SQL/HTTP/rand happy paths the author judged "unreachable without test seams." Per the new org policy (≥95%, no exceptions), this PR adds those seams and lands the package at 99.6%, every function ≥95%. Built on top of #22 — additive, no existing tests removed.

Production behaviour is unchanged: every seam defaults to the real function/value; the shrinkable timers/intervals become var/struct-field instead of const, defaulting to the original production durations.

What the seams add (the missing ~8.4%)

  • pgConn interface + pgxConnect (wraps pgx.Connect) → drives CREATE DATABASE / CREATE USER / ALTER ROLE success paths and each Exec/QueryRow/Close error branch deterministically, with no live Postgres (the coverage CI job is mock-only). test(postgres): raise backend/postgres coverage to 91.6% #22's tests could only reach the connect-fails-then-rollback path; the seam reaches the rest.
  • randInt / randRead seams → the crypto/rand-failure branches in generatePassword and k8sRandHex.
  • jsonMarshal / httpNewRequestWithContext / ioReadAll seams → the Neon + dedicated request-construction and read-body error wraps.
  • Test-shrinkable k8sReadyTimeout/Interval + namespace-terminate timers + cluster-router pollInterval (per-instance field, no shared global) → the pod-ready timeout, terminating-namespace recreate, and poll-ticker branches run in milliseconds.
  • fake.Clientset (+ a create-Service ClusterIP reactor and a preloaded Ready pod) → the full K8sBackend.Provision happy path + all apply* helpers + every rollback branch.

Coverage

  • Package total: 99.6%; every function ≥95% (verified: go tool cover -func | awk '<95' is empty).
  • Hardest defensive line (kubernetes.NewForConfig failure) covered via a kubeconfig with an unknown auth-provider that parses but fails client construction.

Test plan

  • make gate green (build + vet + go test ./... -short — matches deploy.yml)
  • go test ./internal/backend/postgres -short -coverprofile → 99.6%, 0 funcs <95%
  • -race -count=2 clean (no leaked-goroutine / shared-seam races; pollers join via done channels)
  • All pre-existing postgres tests (test(postgres): raise backend/postgres coverage to 91.6% #22) still pass alongside the seam tests

Note: the scan / osv-scan check fails on a pre-existing, unrelated infra issue (the osv-scanner action pins Go 1.23.7 while go.mod requires ≥1.25.0); not caused by this PR.

🤖 Generated with Claude Code

Add test seams to backend/postgres so the SQL/HTTP/k8s code paths can be
exercised in the mock-only coverage CI job (no live cluster). Production
defaults are unchanged — every seam defaults to the real function/value:

  - pgConn interface + pgxConnect seam (wraps pgx.Connect) lets a fake conn
    drive the CREATE DATABASE / CREATE USER / ALTER ROLE happy paths and each
    Exec/QueryRow/Close error branch deterministically.
  - randInt / randRead seams cover the crypto/rand-failure branches in
    generatePassword and k8sRandHex.
  - jsonMarshal / httpNewRequestWithContext / ioReadAll seams cover the
    Neon/dedicated request-construction and read-body error wraps.
  - k8sReadyTimeout/Interval + namespace-terminate timers and the cluster
    router pollInterval become test-shrinkable (var/field, not const) so the
    pod-ready timeout, terminating-namespace, and ticker branches run in ms.
  - fake.Clientset (+ create-Service ClusterIP reactor and a preloaded Ready
    pod) drives the full K8sBackend.Provision happy path, all apply* helpers,
    rollback branches, StorageBytes/Regrade/Deprovision, and the route registry.

Whole-package coverage is 99.5%; every function is >= 95%. make gate is green
and the suite is clean under -race x5.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mastermanas805 mastermanas805 force-pushed the coverage/prov-postgres-seams-95 branch from bfc8b9b to 84e6407 Compare May 22, 2026 02:57
…seam race

The coverage push to 99.6% added seam-driven tests that swap the global
pgxConnect var. ClusterRouter.Shutdown only closed `done` and returned
without waiting for pollLoop to exit, so a poll goroutine could still be
mid-pgxConnect after a test restored the seam — racing later tests. CI's
build-and-test (go test ./... -race, no docker pg) flaked on
TestLocalBackend_Provision_Success with a stale-DSN dial; the local docker
pg on :5432 masked it.

Shutdown now joins the poll goroutine via a sync.WaitGroup (Add in Start,
Done in the Start closure so direct pollLoop callers are unaffected), making
it a true barrier: no router goroutine touches pgxConnect after Shutdown
returns. Production behaviour is strictly improved (clean teardown). Tests
that start a router now install a fast seam / defer Shutdown so the join is
deterministic. Verified: 5x go test -race with no pg env all green;
coverage holds at 99.6% (every func >=95%).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mastermanas805 mastermanas805 merged commit 1186f0e into master May 22, 2026
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant