CacheKit Docs

High-performance cache policies and supporting data structures.

View the Project on GitHub OxidizeLabs/cachekit

Fuzzing Integration with CI/CD

This document describes how fuzz testing is integrated into the CacheKit CI/CD pipeline.

Overview

CacheKit uses comprehensive fuzz testing with 27 fuzz targets covering 9 core data structures. Fuzzing runs automatically in CI/CD to catch bugs, edge cases, and security issues.

Fuzz Target Coverage

Data Structure Fuzz Targets Coverage
ClockRing 3 Arbitrary ops, insert stress, eviction patterns
FixedHistory 3 Arbitrary ops, record stress, property tests
FrequencyBuckets 3 Arbitrary ops, stress, property tests
GhostList 3 Arbitrary ops, LRU stress, property tests
KeyInterner 3 Arbitrary ops, stress, property tests
IntrusiveList 3 Arbitrary ops, stress, property tests
LazyMinHeap 3 Arbitrary ops, stress, property tests
ShardSelector 3 Arbitrary ops, distribution, property tests
SlotArena 3 Arbitrary ops, stress, property tests
Total 27 All core data structures

CI/CD Integration

Dynamic Target Discovery

Zero Configuration Required! 🎉

The CI/CD pipeline automatically discovers all fuzz targets using cargo fuzz list. When you add a new fuzz target to fuzz/fuzz_targets/ and register it in fuzz/Cargo.toml, the CI/CD pipeline will automatically:

No workflow file updates needed!

Naming Convention

For best CI integration, follow this naming convention:

Targets ending in _arbitrary_ops are automatically used for PR smoke tests as they provide the best general-purpose testing.

1. Pull Request Smoke Tests (.github/workflows/ci.yml)

When: Every pull request Duration: ~60 seconds per _arbitrary_ops target Purpose: Catch obvious bugs early before merging

Automatically discovers and runs all _arbitrary_ops targets:

# Automatic discovery
TARGETS=$(cargo fuzz list | grep '_arbitrary_ops$')

# Run each with different seed for reproducibility
for target in $TARGETS; do
  cargo fuzz run "$target" -- -max_total_time=60 -seed=$seed
done

What it catches:

2. Continuous Fuzzing (.github/workflows/fuzz.yml)

When:

Duration: 1 hour per target by default (configurable) Purpose: Deep fuzzing to find subtle bugs

Strategy:

How Discovery Works:

discover-targets:
  steps:
    - name: List fuzz targets
      run: |
        cd fuzz
        TARGETS=$(cargo fuzz list | jq -R -s -c 'split("\n") | map(select(length > 0))')
        echo "targets=$TARGETS" >> $GITHUB_OUTPUT

fuzz-continuous:
  needs: discover-targets
  strategy:
    matrix:
      target: $

Features:

3. Corpus Management

Fuzzing corpora (interesting test inputs) are preserved across runs:

- name: Restore corpus
  uses: actions/cache@v4
  with:
    path: fuzz/corpus/$
    key: fuzz-corpus-$-$
    restore-keys: |
      fuzz-corpus-$-

This ensures:

4. Crash Handling

When crashes are detected:

  1. Artifacts Upload: Crash inputs are uploaded for 90 days
    name: fuzz-crashes-$-$
    path: fuzz/artifacts/$/
    retention-days: 90
    
  2. GitHub Issue Creation (nightly runs only):
    • Creates issue with bug, fuzzing, security labels
    • Includes reproduction instructions
    • Links to artifact downloads
    • Provides debugging guidance
  3. Workflow Failure: Pipeline fails to alert maintainers

5. Coverage Reporting

For nightly runs, coverage is generated for representative targets:

Running Fuzzing Locally

Quick Smoke Test

Run all smoke tests (60 seconds each):

cd fuzz
./run_smoke_tests.sh

Or manually:

cd fuzz
cargo fuzz run clock_ring_arbitrary_ops -- -max_total_time=60 -seed=1
cargo fuzz run fixed_history_arbitrary_ops -- -max_total_time=60 -seed=2
# ... etc

Deep Fuzzing

Run a single target for extended duration:

cd fuzz
cargo fuzz run clock_ring_arbitrary_ops -- -max_total_time=3600

Run all targets (from fuzz/README.md):

cd fuzz
for target in $(cargo fuzz list); do
  echo "Fuzzing $target..."
  cargo fuzz run $target -- -max_total_time=300 -jobs=4
done

Reproducing Crashes

If CI finds a crash:

  1. Download the crash artifact from the GitHub Actions run
  2. Reproduce locally:
    cd fuzz
    cargo fuzz run <target> fuzz/artifacts/<target>/<crash-file>
    
  3. Debug with full backtrace:
    RUST_BACKTRACE=full cargo fuzz run <target> <crash-file>
    

Monitoring and Maintenance

Monitoring Fuzzing Health

Check the following regularly:

  1. GitHub Issues: Look for [FUZZ] prefix and fuzzing label
  2. Actions Tab: Review nightly fuzzing workflow results
  3. Corpus Growth: Ensure corpora are growing over time
  4. Coverage Reports: Check coverage artifacts for code coverage

Corpus Maintenance

Periodically minimize corpora to remove redundant inputs:

cd fuzz
for target in $(cargo fuzz list); do
  cargo fuzz cmin $target
done

This is automatically done in CI after each run.

Adding New Fuzz Targets

When adding new data structures or major features:

  1. Create fuzz target in fuzz/fuzz_targets/:
    // fuzz/fuzz_targets/my_module_arbitrary_ops.rs
    #![no_main]
    use libfuzzer_sys::fuzz_target;
    // ... implementation
    
  2. Register in fuzz/Cargo.toml:
    [[bin]]
    name = "my_module_arbitrary_ops"
    path = "fuzz_targets/my_module_arbitrary_ops.rs"
    test = false
    doc = false
    
  3. Document in fuzz/README.md (optional but recommended)

That’s it! ✅ The CI/CD pipeline will automatically discover and run your new target.

Naming Tips:

Best Practices

For Contributors

  1. Run smoke tests before pushing:
    cd fuzz && ./run_smoke_tests.sh
    
  2. Fix fuzzing failures immediately: Fuzzing bugs often indicate real issues

  3. Don’t disable fuzz tests: If a fuzz test is flaky, fix the test or the code

For Maintainers

  1. Review fuzzing issues promptly: They often reveal security issues
  2. Keep corpora: Don’t delete cached corpora without good reason
  3. Monitor nightly runs: Check for patterns in failures
  4. Update fuzz targets: When APIs change, update fuzz targets accordingly

Configuration

Workflow Configuration

Edit .github/workflows/fuzz.yml to adjust:

Resource Limits

Current limits:

Troubleshooting

Fuzzing Timeouts

If targets timeout:

Corpus Cache Misses

If corpora aren’t being restored:

False Positives

If fuzz tests find “issues” that aren’t real bugs:

Resources