Skip to content

test(coverage): worker internal/circuit + jobs tail → ≥95% (CI-measured)#59

Merged
mastermanas805 merged 1 commit into
masterfrom
coverage/worker-circuit-jobs-tail-95
May 22, 2026
Merged

test(coverage): worker internal/circuit + jobs tail → ≥95% (CI-measured)#59
mastermanas805 merged 1 commit into
masterfrom
coverage/worker-circuit-jobs-tail-95

Conversation

@mastermanas805
Copy link
Copy Markdown
Member

What

Closes the last two per-module coverage gaps in the worker repo so EVERY package clears the 95% floor as measured by the CI coverage job (postgres/redis/mongo service containers + TEST_* env), not just locally.

Test-only change — two files, no production code touched, no go.mod change.

Coverage block

Package Before After
internal/circuit 91.8% 100.0%
internal/jobs 94.7% 95.1% (5319 / 5596 stmts)

Both numbers were reproduced locally under the exact CI environment that .github/workflows/coverage.yml runs: postgres:16-alpine + redis:7-alpine + mongo:6 service containers, api/worker migrations applied, and the TEST_DATABASE_URL / TEST_REDIS_URL / TEST_POSTGRES_CUSTOMERS_URL / TEST_MONGO_URI / INSTANT_API_REPO env block — invoked with the CI's go test ./... -short -count=1 -p 1 -coverprofile -covermode=atomic.

Explicit note: the new tests do NOT depend on TEST_WORKER_STARTUP_DSN. That env var is unset in CI, so the StartWorkers boot test it gates skips in CI (and is why local go test reads ~96.5% while CI read 94.7%). All added coverage runs under the standard CI env via sqlmock + an SDK-disabled New Relic application + pure-value calls — confirmed to pass with that env var unset.

How the gaps were closed

internal/circuit (pure logic, no DB):

  • NewBreakerthreshold < 1 clamp + cooldown <= 0 default arms
  • State() — half_open / open-within-cooldown / open-after-cooldown-before-trial arms
  • Name() — metric-label accessor

circuit_test.go documents that it is kept in lock-step with api/internal/circuit/circuit_test.go; the same test additions should be mirrored there in a follow-up (out of scope for this worker-only PR).

internal/jobs (sqlmock / disabled-NR-app / unmarshalable-meta — no live infra):

  • middleware.WorknrApp != nil transaction path + txn.NoticeError(err) error arm (driven by newrelic.NewApplication(ConfigEnabled(false)), hermetic, no daemon/network)
  • event_email_mapping.build{BackupFailed,RestoreSucceeded,RestoreFailed} — the row.ResourceType != "" column-wins arm (metadata-fallback else arm already covered)
  • billing_reconciler.emit{Upgrade,Cancel}Audit — fail-open err != nil arm
  • checkout_reconcile.emailAbandonedCheckout — non-ErrNoRows claim-row DB-error arm
  • provisioner_reconciler.markAbandonedUPDATE resources error arm
  • otherwise-unreachable json.Marshal degradation arms (writeAudit ×3, insertPropagationAuditRow) — covered by passing a meta map containing a chan value, so no source-level seam is needed

Verification

  • go build ./... clean
  • go vet ./... clean
  • go test ./internal/circuit/... ./internal/jobs/... -race — pass
  • full go test ./... -short -p 1 -coverprofile — all packages pass; project prod floor = 95.4%

Functions still < 95% (with reason — all unreachable without invasive seams)

  • jobs.StartWorkers (3.0%) / Workers.Stop (42.9%) — need a live River client; River exposes no interface seam (documented in workers_lifecycle_test.go). These SKIP in CI regardless.
  • minio wrapper success paths (Upload/List/Delete/Download 66–83%) — require a real S3-compliant server; error-wrap arms are already covered (documented in backup_extra_test.go).
  • NewK8s*Client constructors (75%) — success path needs a reachable kube-config/in-cluster config.

None of these affect the per-package floor: internal/jobs is 95.1% with them present.

DO NOT MERGE without review.

Closes the last two per-module coverage gaps in the worker repo, measured
under the EXISTING coverage.yml CI environment (postgres/redis/mongo
service containers + TEST_* env) — NOT relying on TEST_WORKER_STARTUP_DSN,
which is unset in CI so its StartWorkers boot test skips there.

internal/circuit 91.8% → 100.0%
  - NewBreaker: threshold<1 clamp + cooldown<=0 default arms
  - State(): half_open / within-cooldown / after-cooldown-before-trial arms
  - Name(): metric-label accessor
  (These tests mirror the api/internal/circuit copy by the file's own
   lock-step contract — apply the same additions there in a follow-up.)

internal/jobs 94.7% → 95.1%
  Reachable arms covered with sqlmock + an SDK-disabled New Relic app +
  pure-value calls (no live infra):
  - middleware Work: nrApp != nil transaction path + txn.NoticeError arm
  - event_email_mapping build{BackupFailed,RestoreSucceeded,RestoreFailed}:
    the row.ResourceType != "" column-wins arm
  - billing_reconciler emit{Upgrade,Cancel}Audit: fail-open err != nil arm
  - checkout_reconcile emailAbandonedCheckout: non-ErrNoRows claim error arm
  - provisioner_reconciler markAbandoned: UPDATE-error arm
  Otherwise-unreachable json.Marshal degradation arms (writeAudit ×3,
  insertPropagationAuditRow) covered by passing an unmarshalable meta map
  (chan value) — no source-level seam required.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@mastermanas805 mastermanas805 merged commit 088f61c into master May 22, 2026
9 checks passed
@mastermanas805 mastermanas805 deleted the coverage/worker-circuit-jobs-tail-95 branch May 22, 2026 17:37
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