app: autorun mode (unattended run + upload + auto-exit); IPv6 severity rework

IPv6: absence is no longer a defect. If the network never provisioned v6
(no global address, no ::/0 route) the finding is ipv6.not_offered at INFO
(green) — most networks are still IPv4-only. If v6 IS advertised but
doesn't work, it's ipv6.broken at MEDIUM (yellow), because half-working v6
stalls connections. Verified on-device: our LAN advertises a v6 default
route with no path, and now reports ipv6.broken.

Autorun: `am start ... --ez autorun true` runs the suite immediately,
POSTs the report to the collection endpoint, shows the result for 3s and
finishes the activity (stays open if the upload failed). receiver.py gains
POST /report + GET /reports + GET /report/<name>. Verified end to end: one
adb command, report retrieved over HTTP, app closed itself.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mrambossek
2026-08-01 09:27:04 +02:00
co-authored by Claude Opus 5
parent 483de5ca54
commit dc094d1631
6 changed files with 186 additions and 17 deletions
+22
View File
@@ -430,3 +430,25 @@ Finding wired: `nat.symmetric` (medium) when mapping is address/port-dependent.
Two bugs caught by running it for real: port preservation was misread as "no NAT" (now compares
ADDRESSES), and an unbound socket reports the wildcard as its local address (now resolved via a
throwaway connected socket). 7 tests/run.
## App: autorun mode + IPv6 severity rework (2026-08-01)
**IPv6 is no longer treated as a defect just for being absent.** The finding now depends on
whether the network actually provisioned IPv6 (a global v6 address or a `::/0` route):
- not provisioned → `ipv6.not_offered`, severity **INFO → green**. Most networks are still
IPv4-only and that is not a fault.
- provisioned but ICMPv6 fails → `ipv6.broken`, severity **MEDIUM → yellow**. Half-configured
IPv6 is worse than none (Happy-Eyeballs stalls). Verified on the OnePlus: our LAN advertises a
v6 default route with no working path, so it correctly reports `ipv6.broken`.
**Autorun mode** — one adb command runs a full measurement unattended and collects the result
without any UI tapping or adb round-trip:
```
adb shell am start -n app.echo_lot.app/.MainActivity --ez autorun true
curl http://<fmr>/reports # list
curl http://<fmr>/report/<name> # fetch
```
The app runs the suite, POSTs the MeasurementDocument to the collection endpoint (receiver.py
gained `POST /report`, `GET /reports`, `GET /report/<name>`), shows the result for 3 s, then
finishes itself — leaving the device as it was found. On upload failure it stays open so the
error is visible. Grant permissions once via `adb shell pm grant app.echo_lot.app
android.permission.ACCESS_FINE_LOCATION` so nothing blocks on a dialog.