Building & Testing
How to build, test, and develop Felix — the same commands CI runs.
Build System
Section titled “Build System”Felix uses Cargo (Rust’s build tool) and Task (optional task runner) for builds.
Prerequisites
Section titled “Prerequisites”Required:
- Rust 1.97.1+: 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
Section titled “Check Versions”# Rust and Cargorustc --versioncargo --version
# Should show 1.97.1 or laterBuilding
Section titled “Building”Workspace Build
Section titled “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 Tasktask buildBuild profiles:
- Debug: Fast compilation, slow runtime, debug symbols
- Release: Slow compilation, fast runtime, optimized
Building Specific Crates
Section titled “Building Specific Crates”# Build only the brokercargo build -p broker --release
# Build only the wire protocol cratecargo build -p felix-wire
# Build client SDKcargo build -p felix-clientBuilding with Features
Section titled “Building with Features”# Build with telemetry enabledcargo build --workspace --release --features telemetry
# Build without default featurescargo build --workspace --no-default-features
# List available featurescargo metadata --format-version 1 | jq '.packages[0].features'Build Output
Section titled “Build Output”Build artifacts go to target/:
target/ debug/ # Debug builds broker # Broker binary libfelix_*.so # Library artifacts release/ # Release builds broker # Optimized binaryClean Builds
Section titled “Clean Builds”# Remove build artifactscargo clean
# Or with Tasktask clean
# Remove everything including downloaded cratestask clean-all# Or: rm -rf targetRunning
Section titled “Running”Broker Service
Section titled “Broker Service”# Run broker (debug)cargo run -p broker
# Run broker (release)cargo run --release -p broker
# Run with environment variablesFELIX_QUIC_BIND=0.0.0.0:5001 cargo run --release -p brokerDemo Applications
Section titled “Demo Applications”# Demos are self-contained (in-process broker)
# Pub/sub democargo run --release -p broker --bin pubsub-demo-simple
# Cache democargo run --release -p broker --bin cache-demo
# Latency benchmarkcargo run --release -p broker --bin latency-demo
# Notifications democargo run --release -p broker --bin pubsub-demo-notifications
# Orders/payments pipeline democargo 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 Tasktask demo:pubsubtask demo:cachetask demo:latencytask demo:notificationstask demo:orderstask demo:rbac-livetask demo:cross-tenant-isolationCustom Demo Arguments
Section titled “Custom Demo Arguments”# Latency demo with custom settingscargo run --release -p broker --bin latency-demo -- \ --binary \ --fanout 10 \ --batch 64 \ --payload 4096 \ --total 10000 \ --warmup 500Testing
Section titled “Testing”Running Tests
Section titled “Running Tests”# Run all testscargo test --workspace
# Run tests for specific cratecargo test -p felix-broker
# Run specific testcargo test test_name
# Run with outputcargo test -- --nocapture
# Run with Tasktask testTest Organization
Section titled “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):
crates/felix-broker/ tests/ integration_test.rsDoc tests (in documentation):
/// Example usage:/// ```/// use felix_broker::Broker;/// let broker = Broker::new();/// ```Test Patterns
Section titled “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 paralleluse serial_test::serial;
#[test]#[serial]fn test_that_uses_global_state() { // Test logic}Test Filters
Section titled “Test Filters”# Run tests matching patterncargo test broker
# Run tests in specific modulecargo test broker::tests::
# Exclude slow testscargo test --exclude-tag slowCode Coverage
Section titled “Code Coverage”Installing cargo-llvm-cov
Section titled “Installing cargo-llvm-cov”cargo install cargo-llvm-covGenerating Coverage
Section titled “Generating Coverage”# Generate coverage reportcargo llvm-cov --all-features --workspace
# Generate HTML reportcargo llvm-cov --all-features --workspace --htmlopen target/llvm-cov/html/index.html
# Or with Tasktask coverageConfiguration (in .cargo/config.toml):
The coverage task skips demo binaries:
cargo llvm-cov --ignore-filename-regex 'demos/broker/.*demo.*' \ --skip-functions --all-features --workspaceCoverage Targets
Section titled “Coverage Targets”- Target: >80% code coverage
- Critical paths: >95% coverage
- Tested in CI: Coverage tracked in PRs
Linting and Formatting
Section titled “Linting and Formatting”Formatting
Section titled “Formatting”Felix uses rustfmt for consistent code formatting:
# Format all codecargo fmt --all
# Check formatting (CI mode)cargo fmt -- --check
# Or with Tasktask fmtConfiguration (.rustfmt.toml):
edition = "2021"max_width = 100tab_spaces = 4Linting with Clippy
Section titled “Linting with Clippy”# Run clippycargo clippy --workspace --all-targets --all-features -- -D warnings
# Fix automatically where possiblecargo clippy --fix
# Or with Tasktask clippyClippy checks:
- Common mistakes
- Performance issues
- Style violations
- Idiomatic Rust patterns
Combined Lint Check
Section titled “Combined Lint Check”# Format and lintcargo fmt --all && cargo clippy --workspace --all-targets --all-features -- -D warnings
# Or with Tasktask lintDependency Auditing
Section titled “Dependency Auditing”Installing cargo-deny
Section titled “Installing cargo-deny”cargo install cargo-deny --version 0.19.0 --lockedRunning Audit
Section titled “Running Audit”# Check dependenciescargo-deny check
# Or with Tasktask denyWhat 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
Section titled “Continuous Integration”GitHub Actions Workflows
Section titled “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
Section titled “Running CI Locally”Replicate CI checks locally:
# Format checkcargo fmt -- --check
# Clippycargo clippy --workspace --all-targets --all-features -- -D warnings
# Testscargo test --workspace
# Buildcargo build --workspace --release
# Or run all checkstask lint && task test && task buildCI Requirements for PRs
Section titled “CI Requirements for PRs”CI runs the same commands as task lint and task test: formatting, clippy
with warnings denied, the full test suite, the docs build, and dependency
audit. A PR that passes those locally passes CI.
Performance Testing
Section titled “Performance Testing”Latency Benchmarks
Section titled “Latency Benchmarks”Basic run:
cargo run --release -p broker --bin latency-demoCustom configuration:
cargo run --release -p broker --bin latency-demo -- \ --binary \ --fanout 10 \ --batch 64 \ --payload 4096 \ --total 10000 \ --warmup 500Batch latency matrix:
# Run full benchmark matrixtask perf:latency-matrix
# Or manuallypython3 scripts/perf/run_latency_matrix.pypython3 scripts/perf/normalize_and_aggregate.pypython3 scripts/perf/make_charts.pypython3 scripts/perf/render_markdown_snippets.pyCache Benchmarks
Section titled “Cache Benchmarks”# Run cache benchmarkscargo run --release -p broker --bin cache-demo
# Or with Tasktask demo:cacheConfigurable parameters:
export FELIX_CACHE_CONN_POOL=8export FELIX_CACHE_STREAMS_PER_CONN=4export FELIX_CACHE_BENCH_CONCURRENCY=32export FELIX_CACHE_BENCH_KEYS=1024
cargo run --release -p broker --bin cache-demoProfiling
Section titled “Profiling”CPU Profiling
Section titled “CPU Profiling”Linux (perf):
# Record profilesudo perf record -g --call-graph dwarf cargo run --release -p broker
# View reportsudo perf report
# Generate flamegraphcargo install flamegraphcargo flamegraph -p brokermacOS (Instruments):
# Build with debug symbolscargo build --profile release-with-debug -p broker
# Profile with Instrumentsinstruments -t "Time Profiler" ./target/release-with-debug/brokerMemory Profiling
Section titled “Memory Profiling”Valgrind (Linux):
# Build debugcargo build -p broker
# Run with valgrindvalgrind --leak-check=full --show-leak-kinds=all ./target/debug/brokerHeaptrack (Linux):
# Install heaptracksudo apt install heaptrack heaptrack-gui
# Profileheaptrack cargo run --release -p broker
# Analyzeheaptrack_gui heaptrack.broker.*.gzDocumentation
Section titled “Documentation”API Documentation
Section titled “API Documentation”Build and view:
# Build docscargo doc --workspace --no-deps
# Open in browsercargo doc --open --no-depsDocument private items:
cargo doc --workspace --document-private-itemsUser Documentation
Section titled “User Documentation”Install the documentation dependencies:
cd docs-sitenpm installBuild and serve:
# Serve locally (live reload)npm run dev
# Build static sitenpm run build
# Output to dist/ directoryOpen documentation:
Use the local URL printed by Astro.Task Reference
Section titled “Task Reference”Felix includes a Taskfile.yml for common tasks:
Available Tasks
Section titled “Available Tasks”# Buildtask build # Build workspacetask clean # Clean artifactstask clean-all # Remove target/ directory
# Code qualitytask fmt # Format codetask lint # Format check + clippytask clippy # Run clippy
# Testingtask test # Run teststask coverage # Generate coverage report
# Securitytask deny # Audit dependencies
# Demostask demo:pubsub # Run pubsub demotask demo:cache # Run cache demotask demo:latency # Run latency demotask demo:notifications # Run notifications demotask demo:orders # Run orders pipeline demotask demo:rbac-live # Run live RBAC mutation demotask demo:cross-tenant-isolation # Run cross-tenant isolation demo
# Benchmarkingtask perf:latency-matrix # Run full latency benchmark matrix
# Wire protocoltask conformance # Run wire protocol conformance testsUsing Task
Section titled “Using Task”# List all taskstask --list
# Run tasktask build
# Chain taskstask lint && task testTroubleshooting Builds
Section titled “Troubleshooting Builds”Rust Version Issues
Section titled “Rust Version Issues”# Check versionrustc --version
# Update Rustrustup update
# Override for projectrustup override set 1.97.1Dependency Issues
Section titled “Dependency Issues”# Update dependenciescargo update
# Clear registry cacherm -rf ~/.cargo/registry
# Rebuild from scratchcargo cleancargo build --workspaceLinker Errors
Section titled “Linker Errors”Linux:
sudo apt-get install build-essential pkg-config libssl-devmacOS:
xcode-select --installOut of Disk Space
Section titled “Out of Disk Space”# Clean build artifactscargo clean
# Remove old buildsrm -rf target
# Check disk usagedu -sh targetSlow Builds
Section titled “Slow Builds”# Limit parallel jobscargo build -j 2
# Use faster linker (Linux)sudo apt install lldexport RUSTFLAGS="-C link-arg=-fuse-ld=lld"
# Or use moldexport RUSTFLAGS="-C link-arg=-fuse-ld=mold"Before committing
Section titled “Before committing”task lint && task test is the whole pre-commit ritual — it is exactly what
CI runs. For performance work, measure release builds only, warm up first,
average several runs, change one variable at a time, and write down the
environment the numbers came from.
Next Steps
Section titled “Next Steps”- Contributing guide: Contributing
- Project structure: Project Structure
- Architecture: System Design
