Skip to content

Testing

Policy: No Crate Is Ignored

Every crate must be tested when its code changes. No crate is silently skipped. Crates that can't run in the default test suite get their own dedicated CI jobs on the appropriate runner.

CI Runners (Azure Self-Hosted)

All CI runs on self-hosted Azure runners managed via Terraform (infra/terraform/github-runner/).

General pool (VMSS, auto-scaling):

  • Standard_D2s_v5 (2 vCPU, 8 GB RAM, 30 GB disk)
  • Labels: self-hosted, linux, x64, azure
  • Auto-scales from 1 to 4 instances based on CPU utilization
  • Used by: detect, check, docker, release Linux builds

Heavy runner (single VM):

  • Standard_D4s_v5 (4 vCPU, 16 GB RAM, 64 GB disk)
  • Labels: self-hosted, linux, x64, azure, heavy
  • Used by: check (full suite), kernel-tests, filter-tests
  • Also accepts general CI jobs when pool instances are busy

Runner registration uses a GitHub PAT stored in Azure Key Vault. VMSS instances self-register on boot.

CI Test Suite

CI runs on every push to main/dev and on pull requests. The workflow (ci.yaml) uses affected-crate detection (scripts/affected-crates.sh) to only test crates whose source files — or whose dependencies — changed in the current diff. Workspace-wide files (Cargo.toml, Cargo.lock, patches/, ci.yaml) trigger a full workspace run.

Jobs

JobRunnerRuns whenWhat it tests
checkgeneral poolAny crate changedfmt, clippy, workspace tests (excluding heavy crates)
kernel-testsheavyspt-kernel changed or full releasecargo test -p spt-kernel
filter-testsheavyspt-filter changed or full releasecargo test -p spt-filter with 16 MB stack

Default test commands

bash
# Unit tests (quick — default for pushes/PRs, run on general pool)
cargo test --workspace --lib --exclude spt-filter --exclude spt-kernel -- --test-threads=2

# Full suite (releases, run on general pool)
cargo test --workspace --exclude spt-filter --exclude spt-kernel -- --test-threads=2

Heavy Crates

These crates are tested in dedicated CI jobs on the heavy runner because they have special requirements.

spt-filter

Problem: rustc hits a stack overflow (SIGSEGV) during trait resolution. The crate uses deeply recursive type-level computation (recursion_limit = 4096) that exceeds rustc's default 8 MB thread stack.

CI behavior: The filter-tests job runs on the heavy runner with RUST_MIN_STACK=16777216 (16 MB) when spt-filter or its dependencies change, and always during full release suites.

bash
# Test spt-filter locally (16 MB stack)
RUST_MIN_STACK=16777216 cargo test -p spt-filter --lib -- --test-threads=1

# Or use the helper script
bash scripts/test-heavy-crates.sh spt-filter

spt-kernel

Problem: KernelBuilder::build() tries Docker first, which downloads Linux kernel source and compiles a bzImage inside a container (~20 min).

CI behavior: The kernel-tests job runs on the heavy runner (4 vCPU, 64 GB disk) when spt-kernel code changes, and always during full release suites. 40-minute timeout.

bash
# Test spt-kernel locally
cargo test -p spt-kernel --lib -- --test-threads=1

# Skip the Docker kernel build (uses builtin minimal stub)
NO_DOCKER=1 bash scripts/test-heavy-crates.sh spt-kernel

Testing All Heavy Crates Locally

bash
# Run both spt-filter and spt-kernel tests
bash scripts/test-heavy-crates.sh

# Skip Docker for spt-kernel
NO_DOCKER=1 bash scripts/test-heavy-crates.sh

Adding New Heavy Crates

If a new crate needs a dedicated CI job:

  1. Add it to HEAVY_CRATES in scripts/affected-crates.sh
  2. Add a <name>_changed output flag in the same script
  3. Add --exclude <crate> to the default test commands in ci.yaml
  4. Add a dedicated job in ci.yaml targeting [self-hosted, linux, azure, heavy]
  5. Add a test function to scripts/test-heavy-crates.sh
  6. Document the reason here

Released under the MIT License.