Tests
tracexec currently contains two kinds of tests:
- the normal tests that are executed when running
cargo test --workspace, - tests requiring root that are excluded by default.
Running the Tests
To run the normal tests, use
cargo test --workspace
sudo is needed to run the tests that requires root:
CARGO_TARGET_<TARGET_TRIPLE>_RUNNER='sudo -E' cargo test --workspace -- --ignored
For example, if you are testing on a x86_64 linux machine, use
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER='sudo -E' cargo test --workspace -- --ignored
eBPF Verifier Complexity
Verifier complexity collection is available as an optional UKCI-style Nix runner. It boots the same UKCI kernels in QEMU, loads tracexec’s eBPF programs with verifier stats enabled, and writes one JSON file per kernel/LLVM combination:
nix run .#ukci-complexity
By default, results are written to verifier-complexity/.
Set UKCI_COMPLEXITY_OUT_DIR to use a different output directory.
This runner is intentionally separate from ukci and is not part of the
required UKCI test pass.
For pull requests, a dedicated Nix workflow runs this collector on x86_64 when
the compiled kernel-space eBPF sources or x86 BTF headers change. It uploads the
raw JSON and rendered plots as Actions artifacts and updates a folded summary
comment as soon as the complexity run finishes. The reporter also stores the
PNG plots on ImgBB without an expiration and embeds them in the comment so they
remain available after the artifacts expire. Configure the reporter with an
IMGBB_API_KEY repository secret.
To plot the collected results from the repository root:
nix run .#plot-verifier-complexity -- verifier-complexity
The plotting script writes charts and a summary under
verifier-complexity-plots/ by default. Use -o to choose another output
directory, and --log-scale when comparing runs with large differences between
the smallest and largest verifier counts.
Test Coverage
Most of the time you do not need to calculate the test coverage by yourself because we are tracking the test coverage continuously with CodeCov.
You will see the patch coverage and code coverage diff in a comment by CodeCov once you opened a pull request and all the tests pass.
Continue to read this section if you want to calculate the test coverage by yourself.
First, install cargo-llvm-cov
if you haven’t already installed.
Then run the normal tests with coverage instrumentation to generate a coverage report named lcov.info:
cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info
After that, run the root-only tests with coverage instrumentation.
We use bpfcov-rs to collect coverage of eBPF code that executes in kernel-space.
export CARGO_TARGET_<TARGET_TRIPLE>_RUNNER='sudo -E env TRACEXEC_BPFCOV_OUTDIR=/tmp/bpfcov'
# Replace <TARGET_TRIPLE> with your rust target triple in uppercase and replace dash with underscore.
# For example: export CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER='sudo -E env TRACEXEC_BPFCOV_OUTDIR=/tmp/bpfcov'
cargo llvm-cov --all-features --workspace --lcov \
--output-path root-lcov.info -- --ignored
After the tests finish,
- a user-space coverage report named
root-lcov.infois produced, - and kernel-space test coverage reports for each eBPF test is located
in
/tmp/bpfcov.
Then, combine all the kernel-space test coverage reports:
find /tmp/bpfcov -name '*.lcov' -print0 \
| xargs -0 -I{} echo -a {} \
| xargs lcov -o ebpf.lcov
And finally combine all three coverage reports into one:
lcov -a ebpf.lcov -a lcov.info -a root-lcov.info -o tracexec.info
Optionally you can generate an HTML report with:
genhtml tracexec.info --output-directory cov-out
Add a Test
Feel free to add new tests to cover new/modified code.
When adding a test that requires root, please mark it with
#![allow(unused)]
fn main() {
#[ignore = "root"]
}
When the test loads eBPF program, please make sure that it runs sequentially with respect to other eBPF tests by marking it with:
#![allow(unused)]
fn main() {
#[rstest]
#[file_serial(bpf)]
}
The outer rstest attribute is a workaround for getting the real test name.