Skip to content

ci: gate on the s3-website-test-kit conformance suite#152

Merged
gmoon merged 1 commit into
masterfrom
ci/conformance-gate
Jul 14, 2026
Merged

ci: gate on the s3-website-test-kit conformance suite#152
gmoon merged 1 commit into
masterfrom
ci/conformance-gate

Conversation

@gmoon

@gmoon gmoon commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Problem

CI's Performance Tests job runs only the kit's load config (configs/load-test.yml), which enables no assertions — it measures throughput and that requests don't error out, but never checks the HTTP contract. A correctness regression that still returns 200 sails through green.

Concretely: earlier this session I dropped the ContentType mapping in s3-gateway.ts (a realistic "refactor dropped a line" bug). The load run stayed green (vusers.failed: 0, every object still 200); only the conformance gate caught it (4 contentType assertions failed, exit 21). That gate wasn't in CI — this PR adds it.

Change

  • make conformance-docker — stands up the same s3proxy:test image on port 8081 and runs the kit's expect-enabled configs/conformance.yml against two scenarios:

    • scenarios/core/conformance.yml — portable: status codes, content-types, content-lengths.
    • scenarios/s3proxy/error-contract.yml — s3proxy-specific: 404/403application/xml, which fastify-docker.ts (the image's server) renders.

    Any mismatch exits non-zero. Modeled on the existing test-validation-docker container lifecycle.

  • CI: a Run conformance gate step in Performance Tests, placed before the load run so a contract regression fails fast.

  • Docs updated (docs/maintenance.md).

Deliberately not gating on load timing

Absolute p95/latency thresholds are flaky on shared CI runners — noisy neighbours, variable network to real S3, a shifting runner baseline (cf. the streaming-memory RSS-threshold flake that already bit this repo). Timing stays a tracked artifact; correctness is what we gate on.

Verification

Ran make conformance-docker locally against the built container:

  • core: 16/16 expectations pass
  • error-contract: 4/4 pass
  • make exit 0

🤖 Generated with Claude Code

CI's Performance Tests job only ran the kit's load config, which enables
no assertions — it measures throughput and that requests don't error, but
never checks the HTTP contract. A regression that still returns 200 (e.g.
a dropped content-type header) slips through green.

Add `make conformance-docker`: stands up the same test image on port 8081
and runs the kit's `expect`-enabled conformance config against two
scenarios — the portable `scenarios/core/conformance.yml` (status /
content-type / content-length) and the s3proxy-specific
`scenarios/s3proxy/error-contract.yml` (404/403 -> application/xml, which
fastify-docker.ts renders). Any mismatch exits non-zero.

Wire it into the Performance Tests job as a fail-fast step before the load
run. No load-timing gate: absolute p95/latency thresholds are flaky on
shared CI runners (cf. the streaming-memory RSS-threshold flake); timing
stays a tracked artifact, correctness is what we gate on.

Verified locally against the built container: core 16/16 and error-contract
4/4 expectations pass, `make conformance-docker` exits 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gmoon
gmoon merged commit 4dd2102 into master Jul 14, 2026
9 checks passed
gmoon added a commit that referenced this pull request Jul 14, 2026
The lattice was ~878h behind code (health WARN). Reconciled via the lattice
CLI (add/resolve/verify/edit/edge, then drift --acknowledge; lint + drift now
clean). New nodes:

- REQ-CORE-007 / IMP-CORE-005 — fetchWeb() Web-standard adapter (PR #144/#145);
  IMP supersedes IMP-EXAMPLE-001's hand-rolled Hono conversion.
- REQ-BUILD-003 / IMP-BUILD-002 — @forkzero/s3-website-test-kit extraction +
  adoption and the conformance CI gate (PRs #150-#152).
- REQ-EXAMPLE-003 / IMP-EXAMPLE-002 — container-server consolidation into
  forkzero/s3proxy-docker + local tsx CI targets (PR #156; #153/#155 context
  folded in); supersedes REQ-EXAMPLE-002.
- REQ-TEST-002 / IMP-TEST-002 — de-flake of the streaming-memory RSS bound
  under coverage instrumentation (PR #154).

Modified: REQ-EXAMPLE-002 -> wontfix + status superseded (its premise,
examples/fastify-docker.ts, was deleted); IMP-EXAMPLE-001 -> status superseded
(historical body preserved).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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