# Perf gate preflight — health-check before PT-01 **Task**: AZ-1133_perf_gate_preflight **Name**: Perf gate preflight — health-check before PT-01 **Description**: Add a preflight reachability check to `scripts/run-performance-tests.sh` so Step 15 fails fast with actionable instructions when the perf compose stack is not running. **Complexity**: 1 point **Dependencies**: AZ-492 (perf harness), AZ-1123 (perf compose documentation) **Component**: test tooling — `scripts/run-performance-tests.sh` + deployment/test env docs **Tracker**: AZ-1133 **Epic**: None ## Problem Cycle 13 Step 15 first run failed at PT-01 because `API_URL` (`https://localhost:18980`) was unreachable — the perf overlay (`docker compose -f docker-compose.yml -f docker-compose.perf.yml up -d`) had not been started. The script proceeded through JWT mint/bootstrap and only surfaced the failure as a cryptic PT-01 HTTP error / non-zero exit, wasting operator time. This carry-over appears in cycle 13, 14, and 15 retros. ## Outcome - `run-performance-tests.sh` verifies API reachability after JWT mint and before PT-01 - Unreachable API exits with exit code **7** and prints the canonical compose-up command - Reachable API proceeds to PT-01 unchanged - `environment.md` and `containerization.md` document the preflight behavior ## Scope ### Included - Add `preflight_api_reachable` (or equivalent) helper in `scripts/run-performance-tests.sh`: - Probe `$API_URL` with the same `CURL_OPTS` / TLS trust as PT-01 (e.g. `curl --connect-timeout 5` to a lightweight endpoint — authenticated `GET /api/satellite/tiles/latlon` with valid coords is acceptable since JWT is already minted) - On connection failure / empty response → print error + `docker compose -f docker-compose.yml -f docker-compose.perf.yml up -d --build` and `exit 7` - Update `_docs/02_document/tests/environment.md` § Performance tests — mention script preflight + exit 7 - Update `_docs/02_document/deployment/containerization.md` § Compose overlays — cross-link preflight ### Excluded - Auto-starting the compose stack from the script (operator still starts it explicitly) - Changing PT-01..PT-10 thresholds or scenario logic - CI integration (perf remains local-only per `ci_cd_pipeline.md`) ## Acceptance Criteria **AC-1: Preflight runs before PT-01** Given `run-performance-tests.sh` with valid `JWT_SECRET` / iss / aud When the script reaches the performance scenarios section Then a reachability probe executes after JWT mint and before the PT-01 banner. **AC-2: Unreachable API fails fast with instructions** Given the perf compose stack is not running (`API_URL` connection refused or timeout) When `run-performance-tests.sh` is executed Then the script exits with code **7**, stderr/stdout includes the perf overlay `docker compose … up` command, and PT-01 does not run. **AC-3: Reachable API proceeds unchanged** Given the perf stack is up and `API_URL` accepts authenticated requests When `run-performance-tests.sh` is executed Then preflight passes silently (or with a single "API reachable" line) and PT-01..PT-10 behave as before. **AC-4: Documentation reflects preflight** Given the post-task docs When `environment.md` and `containerization.md` are read Then both mention the script preflight and exit code 7 when the stack is down. ## Non-Functional Requirements **Reliability** - Preflight must use the same TLS trust path as the rest of the script (`CURL_OPTS` / `certs/api.crt`). **Compatibility** - No change to default env vars (`API_URL`, `PERF_REPEAT_COUNT`, etc.). ## Unit Tests | AC Ref | What to Test | Required Outcome | |--------|-------------|-----------------| | — | Shell-only change; no new C# unit tests required | N/A | ## Blackbox Tests | AC Ref | Initial Data/Conditions | What to Test | Expected Behavior | NFR References | |--------|------------------------|-------------|-------------------|----------------| | AC-2 | Perf stack stopped; JWT env set | `./scripts/run-performance-tests.sh` | Exit 7 + compose instruction; no PT-01 timing output | Reliability | | AC-3 | Perf stack running | `./scripts/run-performance-tests.sh` (smoke: `PERF_REPEAT_COUNT=1` if needed) | Exit 0 or threshold fail only after PT-01 starts | Compatibility | ## Constraints - Preserve `set -euo pipefail` globally — preflight must not mask real curl failures in scenario bodies. - Exit code **7** is reserved for "stack not up" to match cycle 13 perf report convention. ## Risks & Mitigation **Risk 1: False negative when API returns 401/403** - *Risk*: Preflight treats auth errors as "reachable" vs connection errors as "down" — must distinguish connection/TLS failure from HTTP 4xx. - *Mitigation*: Use curl exit code / `--connect-timeout`; treat HTTP responses (even 401) as reachable. **Risk 2: Preflight adds latency to every perf run** - *Risk*: Extra round-trip before 10 scenarios. - *Mitigation*: Single lightweight GET; acceptable vs minutes-long perf suite.