Skip to content

Commit ddda239

Browse files
committed
Run Miri on CI
1 parent 7f3f6cf commit ddda239

File tree

24 files changed

+390
-26
lines changed

24 files changed

+390
-26
lines changed

.github/workflows/ci.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,15 @@ jobs:
125125
- name: clippy
126126
run: ./ci/clippy.sh
127127

128+
# Run miri.
129+
miri:
130+
name: miri
131+
runs-on: ubuntu-latest
132+
steps:
133+
- uses: actions/checkout@v2
134+
- name: miri
135+
run: ./ci/miri.sh
136+
128137
# Run sanitizers.
129138
san:
130139
name: san
@@ -174,6 +183,7 @@ jobs:
174183
- codegen
175184
- rustfmt
176185
- clippy
186+
- miri
177187
- san
178188
- loom
179189
- docs

ci/miri.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/bin/bash
2+
3+
cd "$(dirname "$0")"/..
4+
set -ex
5+
6+
toolchain=nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri)
7+
rustup set profile minimal
8+
rustup default "$toolchain"
9+
rustup component add miri
10+
11+
MIRIFLAGS="-Zmiri-tag-raw-pointers" \
12+
cargo miri test \
13+
-p crossbeam-queue
14+
15+
# -Zmiri-tag-raw-pointers doesn't work with std::thread::Builder::name on Linux: https://github.com/rust-lang/miri/issues/1717
16+
MIRIFLAGS="-Zmiri-disable-isolation" \
17+
cargo miri test \
18+
-p crossbeam-utils
19+
20+
# -Zmiri-ignore-leaks is needed because we use detached threads in tests/docs: https://github.com/rust-lang/miri/issues/1371
21+
# When enable -Zmiri-tag-raw-pointers, miri reports stacked borrows violation: https://github.com/crossbeam-rs/crossbeam/issues/762
22+
MIRIFLAGS="-Zmiri-disable-isolation -Zmiri-ignore-leaks" \
23+
cargo miri test \
24+
-p crossbeam-channel
25+
26+
# -Zmiri-ignore-leaks is needed for https://github.com/crossbeam-rs/crossbeam/issues/579
27+
# -Zmiri-disable-stacked-borrows is needed for https://github.com/crossbeam-rs/crossbeam/issues/545
28+
MIRIFLAGS="-Zmiri-disable-isolation -Zmiri-ignore-leaks -Zmiri-disable-stacked-borrows" \
29+
cargo miri test \
30+
-p crossbeam-epoch \
31+
-p crossbeam-skiplist \
32+
-p crossbeam
33+
34+
MIRIFLAGS="-Zmiri-disable-isolation -Zmiri-ignore-leaks -Zmiri-disable-stacked-borrows -Zmiri-compare-exchange-weak-failure-rate=1.0" \
35+
cargo miri test \
36+
-p crossbeam-deque

crossbeam-channel/tests/after.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Tests for the after channel flavor.
22
3+
#![cfg(not(miri))] // TODO: many assertions failed due to Miri is slow
4+
35
use std::sync::atomic::AtomicUsize;
46
use std::sync::atomic::Ordering;
57
use std::thread;

crossbeam-channel/tests/array.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Tests for the array channel flavor.
22
3+
#![cfg(not(miri))] // TODO: many assertions failed due to Miri is slow
4+
35
use std::any::Any;
46
use std::sync::atomic::AtomicUsize;
57
use std::sync::atomic::Ordering;

