# Test Roadmap Tests planned for the [`test` command](test-command.md) that depend on hardware or services not yet integrated. Each lands as a new subsystem/leaf in the existing framework (profiles, baseline comparison, text report, Esc-cancel lock-out all apply unchanged). **Status: planned — blocked on component.** When a component lands, promote its entry into [test-command.md](test-command.md) and the taxonomy table. ## 1. `env / *` — environmental sensing — *unblocked: ready to implement* The ambient sensor is an SHT41 on the LattePanda's **own I2C bus** (not the Arduino) — see [configuration.md](configuration.md) `[Env]`. The software side has landed: `IEnvSensor` / `Sht41EnvSensor` / `MockEnvSensor`, config-gated, wired into the Sensors panel, the expanded `i` view and the MQTT `Env` topic; the wire protocol is pure and unit-tested ([Sht41Protocol](../include/fgc/sensors/Sht41Protocol.h), `tests/test_sht41.cpp`). The real backend has been **validated against the physical sensor on the LattePanda**, so this leaf is no longer blocked — only unimplemented. Note the two distinct absence states it should tell apart: `pending` (driver never constructed — `enable_env` off) vs `no fix` (enabled but no valid sample within 2× `period_ms`). - **`env / sht41`** — _Healthy:_ sensor responds every poll (`period_ms`); temperature and humidity in plausible range; values update (not stuck); CRC-8 failures stay rare. _Checks:_ read the sensor N times over a window via `Sht41EnvSensor`; verify each returns a CRC-valid frame; count CRC failures / stale (`connected() == false`) periods. _Metrics:_ temperature °C, relative humidity %, read-failure count, **dewpoint margin** (flag condensation risk when humidity is high and temperature is near the computed dewpoint — relevant for an outdoor tower enclosure). _Host:_ a `TestRunner` leaf reading `IEnvSensor::sample()` directly (no new wire protocol needed — the abstraction the IMU-style tests already use). ## 2. `comms / *` — message bus — *blocked on: RabbitMQ integration* Validates the telemetry/control transport. Tests whichever `IControlChannel` is active (MQTT today, RabbitMQ once integrated — see the MQTT→RabbitMQ migration in [roadmap.md](roadmap.md)). - **`comms / broker`** — _Healthy:_ broker reachable; auth succeeds; the expected exchange/queue (or MQTT topic tree) exists. _Checks:_ connect with configured credentials; assert connection within timeout; for RabbitMQ assert the exchange/queue topology is present. _Metrics:_ connect latency, auth ok, topology-present. - **`comms / roundtrip`** — _Healthy:_ a published message returns to a subscriber promptly with no loss. _Checks:_ subscribe to a loopback/test topic (or a dedicated test queue), publish K sequenced messages, time each round-trip, detect gaps. _Metrics:_ mean/95th round-trip latency, loss %, out-of-order count. The message-bus analogue of `system/link`; for RabbitMQ also surface confirms/acks. ## 3. `camera / *` — imaging — *`rgb` unblocked; `thermal` blocked on the thermal camera* One leaf per physical sensor; shares a common frame-quality core. Uses the existing `ICameraSource`/`ImagePipeline`. **The shared frame-quality core already exists.** `analyzeFrame()` in [ImageQuality.h](../include/fgc/ImageQuality.h) computes mean luma, clipped/dark fraction and a variance-of-Laplacian sharpness score over a raw buffer, with no OpenCV dependency, and is unit-tested against synthetic frames. The `camera / rgb` leaf should call it rather than reimplementing the histogram and sharpness checks below — it already covers "usable histogram (not clipped)" and "sharpness/focus metric". What it does **not** yet provide is dead/hot-pixel counting, realized-FPS measurement, timestamp monotonicity or encode-throughput timing. The RGB camera itself is integrated and verified on the rig (see [architecture.md](architecture.md#image-capture)), so this leaf is now an implementation task rather than a blocked one. Note that a self-test asserting exposure health needs the lens uncovered and the limits in `[Camera]` tuned first — [known-issues.md](known-issues.md) #15–#18. - **`camera / rgb`** — _Healthy:_ enumerates and connects; delivers frames at ~the configured rate; exposure/gain give a usable histogram (not clipped); few dead/hot pixels; frames sharp when focused; timestamps strictly increase; few dropped frames; JXL encode keeps up. _Checks:_ acquire a short burst; measure realized FPS vs configured, histogram clipping %, dead/hot-pixel count (dark/flat-field heuristic), a **sharpness/focus metric** (variance-of-Laplacian), timestamp monotonicity, dropped-frame count from sequence gaps, mean JXL encode time vs frame interval. _Metrics:_ realized FPS, exposure/histogram health, dead/hot-pixel count, focus score, dropped frames, encode throughput. - **`camera / thermal`** — all of the above **plus** radiometric sanity: temperatures within expected range, NUC (non-uniformity correction) recent/valid, no excessive fixed-pattern noise. _Checks:_ as RGB, plus a flat-scene uniformity check and a temperature range/sanity check; verify NUC/shutter recency if exposed. - _Shared:_ factor a `frameQualityMetrics(frame)` helper so both leaves (and future cameras) reuse the histogram/sharpness/dead-pixel code. ## 4. Deferred / needs additional hardware to measure - **`gimbal / supply`** — supply-voltage sag during high-acceleration moves. _Blocked on:_ a voltage-sense path to the firmware (the TMC/board doesn't report bus voltage today). If added, the firmware reports it alongside the `LP` load capture; metric = min bus voltage under load vs nominal. ## Conventions for all roadmap tests Same as the live suite: profiles carry per-metric thresholds + drift gates; results go into the one text report with baseline/prev comparison; new firmware lines keep the `OK`/`ERR` + 2-letter-prefix contract with a matching pure host parser and `firmware/test/` coverage; new host-only sources (cameras, broker) need no firmware.