Files
satellite-provider/_docs/02_document/tests/performance-tests.md
T
Oleksandr Bezdieniezhnykh 1802d32107 [AZ-488] UAV tile batch upload + 5-rule quality gate
Replaces the 501 stub at POST /api/satellite/upload with a multipart
batch endpoint that ingests UAV-captured tiles, runs each item through
a 5-rule quality gate, and persists accepted tiles via the AZ-484
multi-source storage path with source='uav'.

Quality gate (in fixed order, first failure wins): JPEG format
(content-type + magic), size band 5 KiB-5 MiB, exact 256x256
dimensions, captured-at age (no future >30 s skew, no older than
7 days), luminance variance on 32x32 downsample. Closed reject-reason
enumeration in v1.0.0 contract.

Authorization: custom PermissionsRequirement / PermissionsAuthorization
Handler that reads the JWT `permissions` claim (tolerates both
repeated-string and JSON-array shapes). Endpoint protected by
RequiresGpsPermission policy; 401 without token, 403 without GPS perm.

Persistence: file-first to ./tiles/uav/{z}/{x}/{y}.jpg, then
ITileRepository.InsertAsync UPSERT (per-source UPSERT contract from
AZ-484). Per-item failures reported in response without aborting the
batch. Kestrel MaxRequestBodySize and FormOptions limits set to
MaxBatchSize x MaxBytes (default 100 x 5 MiB = 500 MiB).

New frozen contract: _docs/02_document/contracts/api/uav-tile-upload.md
v1.0.0. PT-08 NFR added to performance-tests.md as Deferred (harness
work tracked in PT-07 leftover, per AZ-488 § Risk 4).

Tests: 11 quality-gate unit tests, 5 handler unit tests, 3 file-path
unit tests, 12 permission-handler unit tests, 7 integration tests
(AC-1..AC-6, AC-8). All 253 unit tests + smoke integration suite
green.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 23:50:49 +03:00

64 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Performance Test Scenarios
## PT-01: Single Tile Download Latency
**Trigger**: GET /api/satellite/tiles/latlon (uncached tile)
**Load**: 1 request
**Expected**: Response within 30s (includes Google Maps round-trip)
**Pass criterion**: Response time < 30000ms; HTTP 200
## PT-02: Cached Tile Retrieval Latency
**Trigger**: GET /api/satellite/tiles/latlon (cached tile)
**Load**: 1 request
**Expected**: Response within 500ms (DB lookup + response)
**Pass criterion**: Response time < 500ms; HTTP 200
## PT-03: Region Processing Throughput (200m)
**Trigger**: POST /api/satellite/request with 200m region
**Load**: 1 region
**Expected**: Complete processing within 60s
**Pass criterion**: status="completed" within 60s; tiles downloaded > 0
## PT-04: Region Processing Throughput (500m with stitch)
**Trigger**: POST /api/satellite/request with 500m region + stitch
**Load**: 1 region
**Expected**: Complete processing within 120s (more tiles + stitching)
**Pass criterion**: status="completed" within 120s; stitched image exists
## PT-05: Concurrent Region Requests
**Trigger**: 5 simultaneous POST /api/satellite/request (different coordinates)
**Load**: 5 concurrent requests
**Expected**: All queued immediately; all complete within 5 minutes
**Pass criterion**: All 5 regions reach status="completed"; queue does not reject
## PT-06: Route Point Interpolation Speed
**Trigger**: POST /api/satellite/route with 20 points
**Load**: 1 request
**Expected**: Route created (with interpolation) within 5s
**Pass criterion**: HTTP 200 response within 5000ms; totalPoints > 20
## PT-07: GetTilesByRegionAsync Latency Post-AZ-484 (multi-source baseline)
**Trigger**: TileRepository.GetTilesByRegionAsync exercised via POST /api/satellite/request (200m region, zoom 18) against a tiles table seeded with the pre-AZ-484 data shape (single-source rows backfilled to source='google_maps').
**Load**: 1 request, repeated 20 times to get a stable distribution.
**Expected**: 95th-percentile latency must not regress more than 10% vs the pre-AZ-484 baseline measured against PT-03 / PT-04. The new 5-column unique index `idx_tiles_unique_location_source` covers the same `(latitude, longitude, tile_zoom, tile_size_meters)` filter columns as the pre-AZ-484 4-column index, so no regression is expected.
**Pass criterion**: p95(GetTilesByRegionAsync) ≤ 1.10 × pre-AZ-484 p95 baseline.
**Source**: AZ-484 NFR (Performance) — `_docs/02_tasks/done/AZ-484_multi_source_tile_storage.md` § Non-Functional Requirements.
**Note**: This NFR is recorded for tracking. Active enforcement (running PT-07 against a real workload and comparing) is deferred to autodev Step 15 (Performance Test) when a baseline run is available. Until then, the integration test `MostRecentAcrossSourcesSelection_AZ484_AC2` provides correctness coverage for the new query shape.
## PT-08: UAV Tile Batch Upload Latency
**Status**: **Deferred — harness work tracked in `_docs/_process_leftovers/2026-05-11_perf-pt07-harness.md`.** PT-08 reuses the same perf harness expansion (baseline capture + p95 ratio computation) that PT-07 is waiting for; no separate runner-script scenario was added in this commit. Active enforcement starts at cycle 2 Step 15 once the PT-07 harness lands.
**Trigger**: `POST /api/satellite/upload` exercised via the integration test fixtures generated by `UavTileImageFactory.CreateRandomJpeg` — a single 10-item batch of 256×256 / ~50 KiB JPEGs carrying a valid `GPS` JWT.
**Load**: 1 request, repeated 20 times to get a stable distribution.
**Expected**: Per-item quality-gate cost target < 50 ms (Rule 5 dominates — luminance variance after the 32×32 downsample). End-to-end p95 for a 10-item batch < 2 s on the dev hardware (8-core x86 baseline; revise on hardware change).
**Pass criterion**: `p95(UploadUavTileBatch[10 items]) ≤ 2000ms` AND `p95(UavTileQualityGate.Validate[single item]) ≤ 50ms`.
**Source**: AZ-488 NFR (Performance) — `_docs/02_tasks/done/AZ-488_uav_tile_upload.md` § Non-Functional Requirements.
**Process compliance**: AZ-488 § Risk 4 + cycle 1 retro Action 2 require that PT-08 ship with a runner-script scenario in the same commit OR be marked Deferred with a tracked follow-up. This entry takes the Deferred branch because the PT-07 harness expansion is the prerequisite for both scenarios, and a duplicated stub-runner for PT-08 would diverge from PT-07 once the real harness lands.