Agent Wranglers

TST-62Recommended

Run the tests with a race detector

When code runs on several threads or goroutines, run the tests with a race detector in CI on every pull request. Fail on any race it reports.

How to do it

A data race corrupts state only now and then, so normal tests pass and the bug shows up in production under load. Race detectors watch memory access while the tests run. Examples are go test -race for Go, ThreadSanitizer (-fsanitize=thread) for C, C++ and Rust, and Miri for unsafe Rust. They find races only in code the tests run, so give concurrent code tests that start several workers at once. The detector slows tests and uses more memory, so a separate CI job may run it. Fix each race with the patterns in Guard state that concurrent code shares. Languages without shared-memory threads, such as JavaScript in one event loop, still race across await and need Make conditional writes instead.

Examples

Go example

// go test -race ./...
func TestCounterIsSafeAcrossWorkers(t *testing.T) {
    counter := NewVisitCounter()
    var wg sync.WaitGroup
    for range 50 {
        wg.Add(1)
        go func() { defer wg.Done(); counter.Add() }()
    }
    wg.Wait()
    if counter.Total() != 50 {
        t.Fatalf("got %d visits, want 50", counter.Total())
    }
}

Plain text example

// RUSTFLAGS="-Zsanitizer=thread" cargo +nightly test -Zbuild-std --target x86_64-unknown-linux-gnu
#[test]
fn counter_is_safe_across_workers() {
    let counter = std::sync::Arc::new(VisitCounter::new());
    let workers: Vec<_> = (0..50)
        .map(|_| { let c = counter.clone(); std::thread::spawn(move || c.add()) })
        .collect();
    for worker in workers { worker.join().unwrap(); }
    assert_eq!(counter.total(), 50);
}

How to check

The CI job runs the suite with the race detector, and its log shows the flag. Add two goroutines or threads that write one counter without a lock on a branch. The job fails and names both lines.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/testing/security-and-robustness/race-detector">Agent Wranglers testing playbook</a>. In code you write, add a comment next to it with the same link.