The 60s bootstrap timeout this branch adds is invisible to every JVM test —
it only manifests against a real radio. Add a device-driven harness that drives
the network transitions that have historically wedged Tor and asserts the
lifecycle invariants from logcat, so the behavior can be re-verified whenever
Arti is bumped or the Tor management path changes.
tools/tor-network-tests/run.sh — adb-driven runner, one function per scenario,
PASS/FAIL per check, restores a clean network state on exit:
- cold_start Active reached + no pre-ready dial storm (the #3223 gate)
- offline_bootstrap empty cache + airplane: asserts the bootstrap is bounded
('bootstrap timed out' logged), then recovers on restore.
This is the regression test for this PR — it FAILS on a
build without the timeout (create_bootstrapped blocks 95s+).
- wifi_cellular WiFi->Cellular handover recovers to Active
- airplane offline pauses relays cleanly; restore recovers
- pause_resume backgrounding winds relays down (~30s); resume reconnects
README.md documents each scenario's rationale, device setup, when to re-run
(new Arti version, TorService/TorManager/dial-gate changes), and how the suite
relates to TorManagerTest / TorCircuitHealthTrackerTest / the instrumented test.
Verified on a Pixel emulator (WiFi + Cellular): all scenarios pass on this
branch; offline_bootstrap fails on main (no timeout), confirming the suite
discriminates fixed from broken.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>