Skip to content

A helper for writing unit test for multi-threaded applications

License

Notifications You must be signed in to change notification settings

trtsl/waypoints

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

waypoints

Summary

This is a helper crate for writing unit tests and debugging in Rust. It allows specifying a sequence at which points of execution may be passed in multi-threaded code. Execution will not pass a waypoint until its designated number is reached.

When writing unit tests (where brevity and simplicity wins over style) it can be helpful to enforce an execution order on points in different threads to assess whether a particular condition is handled appropriately. This crate is a way to do that. While waypoints could be used outside unit tests or debugging, there are likely more robust solutions.

The docs can be found on here.

Example

The example below uses two threads to push numbers 0-5 onto a vector; waypoints are set to enforce the order in which the numbers are pushed.

use waypoints::Waypoints;
use std::sync::{Arc, Mutex};

// A vector of observations
let obs = Arc::new(Mutex::new(Vec::new()));

// A thread-safe series of waypoints
let w = Waypoints::new_arc();

let mut threads = Vec::new();
threads.push({
    let obs = obs.clone();
    let w = w.clone();
    std::thread::spawn(move || {
        obs.lock().unwrap().push(0);
        obs.lock().unwrap().push(1);
        // the other thread may not proceed past waypoint 1
        // until waypoint 0 is passed
        w.point(0, None).unwrap();
        // this thread has to wait on waypoint 2 to be
        // passed in the other thread before proceeding
        w.point(3, None).unwrap();
        obs.lock().unwrap().push(4);
        obs.lock().unwrap().push(5);
    })
});

threads.push({
    let obs = obs.clone();
    let w = w.clone();
    std::thread::spawn(move || {
        w.point(1, None).unwrap();
        obs.lock().unwrap().push(2);
        obs.lock().unwrap().push(3);
        w.point(2, None).unwrap();
    })
});

threads.into_iter().for_each(|t| {
    t.join().ok();
});

let obs = Arc::try_unwrap(obs).unwrap().into_inner().unwrap();
println!("obs: {:?}", &obs); // obs: [0, 1, 2, 3, 4, 5]
assert_eq!(obs, (0..6).into_iter().collect::<Vec<_>>());

About

A helper for writing unit test for multi-threaded applications

Resources

License

Stars

Watchers

Forks

Languages