Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions shuttle-engine/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# shuttle-engine

This crate contains the core runtime of the [Shuttle](https://crates.io/crates/shuttle) concurrency
testing tool. It provides the building blocks for creating functionality on top of Shuttle: the
execution engine, the `Scheduler` trait, and the primitives that schedulers and `std` replacements
are built from. Reach for it when you want to build something new atop the runtime, such as a custom
scheduler or a Shuttle-compatible version of a concurrency primitive.

## Contents

This crate holds the machinery that executes and controls a Shuttle test:

* `runtime` — the execution engine: tasks, threads (built on
[corosensei](https://crates.io/crates/corosensei) continuations), thread-local storage, vector
clocks, and failure reporting.
* `scheduler` — the `Scheduler` trait that every scheduler implements, along with schedule
serialization, metrics, and the data-source traits used to control nondeterministic values. The
built-in schedulers themselves live in
[shuttle-schedulers](https://crates.io/crates/shuttle-schedulers).
* `config` — `Config` and the associated knobs (`MaxSteps`, `FailurePersistence`,
`UngracefulShutdownConfig`, ...).
* `future` — the async primitives underpinning Shuttle's executor, including `BatchSemaphore`.
* `current`, `hint`, `sync_types`, `thread_support` — the supporting APIs that
[shuttle-std](https://crates.io/crates/shuttle-std) builds its `std` mirrors on top of.

## Features

* `vector-clocks` — track causality between tasks. Required for the `current` clock APIs.
* `annotation` — emit annotated schedules for the
[Shuttle Explorer](https://github.com/awslabs/shuttle/tree/main/shuttle-explorer) extension.

## Stability

This crate exposes considerably more of Shuttle's internals than the `shuttle` crate does, and that
surface evolves alongside the runtime. Expect it to change more freely than a typical crate's public
API, and pin a version if you build against it.
25 changes: 25 additions & 0 deletions shuttle-schedulers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# shuttle-schedulers

This crate contains schedulers for the [Shuttle](https://crates.io/crates/shuttle)
concurrency testing tool, along with the `check`/`replay` entry points that run a test with them.

## Contents

Each scheduler implements the `Scheduler` trait from
[shuttle-engine](https://crates.io/crates/shuttle-engine):

* `RandomScheduler` — chooses a runnable task uniformly at random at each scheduling point. The
default choice for most tests.
* `PctScheduler` — the probabilistic concurrency testing algorithm from
[A Randomized Scheduler with Probabilistic Guarantees of Finding Bugs](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/asplos277-pct.pdf),
which biases towards the low-preemption schedules that tend to expose real bugs.
* `DfsScheduler` — exhaustively enumerates schedules, in the style of
[Loom](https://github.com/tokio-rs/loom). Only tractable for small tests.
* `ReplayScheduler` — replays a previously recorded schedule, which is how a failing Shuttle test is
reproduced and debugged.
* `RoundRobinScheduler` — cycles through runnable tasks in a fixed order. This is more or less never the scheduler you want to use.
* `UrwRandomScheduler` — uniform random walk over the schedule space.
* `UncontrolledNondeterminismCheckScheduler` — detects tests whose behavior depends on
nondeterminism Shuttle does not control, which would otherwise make failures unreproducible.
* `AnnotationScheduler` — records an annotated schedule for the Shuttle Explorer extension. Requires
the `annotation` feature.
27 changes: 27 additions & 0 deletions shuttle-std/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# shuttle-std

This crate contains Shuttle-compatible mirrors of the `std` concurrency primitives, used by the
[Shuttle](https://crates.io/crates/shuttle) concurrency testing tool. Each type here shows how to
express a `std` API in terms of the [shuttle-engine](https://crates.io/crates/shuttle-engine)
runtime, which makes this a useful reference for building Shuttle-compatible versions of other
concurrency primitives.

Most codebases should get these primitives through the
[shuttle-sync](https://crates.io/crates/shuttle-sync) wrapper rather than from here. That wrapper
exposes either `std::sync` or the Shuttle-compatible implementation depending on a feature flag, so
the same code can run both with and without Shuttle and no imports need to change.

## Contents

Each type mirrors its `std` counterpart's API, but defers to the Shuttle runtime in
[shuttle-engine](https://crates.io/crates/shuttle-engine) so that the scheduler can control and
observe every operation:

* `sync` — `Mutex`, `RwLock`, `Condvar`, `Barrier`, `Once`, `mpsc` channels, and the `atomic`
types (including 128-bit atomics).
* `thread` — thread spawning, joining, parking, scoped threads, and thread-local storage.
* `future` — the async equivalents: task spawning, `block_on`, and `yield_now`.

Because these are drop-in mirrors rather than the real primitives, they only work inside a Shuttle
test. Note also that they cover the concurrency surface of `std` rather than all of it, so code that
uses parts of `std::sync` which Shuttle does not model will need to keep taking those from `std`.
4 changes: 2 additions & 2 deletions wrappers/async_stream/async_stream_impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ shuttle = { path = "../../../shuttle", version = "<0.10" }
futures-util = "0.3"
rustversion = "1"
trybuild = "1"
tokio = { package = "shuttle-tokio-impl", path = "../../tokio/impls/tokio", version = "*", features = ["full"] }
tokio-test = { package = "shuttle-tokio-test-impl", path = "../../tokio/impls/tokio-test", version = "*" }
tokio = { package = "shuttle-tokio-impl", path = "../../tokio/impls/tokio", features = ["full"] }
tokio-test = { package = "shuttle-tokio-test-impl", path = "../../tokio/impls/tokio-test" }
7 changes: 7 additions & 0 deletions wrappers/async_stream/async_stream_impl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Shuttle support for `async-stream`

This crate contains the implementation that enables testing of applications that use [async-stream](https://crates.io/crates/async-stream) with Shuttle. It should not be depended on directly, depend on `shuttle-async-stream` instead.

## Limitations

There should be no limitations compared to [async-stream](https://crates.io/crates/async-stream). This crate is a fork of the 0.3.6 version, where the only change from the original is that the thread-local in `yielder.rs` has been made Shuttle-compatible.
23 changes: 23 additions & 0 deletions wrappers/lazy_static/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Shuttle support for `lazy_static`

This crate contains the wrapper that enables testing of applications that use [lazy_static](https://crates.io/crates/lazy_static) with Shuttle.

## How to use

To use it, add the following in your Cargo.toml:

```
[features]
shuttle = [
"lazy_static/shuttle",
]

[dependencies]
lazy_static = { package = "shuttle-lazy_static", version = "VERSION_NUMBER" }
```

The code will then behave as before when the `shuttle` feature flag is not provided, and will run with Shuttle-compatible primitives when the `shuttle` feature flag is provided.

## Limitations

For the list of current limitations, see the [shuttle-lazy_static-impl](https://crates.io/crates/shuttle-lazy_static-impl) inner crate.
9 changes: 9 additions & 0 deletions wrappers/lazy_static/lazy_static_impl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Shuttle support for `lazy_static`

This crate contains the implementation that enables testing of applications that use [lazy_static](https://crates.io/crates/lazy_static) with Shuttle. It should not be depended on directly, depend on `shuttle-lazy_static` instead.

## Limitations

Shuttle's `lazy_static` drops the static value at the end of each execution, and so runs the value's `Drop` implementation. The real `lazy_static` crate never drops its static values, so this difference may cause false positives. Shuttle prints a warning about this; to silence it, set the `SHUTTLE_SILENCE_WARNINGS` environment variable to any value, or set the `silence_warnings` field of `Config` to true.

The `spin_no_std` feature is accepted for compatibility with `lazy_static`, but has no effect on the Shuttle implementation.
5 changes: 5 additions & 0 deletions wrappers/tokio/impls/tokio-macros/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Shuttle support for `tokio-macros`

This crate contains the procedural macros that enable testing of applications that use [tokio](https://crates.io/crates/tokio) with Shuttle. It should not be depended on directly, depend on `shuttle-tokio` instead.

This crate is a fork of `tokio-macros` 2.2.0. It provides the `#[tokio::main]` and `#[tokio::test]` attribute macros, expanded to drive the Shuttle-compatible runtime rather than the real tokio runtime.
9 changes: 9 additions & 0 deletions wrappers/tokio/impls/tokio-util/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Shuttle support for `tokio-util`

This crate contains the implementation that enables testing of applications that use [tokio-util](https://crates.io/crates/tokio-util) with Shuttle. It should not be depended on directly, depend on `shuttle-tokio-util` instead.

This crate is a fork of `tokio-util` 0.7.11, with the `tokio` dependency replaced by Shuttle's tokio implementation so that Shuttle's scheduler can control and observe the concurrency within it.

## Limitations

The implemented surface covers the `sync` module, the `codec` module (under the `codec` feature), and the `task` module (under the `rt` feature). Other parts of `tokio-util`, such as `io` and `compat`, are not yet provided; the corresponding Cargo features are accepted for compatibility with upstream's feature set but currently expose no Shuttle implementation. If your project needs functionality which is not currently supported, please file an issue or, better yet, open a PR to contribute the functionality.
13 changes: 13 additions & 0 deletions wrappers/tokio/impls/tokio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Shuttle support for `tokio`

This crate contains the implementation that enables testing of applications that use [tokio](https://crates.io/crates/tokio) with Shuttle. It should not be depended on directly, depend on `shuttle-tokio` instead.

## Implementation

This crate re-exports the parts of tokio that Shuttle does not need to model (from the real `tokio` crate) alongside the Shuttle-compatible replacements for the parts it does (from the [shuttle-tokio-impl-inner](https://crates.io/crates/shuttle-tokio-impl-inner) crate), so that the combined surface matches `tokio`'s module layout.

## Limitations

Shuttle's tokio support does not currently model all tokio functionality. Some parts of tokio have not been implemented or may not be modeled faithfully. Keep this in mind when using Shuttle with tokio, as you may encounter missing functionality that needs to be added. If you encounter missing features, please file an issue or, better yet, open a PR to contribute the functionality.

The list of constructs not supported by Shuttle are in [Issue 241](https://github.com/awslabs/shuttle/issues/241).
11 changes: 11 additions & 0 deletions wrappers/tokio/impls/tokio/inner/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Shuttle support for `tokio`

This crate contains the Shuttle-compatible replacements for the tokio primitives that Shuttle needs to model, and is an internal dependency of [shuttle-tokio-impl](https://crates.io/crates/shuttle-tokio-impl). It should not be depended on directly, depend on `shuttle-tokio` instead.

The types here (the runtime entry points, the `sync` primitives, `time`, and the task APIs) are backed by Shuttle's own primitives so that Shuttle's scheduler can control and observe every operation. `shuttle-tokio-impl` combines them with re-exports of the real `tokio` crate to present tokio's full module layout.

## Limitations

Shuttle's tokio support does not currently model all tokio functionality. Some parts of tokio have not been implemented or may not be modeled faithfully. Keep this in mind when using Shuttle with tokio, as you may encounter missing functionality that needs to be added. If you encounter missing features, please file an issue or, better yet, open a PR to contribute the functionality.

The list of constructs not supported by Shuttle are in [Issue 241](https://github.com/awslabs/shuttle/issues/241).
23 changes: 23 additions & 0 deletions wrappers/tokio/wrappers/shuttle-tokio-stream/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Shuttle support for `tokio-stream`

This crate contains the wrapper that enables testing of applications that use [tokio-stream](https://crates.io/crates/tokio-stream) with Shuttle.

## How to use

To use it, add the following in your Cargo.toml:

```
[features]
shuttle = [
"tokio-stream/shuttle",
]

[dependencies]
tokio-stream = { package = "shuttle-tokio-stream", version = "VERSION_NUMBER" }
```

The code will then behave as before when the `shuttle` feature flag is not provided, and will run with Shuttle-compatible primitives when the `shuttle` feature flag is provided.

## Limitations

For the list of current limitations, see the [shuttle-tokio-stream-impl](https://crates.io/crates/shuttle-tokio-stream-impl) inner crate.
23 changes: 23 additions & 0 deletions wrappers/tokio/wrappers/shuttle-tokio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Shuttle support for `tokio`

This crate contains the wrapper that enables testing of applications that use [tokio](https://crates.io/crates/tokio) with Shuttle.

## How to use

To use it, add the following in your Cargo.toml:

```
[features]
shuttle = [
"tokio/shuttle",
]

[dependencies]
tokio = { package = "shuttle-tokio", version = "VERSION_NUMBER" }
```

The code will then behave as before when the `shuttle` feature flag is not provided, and will run with Shuttle-compatible primitives when the `shuttle` feature flag is provided.

## Limitations

For the list of current limitations, see the [shuttle-tokio-impl](https://crates.io/crates/shuttle-tokio-impl) inner crate.
Loading