crossbeam-channel/tests/golang.rs

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,9 @@ macro_rules! go {
232232
mod doubleselect {
233233
use super::*;
234234

235+
#[cfg(miri)]
236+
const ITERATIONS: i32 = 100;
237+
#[cfg(not(miri))]
235238
const ITERATIONS: i32 = 10_000;
236239

237240
fn sender(n: i32, c1: Chan<i32>, c2: Chan<i32>, c3: Chan<i32>, c4: Chan<i32>) {
@@ -691,6 +694,11 @@ mod select {
691694
mod select2 {
692695
use super::*;
693696

697+
#[cfg(miri)]
698+
const N: i32 = 1000;
699+
#[cfg(not(miri))]
700+
const N: i32 = 100000;
701+
694702
#[test]
695703
fn main() {
696704
fn sender(c: &Chan<i32>, n: i32) {
@@ -717,15 +725,18 @@ mod select2 {
717725

718726
ALLOCATED.store(0, SeqCst);
719727

720-
go!(c, sender(&c, 100000));
721-
receiver(&c, &dummy, 100000);
728+
go!(c, sender(&c, N));
729+
receiver(&c, &dummy, N);
722730

723731
let alloc = ALLOCATED.load(SeqCst);
724732

725-
go!(c, sender(&c, 100000));
726-
receiver(&c, &dummy, 100000);
733+
go!(c, sender(&c, N));
734+
receiver(&c, &dummy, N);
727735

728-
assert!(!(ALLOCATED.load(SeqCst) > alloc && (ALLOCATED.load(SeqCst) - alloc) > 110000))
736+
assert!(
737+
!(ALLOCATED.load(SeqCst) > alloc
738+
&& (ALLOCATED.load(SeqCst) - alloc) > (N as usize + 10000))
739+
)
729740
}
730741
}
731742

@@ -913,6 +924,9 @@ mod chan_test {
913924

914925
#[test]
915926
fn test_chan() {
927+
#[cfg(miri)]
928+
const N: i32 = 20;
929+
#[cfg(not(miri))]
916930
const N: i32 = 200;
917931

918932
for cap in 0..N {
@@ -1052,6 +1066,9 @@ mod chan_test {
10521066

10531067
#[test]
10541068
fn test_nonblock_recv_race() {
1069+
#[cfg(miri)]
1070+
const N: usize = 100;
1071+
#[cfg(not(miri))]
10551072
const N: usize = 1000;
10561073

10571074
for _ in 0..N {
@@ -1073,6 +1090,9 @@ mod chan_test {
10731090

10741091
#[test]
10751092
fn test_nonblock_select_race() {
1093+
#[cfg(miri)]
1094+
const N: usize = 100;
1095+
#[cfg(not(miri))]
10761096
const N: usize = 1000;
10771097

10781098
let done = make::<bool>(1);
@@ -1106,6 +1126,9 @@ mod chan_test {
11061126

11071127
#[test]
11081128
fn test_nonblock_select_race2() {
1129+
#[cfg(miri)]
1130+
const N: usize = 100;
1131+
#[cfg(not(miri))]
11091132
const N: usize = 1000;
11101133

11111134
let done = make::<bool>(1);
@@ -1142,6 +1165,11 @@ mod chan_test {
11421165
// Ensure that send/recv on the same chan in select
11431166
// does not crash nor deadlock.
11441167

1168+
#[cfg(miri)]
1169+
const N: usize = 100;
1170+
#[cfg(not(miri))]
1171+
const N: usize = 1000;
1172+
11451173
for &cap in &[0, 10] {
11461174
let wg = WaitGroup::new();
11471175
wg.add(2);
@@ -1151,7 +1179,7 @@ mod chan_test {
11511179
let p = p;
11521180
go!(wg, p, c, {
11531181
defer! { wg.done() }
1154-
for i in 0..1000 {
1182+
for i in 0..N {
11551183
if p == 0 || i % 2 == 0 {
11561184
select! {
11571185
send(c.tx(), p) -> _ => {}
@@ -1180,15 +1208,18 @@ mod chan_test {
11801208

11811209
#[test]
11821210
fn test_select_stress() {
1211+
#[cfg(miri)]
1212+
const N: usize = 100;
1213+
#[cfg(not(miri))]
1214+
const N: usize = 10000;
1215+
11831216
let c = vec![
11841217
make::<i32>(0),
11851218
make::<i32>(0),
11861219
make::<i32>(2),
11871220
make::<i32>(3),
11881221
];
11891222

1190-
const N: usize = 10000;
1191-
11921223
// There are 4 goroutines that send N values on each of the chans,
11931224
// + 4 goroutines that receive N values on each of the chans,
11941225
// + 1 goroutine that sends N values on each of the chans in a single select,
@@ -1286,6 +1317,9 @@ mod chan_test {
12861317

12871318
#[test]
12881319
fn test_select_fairness() {
1320+
#[cfg(miri)]
1321+
const TRIALS: usize = 100;
1322+
#[cfg(not(miri))]
12891323
const TRIALS: usize = 10000;
12901324

12911325
let c1 = make::<u8>(TRIALS + 1);
@@ -1369,6 +1403,9 @@ mod chan_test {
13691403

13701404
#[test]
13711405
fn test_pseudo_random_send() {
1406+
#[cfg(miri)]
1407+
const N: usize = 20;
1408+
#[cfg(not(miri))]
13721409
const N: usize = 100;
13731410

13741411
for cap in 0..N {
@@ -1412,6 +1449,9 @@ mod chan_test {
14121449
#[test]
14131450
fn test_multi_consumer() {
14141451
const NWORK: usize = 23;
1452+
#[cfg(miri)]
1453+
const NITER: usize = 100;
1454+
#[cfg(not(miri))]
14151455
const NITER: usize = 271828;
14161456

14171457
let pn = [2, 3, 7, 11, 13, 17, 19, 23, 27, 31];
@@ -1510,6 +1550,9 @@ mod chan1 {
15101550
use super::*;
15111551

15121552
// sent messages
1553+
#[cfg(miri)]
1554+
const N: usize = 100;
1555+
#[cfg(not(miri))]
15131556
const N: usize = 1000;
15141557
// receiving "goroutines"
15151558
const M: usize = 10;

crossbeam-channel/tests/list.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ fn disconnect_wakes_receiver() {
239239

240240
#[test]
241241
fn spsc() {
242+
#[cfg(miri)]
243+
const COUNT: usize = 100;
244+
#[cfg(not(miri))]
242245
const COUNT: usize = 100_000;
243246

244247
let (s, r) = unbounded();
@@ -261,6 +264,9 @@ fn spsc() {
261264

262265
#[test]
263266
fn mpmc() {
267+
#[cfg(miri)]
268+
const COUNT: usize = 100;
269+
#[cfg(not(miri))]
264270
const COUNT: usize = 25_000;
265271
const THREADS: usize = 4;
266272

@@ -295,6 +301,9 @@ fn mpmc() {
295301

296302
#[test]
297303
fn stress_oneshot() {
304+
#[cfg(miri)]
305+
const COUNT: usize = 100;
306+
#[cfg(not(miri))]
298307
const COUNT: usize = 10_000;
299308

300309
for _ in 0..COUNT {
@@ -310,6 +319,9 @@ fn stress_oneshot() {
310319

311320
#[test]
312321
fn stress_iter() {
322+
#[cfg(miri)]
323+
const COUNT: usize = 100;
324+
#[cfg(not(miri))]
313325
const COUNT: usize = 100_000;
314326

315327
let (request_s, request_r) = unbounded();
@@ -371,8 +383,11 @@ fn stress_timeout_two_threads() {
371383
.unwrap();
372384
}
373385

386+
#[cfg_attr(miri, ignore)] // Miri is too slow
374387
#[test]
375388
fn drops() {
389+
const RUNS: usize = 100;
390+
376391
static DROPS: AtomicUsize = AtomicUsize::new(0);
377392

378393
#[derive(Debug, PartialEq)]
@@ -386,7 +401,7 @@ fn drops() {
386401

387402
let mut rng = thread_rng();
388403

389-
for _ in 0..100 {
404+
for _ in 0..RUNS {
390405
let steps = rng.gen_range(0..10_000);
391406
let additional = rng.gen_range(0..1000);
392407

@@ -421,6 +436,9 @@ fn drops() {
421436

422437
#[test]
423438
fn linearizable() {
439+
#[cfg(miri)]
440+
const COUNT: usize = 100;
441+
#[cfg(not(miri))]
424442
const COUNT: usize = 25_000;
425443
const THREADS: usize = 4;
426444

@@ -441,6 +459,9 @@ fn linearizable() {
441459

442460
#[test]
443461
fn fairness() {
462+
#[cfg(miri)]
463+
const COUNT: usize = 100;
464+
#[cfg(not(miri))]
444465
const COUNT: usize = 10_000;
445466

446467
let (s1, r1) = unbounded::<()>();
@@ -463,6 +484,9 @@ fn fairness() {
463484

464485
#[test]
465486
fn fairness_duplicates() {
487+
#[cfg(miri)]
488+
const COUNT: usize = 100;
489+
#[cfg(not(miri))]
466490
const COUNT: usize = 10_000;
467491

468492
let (s, r) = unbounded();
@@ -496,6 +520,9 @@ fn recv_in_send() {
496520

497521
#[test]
498522
fn channel_through_channel() {
523+
#[cfg(miri)]
524+
const COUNT: usize = 100;
525+
#[cfg(not(miri))]
499526
const COUNT: usize = 1000;
500527

501528
type T = Box<dyn Any + Send>;

0 commit comments

Comments
 (0)