Files
Rendezvous/docs/integration/test-client.md
T
KyuubiYoru 2ff7cd6d9d
quality-gate / quality (push) Failing after 1m3s
test(integration): add deterministic NAT topology harness (#14)
2026-07-16 11:50:53 +02:00

98 lines
4.3 KiB
Markdown

# Diagnostic TestClient integration guide
Tracking: #25
`FinalFactory.Rendezvous.TestClient` is the smallest supported public-SDK consumer.
It exists for integration development, CI smoke checks, deployment verification,
and operator diagnosis. It is intentionally not a production game client, game
server, matchmaking UI, or relay.
The automated scenario matrix, privileged Linux namespace run, and topology
limitations are documented in the [deterministic topology harness](topology-harness.md).
## Prerequisites
Start a configured Rendezvous service and note both its HTTP base URL and UDP
mediator endpoint. The host needs a tenant-scoped publisher credential from the
deployment secret boundary. Put it in an environment variable and pass only that
variable's name when the default is unsuitable:
```bash
export RENDEZVOUS_PUBLISHER_CREDENTIAL='<deployment-supplied value>'
```
Never put the credential in a command argument, URL, checked-in configuration,
shell trace, or captured test fixture. The development server's signing material
is process-ephemeral; credentials from a prior development process are invalid.
## Manual three-terminal flow
Start the host:
```bash
dotnet run --project src/FinalFactory.Rendezvous.TestClient -- \
host --service http://127.0.0.1:5000/ --mediator 127.0.0.1:9050 \
--game space-game --environment development --region local --protocol 1
```
Browse from another terminal:
```bash
dotnet run --project src/FinalFactory.Rendezvous.TestClient -- \
browse --service http://127.0.0.1:5000/ \
--game space-game --environment development --region local --protocol 1
```
Join from a third terminal. Omit `--listing` for an interactive choice:
```bash
dotnet run --project src/FinalFactory.Rendezvous.TestClient -- \
join --service http://127.0.0.1:5000/ --mediator 127.0.0.1:9050 \
--game space-game --environment development --region local --protocol 1 \
--listing 00000000-0000-0000-0000-000000000000
```
Replace the sample UUID with the public listing ID printed by host or browse.
Host and join each create one caller-owned LiteNetLib manager. That same socket
sends presence/punch traffic, establishes the authenticated direct connection,
and carries the ping/echo/ack/completion payload. The final completion confirms
that the host received the reliable acknowledgement; none of this traffic passes through the HTTP
service or UDP mediator.
## CI and deployment smoke flow
Use `--script --json`, set `--listing` when deterministic selection matters, and
check the documented process exit code. `--timeout-seconds` bounds each startup,
traversal, or direct-traffic stage; a script host also uses it as its total runtime
unless `--run-seconds` is explicit. A host can add `--exit-after-echo` so it
terminates after the joining peer acknowledges direct traffic and receives the
host's completion confirmation. Every wait is
bounded by coordinator state and `--timeout-seconds`; no orchestration should use
an unbounded sleep.
The normal test suite contains a real process gate that starts the built Server,
host TestClient, and join TestClient, waits for readiness and versioned events,
and verifies direct traffic, cleanup, JSON shape, and secret canaries. Process
trees are force-terminated in the test cleanup path if normal shutdown fails.
Useful success events are:
- `host.registered`, `host.ready`, `host.direct-traffic`, and `host.deregistered`;
- `browse.completed` and `browse.session`; and
- `join.connected`, `join.direct-traffic`, and `join.outcome-report`.
Failure events preserve stable typed phases and outcomes. When a terminal outcome
contains a configured dedicated endpoint, `join.fallback` reports `available`
with endpoint type `dedicated`; no raw address is printed and no fallback is
started implicitly.
## What the proof does and does not establish
The deterministic loopback test proves the complete service/host/client protocol,
ticket admission, and peer-to-peer payload path. Loopback is not evidence that all
consumer routers, carrier-grade NATs, symmetric NATs, firewalls, VPNs, IPv6 paths,
or platform policies permit hole punching. Same-LAN, separated observed endpoints,
network namespaces/containers, mediator restart, and adverse topology coverage
belong to the topology harness tracked by #14. Production rollout still requires
tests from representative networks and a game-owned fallback policy.