Files
amethyst/quic/interop/plans/2026-05-06-interop-runner.md
T
Claude 1586c0cced feat(quic-interop): scaffold quic-interop-runner endpoint module
Adds :quic-interop, a JVM-only module at quic/interop/ that implements
the quic-interop-runner Docker contract so we can drive matrix tests
against aioquic / quiche / picoquic / msquic / ngtcp2 / etc. as a
bug-finding harness.

Phase 0 supports only the `handshake` testcase; everything else returns
127 so the runner skips rather than fails. SSLKEYLOGFILE / QLOGDIR
plumbing is deferred to Phase 1.

https://claude.ai/code/session_01HcvfQq1ttPV9PkRoJb4nyT
2026-05-06 21:08:02 +00:00

2.7 KiB
Raw Blame History

quic-interop-runner endpoint — Phase 0 scaffolding

Date: 2026-05-06

Why

We want the quic-interop-runner matrix as a bug-finding harness, not a vanity scoreboard. Each peer impl (quiche, aioquic, picoquic, ngtcp2, msquic, mvfst, lsquic, neqo, kwik) enforces different parts of RFC 9000/9001/9002/9114 strictly, so failures triangulate to specific bugs in :quic. The runner's ns-3 sim also exposes loss / reorder / migration scenarios that are awkward to reproduce in unit tests.

What's in Phase 0

  • :quic-interop Gradle module (JVM-only application, registered at quic/interop/ via settings.gradle).
  • InteropClient.kt reads the runner's env-var contract (ROLE, TESTCASE, REQUESTS, …) and dispatches by testcase. Phase 0 implements only handshake; everything else returns 127 (runner-skip).
  • Dockerfile based on martenseemann/quic-network-simulator-endpoint + OpenJDK 21 runtime, copies the installDist output.
  • run_endpoint.sh sources the base image's /setup.sh then execs our JVM binary.
  • Makefile wrappers: make build, make smoke, make clean.

Local iteration loop

# In our repo:
make -C quic/interop build

# In a sibling clone of quic-interop-runner, add to implementations.json:
"amethyst": {
    "image": "amethyst-quic-interop:latest",
    "url":   "https://github.com/vitorpamplona/amethyst",
    "role":  "client"
}

python run.py -d -i amethyst -s aioquic -t handshake --log-dir ./logs

Inspect ./logs/<run>/client_qlog/*.qlog in qvis when something breaks.

Phase ladder (excerpt — full plan in conversation)

Phase Goal Tests Exit criterion
0 Minimum harness handshake one test reproducible end-to-end
1 Triangulate handshake bugs + versionnegotiation, chacha20 green vs aioquic + quiche + picoquic
2 Streams + loss + multiplexing + transfer, multiplexing, *loss, http3 green vs aioquic + quiche; soak 500/500
3 Edge cases retry, resumption, zerortt, keyupdate, rebinding-*, blackhole, amplificationlimit every test green or unsupported-127 with a written reason
4 CI gate nightly Phases 12; PR-blocking subset on every push qlogs uploaded as artifacts on red

Known follow-ups (NOT in Phase 0)

  • SSLKEYLOGFILE and QLOGDIR are not yet wired through to :quic — the runner will set them but our endpoint ignores them. Phase 1 must surface TLS keys (so Wireshark can decrypt the sim's pcap captures) and qlog output (so qvis is useful).
  • Server role: we are client-first. Reassess after Phase 3.
  • WebTransport is not part of the standard interop matrix; it needs a separate harness against moq-rs / chrome-headless.