274b9d2fd4
Add deeper peer CLI coverage for file-transfer integrity and multi-peer chunking. The alpha fixture now carries a real renamed RAR archive larger than 100 MB for alienswarm, which gives the chunk planner enough work to split a single game archive across multiple peers. Expose completed chunk source details as a peer event and have the CLI print that event as JSONL. This keeps transfer behavior in lanspread-peer while the CLI remains a harness that reports what the peer runtime did. The Tauri shell logs the event at debug level so the shared PeerEvent enum stays exhaustive. Document the new S13/S14 scenarios and record the manual run evidence, including SHA-256 manifests and the per-peer byte split for the large archive. Test Plan: - just fmt - just test - just peer-cli-build - just clippy - just peer-cli-image - unrar t -idq crates/lanspread-peer-cli/fixtures/fixture-alpha/alienswarm/alienswarm.eti - Manual peer CLI: bravo -> deep-small-client bfbc2 download with matching SHA-256 manifests - Manual peer CLI: alpha -> deep-stage-b alienswarm download with matching SHA-256 manifests - Manual peer CLI: alpha + deep-stage-b -> deep-stage-c alienswarm download with chunk events from both peers and matching SHA-256 manifests Refs: PEER_CLI_SCENARIOS.md S13 S14
59 lines
5.5 KiB
Markdown
59 lines
5.5 KiB
Markdown
# Peer CLI P2P Scenarios
|
|
|
|
This matrix tracks the headless peer-to-peer contract exercised through
|
|
`lanspread-peer-cli`. It intentionally avoids the GUI and uses direct connect
|
|
for deterministic local runs; mDNS/macvlan remains an environment smoke path.
|
|
|
|
## Scenario Matrix
|
|
|
|
| ID | Scenario | Setup | Expected result |
|
|
| --- | --- | --- | --- |
|
|
| S1 | Startup scan | Start one peer with `fixture-alpha`. | Peer emits `local-peer-ready` and `local-games-updated`; catalog fixture games are `downloaded=true`, `installed=false`, `availability=Ready`. |
|
|
| S2 | Direct connect handshake | Start alpha and bravo, send alpha `connect` to bravo's ready address. | Both peers record one remote peer, no self-peer entry appears, and each peer receives the other's library. |
|
|
| S3 | Remote aggregation | Empty client connects to alpha and bravo. | `list-games` shows remote-only games once; shared `ggoo` has `peer_count=2`, unique games have `peer_count=1`. |
|
|
| S4 | Single-source download, no install | Empty client connected to bravo downloads `bfbc2` with `install=false`. | Client emits `got-game-files`, `download-begin`, `download-finished`, then local `bfbc2` is `downloaded=true`, `installed=false`; root files exist and `local/` does not. |
|
|
| S5 | Auto-install download | Empty client connected to bravo downloads `cnctw` with default install. | Download finishes, install begins and finishes, and local `cnctw` is `downloaded=true`, `installed=true` with `local/fixture-payload.txt`. |
|
|
| S6 | Manual install and uninstall | After S4, client sends `install bfbc2`, then `uninstall bfbc2`. | Install marks `bfbc2` installed and creates `local/`; uninstall removes `local/` while preserving downloaded root files. |
|
|
| S7 | Duplicate-source majority download | Empty client connects to alpha and bravo, then downloads shared `ggoo`. | Metadata from both peers validates by majority/plurality, download completes once, and installed state matches the install flag. |
|
|
| S8 | Ambiguous metadata rejection | Two peers advertise the same game/version with conflicting file sizes. | Download fails with a `download-failed` event; no committed `version.ini` is left for the target game. |
|
|
| S9 | Missing game | Client asks for a game none of its peers can serve. | CLI reports a deterministic command failure and emits `no-peers-have-game`; no local files are created. |
|
|
| S10 | Shutdown and goodbye cleanup | Alpha and bravo are connected, then bravo shuts down. | Alpha receives peer loss/removal and remote games from bravo disappear. |
|
|
| S11 | Same identity reconnect | Bravo restarts with the same state dir but a new port, then alpha connects to the new address. | Alpha has one bravo peer entry with the updated address, not duplicate identities. |
|
|
| S12 | Transfer serving gates | A peer has a non-catalog, missing-sentinel, active-operation, or `local/` path request. | The serving peer declines metadata/data; covered by unit tests where timing is too small for a stable CLI race test. |
|
|
| S13 | Exact transferred-file equality | Repeat small and large downloads, then compare every transferred regular file against its source with SHA-256 manifests. | Source and receiver manifests match exactly for each transferred file; no extra or missing files appear in the downloaded game root. |
|
|
| S14 | Large multi-peer chunked download | `fixture-alpha/alienswarm` contains a renamed RAR `.eti` larger than 100 MB. A second peer downloads it, then a third peer downloads `alienswarm` from both peers. | The third peer's downloaded files match the source by SHA-256; `download-chunk-finished` events show the large `.eti` chunks coming from both peers with byte counts balanced within one chunk. |
|
|
|
|
## Run Log
|
|
|
|
### 2026-05-17 - Exact Transfer And Large Multi-Peer Chunking
|
|
|
|
- Fixture update: `fixture-alpha/alienswarm/alienswarm.eti` was rebuilt with
|
|
`rar a -idq -m0` from three random 40 MiB payload files, then renamed to
|
|
`.eti`. Final archive size: `125,829,913` bytes. `unrar t -idq` passed.
|
|
- Gates before manual runs: `just fmt`, `just test`, `just peer-cli-build`,
|
|
`just clippy`, and `just peer-cli-image` passed.
|
|
- S13 small exact transfer: `deep-small-client` downloaded `bfbc2` from
|
|
`fixture-bravo` with `install=false`. SHA-256 manifests matched exactly:
|
|
`bfbc2/bfbc2.eti`
|
|
`f7accef0833f29481acdeaac58261bc4fc23ebb58b7197049024d354f60daabc`;
|
|
`bfbc2/version.ini`
|
|
`f3d94f70edcebbbc7d8ce38fdf076412fb95114ce1ecf071b26c9c2f93586372`.
|
|
- S13 large exact transfer: `deep-stage-b` downloaded `alienswarm` from
|
|
`fixture-alpha` with `install=false`. SHA-256 manifests matched exactly:
|
|
`alienswarm/alienswarm.eti`
|
|
`8a4fb1fd458e731affb175134b7b99efc8d8a5eda80e978ba81f721d01aecc43`;
|
|
`alienswarm/notes.txt`
|
|
`3832bcb7057a4453981e975d2d2d528bfd9a26671423352f4a8527362d5b9810`;
|
|
`alienswarm/version.ini`
|
|
`8dfdc51d4dbfb06015b41a85a5f5d47f44144139e4a12db2b17eb040773082a3`.
|
|
- S14 multi-peer setup: `deep-stage-c` connected to alpha
|
|
(`10.66.0.3:53514`) and `deep-stage-b` (`10.66.0.2:58491`). `list-games`
|
|
showed `alienswarm` with `peer_count=2` before the download.
|
|
- S14 chunk-source evidence for `alienswarm/alienswarm.eti`: `deep-stage-c`
|
|
received chunks from `deep-stage-b` at offsets `0` and `67,108,864`
|
|
(`67,108,864` bytes total) and from alpha at offsets `33,554,432` and
|
|
`100,663,296` (`58,721,049` bytes total). The source-byte difference was
|
|
`8,387,815` bytes, below one `32 MiB` chunk.
|
|
- S14 final exactness: `deep-stage-c`'s `alienswarm` SHA-256 manifest matched
|
|
`fixture-alpha` exactly for `alienswarm.eti`, `notes.txt`, and `version.ini`.
|