RustyBGP End-to-End Tests

July 4, 2026 · View on GitHub

Each subdirectory is a self-contained test scenario. Every test starts its own Docker Compose topology, runs assertions against live BGP sessions, and tears everything down on exit.

Prerequisites

  • Docker with Compose v2 (docker compose)
  • Rust toolchain with a musl target (for local builds)

On x86_64:

rustup target add x86_64-unknown-linux-musl
sudo apt-get install musl-tools   # Debian/Ubuntu

On aarch64 (Apple Silicon, ARM servers):

rustup target add aarch64-unknown-linux-musl

Running all tests locally

tests/e2e/run-all.sh

The script builds rustybgpd once with the musl target, then runs every test in sequence and prints a pass/fail summary. Docker layer caching makes repeated runs fast.

To run a subset of tests, pass their directory names as arguments:

tests/e2e/run-all.sh evpn sr-policy

To skip the build and reuse the binary from a previous run:

SKIP_BUILD=1 tests/e2e/run-all.sh

To override the target triple:

RUST_TARGET=x86_64-unknown-linux-musl tests/e2e/run-all.sh

Running a single test locally

cd tests/e2e/<test-name>
./run-test.sh

The script builds a fresh rustybgpd image from the workspace root, starts the containers, runs the assertions, and removes the containers on exit.

On x86_64 the image build defaults to aarch64-unknown-linux-musl; pass the correct target explicitly:

RUST_TARGET=x86_64-unknown-linux-musl ./run-test.sh

To skip the build and use a prebuilt binary (faster for repeated runs):

# Build once
cargo build --release --target x86_64-unknown-linux-musl

# Point the test at the binary
mkdir -p /tmp/rusty-prebuilt
cp target/x86_64-unknown-linux-musl/release/rustybgpd /tmp/rusty-prebuilt/
cp tests/e2e/shared/Dockerfile.rustybgp-prebuilt /tmp/rusty-prebuilt/Dockerfile

RUSTYBGP_BUILD_CONTEXT=/tmp/rusty-prebuilt \
RUSTYBGP_DOCKERFILE=Dockerfile \
  tests/e2e/<test-name>/run-test.sh

Test directory overview

DirectoryFeatureRFC(s)
add-pathADD-PATH (multiple paths per prefix)RFC 7911
bfdBFD session down triggers BGP teardown without NOTIFICATIONRFC 5880, RFC 5881, RFC 5882
bmp-preBMP pre-policy monitoringRFC 7854
bmp-postBMP pre+post-policy monitoringRFC 7854
bmp-localBMP Loc-RIB monitoringRFC 7854, RFC 9069
bmp-allBMP all policies (pre+post+Loc-RIB+Adj-Out)RFC 7854, RFC 9069
confederationBGP ConfederationRFC 5065
evpnEVPN Types 1-5, AddPathRFC 7432, RFC 9136
extended-nexthopExtended Nexthop EncodingRFC 8950
flowspecBGP Flowspec (IPv4 and IPv6)RFC 8955, RFC 8956
graceful-restart-helperGraceful Restart — helper sideRFC 4724
graceful-restart-restartingGraceful Restart — restarting speakerRFC 4724
link-stateBGP-LS (Node, Link, PrefixV4 NLRIs + BGP-LS attribute)RFC 7752
route-reflectorRoute ReflectorRFC 4456
route-serverBGP Route ServerRFC 7947
rpkiRPKI Route Origin ValidationRFC 6811, RFC 8210
rtcRoute Target Membership — RT-based VPN route filteringRFC 4684
sr-policySR Policy (IPv4, MPLS binding SID, segment list)RFC 9830
two-byte-asTwo-Octet AS Number Peer (AS4_PATH/AS4_AGGREGATOR interop with a real BIRD OLD BGP speaker)RFC 6793
unnumbered-bgpUnnumbered BGP over IPv6 link-local + Extended NexthopRFC 7938, RFC 8950

Shared infrastructure

shared/ contains Dockerfiles and helpers used by all tests:

  • Dockerfile.rustybgp — builds rustybgpd from source (used by default locally)
  • Dockerfile.rustybgp-prebuilt — copies a prebuilt binary (used by CI)
  • Dockerfile.gobgp — GoBGP image used as a BGP peer in most tests
  • Dockerfile.bird — BIRD image built from source (CZ.NIC publishes no official prebuilt image); used as a real RFC 6793 OLD BGP speaker in two-byte-as
  • helpers.sh — shell functions sourced by every run-test.sh