QUIC(k) Start β Your First Experiment in β10(30) min πΒ€
This guide shows how to install PANTHER with the new enhanced Click CLI, spin up a simple client β server experiment, and inspect the results using modern command-line tools.
We use QUIC as a concrete example because multiple ready-made QUIC implementations ship with PANTHER, yet the exact same steps apply to MiniP, HTTP/3, a custom protocol plugin, or any future protocol you add.
[!NOTE] "System Requirements" Target platform: Linux (x86-64) or Mac with Docker >= 27 Estimated time (the first time): β 10 minutes if you do not use Ivy tester and β 30 minutes (due to containers building times of implementation), then around 2 minutes. Ivy is very long to compile and depend on your computer.
1 β Write a Minimal Experiment (YAML)Β€
[!NOTE] "Experiments vs Tests" In PANTHER, an experiment is the overall configuration file that defines what to run, while tests are individual scenarios within that experiment. A single experiment can contain multiple tests, each with its own configuration, network setup, and measurements.
# Basic logging configuration
logging:
level: INFO # Controls how much detail you see (DEBUG for troubleshooting)
# Where to save experiment results
paths:
output_dir: outputs # All results saved in 'outputs' folder
# Docker container settings
docker:
build_docker_image: true # Build fresh containers (set false for faster reruns)
# Tests define what protocols and implementations to run
tests:
- name: "QUIC Connection (PicoQUIC)"
description: "My first experiment - basic QUIC client-server test"
network_environment:
type: docker_compose # Run in separate Docker containers
services:
server:
implementation:
name: picoquic # Use PicoQUIC implementation
type: iut # IUT = Implementation Under Test
protocol:
name: quic # Test QUIC protocol
version: rfc9000 # Use official QUIC standard
role: server # This service acts as server
client:
implementation:
name: picoquic # Same implementation for client
type: iut
protocol:
name: quic
version: rfc9000
role: client # This service acts as client
target: server # Connect to the 'server' service above
steps:
wait: 15 # Run test for 15 seconds
- name: "QUIC Connection Tested (PicoQUIC)"
description: "My second experiement"
network_environment:
type: docker_compose
execution_environment: # strace
- type: strace
services:
server:
timeout: 100
implementation:
name: panther_ivy
type: testers
test: quic_client_test_max
protocol:
name: quic
version: rfc9000
role: server
ports:
- "4443:4443"
- "4987:4987"
client:
timeout: 100
implementation:
name: picoquic
type: iut
protocol:
name: quic
version: rfc9000
role: client
target: server
steps:
wait: 100
2 β Run the ExperimentΒ€
[!WARNING] "Docker Buildkit" You SHOULD disable buildkit (experimental) in the config files:
docker: force_build_docker_image: true log_docker_image_build: true # Enable Docker build log files use_buildx: false
With the CLI, experiment execution is more intuitive and provides better feedback (In Progress):
# Preview what will happen (optional dry run) without building images and running them.
panther --debug run --config quic_demo.yaml --dry-run
panther run --config quic_demo.yaml --dry-run --verbose
# Run the actual experiment with metrics
panther --debug run --config quic_demo.yaml --verbose
PANTHER validates the YAML, builds images if absent, launches the two
containers under Docker Compose, runs the handshake for 15 s, and writes
results to outputs/.
[!NOTE] "Alternative Test Configuration" You can also test with built-in examples:
panther run --config experiment-config/experiment_config_example.yaml
3 β Inspect ResultsΒ€
PANTHER creates a timestamped output directory with subfolders for each test:
outputs/
βββ 2025-β¦_experiment_run/
βββ metrics/ # contains experiments monitored metrics
βββ experiment.log # high-level timeline + any errors
βββ experiment_config.yaml # full experiment configuration (including defaults)
βββ QUIC_Connection_PicoQUIC/ # first test results
β βββ metrics/ # contains test monitored metrics
β βββ server/ # server container logs and artifacts
β β βββ stdout.log # server process standard output
β β βββ stderr.log # server process standard error
β β βββ cpu_profile.prof # CPU profile (from gperf_cpu)
β βββ client/ # client container logs and artifacts
β βββ stdout.log # client process standard output
β βββ stderr.log # client process standard error
β βββ cpu_profile.prof # CPU profile (from gperf_cpu)
βββ QUIC_Connection_Tested_PicoQUIC/ # second test results
βββ server/ # server container logs and artifacts
β βββ stdout.log # server process standard output
β βββ stderr.log # server process standard error
β βββ strace.log # system call trace (from strace)
βββ client/ # client container logs and artifacts
βββ stdout.log # client process standard output
βββ stderr.log # client process standard error
βββ strace.log # system call trace (from strace)
4 β Next Steps π§Β€
| Idea | How |
|---|---|
| Test another protocol | Change protocol.name (e.g. minip) and swap implementations. |
| Use Shadow NS | network_environment.type: shadow_ns + topology, duration. |
| Add formal testing | Add tester: name: panther_ivy, test: quic_server_stream. |
| Single-container mode | network_environment.type: localhost_single_container. |
| Create a new plugin | See the Plugin Developer Guide. |
| Enable telemetry | Check the Metrics Guide for performance data. |
Enjoy experimentingβwhether with QUIC or any protocol you plug in!
Check the existing tests configuration at experiment-config/*.yml !