Skip to content

Commit

Permalink
Add miri builder
Browse files Browse the repository at this point in the history
This adds a builder to run `cargo miri` in order to check for certain
classes of undefined behavior.

One thing to note is that we've had to parameterize a number of tests to
use a smaller cycle count under miri. This is because miri's stacked
borrows checker is superlinear:

rust-lang/miri#1367

This can cause the miri builder to run out of memory. To avoid this, we
reduce the cycle counts for a few tests that are particularly expensive
when we're running inside miri.
  • Loading branch information
erickt committed Feb 8, 2022
1 parent 10ee11e commit c80a00c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 5 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,18 @@ jobs:
components: clippy
- run: cargo clippy

miri:
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- nightly
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.rust }}
override: true
components: miri
- run: cargo miri test
2 changes: 1 addition & 1 deletion src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1567,7 +1567,7 @@ mod tests {

let mut keys = vec![];
keys.extend(0..16);
keys.extend(128..267);
keys.extend(if cfg!(miri) { 32..64 } else { 128..267 });

for &i in &keys {
let old_map = map.clone();
Expand Down
2 changes: 1 addition & 1 deletion src/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1426,7 +1426,7 @@ mod tests {

let mut values = vec![];
values.extend(0..16);
values.extend(128..267);
values.extend(if cfg!(miri) { 32..64 } else { 128..267 });

for &i in &values {
let old_set = set.clone();
Expand Down
40 changes: 37 additions & 3 deletions tests/quick.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use indexmap::{IndexMap, IndexSet};
use itertools::Itertools;

use quickcheck::quickcheck;
use quickcheck::Arbitrary;
use quickcheck::Gen;
use quickcheck::TestResult;
Expand Down Expand Up @@ -39,7 +38,42 @@ where
IndexMap::from_iter(iter.into_iter().copied().map(|k| (k, ())))
}

quickcheck! {
// Helper macro to allow us to use smaller quickcheck limits under miri.
macro_rules! quickcheck_limit {
(@as_items $($i:item)*) => ($($i)*);
{
$(
$(#[$m:meta])*
fn $fn_name:ident($($arg_name:ident : $arg_ty:ty),*) -> $ret:ty {
$($code:tt)*
}
)*
} => (
quickcheck::quickcheck! {
@as_items
$(
#[test]
$(#[$m])*
fn $fn_name() {
fn prop($($arg_name: $arg_ty),*) -> $ret {
$($code)*
}
let mut quickcheck = quickcheck::QuickCheck::new();
if cfg!(miri) {
quickcheck = quickcheck
.gen(quickcheck::Gen::new(10))
.tests(10)
.max_tests(100);
}

quickcheck.quickcheck(prop as fn($($arg_ty),*) -> $ret);
}
)*
}
)
}

quickcheck_limit! {
fn contains(insert: Vec<u32>) -> bool {
let mut map = IndexMap::new();
for &key in &insert {
Expand Down Expand Up @@ -260,7 +294,7 @@ where
true
}

quickcheck! {
quickcheck_limit! {
fn operations_i8(ops: Large<Vec<Op<i8, i8>>>) -> bool {
let mut map = IndexMap::new();
let mut reference = HashMap::new();
Expand Down

0 comments on commit c80a00c

Please sign in to comment.