# 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`.

