Add firmware verification harness
CI / Non-hardware verification (push) Has been cancelled

This commit is contained in:
2026-07-13 11:10:19 +02:00
parent def09160d0
commit 99c07ecda6
16 changed files with 1004 additions and 32 deletions
+80 -29
View File
@@ -1,47 +1,98 @@
# Legacy Unity Tests
# Firmware Tests
This change intentionally keeps the existing PlatformIO legacy Unity harness unchanged.
No `platformio.ini`, CI, or test-runner configuration was modified.
The canonical non-hardware command is:
## Compile-Only (Legacy Gate)
Use compile-only checks in environments that do not have a connected board:
```powershell
pio test -e lilygo-t3-v1-6-1-test --without-uploading --without-testing
pio test -e lilygo-t3-v1-6-1-868-test --without-uploading --without-testing
```bash
python tools/verify.py
```
Suite-specific compile checks:
Current PlatformIO environments from `platformio.ini`:
```powershell
pio test -e lilygo-t3-v1-6-1-test --without-uploading --without-testing -f test_html_escape
pio test -e lilygo-t3-v1-6-1-test --without-uploading --without-testing -f test_payload_codec
pio test -e lilygo-t3-v1-6-1-test --without-uploading --without-testing -f test_lora_transport
pio test -e lilygo-t3-v1-6-1-test --without-uploading --without-testing -f test_json_codec
pio test -e lilygo-t3-v1-6-1-test --without-uploading --without-testing -f test_refactor_smoke
- `production`: deployment build, serial debug off, light sleep on.
- `debug`: serial diagnostics on, real meter and real LoRa.
- `test`: synthetic meter samples and payload codec self-test.
Payload schema: v4.
## Compile-Only Tests
These commands do not require USB devices or physical boards.
```bash
python -m platformio test -e test --without-uploading --without-testing
python -m platformio test -e test --without-uploading --without-testing -f test_html_escape
python -m platformio test -e test --without-uploading --without-testing -f test_payload_codec
python -m platformio test -e test --without-uploading --without-testing -f test_lora_transport
python -m platformio test -e test --without-uploading --without-testing -f test_json_codec
python -m platformio test -e test --without-uploading --without-testing -f test_refactor_smoke
python -m platformio test -e test --without-uploading --without-testing -f test_meter_fault_count
python -m platformio test -e test --without-uploading --without-testing -f test_security_fuzz
```
## Full On-Device Unity Run
## On-Device Unity Tests
When hardware is connected, run full legacy Unity tests:
These commands require one connected LilyGO T3 v1.6.1 board. They do not require a sender/receiver pair unless the test itself is changed to exercise radio interaction.
```powershell
pio test -e lilygo-t3-v1-6-1-test
pio test -e lilygo-t3-v1-6-1-868-test
```bash
python -m platformio test -e test
python -m platformio test -e test -f test_html_escape
python -m platformio test -e test -f test_payload_codec
python -m platformio test -e test -f test_lora_transport
python -m platformio test -e test -f test_json_codec
python -m platformio test -e test -f test_refactor_smoke
python -m platformio test -e test -f test_meter_fault_count
python -m platformio test -e test -f test_security_fuzz
```
Do not run upload, flash, monitor, or HIL commands from non-hardware CI.
## Suite Coverage
- `test_html_escape`: `html_escape`, `url_encode_component`, and `sanitize_device_id` edge/adversarial coverage.
- `test_payload_codec`: payload schema v3 roundtrip/reject paths and golden vectors.
- `test_lora_transport`: CRC16, frame encode/decode integrity, and chunk reassembly behavior.
- `test_json_codec`: state JSON key stability and Home Assistant discovery payload manufacturer/key stability.
- `test_refactor_smoke`: baseline include/type smoke and manufacturer constant guard, using stable public headers from `include/` (no `../../src` includes).
| Suite | Coverage | Hardware notes |
|---|---|---|
| `test_payload_codec` | Payload schema v4 roundtrip/reject paths, sparse masks, sync packets, golden vectors. | Compile-only works; on-device needs one board. |
| `test_lora_transport` | CRC16, LoRa frame encode/decode integrity, malformed frame rejection, chunk reassembly. | Compile-only works; on-device needs one board. |
| `test_json_codec` | MQTT state JSON key stability and Home Assistant discovery field stability. | Compile-only works; no Wi-Fi/MQTT broker required. |
| `test_html_escape` | HTML escaping, URL encoding, and web device-ID input validation. | Compile-only works; no web server required. |
| `test_refactor_smoke` | Public sender/receiver headers and HA manufacturer constant guard. | Compile-only works. |
| `test_meter_fault_count` | Regression for stale-meter fault counting during catch-up ticks. | Compile-only works; no smart meter required. |
| `test_security_fuzz` | Negative/fuzz seeds for payload decode, varints, LoRa frames, and reassembly. | Compile-only works. |
## Manufacturer Drift Guard
## Hardware Feature Requirements
Run the static guard script to enforce Home Assistant manufacturer wiring:
| Check | Boards | Sender/receiver pair | Smart meter | Wi-Fi | MQTT | SD |
|---|---:|---:|---:|---:|---:|---:|
| Compile-only Unity tests | 0 | No | No | No | No | No |
| On-device Unity tests | 1 | No | No | No | No | No |
| Test-mode LoRa smoke | 2 | Yes | No | Optional | Optional | Optional |
| Production sender sampling | 1 sender | No | Yes or UART simulator | No | No | No |
| Production receiver AP/STA smoke | 1 receiver | No | No | Optional | Optional | Optional |
| End-to-end production transfer | 2 | Yes | Yes or UART simulator | Yes | Yes | Optional |
| SD logging and history | 1 receiver plus traffic | Usually | No | Optional | Optional | Yes |
## Traceability
| Contract | Current tests |
|---|---|
| LoRa frame format | `test_lora_transport`, `test_security_fuzz` |
| CRC validation | `test_lora_transport`, `test_security_fuzz` |
| Chunk reassembly | `test_lora_transport`, `test_security_fuzz` |
| Payload schema | `test_payload_codec`, `test_security_fuzz` |
| Sender-ID validation | `test_refactor_smoke` compile coverage; HIL planned for runtime rejection path |
| ACK matching | HIL planned; runtime contract documented in `README.md` |
| Time bootstrap | `test_payload_codec` sync vector; HIL planned for runtime bootstrap |
| Retry bounds | `test_meter_fault_count` adjacent regression; helper extraction planned |
| Queue bounds | `test_refactor_smoke` compile coverage; helper extraction planned |
| Duplicate handling | HIL planned; runtime contract documented in `README.md` |
| MQTT JSON keys | `test_json_codec` |
| Home Assistant discovery fields | `test_json_codec`, `test_refactor_smoke`, `test/check_ha_manufacturer.ps1` |
| CSV compatibility | HIL or extracted parser tests planned; contract documented in `README.md` |
| HTML escaping | `test_html_escape` |
| Web input validation | `test_html_escape`; route-level tests planned |
## Additional Static Guard
Run the Home Assistant manufacturer drift guard:
```powershell
powershell -ExecutionPolicy Bypass -File test/check_ha_manufacturer.ps1