Skip to content

Commit 49faea2

Browse files
authored
Update wrappers README to cover wrapper versioning (#240)
* Update wrappers README to cover wrapper versioning * Update README.md
1 parent 3dbfc3d commit 49faea2

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Shuttle is a library for testing concurrent Rust code. It is an implementation o
88
*randomized concurrency testing* techniques, including
99
[A Randomized Scheduler with Probabilistic Guarantees of Finding Bugs](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/asplos277-pct.pdf).
1010

11+
This repository also houses a collection of [wrappers](/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](/wrappers/README.md).
12+
1113
## Getting started
1214

1315
Consider this simple piece of concurrent code:

wrappers/README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Wrappers
2+
3+
This directory contains a collection of wrappers and their implementations. The general scheme to use these is by doing the following:
4+
5+
```toml
6+
[features]
7+
shuttle = [
8+
"tokio/shuttle",
9+
"parking-lot/shuttle",
10+
# ... etc. for all wrapped dependencies
11+
]
12+
13+
[dependencies]
14+
tokio = { package = "shuttle-tokio", version = "1" }
15+
parking_lot = { package = "shuttle-parking_lot", version = "0.12" }
16+
# ... etc. for all wrapped dependencies
17+
```
18+
19+
When running without the `shuttle` feature flag enabled, the code will behave as normal (ie., run with primitives from `std`, `rand`, `tokio` etc), and when the `shuttle` feature flag is enabled, the code will use primitives which are compatible with Shuttle.
20+
21+
When depending on many crates with wrappers, the entries in the `shuttle` feature may become fairly long. You also run the risk of forgetting to update the list when adding a dependency, causing you to not use the Shuttle-compatible version when running under Shuttle. To solve these issues, the [shuttle_enabler](shuttle_enabler) crate exists. To use it, make your `Cargo.toml` the following instead of the above:
22+
23+
```toml
24+
[features]
25+
shuttle = [
26+
"shuttle_enabler/shuttle",
27+
]
28+
29+
[dependencies]
30+
shuttle_enabler = "0.1.0"
31+
tokio = { package = "shuttle-tokio", version = "1" }
32+
parking_lot = { package = "shuttle-parking_lot", version = "0.12" }
33+
```
34+
35+
Note that depending on `shuttle_enabler` will cause all crates in `shuttle_enabler` to be compiled when the `shuttle` flag is enabled.
36+
37+
## A note on versioning
38+
39+
The wrappers use minimal version constraints for the crates they wrap:
40+
- For crates at version 1.x or higher (like `tokio`, `lazy_static`), the dependency is set to `1`
41+
- For crates at version 0.x (like `rand`, `parking_lot`), the dependency is the minor version (e.g., `0.8`, `0.12`)
42+
43+
Thus, by default, cargo will select the latest compatible version of the wrapped crate.
44+
45+
This means that if no further constraining of the versioning is done, then depending on the wrapper will give you the latest version of the wrapped crate. If you want to use a specific version of a crate, or want to constrain the versioning, then this can be done by adding a second field in your `Cargo.toml`.
46+
47+
For example, if you want to pin `tokio` to `1.36.0`, you can add the following:
48+
49+
```toml
50+
[dependencies]
51+
tokio = { package = "shuttle-tokio", version = "0.1.0" }
52+
tokio-version-importer-do-not-use-directly = { version = "=1.36.0" }
53+
```
54+
55+
A more robust alternative which removes the possibility of accidentally using the version importer crate is the following:
56+
- create a dedicated `versions` crate that specifies the dependency versions you want (e.g., for `tokio`)
57+
- have all your crates depend on this `versions` crate
58+
59+
For projects spanning multiple workspaces, you should use workspace dependencies with `workspace = true`.

0 commit comments

Comments
 (0)