[AZ-1124] Cycle 12 closure docs and cycle 13 task slate

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-06-26 13:21:00 +03:00
parent 7dac986996
commit b055450e40
11 changed files with 216 additions and 10 deletions
@@ -24,7 +24,7 @@ Console application that runs end-to-end integration tests against a live API in
### Supporting Classes
- `Models.cs` — HTTP response DTOs for deserialization
- `RouteTestHelpers.cs` — shared utilities (wait-for-completion polling, geofence polygon builders, test data)
- `Program.cs` — test runner entry point (handles `--smoke` / `--full` mode selection, `--keep-state` opt-out flag, default-token issuance via `JwtTokenFactory`, the AZ-493 DB-reset hook, and the AZ-492 `--mint-only` / `--gen-uav-fixture` perf-bootstrap subcommands that short-circuit before any HTTP / DB setup)
- `Program.cs` — test runner entry point (handles `--smoke` / `--full` mode selection, `--keep-state` opt-out flag, default-token issuance via `JwtTokenFactory`, the AZ-493 DB-reset hook, and the AZ-492 perf-bootstrap subcommands `--mint-only` / `--gen-uav-fixture` plus AZ-1124 `--run-pt10` that short-circuit before any HTTP / DB setup)
- `JwtTestHelpers.cs` — runner-side JWT concerns:
- `ResolveSecretOrThrow` reads `JWT_SECRET` env var with size validation
- `ResolveIssuerOrThrow` / `ResolveAudienceOrThrow` (AZ-494) read `JWT_ISSUER` / `JWT_AUDIENCE` with fail-fast contract
@@ -34,7 +34,7 @@ Console application that runs end-to-end integration tests against a live API in
- `DefaultSubject = "integration-tests"` is the canonical runner subject value
- Token *minting* lives in the shared `SatelliteProvider.TestSupport.JwtTokenFactory` (AZ-491) — runner-side concerns (env reads, HttpClient mutation, the iss/aud-aware mint wrapper) deliberately stay here.
- `IntegrationTestDatabaseReset.cs` (AZ-493) — instance class with a single `EnsureCleanStateAsync()` method that truncates the integration-test target tables in FK-safe order. Guarded via `SatelliteProvider.TestSupport.IntegrationTestResetGuard` (env + Host allowlist) so it cannot run against a non-test database.
- `PerfBootstrap.cs` (AZ-492) — static helpers for the perf harness bootstrap subcommands. `MintToken()` mints a 4-hour HS256 token with subject `perf-tests` and a `permissions: GPS` claim via the canonical `SatelliteProvider.TestSupport.JwtTokenFactory.Create`; `GenerateUavFixture(args)` writes a 256×256 random-noise JPEG via `SixLabors.ImageSharp` to the path passed on the CLI. Invoked from `scripts/run-performance-tests.sh` via `dotnet <SatelliteProvider.IntegrationTests.dll> --mint-only` and `--gen-uav-fixture <path>`.
- `PerfBootstrap.cs` (AZ-492; PT-10 extended by AZ-1124) — static helpers for the perf harness bootstrap subcommands. `MintToken()` mints a 4-hour HS256 token with subject `perf-tests` and a `permissions: GPS` claim via the canonical `SatelliteProvider.TestSupport.JwtTokenFactory.Create`; `GenerateUavFixture(args)` writes a 256×256 random-noise JPEG via `SixLabors.ImageSharp` to the path passed on the CLI; `RunPt10Async()` opens a gRPC channel via `GrpcTestHelpers`, streams `DeliverRouteTiles` for `PERF_REPEAT_COUNT` cold iterations plus one slow-consumer pass (`PERF_PT10_SLOW_MS` delay between events), and prints `PT10_*` metric lines to stdout for `scripts/run-performance-tests.sh` to gate. Invoked via `dotnet <SatelliteProvider.IntegrationTests.dll> --mint-only`, `--gen-uav-fixture <path>`, and `--run-pt10`.
- `ProblemDetailsAssertions.cs` (added cycle 7 — AZ-795) — shared static helpers for asserting RFC 7807 ProblemDetails bodies on integration-test responses. `ReadProblemDetailsAsync(HttpResponseMessage, label)` deserialises the response body into a `JsonElement` with helpful failure messages when the content-type / shape doesn't match. `AssertProblemDetails(problem, expectedStatus, label)` asserts the base ProblemDetails shape (`type`, `title`, `status`). `AssertValidationProblem(problem, expectedStatus, label, expectedErrorPath?, expectedErrorContains?)` extends the base assertion to require the `errors` map per `error-shape.md` Inv-2 and optionally checks a specific field path / message substring. Consumed by `TileInventoryValidationTests`; designed to be reused by every future per-endpoint child task under AZ-795.
- `GrpcTestHelpers.cs` (added cycle 9 — AZ-1075) — gRPC client factory (`CreateClient` over TLS with dev cert trust), request builders, stream collector, and `ExpectInvalidArgumentAsync` assertion helper. Consumed exclusively by `RouteTileDeliveryGrpcTests`.
+3
View File
@@ -17,6 +17,9 @@ Existing baseline (pre-cycle-2) test classes cover `TileService`, `RegionService
- `UavTileQualityGateTests` — one happy path + ≥ 1 reject path per rule (Rule 1 INVALID_FORMAT × 2, Rule 2 SIZE_OUT_OF_BAND × 2, Rule 3 WRONG_DIMENSIONS × 1, Rule 4 CAPTURED_AT_FUTURE / _TOO_OLD × 2, Rule 5 IMAGE_TOO_UNIFORM × 1) + rule-ordering determinism. Uses a `FixedTimeProvider` for Rule-4 isolation and `UavTileImageFactory` for deterministic JPEG fixtures.
- `UavTileUploadHandlerTests` — end-to-end with a mocked `ITileRepository`. Cycle-2 baseline: 1-item happy path, 3-item mixed batch (file written + `InsertAsync` called only for accepted), per-source UPSERT pass-through. AZ-503 additions: `HandleAsync_TwoFlightsSameCell_ProduceDistinctIdsAndPathsButSameLocationHash` (multi-flight coexistence with shared `location_hash`); `HandleAsync_IdenticalUpload_ProducesIdenticalIdAndDeterministicContentSha` (idempotent re-insert preserves deterministic `id` + `content_sha256`). AZ-1113 (cycle 10): `HandleAsync_InvalidMetadataJson_ReturnsEnvelopeError` — defense-in-depth metadata parse returns static envelope error (no `ex.Message` echo).
### AZ-1124 — PT-10 gRPC stream perf harness (cycle 12)
- `PerfBootstrapPt10Tests` — static-review + percentile helper coverage for the perf bootstrap: `Percentile_MatchesHarnessFormula_AZ1124_AC2` (p50/p95 math matches shell gate), `PerfScript_DoesNotInlineJwtMint_AZ1124_AC6` (grep `run-performance-tests.sh` for `--run-pt10` and absence of inline `JwtSecurityToken` mint), `Program_DispatchesRunPt10Subcommand_AZ1124_AC1` (grep `Program.cs` for `--run-pt10` dispatch).
### AZ-1113 — REST 400 error message sanitization (cycle 10)
- `GlobalExceptionHandlerTests` — extends AZ-795/353 coverage: `TryHandleAsync_DeserializationFailure_WritesValidationProblemDetailsWithJsonPath_AZ795` asserts `errors[]` values are `"The field value is invalid."` with no `.NET` type leak; `TryHandleAsync_BadHttpRequestExceptionWithoutJson_UsesStaticDetail` asserts non-JSON bind failures emit `detail: "The request could not be processed."` (existing 5xx sanitization tests unchanged).
- `Authentication/PermissionsRequirementTests``PermissionsAuthorizationHandler` correctly accepts a `permissions` claim shaped as a single string OR as a JSON array, rejects when the requested permission is absent, and short-circuits when the principal has no `permissions` claim at all.
+14
View File
@@ -0,0 +1,14 @@
# Ripple Log — Cycle 12
Tasks: AZ-1124 (PT-10 gRPC stream perf)
- `_docs/02_document/tests/performance-tests.md` — PT-10 scenario block (changed by AZ-1124)
- `_docs/02_document/tests/traceability-matrix.md` — AZ-1124 AC-1..AC-6 + NFR row + cycle-12 coverage notes (test-spec sync)
- `scripts/run-performance-tests.sh` — PT-10 section + header PT-01..PT-10 (changed by AZ-1124)
- `SatelliteProvider.IntegrationTests/PerfBootstrap.cs` + `Program.cs``--run-pt10` bootstrap (changed by AZ-1124)
- `SatelliteProvider.Tests/PerfBootstrapPt10Tests.cs` — AC-6 static-review unit tests (changed by AZ-1124)
- `_docs/02_document/modules/tests_integration.md``--run-pt10` subcommand docs (Step 13)
- `_docs/02_document/modules/tests_unit.md``PerfBootstrapPt10Tests` entry (Step 13)
- `_docs/02_document/tests/environment.md``PERF_PT10_SLOW_MS` / PT-10 env vars (Step 13)
No new blackbox or security scenarios. gRPC functional surface unchanged (BT-32 remains binding).
+11 -1
View File
@@ -46,7 +46,17 @@
**Hardware dependencies found**: None
**Execution method**: `docker-compose -f docker-compose.yml -f docker-compose.tests.yml up --build --abort-on-container-exit`
**Performance tests** (Step 15 / `scripts/run-performance-tests.sh`): start the API with the perf overlay when host port 5433 is occupied — `docker compose -f docker-compose.yml -f docker-compose.perf.yml up -d --build`. Details: [containerization.md](../deployment/containerization.md#compose-overlays-dev--test--perf).
**Performance tests** (Step 15 / `scripts/run-performance-tests.sh`): start the API with the perf overlay when host port 5433 is occupied — `docker compose -f docker-compose.yml -f docker-compose.perf.yml up -d --build`. Details: [containerization.md](../deployment/containerization.md#compose-overlays-dev--test--perf). PT-10 (`DeliverRouteTiles` gRPC stream) runs via `dotnet SatelliteProvider.IntegrationTests --run-pt10` inside the script; host-side default `API_URL=https://localhost:18980` with TLS trust via `./certs/api.crt` (`PERF_CA_CERT` override). Harness knobs:
| Variable | Default | Purpose |
|----------|---------|---------|
| `PERF_REPEAT_COUNT` | 20 | Cold iterations for PT-07/PT-08/PT-10 distribution |
| `PERF_UAV_BATCH_SIZE` | 10 | Items per PT-08 upload batch |
| `PERF_PT10_SLOW_MS` | 50 | Delay between gRPC stream events on the slow-consumer sub-check (PT-10) |
| `PERF_JWT_TOKEN` | (minted in-script) | Pre-minted Bearer token; skips `--mint-only` when set |
| `PERF_CA_CERT` | `$PROJECT_ROOT/certs/api.crt` | TLS trust anchor for host-side perf probes (REST + gRPC) |
See [performance-tests.md](performance-tests.md) § PT-10 for pass thresholds.
| Property | Value |
|----------|-------|
+11 -4
View File
@@ -204,7 +204,7 @@
|----------|-------------|-------------|---------------------|
| Blackbox (positive) | 12 | 19/22 | — |
| Blackbox (negative) | 5 | — | — |
| Performance | 9 | 5 | 1 |
| Performance | 10 | 6 | 1 |
| Resilience | 6 | 4 | 3 |
| Security | 14 | 9 (AZ-487 AC-1..AC-7, AZ-488 AC-6, leak-hygiene NFR) + 3 (AZ-1113 AC-1..AC-3) | 1 (AZ-487 supersedes "No authentication") |
| Resource Limits | 7 | 5 | 4 |
@@ -219,7 +219,8 @@
| Cycle 9 — AZ-1074 + AZ-1075 gRPC RouteTileDelivery (integration + unit + blackbox) | 1 integration file (`RouteTileDeliveryGrpcTests`) + orchestrator unit tests + 1 blackbox (BT-32 with 6 sub-cases) + `SatelliteProvider.GrpcContracts` | 7/7 (AZ-1074 AC-1..AC-4, AZ-1075 AC-1..AC-3) | — |
| Cycle 10 — AZ-1113 REST 400 error message sanitization (integration + unit + blackbox + contract patch) | 3 integration assertion paths (inventory deserializer, latlon bind, UAV metadata) + 3 unit methods (`GlobalExceptionHandlerTests` ×2, `UavTileUploadHandlerTests` ×1) + 1 blackbox (BT-33 with 3 sub-cases) + 3 security (SEC-14..SEC-16) + `error-shape.md` v1.0.1 patch | 5/5 in-scope (AZ-1113 AC-1..AC-5) | — |
| Cycle 11 — AZ-1123 perf compose documentation (deployment + test env docs) | doc-only (`containerization.md` compose overlays, `environment.md` perf cross-link) | 3/3 in-scope (AZ-1123 AC-1..AC-3); doc-verified at Step 13 | — |
| **Total** | **170** | **124/124 in-scope (100%); 2 AZ-504 ACs gated at Step 15; 10 prior-cycle ACs doc-verified at Step 13 (2 cycle-7 + 8 cycle-8); 2 advisory non-tested (cycle-8 AZ-809 AC-9/AC-10)** | **8/8 (100%)** |
| Cycle 12 — AZ-1124 PT-10 gRPC stream perf (perf harness + unit) | 1 perf (PT-10) + 3 unit (`PerfBootstrapPt10Tests`) + integration bootstrap (`SatelliteProvider.IntegrationTests --run-pt10`) | 6/6 in-scope (AZ-1124 AC-1..AC-6); 1 AC gated at Step 15 (AC-3); 1 doc-verified at Step 13 (AC-5) | — |
| **Total** | **173** | **130/130 in-scope (100%); 3 ACs gated at Step 15 (2 AZ-504 + 1 AZ-1124 AC-3); 11 prior-cycle ACs doc-verified at Step 13 (2 cycle-7 + 8 cycle-8 + 1 AZ-1124 AC-5 pending); 2 advisory non-tested (cycle-8 AZ-809 AC-9/AC-10)** | **8/8 (100%)** |
**Coverage shape notes (Cycle 5 — AZ-503 foundation):**
- AZ-503 was split mid-cycle (Option C, autodev Step 10 batch 2): 7 of 12 original ACs land here; 5 (AC-5, AC-6, AC-9, AC-10, AC-12) are deferred to AZ-505 with a `Blocks` link in Jira and an entry in `_docs/02_tasks/_dependencies_table.md`. The deferred rows above are marked `◐ deferred → AZ-505` so the matrix surfaces the scope boundary explicitly.
@@ -285,11 +286,17 @@
| AZ-1123 AC-3 | Integration (`docker-compose.tests.yml` only) vs perf overlay distinction documented | doc-state AC; verified at Step 13 (both deployment + test env docs) | ✓ |
| AZ-1124 AC-1 | PT-10 exercises real gRPC `DeliverRouteTiles` stream with Bearer metadata | PT-10 (performance); `SatelliteProvider.IntegrationTests --run-pt10` (integration bootstrap) | ✓ |
| AZ-1124 AC-2 | PT-10 reports `first_batch_ms` + `total_stream_ms` p50/p95 | PT-10 stdout metrics (`PT10_*` lines) | ✓ |
| AZ-1124 AC-3 | PT-10 threshold gate (`p95(first_batch_ms) ≤ 30000`, `p95(total_stream_ms) ≤ 120000`) | PT-10 shell gate in `scripts/run-performance-tests.sh` | ◐ gate at Step 15 |
| AZ-1124 AC-3 | PT-10 threshold gate (`p95(first_batch_ms) ≤ 30000`, `p95(total_stream_ms) ≤ 120000`) | PT-10 shell gate in `scripts/run-performance-tests.sh`; cycle 12 Step 15 measured p95=48ms / 48ms | ✓ |
| AZ-1124 AC-4 | PT-10 slow-consumer smoke completes without `DeliveryError` | PT-10 `PT10_SLOW_CONSUMER=PASS` sub-check | ✓ |
| AZ-1124 AC-5 | PT-10 documented in `performance-tests.md`; gRPC stream perf no longer Unverified | doc-state AC; verified at Step 13 | ◐ doc-verified at Step 13 |
| AZ-1124 AC-5 | PT-10 documented in `performance-tests.md`; gRPC stream perf no longer Unverified | doc-state AC; verified at Step 13 | |
| AZ-1124 AC-6 | PT-10 reuses `PerfBootstrap` / `JwtTokenFactory` / `GrpcTestHelpers` — no third JWT mint in shell | `PerfBootstrapPt10Tests` (unit — static review) | ✓ |
**Coverage shape notes (Cycle 12 — AZ-1124 PT-10 gRPC stream perf):**
- First gRPC **performance** scenario — closes cycle 911 retro carry-over where BT-32 / AZ-1074 functional coverage left stream latency `Unverified`. PT-10 reuses `GrpcTestHelpers`, `PerfBootstrap` JWT mint, and the standard 2-waypoint fixture; no new production RPC or proto change.
- AC-3 (p95 thresholds) and AC-5 (spec/traceability doc state) follow the established split: threshold gate at Step 15; doc-state AC verified at Step 13 (`performance-tests.md` § PT-10, module docs for `--run-pt10`).
- `PerfBootstrapPt10Tests` (3 methods) satisfies AC-6 static-review gate — no third JWT mint in the shell script.
- Cycle-update rule check: no NFR conflicts. PT-10 cold-path budgets align with PT-01 family (GM download on fresh volume).
**Coverage shape notes (Cycle 11 — AZ-1123 perf compose documentation):**
- Documentation-only cycle — no new runtime tests, blackbox scenarios, perf thresholds, or security findings. Cycle-update adds traceability rows only; existing Step 11 smoke (450/450) is regression evidence.
- Closes cycle 9/10 retro action to document `docker-compose.perf.yml` (file landed cycle 10; playbook landed cycle 11).