MCPcopy Index your code
hub / github.com/awslabs/shuttle

github.com/awslabs/shuttle @v0.9.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.9.0 ↗ · + Follow
2,217 symbols 8,344 edges 220 files 608 documented · 27%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Shuttle

crates.io docs.rs Tests

Shuttle is a library for testing concurrent Rust code. It is an implementation of a number of randomized concurrency testing techniques, including A Randomized Scheduler with Probabilistic Guarantees of Finding Bugs.

This repository also houses a collection of wrappers and their implementations. These make it easier to test code using popular libraries such as tokio and rand, as well as synchronization primitives from std::sync and collections from std::collections. For more information on how to use these wrappers, see the wrappers/README.md.

Getting started

Consider this simple piece of concurrent code:

use std::sync::{Arc, Mutex};
use std::thread;

let lock = Arc::new(Mutex::new(0u64));
let lock2 = lock.clone();

thread::spawn(move || {
    *lock.lock().unwrap() = 1;
});

assert_eq!(0, *lock2.lock().unwrap());

There is an obvious race condition here: if the spawned thread runs before the assertion, the assertion will fail. But writing a unit test that finds this execution is tricky. We could run the test many times and try to "get lucky" by finding a failing execution, but that's not a very reliable testing approach. Even if the test does fail, it will be difficult to debug: we won't be able to easily catch the failure in a debugger, and every time we make a change, we will need to run the test many times to decide whether we fixed the issue.

Randomly testing concurrent code with Shuttle

Shuttle avoids this issue by controlling the scheduling of each thread in the program, and scheduling those threads randomly. By controlling the scheduling, Shuttle allows us to reproduce failing tests deterministically. By using random scheduling, with appropriate heuristics, Shuttle can still catch most (non-adversarial) concurrency bugs even though it is not an exhaustive checker.

A Shuttle version of the above test just wraps the test body in a call to Shuttle's check_random function, and replaces the concurrency-related imports from std with imports from shuttle:

use shuttle::sync::{Arc, Mutex};
use shuttle::thread;

shuttle::check_random(|| {
    let lock = Arc::new(Mutex::new(0u64));
    let lock2 = lock.clone();

    thread::spawn(move || {
        *lock.lock().unwrap() = 1;
    });

    assert_eq!(0, *lock2.lock().unwrap());
}, 100);

This test detects the assertion failure with extremely high probability (over 99.9999%).

Shuttle is inspired by the Loom library for testing concurrent Rust code. Shuttle focuses on randomized testing, rather than the exhaustive testing that Loom offers. This is a soundness—scalability trade-off: Shuttle is not sound (a passing Shuttle test does not prove the code is correct), but it scales to much larger test cases than Loom. Empirically, randomized testing is successful at finding most concurrency bugs, which tend not to be adversarial.

License

This project is licensed under the Apache-2.0 License.

Security

See CONTRIBUTING for more information.

Extension points exported contracts — how you extend this code

Scheduler (Interface)
A `Scheduler` is an oracle that decides the order in which to execute concurrent tasks and the data to return to calls f [13 …
shuttle/src/scheduler/mod.rs
FromStream (Interface)
Convert from a [`Stream`]. This trait is not intended to be used directly. Instead, call [`StreamExt::collect()`](super [5 …
wrappers/tokio/impls/tokio-stream/src/stream_ext/collect.rs
WithName (Interface)
Trait to record information about shared objects, such as their name and type. See implementation in [`crate::future::ba [4 …
shuttle/src/annotations/mod.rs
FromStreamPriv (Interface)
(no doc) [5 implementers]
wrappers/tokio/impls/tokio-stream/src/stream_ext/collect.rs
DataSource (Interface)
A `DataSource` is an oracle for generating non-deterministic data to return to a task that asks for random values. [2 …
shuttle/src/scheduler/data/mod.rs
StreamExt (Interface)
An extension trait for the [`Stream`] trait that provides a variety of convenient combinator functions. Be aware that t [1 …
wrappers/tokio/impls/tokio-stream/src/stream_ext.rs
LazyStatic (Interface)
Support trait for enabling a few common operation on lazy static values. This is implemented by each defined lazy stati
shuttle/src/lazy_static.rs
AmbiguousIfSend (Interface)
(no doc) [2 implementers]
wrappers/tokio/impls/tokio-stream/tests/async_send_sync.rs

Core symbols most depended-on inside this repo

spawn
called by 284
shuttle/src/thread.rs
clone
called by 217
wrappers/tokio/impls/tokio-test/src/task.rs
lock
called by 206
shuttle/src/sync/mutex.rs
check_dfs
called by 187
shuttle/src/lib.rs
join
called by 132
shuttle/src/thread.rs
clone
called by 132
shuttle/src/sync/mpsc.rs
map
called by 125
wrappers/tokio/impls/tokio-stream/src/stream_ext.rs
spawn
called by 91
wrappers/tokio/impls/tokio/inner/src/task.rs

Shape

Method 1,101
Function 817
Class 252
Enum 32
Interface 15

Languages

Rust100%
TypeScript1%

Modules by API surface

wrappers/tokio/impls/tokio/inner/src/runtime.rs62 symbols
shuttle/src/runtime/execution.rs58 symbols
shuttle/src/runtime/task/mod.rs57 symbols
shuttle/tests/basic/mpsc.rs48 symbols
wrappers/tokio/impls/tokio/inner/src/task.rs42 symbols
wrappers/tokio/impls/tokio/inner/src/sync/watch.rs40 symbols
shuttle/src/future/batch_semaphore.rs38 symbols
wrappers/tokio/impls/tokio/inner/src/sync/mpsc.rs36 symbols
wrappers/tokio/impls/tokio/inner/src/time.rs35 symbols
shuttle/tests/basic/thread.rs34 symbols
shuttle/src/thread.rs33 symbols
wrappers/tokio/impls/tokio-util/src/task/task_tracker.rs31 symbols

For agents

$ claude mcp add shuttle \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact