Skip to content

Testing

Espilon ships with an automated test harness in espilon-test/ that validates the whole firmware stack against real hardware. It runs an embedded Management Protocol server, waits for a device to connect, compiles and injects test modules, runs commands, and writes a JSON report.

Running tests

cd framework/espilon-test

# free port 2626 from any previous runner first
lsof -ti:2626 | xargs -r kill -9 2>/dev/null

python runner.py --suite core --version v0.2.1 --devices espilon-c6

Runner flags

Flag Default Purpose
--suite core Suite to run (see below)
--version dev Firmware version label (used in the report filename)
--chip auto Override the detected chip
--devices all connected Device id(s) to test
--target none Target device id for red-team tests (attacker + target pair)
--profile wifi gprs selects cellular timing
--emon off Capture serial logs during the run
--compare none Compare two JSON reports: --compare new.json old.json

Suites

Suite Tests Approx time Use
smoke T1-T3 ~30 s Post-flash sanity check
core T1-T8 ~3 min Standard pre-release validation
network T9-T10 ~2 min mod_network / mod_recon changes
ble T11 ~1 min BLE-capable chips only
stress T12-T14 ~10 min Concurrency, crypto, load/unload cycles
tunnel T20-T25 ~5 min C2 resilience
full T1-T14, T20-T22, T25 ~15 min Release sign-off (excludes the long T23)
redteam T1, T15-T19 varies Offensive tests; needs --target

Core tests (T1-T8)

Test Validates
T1 Boot, WiFi connect, C2 handshake, status response
T2 Module lifecycle: inject, list, stop, purge
T3 Syscalls via mod_basic: printf, NVS, hw_trng, HMAC-SHA256, get_local_ip
T4 IRAM no-leak: heap drift under 2 KB over 10 load/unload cycles
T5 Watchdog kills a hanging module; device still responds
T6 Panic isolation: a crashing module does not take down a bystander (Xtensa only; skipped on RISC-V, which reboots)
T7 NVS persist and autoload: a persisted module survives reboot
T8 Built-in commands return valid output

Further suites cover modules (T9-T11), stress (T12-T14), red team (T15-T19, paired boards), and tunnel resilience (T20-T25, including reconnect, mid-inject recovery, keepalive idle, and RTT baseline).

Chip capabilities

The harness knows each chip's capabilities (config.py): BLE, PSRAM, dual-core, IRAM size. BLE tests auto-skip on chips without BLE and on the ESP32-S3 rev2 (v0.2) BLE errata.

Reports

Results are written to results/<timestamp>_<version>_<chip>_<PASS|FAIL>.json with per-test status, timing, and details. With --emon, serial captures are attached under results/logs/.

Process naming

The emon monitor name matches the substring "daemon". Never kill it with pkill -f emon - that can kill unrelated system daemons. Always kill by exact PID.

See also