Files
swaits e8e55b7676 chore: initial release v0.1.0
Runtime-agnostic oneshot broadcast channel for Rust.
2025-10-13 19:36:37 -06:00

183 lines
4.4 KiB
Markdown

# Fuzz Testing for Announcement
This directory contains fuzz testing infrastructure using [cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz) and libFuzzer.
## Overview
We have 4 fuzz targets that test different aspects of the `announcement` library:
1. **fuzz_announce** - Tests the announce operation with various data types and patterns
2. **fuzz_close** - Tests close/drop scenarios and the closed detection API
3. **fuzz_listen** - Tests listener operations (try_listen, is_announced, etc.)
4. **fuzz_concurrent** - Tests concurrent access patterns with multiple threads
## Prerequisites
Fuzzing requires nightly Rust and cargo-fuzz:
```bash
rustup install nightly
cargo install cargo-fuzz
```
## Running Fuzz Tests
Run a single fuzz target:
```bash
cargo +nightly fuzz run fuzz_announce
```
Run with a time limit (recommended for CI):
```bash
cargo +nightly fuzz run fuzz_announce -- -max_total_time=60
```
Run with a specific number of iterations:
```bash
cargo +nightly fuzz run fuzz_announce -- -runs=10000
```
Run all fuzz targets sequentially:
```bash
for target in fuzz_announce fuzz_close fuzz_listen fuzz_concurrent; do
echo "Running $target..."
cargo +nightly fuzz run $target -- -runs=10000
done
```
## Continuous Fuzzing
For deeper testing, run fuzz targets for extended periods:
```bash
# Run overnight (8 hours)
cargo +nightly fuzz run fuzz_concurrent -- -max_total_time=28800
# Run until crash (or Ctrl+C)
cargo +nightly fuzz run fuzz_announce
```
## Understanding Output
Fuzzer output includes:
- `cov: X` - Code coverage (number of edges covered)
- `ft: X` - Feature coverage (number of unique code paths)
- `corp: X/Yb` - Corpus size (X inputs, Y bytes total)
- `exec/s: X` - Executions per second
If a crash is found:
- Crash input is saved to `artifacts/FUZZ_TARGET/crash-*`
- Reproduce with: `cargo +nightly fuzz run FUZZ_TARGET artifacts/FUZZ_TARGET/crash-*`
## Fuzz Target Details
### fuzz_announce
Tests basic announce operations:
- Various data types (Vec<u8>, String, u64, Arc<T>)
- Multiple listeners receiving the same data
- is_announced() flag behavior
- Data integrity verification
### fuzz_close
Tests closed detection API:
- Drop without announce
- Explicit close() call
- Announce then drop (should not be closed)
- Multiple listeners with close
- Listener created after close
### fuzz_listen
Tests listener operations:
- try_listen() before and after announce
- Multiple try_listen() calls
- Multiple listeners
- Clone and listener creation
- is_announced() vs is_closed() states
### fuzz_concurrent
Tests thread safety:
- Multiple threads with concurrent listeners
- Concurrent clone and listener creation
- Concurrent is_announced() checks
- Concurrent is_closed() checks
- Various timing patterns with barriers
## Adding New Fuzz Targets
1. Create a new file in `fuzz_targets/` (e.g., `fuzz_new_feature.rs`)
2. Use the template:
```rust
#![no_main]
use libfuzzer_sys::fuzz_target;
use announcement::Announcement;
fuzz_target!(|data: &[u8]| {
// Your fuzz test here
});
```
3. Add to `fuzz/Cargo.toml`:
```toml
[[bin]]
name = "fuzz_new_feature"
path = "fuzz_targets/fuzz_new_feature.rs"
test = false
doc = false
bench = false
```
4. Build and run:
```bash
cargo +nightly fuzz build
cargo +nightly fuzz run fuzz_new_feature
```
## CI Integration
Fuzzing runs automatically in CI on every push/PR:
- Each target runs for 60-120 seconds
- Targets run 1,000-10,000 iterations minimum
- Any crashes fail the build
See `.github/workflows/ci.yml` for details.
## Corpus Management
The fuzzer builds a corpus of interesting inputs in `corpus/FUZZ_TARGET/`. These inputs:
- Are automatically discovered during fuzzing
- Can be committed to Git for regression testing
- Help future fuzzing sessions start with good coverage
To minimize the corpus:
```bash
cargo +nightly fuzz cmin fuzz_announce
```
## Tips
1. **Start with short runs** - Use `-max_total_time=60` to catch obvious bugs quickly
2. **Run overnight** - For thorough testing, run for hours or days
3. **Check coverage** - Monitor `cov:` values to ensure good code coverage
4. **Save crashes** - Commit crash artifacts as regression tests
5. **Update regularly** - Re-run fuzzing when adding new features
## References
- [cargo-fuzz book](https://rust-fuzz.github.io/book/cargo-fuzz.html)
- [libFuzzer documentation](https://llvm.org/docs/LibFuzzer.html)
- [Fuzzing in Rust](https://rust-fuzz.github.io/book/)