docs: add E2E test progress report 2026-06-17

This commit is contained in:
xieyao
2026-06-17 05:08:23 +08:00
parent a8b411c888
commit e7f1c8e831

View File

@@ -0,0 +1,89 @@
# ZeroMesh E2E Test Progress — 2026-06-17
## Setup
- Environment: Docker Compose on Linux amd64
- Go 1.26.4, SQLite via CGO (`golang:1.26-alpine` with gcc)
- Gitea: `http://gitea.xieyao.vip/xieyao/zeromesh`
- Volume mounts broken → Dockerfiles with `COPY` used instead
- Docker Compose YAML: all shell `$` must be `$$` (interpolation)
## Architecture
```
server (172.30.0.10:10001 HTTP + :19993 UDP/controller)
├─ init — creates admin + testnet (10.7.0.0/24)
├─ client1 — zmclient, UDP 7001, TAP ztmesh0
├─ client2 — zmclient, UDP 7002, TAP ztmesh1
├─ client3 — zmclient, UDP 7003, TAP ztmesh2
└─ tester — curl API queries + verification
```
## What Works
### Server
- HTTP server on `:10001` with Gin + GORM + SQLite auto-migrate
- JWT auth (login, register, init admin)
- Network CRUD with auto IP range generation
- Node registration + authorization
- Online node list
- VL1 controller UDP transport on `:19993`
- Health endpoint at `/api/health`
### Init Container
- Creates admin user (first run) or logs in (subsequent)
- Creates `testnet` network with `10.7.0.0/24`
### Test Clients (`cmd/testclient/main.go`)
- Admin login → init admin if not exists (retry up to 30×2s)
- Identity generation via ed25519 key pair → JSON key file
- Node registration on controller
- Network auto-join: finds existing testnet, creates one if none found
- Self-authorization on network → gets virtual IP
- Agent starts: UDP bind + TAP device open
- `ControllerHello()` — sends public key to controller UDP :19993
- `SyncPeers()` — fetches online nodes, establishes encrypted P2P handshake
- `SetTAPIP()` — configures TAP with MAC + IP
- TCP echo server on virtual IP `:7777`
- Client ready log: `name=` + `ip=` + `tap=` + `peers=N` (all 3 see 2 peers)
### Tester Container
- Login as admin, query `/api/v1/network/list` → sees testnet
- Query `/api/v1/node/online` → sees 3 clients with docker IPs and names
### SDK Components (`sdk/`)
| Component | File | Status |
|-----------|------|--------|
| REST client | `api.go` | Working (login, register, init, networks, nodes, members, authorize, dashboard) |
| Identity | `identity.go` | Working (load/generate/save JSON key file) |
| Agent | `agent.go` | Handshake OK; data plane WIP |
| TAP (Linux) | `tap_linux.go` | Working (open, set MAC, set IP, read/write) |
| TAP (stub) | `tap_stub.go` | Placeholder for non-Linux |
| VL1 protocol | `agent.go` | Header (ver/type/netID/len) + Handshake/Data/Keepalive packets |
| Encryption | `agent.go` | ChaCha20-Poly1305 with PSK + key derivation |
## What's Broken (Next Session)
### P2P Data Plane — Decrypt Failure
- **Symptom**: ping between virtual IPs → 100% packet loss; ARP `FAILED`
- **Root cause**: `deriveKeys` used `(localPub, remotePub)` in fixed order → each side computed different send/recv keys
- **Fix committed** in `a8b411c`: sort public keys with `bytes.Compare` before hashing → both sides get same key pair
- **Status**: fix committed but **untested** — rebuild images + restart compose needed
### Debug Logging Still Active
- `tap miss`, `send data`, `handle data`, `decrypt failed` — Info-level logs in `agent.go`
- Remove after data plane is verified
## Key Learnings
1. Docker volume mounts (`-v /host/path:/container/path`) don't work in this environment → use `COPY` in Dockerfiles
2. Docker Compose v2 interprets `$VAR` in YAML strings → must use `$$VAR` for shell variables
3. TAP MAC must match agent's software-generated MAC → call `SetMAC()` during `SetTAPIP()`
4. ChaCha20-Poly1305 key derivation must sort public keys so both sides agree on send/recv keys
## Next Tasks
1. Rebuild Docker images → `docker compose up -d` → test ping + TCP echo
2. Remove debug logging from `agent.go`
3. Write Go unit tests (VL1 packet, key derivation, MAC table, peer manager, API client)
4. Implement IP collision detection + retry in network service
5. Build standalone agent binary (`cmd/zeromesh-agent-sdk/`)
6. Start Flutter plugin (gomobile/FFI binding)
7. WebSocket real-time updates for Dashboard