Building & Testing¶
Complete guide to building, testing, and developing Felix.
Build System¶
Felix uses Cargo (Rust's build tool) and Task (optional task runner) for builds.
Prerequisites¶
Required:
- Rust 1.92.0+: Install via rustup
- Cargo: Included with Rust
Optional:
- Task: Convenience task runner (install)
- cargo-llvm-cov: Code coverage (install)
- cargo-deny: Dependency auditing (install)
Check Versions¶
Building¶
Workspace Build¶
Felix uses a Cargo workspace with multiple crates:
# Build entire workspace (debug)
cargo build --workspace
# Build release (optimized)
cargo build --workspace --release
# Or with Task
task build
Build profiles:
- Debug: Fast compilation, slow runtime, debug symbols
- Release: Slow compilation, fast runtime, optimized
Always Use Release for Testing
Debug builds are 10-100x slower. Use --release for performance testing.
Building Specific Crates¶
# Build only the broker
cargo build -p broker --release
# Build only the wire protocol crate
cargo build -p felix-wire
# Build client SDK
cargo build -p felix-client
Building with Features¶
# Build with telemetry enabled
cargo build --workspace --release --features telemetry
# Build without default features
cargo build --workspace --no-default-features
# List available features
cargo metadata --format-version 1 | jq '.packages[0].features'
Build Output¶
Build artifacts go to target/:
target/
debug/ # Debug builds
broker # Broker binary
libfelix_*.so # Library artifacts
release/ # Release builds
broker # Optimized binary
Clean Builds¶
# Remove build artifacts
cargo clean
# Or with Task
task clean
# Remove everything including downloaded crates
task clean-all
# Or: rm -rf target
Running¶
Broker Service¶
# Run broker (debug)
cargo run -p broker
# Run broker (release)
cargo run --release -p broker
# Run with environment variables
FELIX_QUIC_BIND=0.0.0.0:5001 cargo run --release -p broker
Demo Applications¶
# Demos are self-contained (in-process broker)
# Pub/sub demo
cargo run --release -p broker --bin pubsub-demo-simple
# Cache demo
cargo run --release -p broker --bin cache-demo
# Latency benchmark
cargo run --release -p broker --bin latency-demo
# Notifications demo
cargo run --release -p broker --bin pubsub-demo-notifications
# Orders/payments pipeline demo
cargo run --release -p broker --bin pubsub-demo-orders
# Live RBAC policy change demo (control plane + broker + token exchange)
cargo run --manifest-path demos/rbac-live/Cargo.toml
# Cross-tenant isolation demo (control plane + broker + token exchange)
cargo run --manifest-path demos/cross_tenant_isolation/Cargo.toml
# Or with Task
task demo:pubsub
task demo:cache
task demo:latency
task demo:notifications
task demo:orders
task demo:rbac-live
task demo:cross-tenant-isolation
Custom Demo Arguments¶
# Latency demo with custom settings
cargo run --release -p broker --bin latency-demo -- \
--binary \
--fanout 10 \
--batch 64 \
--payload 4096 \
--total 10000 \
--warmup 500
Testing¶
Running Tests¶
# Run all tests
cargo test --workspace
# Run tests for specific crate
cargo test -p felix-broker
# Run specific test
cargo test test_name
# Run with output
cargo test -- --nocapture
# Run with Task
task test
Test Organization¶
Tests are organized in multiple ways:
Unit tests (inline):
// In src/my_module.rs
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_my_function() {
assert_eq!(my_function(1), 2);
}
}
Integration tests (separate files):
Doc tests (in documentation):
Test Patterns¶
Async tests:
#[tokio::test]
async fn test_async_operation() {
let result = my_async_fn().await;
assert!(result.is_ok());
}
Test fixtures:
fn setup_test_broker() -> Broker {
BrokerBuilder::new()
.with_config(test_config())
.build()
.unwrap()
}
#[test]
fn test_with_fixture() {
let broker = setup_test_broker();
// Test logic
}
Test isolation:
// Use serial_test for tests that can't run in parallel
use serial_test::serial;
#[test]
#[serial]
fn test_that_uses_global_state() {
// Test logic
}
Test Filters¶
# Run tests matching pattern
cargo test broker
# Run tests in specific module
cargo test broker::tests::
# Exclude slow tests
cargo test --exclude-tag slow
Code Coverage¶
Installing cargo-llvm-cov¶
Generating Coverage¶
# Generate coverage report
cargo llvm-cov --all-features --workspace
# Generate HTML report
cargo llvm-cov --all-features --workspace --html
open target/llvm-cov/html/index.html
# Or with Task
task coverage
Configuration (in .cargo/config.toml):
The coverage task skips demo binaries:
cargo llvm-cov --ignore-filename-regex 'demos/broker/.*demo.*' \
--skip-functions --all-features --workspace
Coverage Targets¶
- Target: >80% code coverage
- Critical paths: >95% coverage
- Tested in CI: Coverage tracked in PRs
Linting and Formatting¶
Formatting¶
Felix uses rustfmt for consistent code formatting:
# Format all code
cargo fmt --all
# Check formatting (CI mode)
cargo fmt -- --check
# Or with Task
task fmt
Configuration (.rustfmt.toml):
Linting with Clippy¶
# Run clippy
cargo clippy --workspace --all-targets --all-features -- -D warnings
# Fix automatically where possible
cargo clippy --fix
# Or with Task
task clippy
Clippy checks:
- Common mistakes
- Performance issues
- Style violations
- Idiomatic Rust patterns
Combined Lint Check¶
# Format and lint
cargo fmt --all && cargo clippy --workspace --all-targets --all-features -- -D warnings
# Or with Task
task lint
Dependency Auditing¶
Installing cargo-deny¶
Running Audit¶
What it checks:
- Security vulnerabilities
- License compliance
- Banned dependencies
- Duplicate dependencies
Configuration (deny.toml):
[advisories]
vulnerability = "deny"
unmaintained = "warn"
[licenses]
unlicensed = "deny"
allow = ["Apache-2.0", "MIT"]
[bans]
multiple-versions = "warn"
Continuous Integration¶
GitHub Actions Workflows¶
Felix uses GitHub Actions for CI:
.github/workflows/ci.yml: - Build on Linux, macOS, Windows - Run tests - Check formatting - Run clippy - Verify documentation builds
.github/workflows/coverage.yml: - Generate code coverage - Upload to coverage service - Update coverage badge
Running CI Locally¶
Replicate CI checks locally:
# Format check
cargo fmt -- --check
# Clippy
cargo clippy --workspace --all-targets --all-features -- -D warnings
# Tests
cargo test --workspace
# Build
cargo build --workspace --release
# Or run all checks
task lint && task test && task build
CI Requirements for PRs¶
All PRs must pass:
- ✅ Formatting check
- ✅ Clippy with no warnings
- ✅ All tests passing
- ✅ Documentation builds
- ✅ No new security vulnerabilities
Performance Testing¶
Latency Benchmarks¶
Basic run:
Custom configuration:
cargo run --release -p broker --bin latency-demo -- \
--binary \
--fanout 10 \
--batch 64 \
--payload 4096 \
--total 10000 \
--warmup 500
Batch latency matrix:
# Run full benchmark matrix
task perf:latency-matrix
# Or manually
python3 scripts/perf/run_latency_matrix.py
python3 scripts/perf/normalize_and_aggregate.py
python3 scripts/perf/make_charts.py
python3 scripts/perf/render_markdown_snippets.py
Cache Benchmarks¶
# Run cache benchmarks
cargo run --release -p broker --bin cache-demo
# Or with Task
task demo:cache
Configurable parameters:
export FELIX_CACHE_CONN_POOL=8
export FELIX_CACHE_STREAMS_PER_CONN=4
export FELIX_CACHE_BENCH_CONCURRENCY=32
export FELIX_CACHE_BENCH_KEYS=1024
cargo run --release -p broker --bin cache-demo
Profiling¶
CPU Profiling¶
Linux (perf):
# Record profile
sudo perf record -g --call-graph dwarf cargo run --release -p broker
# View report
sudo perf report
# Generate flamegraph
cargo install flamegraph
cargo flamegraph -p broker
macOS (Instruments):
# Build with debug symbols
cargo build --profile release-with-debug -p broker
# Profile with Instruments
instruments -t "Time Profiler" ./target/release-with-debug/broker
Memory Profiling¶
Valgrind (Linux):
# Build debug
cargo build -p broker
# Run with valgrind
valgrind --leak-check=full --show-leak-kinds=all ./target/debug/broker
Heaptrack (Linux):
# Install heaptrack
sudo apt install heaptrack heaptrack-gui
# Profile
heaptrack cargo run --release -p broker
# Analyze
heaptrack_gui heaptrack.broker.*.gz
Documentation¶
API Documentation¶
Build and view:
Document private items:
User Documentation¶
Install MkDocs:
Build and serve:
cd docs-site
# Serve locally (live reload)
mkdocs serve
# Build static site
mkdocs build
# Output to site/ directory
Open documentation:
Task Reference¶
Felix includes a Taskfile.yml for common tasks:
Available Tasks¶
# Build
task build # Build workspace
task clean # Clean artifacts
task clean-all # Remove target/ directory
# Code quality
task fmt # Format code
task lint # Format check + clippy
task clippy # Run clippy
# Testing
task test # Run tests
task coverage # Generate coverage report
# Security
task deny # Audit dependencies
# Demos
task demo:pubsub # Run pubsub demo
task demo:cache # Run cache demo
task demo:latency # Run latency demo
task demo:notifications # Run notifications demo
task demo:orders # Run orders pipeline demo
task demo:rbac-live # Run live RBAC mutation demo
task demo:cross-tenant-isolation # Run cross-tenant isolation demo
# Benchmarking
task perf:latency-matrix # Run full latency benchmark matrix
# Wire protocol
task conformance # Run wire protocol conformance tests
Using Task¶
Troubleshooting Builds¶
Rust Version Issues¶
# Check version
rustc --version
# Update Rust
rustup update
# Override for project
rustup override set 1.92.0
Dependency Issues¶
# Update dependencies
cargo update
# Clear registry cache
rm -rf ~/.cargo/registry
# Rebuild from scratch
cargo clean
cargo build --workspace
Linker Errors¶
Linux:
macOS:
Out of Disk Space¶
# Clean build artifacts
cargo clean
# Remove old builds
rm -rf target
# Check disk usage
du -sh target
Slow Builds¶
# Limit parallel jobs
cargo build -j 2
# Use faster linker (Linux)
sudo apt install lld
export RUSTFLAGS="-C link-arg=-fuse-ld=lld"
# Or use mold
export RUSTFLAGS="-C link-arg=-fuse-ld=mold"
Best Practices¶
Development Workflow¶
- Start with tests: Write test first (TDD)
- Format often: Run
cargo fmtfrequently - Check clippy: Fix warnings as you go
- Run tests: Before committing
- Build release: Test performance changes
Before Committing¶
# Pre-commit checklist
task fmt # Format code
task lint # Check style
task test # Run tests
task build # Verify build
Performance Testing¶
- Always use release builds:
--release - Warm up: Run warmup iterations
- Multiple runs: Average results
- Isolate variables: Change one thing at a time
- Document environment: Hardware, OS, config
Next Steps¶
- Contributing guide: Contributing
- Project structure: Project Structure
- Architecture: System Design