Reactor/loop-pool engine with TCP/µTP/MSE transports, per-connection pipelining, priority-driven piece selection with endgame, and the Python FFI test harness. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
91 lines
2.5 KiB
Markdown
91 lines
2.5 KiB
Markdown
# Offline Client Interop
|
|
|
|
This harness starts several seed-only BitTorrent clients on a Docker Compose
|
|
network with `internal: true`, generates one private test torrent,
|
|
mounts the same data into every seeder, and drives this engine against each
|
|
client independently.
|
|
|
|
It is meant to catch interoperability failures: bad handshakes, encryption/uTP
|
|
negotiation mistakes, malformed requests, or behavior that makes common clients
|
|
reject us. It is not a public-swarm or tracker test.
|
|
|
|
## Clients
|
|
|
|
Default matrix:
|
|
|
|
- `libtorrent-plain-tcp`
|
|
- `libtorrent-mse-tcp` with RC4 required
|
|
- `libtorrent-utp`
|
|
- `libtorrent-utp-mse`
|
|
- `transmission-tcp`
|
|
- `transmission-utp`
|
|
- `transmission-mse-tcp` with encryption required
|
|
- `aria2-tcp`
|
|
- `qbittorrent-tcp`
|
|
- `deluge-tcp`
|
|
- `rtorrent-tcp`
|
|
|
|
All clients run with DHT, PEX, local peer discovery, UPnP, and NAT-PMP disabled.
|
|
The fixture torrent includes the deterministic dummy announce URL
|
|
`http://fixture:9/announce` because rTorrent rejects trackerless torrents, but
|
|
the runner still injects peers directly. The Compose network is internal-only,
|
|
so containers cannot route to the internet during the test run.
|
|
|
|
## Run
|
|
|
|
From the repository root:
|
|
|
|
```sh
|
|
docker compose -f interop/docker-compose.yml up --build \
|
|
--abort-on-container-exit --exit-code-from runner
|
|
```
|
|
|
|
Useful overrides:
|
|
|
|
```sh
|
|
FIXTURE_SIZE=128M TEST_TIMEOUT=180 \
|
|
docker compose -f interop/docker-compose.yml up --build \
|
|
--abort-on-container-exit --exit-code-from runner
|
|
```
|
|
|
|
Results are written to `interop/results/results.json`.
|
|
|
|
Clean generated containers, networks, and the fixture volume:
|
|
|
|
```sh
|
|
docker compose -f interop/docker-compose.yml down -v
|
|
```
|
|
|
|
## Run One Client
|
|
|
|
The runner supports `--only`, but Compose still starts all default dependencies.
|
|
For focused debugging, run a shell after the stack is up:
|
|
|
|
```sh
|
|
docker compose -f interop/docker-compose.yml run --rm runner \
|
|
python3 /work/interop/run_matrix.py \
|
|
--fixture /fixture \
|
|
--clients /work/interop/clients.json \
|
|
--results /results/one.json \
|
|
--only transmission-tcp
|
|
```
|
|
|
|
## Adding Clients
|
|
|
|
Add a seeder service to `docker-compose.yml`, disable all discovery/tracker/NAT
|
|
features for that client, expose it only on `torrent_lab`, then add an entry to
|
|
`clients.json`:
|
|
|
|
```json
|
|
{
|
|
"name": "new-client-tcp",
|
|
"host": "seed-new-client",
|
|
"port": 6900,
|
|
"utp": 0,
|
|
"encryption": 0,
|
|
"fallback": 0
|
|
}
|
|
```
|
|
|
|
The engine currently needs a numeric IP, so the runner resolves the Compose DNS
|
|
name to IPv4 before calling `engine_add_peer`.
|