Table of Contents

Testing and interop

Run the local suite, the benchmarks, and the opt-in Rust interop gates that back the wire-compatibility claim.

go-iroh’s central claim is wire compatibility with Rust iroh. This page is how you check it rather than take it on faith. The commands are the ones the go-iroh README documents; run them from a checkout of the module.

The local suite

go test ./...

For a repeatable check that ignores the test cache:

go test ./... -count=1

This covers the public packages, the qng transport extensions, and local relay and direct behavior. It requires nothing beyond a Go toolchain — no Rust, no network.

Benchmarks

Loopback stream and datagram latency and throughput, with raw TCP and UDP baselines:

GOMAXPROCS=4 go test ./iroh -run '^$' -bench 'Benchmark(Conn|RawTCP|RawUDP)' \
    -benchtime=5s -count=5

BenchmarkRawUDPMagicQueuedPingPong is the closest raw-UDP latency baseline for the magic-socket path: it uses the same receive queue depth, pooled receive buffers, caller-buffer copy, and separate write queue shape as the direct IP transport. Compare against that rather than against a naive UDP loop, which measures a different program.

Live Rust interop gates

These are opt-in because they require a checked-out and built Rust iroh tree. They are the only tests in the module where a real Rust process is on the other end of the wire.

Connectivity and transfer:

GO_IROH_LIVE_RUST_INTEROP=1 \
IROH_RUST_REPO=/path/to/n0-computer/iroh \
go test ./internal/compat -run 'TestLiveRust' -count=1 -v

GO_IROH_LIVE_RUST_INTEROP=1 \
IROH_RUST_REPO=/path/to/n0-computer/iroh \
go test ./iroh -run TestLiveRustTransferFetchPingDirectPath -count=1 -v

Gossip has its own gate, which builds a Rust iroh-gossip helper from gossip/testdata/rust-gossip-interop and exchanges membership and broadcast over /iroh-gossip/1. It requires cargo:

GO_IROH_LIVE_RUST_GOSSIP=1 go test ./gossip -run TestLiveRustGossipInterop -count=1 -v

The README states these gates cover live echo, the Rust transfer provider/upload path, direct-path selection, qlog evidence for QNT frames, and Go↔Rust gossip membership and broadcast — “when the host environment provides the required binaries and network topology”. That conditional matters: a gate that is skipped is not a gate that passed. Read the test output, not just the exit code.

What is not mechanically proven

Being precise about the boundary is more useful than a badge:

The compatibility matrix

The cross-implementation harness described in design/compat-harness-spec.md now exists as a nested module, iroh-compat-harness/, and produces the COMPATIBILITY.md matrix and the parity badge in the README.

It is worth understanding what its “pass” means, because the harness is deliberately strict:

Scenarios span four groups — handshake, discovery, relay, and vectors — run against pinned Rust iroh releases. The vectors group is the interesting one for day-to-day work: the corpus is generated by the pinned Rust driver and committed, so go test ./vectors re-verifies Rust-generated bytes offline and in pure Go, with make vectors regenerating and requiring byte identity.

Reproduce the full matrix from a clean checkout:

cd iroh-compat-harness
make parity          # Docker: builds the pinned Rust image, runs both sides
make parity-native   # or use native pinned binaries

This writes results/results.json, results/badge.json, and the repository-root COMPATIBILITY.md.

The harness lands with the compat-harness branch. If you are reading a checkout of main that has no iroh-compat-harness/ directory, the branch has not merged yet.

Testing your own protocol

Two patterns from the repository are worth copying:

Next steps

Last updated: 2026-08-10