Files
suaveplan/openspec/changes/enterprise-testing-load-perf/specs/testing/spec.md
2026-05-27 23:29:53 +01:00

3.7 KiB

ADDED Requirements

Requirement: End-to-end performance gate

Every application under apps/ SHALL ship at least one *.smoke.load.ts file exercising the smoke load preset (1 virtual user, 30 seconds) against the app's Docker staging stack. CI SHALL run every *.smoke.load.ts nightly. A threshold violation in any smoke scenario SHALL fail the build. This gate layers on top of — and does not replace — the existing mitata 10% micro-benchmark regression gate; both gates run independently and both must pass.

Scenario: Every app has at least one smoke scenario

  • WHEN a script enumerates directories under apps/ and looks for tests/load/*.smoke.load.ts (or equivalent path) in each
  • THEN every app directory MUST contain at least one matching file

Scenario: Smoke threshold violation fails CI

  • WHEN the nightly CI job runs apps/testbed/tests/load/healthz.smoke.load.ts and the resulting summary reports http_req_duration{p(95)} >= 500ms
  • THEN the CI job MUST exit non-zero AND the failure summary MUST cite the failed threshold predicate and observed value

Scenario: Mitata gate is unaffected

  • WHEN the smoke gate fails for apps/testbed
  • THEN the existing mitata 10%-regression gate for every @suaveplan/* package MUST still run independently AND its result MUST NOT be masked by the smoke-gate failure

Requirement: apps/testbed scenario coverage

apps/testbed SHALL define one smoke load scenario per route declared in its routes.ts (or equivalent route manifest). The scenario SHALL target the route's HTTP method, path, and minimum-viable request body, and SHALL use the default thresholds from @suaveplan/testing-load unless the route documents a per-route override.

Scenario: Every testbed route has a smoke scenario

  • WHEN the routes manifest in apps/testbed/src/routes.ts declares routes [A, B, C]
  • THEN apps/testbed/tests/load/ MUST contain a *.smoke.load.ts covering each of A, B, and C AND each scenario MUST set target to the corresponding route URL

Scenario: Per-route threshold override is documented

  • WHEN a testbed route requires a threshold looser than the @suaveplan/testing-load default
  • THEN the scenario file MUST set the override explicitly via defineLoadScenario({ thresholds: { … } }) AND the route's documentation MUST justify the override

Requirement: Websocket-gateway connection-fan-out scenario

The websocket-gateway app SHALL define a smoke load scenario that opens at least 10 concurrent websocket connections, sends a ping per connection, and asserts message round-trip latency below the smoke threshold. The scenario SHALL run nightly alongside the HTTP smoke scenarios.

Scenario: Connection-fan-out scenario exists and runs nightly

  • WHEN CI's nightly load step runs against the websocket-gateway staging stack
  • THEN a *.smoke.load.ts MUST exercise at least 10 concurrent websocket connections AND the run MUST report message round-trip latency AND a violation of the configured round-trip threshold MUST fail the build

The smoke load-gate result SHALL be exposed as one of the inputs to the release-readiness gate (referenced in the 2026-04-25 audit §7). A red smoke gate SHALL block any "release ready" CI signal. The release-readiness gate definition itself is out of scope for this change but SHALL be authored in a follow-up change that consumes this signal.

Scenario: Red smoke blocks release-readiness signal

  • WHEN any *.smoke.load.ts reports a threshold violation in the nightly run
  • THEN the release-readiness CI job (when present) MUST not emit a green signal AND the failure surface MUST cite the load gate as the cause