Append cycle 2 entries to test-spec artifacts (cycle-update mode): * security-tests.md: SEC-05..SEC-09 (AZ-487 JWT 401/403/parity) + SEC-10..SEC-11 (AZ-488 permission + reject-detail leak hygiene). * blackbox-tests.md: BT-13..BT-17 (UAV happy / mixed / multi-source coexistence / same-source UPSERT / rule-ordering) + BT-18 (existing endpoints parity with Bearer token). * resource-limit-tests.md: RL-05..RL-07 (MaxBatchSize, per-item MaxBytes, Kestrel/Form envelope cap). * performance-tests.md: untouched (PT-08 already landed with AZ-488 as Deferred — see _docs/_process_leftovers/2026-05-11_perf-pt07-harness). * traceability-matrix.md: append AC rows for AZ-487 AC-1..AC-8 and AZ-488 AC-1..AC-10 + AC-7a..AC-7e; annotate "No authentication" restriction as superseded by AZ-487+AZ-488; add NFR rows (perf, security, reliability, compatibility) for both tasks; refresh totals (78 tests; 47/47 ACs; 8/8 restrictions). Coverage shape: AZ-487 AC-7 (Swagger Authorize) and the perf NFRs are recorded but not actively measured this commit (manual UI smoke + deferred PT-08 harness, respectively). Co-authored-by: Cursor <cursoragent@cursor.com>
3.1 KiB
Resource Limit Test Scenarios
RL-01: ZIP File Size Limit (50 MB)
Trigger: Create route with enough tiles to approach 50 MB ZIP limit Observable: ZIP file size Pass criterion: ZIP file ≤ 50 MB; tiles included up to limit; no crash on boundary
RL-02: Queue Capacity (1000)
Trigger: Submit 1000 region requests Observable: Queue accepts all 1000 Pass criterion: All 1000 requests accepted and queued; no rejection until capacity reached
RL-03: Concurrent Download Semaphore (4)
Trigger: Process region with many tiles Observable: Concurrent outbound HTTP connections Pass criterion: Never exceeds 4 simultaneous tile downloads (configurable via ProcessingConfig.MaxConcurrentDownloads)
RL-04: Concurrent Region Processing (20)
Trigger: Queue 25 region requests Observable: Processing parallelism Pass criterion: At most 20 regions processing simultaneously (configurable via ProcessingConfig.MaxConcurrentRegions); remaining wait in queue
Cycle 2 — AZ-488 UAV Upload Limits
RL-05: UAV Batch Size Cap (MaxBatchSize = 100)
Trigger: POST /api/satellite/upload with a multipart envelope containing 101 metadata entries (MaxBatchSize + 1) and 101 placeholder file parts. Authenticated with GPS permission.
Observable: HTTP status code, response body, side-effects on tiles table and ./tiles/uav/.
Pass criterion: status == 400 with an envelope-level error (NOT a per-item reject array); zero new rows in tiles; zero new files under ./tiles/uav/. Reject happens before any item is processed — confirmed by observing zero entries in the per-item result array.
Source: AZ-488 AC-8; configurable via UavQualityConfig.MaxBatchSize.
RL-06: UAV Per-Item Size Cap (MaxBytes = 5 MiB)
Trigger: POST /api/satellite/upload with a 1-item batch whose JPEG body is exactly MaxBytes + 1 = 5 * 1024 * 1024 + 1 bytes (within Kestrel MaxRequestBodySize but above the per-item cap).
Observable: HTTP status code, per-item rejectReason.
Pass criterion: status == 200; items[0].status == "rejected"; items[0].rejectReason == "SIZE_OUT_OF_BAND"; no row, no file. Lower-bound twin: a 1-item batch at MinBytes − 1 bytes also rejects with SIZE_OUT_OF_BAND.
Source: AZ-488 AC-7b; configurable via UavQualityConfig.MinBytes / MaxBytes.
RL-07: Kestrel Request-Body Cap For UAV Endpoint (MaxBatchSize × MaxBytes envelope)
Trigger: POST /api/satellite/upload with a multipart envelope whose total byte length exceeds MaxBatchSize × MaxBytes (the cap Program.cs configures via KestrelServerOptions.Limits.MaxRequestBodySize and FormOptions.MultipartBodyLengthLimit).
Observable: HTTP status code, response body.
Pass criterion: status == 413 (Payload Too Large) OR 400 with a body-size error; no row, no file; per-item result array NOT present (Kestrel/Form parser rejects before MVC binding). Behavior must NOT degrade into OOM, infinite buffering, or disk-fill on the server side.
Source: AZ-488 § Risk 3 (Disk-fill mitigation); enforces the multiplicative envelope cap from UavQualityConfig.