Skip to content

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 !