Fix #289: internal/server coverage gate #291

Merged
crueber merged 1 commit from fix/issue-289 into main 2026-09-10 14:52:02 +00:00
Owner

Fixes #289 — raises the coverage gate back to green with real behavioral tests (no coverage theater: every test pins a status, wire shape, or error contract).

Results (measured with a full make web dist, as CI builds)

  • internal/server: 95.6% → 98.5% (floor 95%)
  • internal/store: 94.97% → 95.1% (was the actual local gate failure — #234 added StatsKey/OwnerProfileKey uncovered; one statement short)
  • make cover: fully green, all packages; go vet clean; go test -race green on both packages (async adoption test also ×5).

Tests (issue value order)

  1. OIDC: forged wgt_ 401, unknown-kid/dead-issuer → unavailable, RSA/ECDSA type-mismatch + bad-signature rejections, malformed-claims after a valid sig, JWKS fetch negatives (bad/refused/truncated jwks_uri, torn discovery), exchangeCode negatives (bad/refused/500/junk → "").
  2. Authenticate unknown-mode → anonymous; wgtPrincipal round-trip + reject; PrincipalForName OIDC admission; VerifyToken wire table (malformed/tampered/expired/no-secret).
  3. PublishSettings revision report (invalid TOML rejected, rev 1→2) + unknown-repo publish/sync → not-found; placeholder adoption (zero ops hintless, consume-once, marker key layout, failures swallowed async).
  4. File-level: serveSPA 304/HEAD, CSS MIME, webAsset guards, ChainExtra order, ReqLog/scheme/CORS tables (incl. query-smuggling bypass refusal), session sliding refresh, atomic-write + BaseContext, pkt-ERR writer, broker 502→local fallback, LFS verify-gate/upstream negatives, routing edges (unwired API 503, bad owner 404, extras on default branch), SSH went-away/broken-advertisement, histogram exposition, oid/glob/error tables, setup auth-test/body/coerce/schema edges, store key-layout pins.

Two real bugs found by the tests (fixed in this change, per AGENTS.md law 12 — doc updated via this description)

  • equalFoldLast panicked on len(s) < len(suf) (only reachable today via direct call; hasSuffixFold guards it). Added the length guard.
  • serveStatic mapped a store outage (nil meta + non-NotFound error) to 404; error kind is now checked first (miss → 404, outage → 503). This also makes the previously dead 503 branch reachable.

Deliberately NOT covered (defensive-dead, for a separate deletion pass per the issue — not excluded from the gate)

verifyStateTicket payload re-checks (subsumed by verifyState), MintToken/MintSession error returns (mint cannot fail), template-error returns (const templates), dist-miss branches (embed always has dist in CI), matchAnyGlob subsumed case, nil-manifest/nil-settings returns, streamRange non-Object, newRequestID rand failure, refresh follower + stale branches, remaining<0 clamp, spool-rewind/client-error paths. Package totals clear the floor with margin regardless.

No production behavior change besides the two fixes above. No new dependencies. No doc edits needed (no interface/behavior contracts changed beyond the outage-status fix, recorded here).

Fixes #289 — raises the coverage gate back to green with real behavioral tests (no coverage theater: every test pins a status, wire shape, or error contract). ## Results (measured with a full `make web` dist, as CI builds) - `internal/server`: 95.6% → **98.5%** (floor 95%) - `internal/store`: 94.97% → **95.1%** (was the actual local gate failure — #234 added `StatsKey`/`OwnerProfileKey` uncovered; one statement short) - `make cover`: fully green, all packages; `go vet` clean; `go test -race` green on both packages (async adoption test also ×5). ## Tests (issue value order) 1. OIDC: forged `wgt_` 401, unknown-kid/dead-issuer → unavailable, RSA/ECDSA type-mismatch + bad-signature rejections, malformed-claims after a valid sig, JWKS fetch negatives (bad/refused/truncated jwks_uri, torn discovery), exchangeCode negatives (bad/refused/500/junk → ""). 2. `Authenticate` unknown-mode → anonymous; `wgtPrincipal` round-trip + reject; `PrincipalForName` OIDC admission; `VerifyToken` wire table (malformed/tampered/expired/no-secret). 3. `PublishSettings` revision report (invalid TOML rejected, rev 1→2) + unknown-repo publish/sync → not-found; placeholder adoption (zero ops hintless, consume-once, marker key layout, failures swallowed async). 4. File-level: serveSPA 304/HEAD, CSS MIME, webAsset guards, ChainExtra order, ReqLog/scheme/CORS tables (incl. query-smuggling bypass refusal), session sliding refresh, atomic-write + BaseContext, pkt-ERR writer, broker 502→local fallback, LFS verify-gate/upstream negatives, routing edges (unwired API 503, bad owner 404, extras on default branch), SSH went-away/broken-advertisement, histogram exposition, oid/glob/error tables, setup auth-test/body/coerce/schema edges, store key-layout pins. ## Two real bugs found by the tests (fixed in this change, per AGENTS.md law 12 — doc updated via this description) - `equalFoldLast` panicked on `len(s) < len(suf)` (only reachable today via direct call; `hasSuffixFold` guards it). Added the length guard. - `serveStatic` mapped a store outage (`nil` meta + non-NotFound error) to **404**; error kind is now checked first (miss → 404, outage → 503). This also makes the previously dead 503 branch reachable. ## Deliberately NOT covered (defensive-dead, for a separate deletion pass per the issue — not excluded from the gate) `verifyStateTicket` payload re-checks (subsumed by `verifyState`), `MintToken`/`MintSession` error returns (`mint` cannot fail), template-error returns (const templates), dist-miss branches (embed always has dist in CI), `matchAnyGlob` subsumed case, nil-manifest/nil-settings returns, `streamRange` non-Object, `newRequestID` rand failure, `refresh` follower + stale branches, `remaining<0` clamp, spool-rewind/client-error paths. Package totals clear the floor with margin regardless. No production behavior change besides the two fixes above. No new dependencies. No doc edits needed (no interface/behavior contracts changed beyond the outage-status fix, recorded here).
Table-driven behavioral tests for the uncovered branches, in the issue's
value order: OIDC/JWKS negatives (forged wgt_, bad kid/sig/claims, fetch +
discovery failures, exchange retries), Authenticate/wgtPrincipal/
principal-admission edges, VerifyToken wire negatives, setup auth-test /
body / coerce / schema edges, PublishSettings revision + unknown-repo
publish, placeholder adoption (incl. async marker-delete contract),
ChainExtra seam order, ReqLog/scheme/CORS tables, session sliding refresh,
atomic-write/listener utils, pkt-ERR writer, broker 502 fallback,
LFS/upstream negatives, routing edges, SSH transport errors, metrics
exposition, oid/glob/error tables.

Two real bugs exposed by the tests, fixed in the same change:
- equalFoldLast panicked on len(s) < len(suf) (health.go; add the
  hasSuffixFold-style length guard — no caller-visible change).
- serveStatic mapped a store outage (nil meta + non-NotFound error) to
  404; error kind is now checked first (miss -> 404, outage -> 503),
  which also makes the existing 503 branch reachable (static.go).

Remaining sub-95%% functions are defensive-dead branches that cannot fire
through their callers (verifyStateTicket payload re-checks, MintToken/
MintSession error returns, template-error returns, miss branches under
the embedded dist, matchAnyGlob subsumed case, nil-manifest returns):
documented in the PR for a separate deletion pass per the issue; the
per-package gate does not require per-function 95%%.

internal/server 95.6%% -> 98.5%%; internal/store 94.97%% -> 95.1%%
(store needs one statement: StatsKey/OwnerProfileKey layout pins added
to the existing key table — #234 added the helpers uncovered).
make cover fully green; go vet clean; -race green (incl. -count=5 on
the async adoption test).
Sign in to join this conversation.
No description provided.