Skip to content

test(perf): add criterion benches and k6 load harness - #29

Open
UberMetroid wants to merge 2 commits into
masterfrom
qa/perf
Open

test(perf): add criterion benches and k6 load harness#29
UberMetroid wants to merge 2 commits into
masterfrom
qa/perf

Conversation

@UberMetroid

@UberMetroid UberMetroid commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Adds performance-test coverage for the helper modules and the auth-friendly API surface.

Frontend (rustle-frontend)

  • src/lib.rs exposes the pure helper modules via #[cfg(test)] | bench feature so cargo bench can reach them without touching the wasm production build.
  • Cargo.toml gains a bench feature, a dev-dep on criterion 0.5, and a [[bench]] benches target.
  • benches/benches.rs covers get_guess_statuses, is_winning_word, encrypt/decrypt round-trip, holiday date math, and add_stats_for_completed_game.

Backend

  • Cargo.toml gains a dev-dep on criterion 0.5 and a [[bench]] benches target that uses #[path = ../src/utils/mod.rs] to avoid adding a backend lib.rs.
  • benches/benches.rs covers get_holiday_for_date, get_easter_sunday, get_thanksgiving_thursday, a 365-day holiday distribution sweep, and a constant_time_eq micro-benchmark mirroring the PIN compare path.

Load test

  • tests/perf/load.js is a k6 script with staged ramp (10 -> 100 VU) that walks /health, /api/pin-required, /api/verify-pin, /api/auth-check, /api/logout and records custom k6 metrics with p95 thresholds.
  • tests/perf/run-load.sh is the wrapper that invokes k6 and writes tests/perf/summary.json.

CI

  • .github/workflows/perf.yml runs the rust benches first, then boots the backend (with a known PIN) and runs the k6 load test, uploading artifacts.

Docs

  • docs/perf.md describes layout, how to run benches/load locally, and CI/threshold semantics.

No production source code was modified; the wasm binary build is unchanged because the new lib.rs is fully gated on cfg(test) || feature = bench.

Adds performance-test coverage for the helper modules and the
auth-friendly API surface.

Frontend (rustle-frontend):
- src/lib.rs exposes the pure helper modules via #[cfg(test)] | bench
  feature so cargo bench can reach them without touching the wasm
  production build.
- Cargo.toml gains a `bench` feature, a dev-dep on criterion 0.5, and
  a `[[bench]] benches` target.
- benches/benches.rs covers get_guess_statuses, is_winning_word,
  encrypt/decrypt round-trip, holiday date math, and
  add_stats_for_completed_game.

Backend:
- Cargo.toml gains a dev-dep on criterion 0.5 and a `[[bench]] benches`
  target that uses #[path = "../src/utils/mod.rs"] to avoid adding a
  backend lib.rs.
- benches/benches.rs covers get_holiday_for_date, get_easter_sunday,
  get_thanksgiving_thursday, a 365-day holiday distribution sweep, and
  a constant_time_eq micro-benchmark mirroring the PIN compare path.

Load test:
- tests/perf/load.js is a k6 script with staged ramp (10 → 100 VU) that
  walks /health, /api/pin-required, /api/verify-pin, /api/auth-check,
  /api/logout and records custom k6 metrics with p95 thresholds.
- tests/perf/run-load.sh is the wrapper that invokes k6 and writes
  tests/perf/summary.json.

CI:
- .github/workflows/perf.yml runs the rust benches first, then boots
  the backend (with a known PIN) and runs the k6 load test, uploading
  artifacts.

Docs:
- docs/perf.md describes layout, how to run benches/load locally, and
  CI/threshold semantics.

No production source code was modified; the wasm binary build is
unchanged because the new lib.rs is fully gated on cfg(test) ||
feature = "bench".
@UberMetroid UberMetroid changed the title qa/perf test(perf): add criterion benches and k6 load harness Jul 27, 2026
Adds tests/perf/soak.js: a k6 constant-vus scenario (8 VUs, 20m by
default) that walks the same auth-friendly API surface as
tests/perf/load.js (/health, /api/pin-required, /api/verify-pin,
/api/auth-check, /api/logout) plus a 10%-per-iteration slow-path
branch that submits 5 repeated wrong-PIN guesses to stress the
rate-limiter sliding window. Per-route p95 thresholds (health<300,
pin-required<400, verify-pin<600, auth-check<300, logout<400)
mirror load.js so per-route latency drift between the short-run
and long-run scenarios is attributable to time exhaustion rather
than workload differences. iteration_throughput acts as a
memory/throughput proxy.

Adds tests/perf/run-soak.sh: builds the backend in release mode,
launches it with RUSTLE_PIN, waits for /api/pin-required, invokes
k6 on tests/perf/soak.js with SOAK_VUS / SOAK_DURATION env
overrides, and tears the backend down on exit.

Adds k6-soak job in .github/workflows/perf.yml: triggered via
workflow_dispatch with a 'soak' checkbox input (not part of the
weekly cron or PR runs). 50-minute timeout, continue-on-error:
true so a leaking rate-limiter never breaks PRs, and uploads the
JSON summary plus backend stdout/stderr as 30-day retention
artifacts. Also adds a weekly cron (Sun 03:50 UTC) so the workflow
itself is discoverable from the schedules page.

Updates docs/perf.md with a Soak section describing the profile,
overrides, thresholds, and the advisory-only policy.
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