-
Notifications
You must be signed in to change notification settings - Fork 2
testing
Pre-Alpha. This page describes behavior that may change.
Ze has four test suites: unit, functional, fuzz, and chaos. You run them through the Makefile. Each suite covers a different layer, and they are independent enough that you can run one without the others while you are iterating, and combined enough that make ze-verify runs lint, unit, functional, and ExaBGP tests when you are ready to submit.
Unit tests. Go unit tests in *_test.go files alongside the code. These run in milliseconds to seconds and cover the small-scale correctness of every exported function. make ze-unit-test runs them.
Functional tests. .ci files under test/, driven by ze-test. They start real or mocked Ze instances, feed them configuration, drive sessions, and assert against the wire bytes, log lines, and exit codes. make ze-functional-test runs them.
Fuzz tests. Go fuzz targets, one per external-input parser. Peer wire input, config files, command-line arguments, plugin JSON, and every other input from outside the trust boundary has a fuzz harness. make ze-fuzz-test runs them in a loop.
Chaos tests. Deterministic, seed-driven fault injection orchestrated by ze-chaos. Validates protocol-level invariants under fault. make ze-chaos-test runs the unit and functional chaos suites, and chaos web tests.
make ze-unit-test # Unit tests
make ze-unit-test-cover # Unit tests with coverage
make ze-functional-test # Full functional suite
make ze-encode-test # Encoding-only functional tests
make ze-plugin-test # Plugin behavior functional tests
make ze-reload-test # Reload-path functional tests
make ze-parse-test # Config parsing tests
make ze-fuzz-test # All fuzz targets, one-shot
make ze-fuzz-one FUZZ=<name> PKG=<path> TIME=<duration> # A single fuzz target, longer run
make ze-chaos-test # Unit + functional chaos, and chaos web tests
make ze-test # Lint, unit, functional, ExaBGP, and fuzz combined
make ze-verify # Lint, unit, functional, and ExaBGP, pre-submission
make ze-verify-changed # Same as ze-verify, only on packages your branch touched
make ze-interop-test # Docker interop against FRR, BIRD, GoBGP
make ze-live-test # Live BGP tests
make ze-stress-test # Stress suitemake ze-verify-changed is the one you want to run on every save. It is fast enough that it does not break flow, and it catches most problems before you push.
ze-test drives the functional suite. Listing and running individual tests is a handful of flags.
ze-test bgp encode --list # List the encode tests
ze-test bgp encode 4 5 6 # Run specific tests by index
ze-test bgp encode --all # Run all encode tests
ze-test bgp plugin --list
ze-test bgp plugin --all
ze-test bgp reload --allStress-testing a flaky test:
ze-test bgp encode --count 10 0 1 # Run tests 0 and 1, ten times eachIf a test passes nine times and fails once, it is flaky and it is a bug. Do not land a PR that introduces a flake.
Functional tests are .ci files. The format is a small scripting language: stdin=..., cmd=..., expect=... lines, with terminator-delimited blocks for config and expected output.
A minimal parse test:
stdin=config:terminator=EOF_CONF
bgp {
peer test-peer {
remote {
ip 127.0.0.1;
as 65533;
}
router-id 10.0.0.2;
local-as 65533;
}
}
EOF_CONF
cmd=foreground:seq=1:exec=ze bgp validate -:stdin=config
expect=exit:code=0
The runner parses the file, executes the commands in order, and asserts the expectations. If an expectation fails, the runner prints a diff showing what it expected and what it saw.
The existing .ci files under test/ are the best reference for how to write a new one. Start with the closest existing test, copy it, and edit.
func FuzzParseWireUpdate(f *testing.F) {
// Seed with known-good inputs.
f.Add([]byte{0x00, 0x18, 0x0a, 0x00, 0x00})
f.Fuzz(func(t *testing.T, data []byte) {
// Must not panic, must not infinite-loop.
_, _ = wireu.ParseUpdate(data)
})
}Fuzz seeds are defined inline in fuzz test functions. Adding a known-bad input that used to crash the parser keeps the regression covered.
The interop suite runs Ze against FRR, BIRD, and GoBGP in Docker containers and asserts that every pair negotiates cleanly and exchanges routes correctly. make ze-interop-test runs it. This is the slowest suite, and the one that catches "technically RFC-compliant but nobody else expects that" bugs.
make ze-live-test runs tests against real RPKI caches (stayrtr container). It requires network access and external services that may be unavailable. It is optional for development and mandatory before a release.
make ze-unit-test-cover produces a coverage profile. Coverage is a sanity check, not a target: the goal is that every non-trivial code path has a test, not that a percentage number stays above a threshold. The maintainer cares about whether the test actually exercises the logic, not whether the line is counted.
Before you submit a patch:
-
make ze-verify-changedis green. -
make ze-verifyon the full tree is green. - Any new code has unit tests.
- Any new user-facing behaviour has a functional test.
- Any new external-input parser has a fuzz harness.
- Documentation updates land in the same commit.
If all six are true, run /ze-review-deep in Claude Code and fix whatever it surfaces. Then submit.
- Building for the make targets that produce the binaries.
- Debugging for what to do when a test fails.
- CI for what runs automatically on every PR.
- Performance for the ze-perf BGP propagation benchmark tool.
- Mock Servers for the ze-test built-in mock servers used in functional tests.
-
In-tree functional tests for the full
.cireference.
Adapted from main/docs/functional-tests.md and main/Makefile.
Unreviewed draft. This wiki was authored in bulk and has not been reviewed. File corrections on the issue tracker.
- Overview
- YANG Model
- Editor Workflow
- Archive and Rollback
- System
- Interfaces
- BFD
- FIB
- Firewall
- Traffic Control
- L2TP/PPP
- VPP Data Plane
- RPKI
- TACACS+ AAA
- Fleet
- BGP
- Starting and Stopping
- Show Commands
- Monitoring
- Logging
- Operational Reports
- Healthcheck
- MRT Analysis
- Upgrade and Restart
- Storage
- Policy
- Core
- Resilience
- Validation
- Capabilities
- Address Families
- Protocol
- Subsystems
- Infrastructure
- Route Server at an IXP
- Transit Edge with RPKI
- Public Looking Glass
- ExaBGP Migration Walkthrough
- FlowSpec Injection
- Chaos-Tested Peering
- AS Path Topology