upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYour Name <you@example.com>2026-05-20 04:09:47 +0530
committerYour Name <you@example.com>2026-05-20 04:09:47 +0530
commit0ba9e591a5ffe9b7e5833341821bd72095b6acb7 (patch)
treea01a06ca4d141804dd624759321c0892e17a2020
parentbb157fcb839d66b98ca375ab0ea657a08b5a21b4 (diff)
docs: test coverage + phase 4/5 + interop plan with checklist
-rw-r--r--TEST_COVERAGE_PLAN.md262
1 files changed, 262 insertions, 0 deletions
diff --git a/TEST_COVERAGE_PLAN.md b/TEST_COVERAGE_PLAN.md
new file mode 100644
index 0000000..887b578
--- /dev/null
+++ b/TEST_COVERAGE_PLAN.md
@@ -0,0 +1,262 @@
1# Test Coverage + Phase 4/5 + Interop Plan
2
3Ensure full hardware + Playwright test coverage at all times. Restructure main/ to delegate
4to tollgate_core. Fix NerdQAxePlus symlink. Add ESP32 ↔ OpenWRT interop tests.
5
6## End State
7
8```
9esp32-tollgate (master)
10 main/ = thin shell calling tollgate_core API
11 components/tollgate_core/ = THE reusable core (cashu, dns, firewall, session, mining, stratum)
12 .env = board nsecs + upstream WiFi secrets (gitignored)
13
14esp-miner-nerdqaxeplus (develop)
15 components/tollgate_core/ = IDF Component Manager override_path → esp32-tollgate
16
17physical-router-test-automation/
18 esp32/Makefile = ESP32 board tests (lock-protected)
19 esp32/boards.env = all 3 boards with derived SSID/IP/MAC
20 mint-health/ = OpenWRT router tests (lock-protected)
21 Interop targets = ESP32 ↔ Go router bidirectional payment tests
22```
23
24## Mutex Rules (MANDATORY)
25
26| Target type | Lock mechanism | Required locks |
27|-------------|---------------|----------------|
28| ESP32 flash/test | `make -C esp32 lock-{a,b,c}` | Per-board lock file in locks/ |
29| OpenWRT router test | `make lock` | hardware.lock |
30| Interop (ESP32+router) | Both | Board lock AND hardware.lock |
31| Unit tests | None | None (no hardware) |
32| Build | None | None (no hardware) |
33
34All hardware access MUST go through lock-protected Makefile targets.
35No direct esptool.py, curl, or nmcli against hardware without locks.
36
37## Mints
38
39| Mint | URL | Purpose |
40|------|-----|---------|
41| Testnut | `https://testnut.cashu.space` | ESP32 boards, auto-pays invoices |
42| Testnut no-fee | `https://nofee.testnut.cashu.space` | Alpha router, feeless swaps |
43| Orangesync compat | `https://testnut-compat.mints.orangesync.tech` | Beta router, mint-token tool default |
44| Minibits | `https://mint.minibits.cash/Bitcoin` | Alpha router (secondary) |
45
46---
47
48## Phase 0: Fix Stale Infrastructure
49
50- [ ] **0.1** Generate random nsec for Board C, store all 3 nsecs in esp32-tollgate/.env
51- [ ] **0.2** Derive Board C identity (SSID, IP, MACs) from nsec via HMAC-SHA512
52- [ ] **0.3** Update physical-router-test-automation/esp32/boards.env:
53 - FIRMWARE_DIR → /home/c03rad0r/esp32-tollgate
54 - ARCH_FIRMWARE_DIR → /home/c03rad0r/esp32-tollgate
55 - RELAY_FIRMWARE_DIR → /home/c03rad0r/esp32-tollgate
56 - Add BOARD_C_SSID, BOARD_C_IP, BOARD_C_UUID
57 - Update ARCH_IP/ARCH_SSID to Board C's derived values
58- [ ] **0.4** Update SPIFFS generation to read nsec from .env per board
59- [ ] **0.5** Fix NerdQAxePlus broken symlink → idf_component.yml with override_path
60- [ ] **0.6** Remove hardcoded include from NerdQAxePlus main/CMakeLists.txt
61- [ ] **0.7** Verify NerdQAxePlus builds: BOARD=NERDAXE TOLLGATE=1 idf.py build
62- [ ] **0.8** Verify esp32-tollgate builds: idf.py build
63- [ ] **0.9** Verify unit tests pass: make test-unit
64- [ ] **0.10** Commit + push
65
66## Phase 1: Baseline Hardware Tests
67
68- [ ] **1.1** make -C esp32 lock-a PHASE="baseline"
69- [ ] **1.2** make -C esp32 flash-a
70- [ ] **1.3** make -C esp32 test-multi-mint-a
71- [ ] **1.4** make -C esp32 test-cvm-a
72- [ ] **1.5** make -C esp32 unlock-a
73- [ ] **1.6** make -C esp32 lock-b PHASE="baseline"
74- [ ] **1.7** make -C esp32 flash-b
75- [ ] **1.8** make -C esp32 test-multi-mint-b
76- [ ] **1.9** make -C esp32 unlock-b
77- [ ] **1.10** make -C esp32 lock-c PHASE="baseline"
78- [ ] **1.11** make -C esp32 flash-c
79- [ ] **1.12** Verify Board C AP reachable (ping derived IP)
80- [ ] **1.13** make -C esp32 arch-test-api-quick
81- [ ] **1.14** make -C esp32 unlock-c
82- [ ] **1.15** make lock PHASE="baseline-router"
83- [ ] **1.16** make status ROUTER=alpha
84- [ ] **1.17** make status ROUTER=beta
85- [ ] **1.18** make smoke-degraded ROUTER=alpha
86- [ ] **1.19** make test-captive-portal ROUTER=alpha
87- [ ] **1.20** make smoke-degraded ROUTER=beta
88- [ ] **1.21** make test-captive-portal ROUTER=beta
89- [ ] **1.22** make unlock
90- [ ] **1.23** Playwright E2E from esp32-tollgate (lock-a, connect-a, test-e2e)
91- [ ] **1.24** Gate: all tests pass before proceeding
92
93## Phase 2: Restructure main/ → tollgate_core
94
95Consolidate 6 duplicated modules. Order: session → firewall → cashu → dns_server → stratum_proxy → mining_payment.
96
97### 2A: session module
98
99- [ ] **2A.1** Diff main/session.c vs tollgate_core/src/tollgate_core_session.c
100- [ ] **2A.2** Merge unique main/ functionality into tollgate_core
101- [ ] **2A.3** Update tollgate_core.h public API if needed
102- [ ] **2A.4** Replace main/session.c with thin wrapper (or remove)
103- [ ] **2A.5** Update main/CMakeLists.txt
104- [ ] **2A.6** idf.py build
105- [ ] **2A.7** make test-unit
106- [ ] **2A.8** Quick hardware verify (lock-a, flash-a, arch-test-api-quick, unlock-a)
107- [ ] **2A.9** Commit + push
108
109### 2B: firewall module
110
111- [ ] **2B.1** Diff main/firewall.c vs tollgate_core/src/tollgate_core_firewall.c
112- [ ] **2B.2** Merge unique main/ functionality into tollgate_core
113- [ ] **2B.3** Keep lwip_tollgate_hooks.h in main/ (build-system concern)
114- [ ] **2B.4** main/firewall.c becomes thin wrapper calling tollgate_core_fw_* functions
115- [ ] **2B.5** Verify LWIP hook still calls tollgate_core_ip4_canforward_filter
116- [ ] **2B.6** Update main/CMakeLists.txt
117- [ ] **2B.7** idf.py build
118- [ ] **2B.8** make test-unit
119- [ ] **2B.9** Quick hardware verify
120- [ ] **2B.10** Commit + push
121
122### 2C: cashu module
123
124- [ ] **2C.1** Diff main/cashu.c vs tollgate_core/src/tollgate_core_cashu.c
125- [ ] **2C.2** Merge unique main/ functionality into tollgate_core
126- [ ] **2C.3** Replace main/cashu.c with thin wrapper
127- [ ] **2C.4** Update main/CMakeLists.txt
128- [ ] **2C.5** idf.py build
129- [ ] **2C.6** make test-unit
130- [ ] **2C.7** Quick hardware verify
131- [ ] **2C.8** Commit + push
132
133### 2D: dns_server module
134
135- [ ] **2D.1** Diff main/dns_server.c vs tollgate_core/src/tollgate_core_dns.c
136- [ ] **2D.2** Merge unique main/ functionality into tollgate_core
137- [ ] **2D.3** Replace main/dns_server.c with thin wrapper
138- [ ] **2D.4** Update main/CMakeLists.txt
139- [ ] **2D.5** idf.py build
140- [ ] **2D.6** make test-unit
141- [ ] **2D.7** Quick hardware verify
142- [ ] **2D.8** Commit + push
143
144### 2E: stratum_proxy module
145
146- [ ] **2E.1** Diff main/stratum_proxy.c vs tollgate_core/src/tollgate_core_stratum_proxy.c
147- [ ] **2E.2** Merge unique main/ functionality into tollgate_core
148- [ ] **2E.3** Replace main/stratum_proxy.c with thin wrapper
149- [ ] **2E.4** Update main/CMakeLists.txt
150- [ ] **2E.5** idf.py build
151- [ ] **2E.6** make test-unit
152- [ ] **2E.7** Quick hardware verify
153- [ ] **2E.8** Commit + push
154
155### 2F: mining_payment module
156
157- [ ] **2F.1** Diff main/mining_payment.c vs tollgate_core/src/tollgate_core_mining.c
158- [ ] **2F.2** Merge unique main/ functionality into tollgate_core
159- [ ] **2F.3** Replace main/mining_payment.c with thin wrapper
160- [ ] **2F.4** Update main/CMakeLists.txt
161- [ ] **2F.5** idf.py build
162- [ ] **2F.6** make test-unit
163- [ ] **2F.7** Quick hardware verify
164- [ ] **2F.8** Commit + push
165
166### 2G: Post-restructure verification
167
168- [ ] **2G.1** Full hardware test (repeat Phase 1)
169- [ ] **2G.2** make test-unit — all suites pass
170- [ ] **2G.3** Commit + push
171
172## Phase 3: NerdQAxePlus Component Manager Verification
173
174- [ ] **3.1** BOARD=NERDAXE TOLLGATE=1 idf.py build (from esp-miner-nerdqaxeplus)
175- [ ] **3.2** Verify tollgate_nerdqaxe_init() links correctly
176- [ ] **3.3** Commit + push (if any changes)
177
178## Phase 4: ESP32 ↔ OpenWRT Interop Tests
179
180### Setup infrastructure
181
182- [ ] **4.1** Create esp32/interop-test.sh orchestration script
183- [ ] **4.2** Add interop Make targets to esp32/Makefile (all require board lock + hardware.lock)
184- [ ] **4.3** Add interop Make targets to top-level Makefile (forwarding)
185- [ ] **4.4** Create tests/protocol/esp32-router-interop.spec.mjs (Playwright)
186
187### Direction 1: ESP32 buys from Go router
188
189- [ ] **4.5** interop-esp32-buy-from-alpha: Board A STA → Alpha AP → discover → pay → internet
190- [ ] **4.6** interop-esp32-buy-from-beta: Board A STA → Beta AP → discover → pay → internet
191
192### Direction 2: Go router buys from ESP32
193
194- [ ] **4.7** interop-alpha-buy-from-a: Alpha STA → Board A AP → discover → pay → internet
195- [ ] **4.8** interop-beta-buy-from-a: Beta STA → Board A AP → discover → pay → internet
196
197### Bidirectional
198
199- [ ] **4.9** interop-bidirectional-a-alpha: Both directions in sequence
200- [ ] **4.10** Commit + push
201
202## Phase 5: Post-Restructure Full Test Suite
203
204- [ ] **5.1** make test-unit — all suites pass
205- [ ] **5.2** ESP32 full suite (all 3 boards)
206- [ ] **5.3** OpenWRT full suite (both routers)
207- [ ] **5.4** Playwright E2E (ESP32 captive portal + Go captive portal)
208- [ ] **5.5** Interop tests (all directions)
209- [ ] **5.6** Final commit + push
210
211---
212
213## LWIP Hook Integration Pattern (for Bitaxe/esp-miner repos)
214
215The LWIP hook provides per-client (per-MAC) NAT access control. Other repos integrate it via:
216
2171. Add to root CMakeLists.txt:
218```cmake
219idf_component_get_property(lwip lwip COMPONENT_LIB)
220target_compile_options(${lwip} PRIVATE "-I${PROJECT_DIR}/main")
221target_compile_definitions(${lwip} PRIVATE "-DESP_IDF_LWIP_HOOK_FILENAME=\"lwip_tollgate_hooks.h\"")
222```
223
2242. Copy lwip_tollgate_hooks.h to main/ (calls tollgate_core_ip4_canforward_filter)
225
2263. Add tollgate_core as component dependency (override_path or git)
227
2284. Call from platform code:
229 - tollgate_core_fw_init(ap_ip)
230 - tollgate_core_fw_grant(client_ip)
231 - tollgate_core_fw_revoke(client_ip)
232 - tollgate_core_fw_is_allowed(client_ip)
233 - tollgate_core_ip4_canforward_filter(p, addr) — called by LWIP hook
234
235## Identity Derivation
236
237All identifiers (SSID, MAC, IP) are derived from nsec via HMAC-SHA512:
238
239```
240nsec → secp256k1 → npub (Nostr public key)
241nsec → HMAC-SHA512("sta-mac", 0) → STA MAC (locally administered)
242nsec → HMAC-SHA512("ap-mac", 0) → AP MAC (locally administered)
243AP MAC → SSID = "TollGate-{MAC[3]}{MAC[4]}{MAC[5]}"
244AP MAC → IP = 10.{MAC[3]}.{(MAC[4]^MAC[5])%200+10}.1
245```
246
247Rotating nsec automatically rotates all identifiers.
248
249## Board Configuration
250
251| Board | nsec source | SSID | AP IP | Port |
252|-------|-----------|------|-------|------|
253| A | .env BOARD_A_NSEC | TollGate-B96D80 | 10.185.47.1 | /dev/ttyACM0 |
254| B | .env BOARD_B_NSEC | TollGate-C0E9CA | 10.192.45.1 | /dev/ttyACM1 |
255| C | .env BOARD_C_NSEC | (derived) | (derived) | /dev/ttyACM2 |
256
257## OpenWRT Routers
258
259| Router | IP (LAN) | SSID (open) | API | Mint |
260|--------|----------|-------------|-----|------|
261| Alpha | 10.47.41.1 | TollGate-EVXZ-2.4GHz | :2121 | nofee.testnut, minibits |
262| Beta | 192.168.244.1 | TollGate-24A6-2.4GHz | :2121 | testnut-compat.orangesync |