Skip to content

Commit

Permalink
Merge pull request #580 from RalfJung/cargo-miri
Browse files Browse the repository at this point in the history
Cargo miri tweaks and test that we can exclude tests
  • Loading branch information
RalfJung authored Dec 19, 2018
2 parents 1f68737 + adba97e commit d8956f0
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 14 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ branches:
env:
global:
- RUST_TEST_NOCAPTURE=1
- RUST_BACKTRACE=1
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,28 @@ example above), overriding it in your project directory as well, or use `rustup
default nightly` (or `rustup default nightly-YYYY-MM-DD`) to globally make
`nightly` the default toolchain.

Now you can run your project in miri:
Now you can run your project in Miri:

1. Run `cargo clean` to eliminate any cached dependencies. Miri needs your
dependencies to be compiled the right way, that would not happen if they have
previously already been compiled.
2. To run all tests in your project through Miri, use `cargo +nightly miri test`.
**NOTE**: This is currently broken, see the discussion in
[#479](https://github.com/solson/miri/issues/479).
3. If you have a binary project, you can run it through Miri using `cargo
+nightly miri run`.

When running code via `cargo miri`, the `cargo-miri` feature is set. You can
use this to exclude test cases that will fail under Miri because they do things
Miri does not support:

```rust
#[cfg(not(feature = "cargo-miri"))]
#[test]
fn does_not_work_on_miri() {
let x = 0u8;
assert!(&x as *const _ as usize % 4 < 4);
}
```

### Common Problems

When using the above instructions, you may encounter a number of confusing compiler
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ install:
build: false

test_script:
- set RUSTFLAGS=-g
- set RUST_TEST_NOCAPTURE=1
- set RUST_BACKTRACE=1
# Build miri
- cargo build --release --all-features --all-targets
Expand Down
12 changes: 8 additions & 4 deletions src/bin/cargo-miri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,14 @@ fn xargo_version() -> Option<(u32, u32, u32)> {
let line = out.stderr.lines().nth(0)
.expect("malformed `xargo --version` output: not at least one line")
.expect("malformed `xargo --version` output: error reading first line");
let version = line.split(' ').nth(1)
.expect("malformed `xargo --version` output: not at least two words");
let (name, version) = {
let mut split = line.split(' ');
(split.next().expect("malformed `xargo --version` output: empty"),
split.next().expect("malformed `xargo --version` output: not at least two words"))
};
if name != "xargo" {
panic!("malformed `xargo --version` output: application name is not `xargo`");
}
let mut version_pieces = version.split('.');
let major = version_pieces.next()
.expect("malformed `xargo --version` output: not a major version piece")
Expand Down Expand Up @@ -414,8 +420,6 @@ where
args.push("--".to_owned());
}
args.push("--emit=dep-info,metadata".to_owned());
args.push("--cfg".to_owned());
args.push(r#"feature="cargo-miri""#.to_owned());

let path = std::env::current_exe().expect("current executable path invalid");
let exit_status = Command::new("cargo")
Expand Down
2 changes: 1 addition & 1 deletion src/fn_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
Err(_) => -1,
}
} else {
warn!("Ignored output to FD {}", fd);
eprintln!("Miri: Ignored output to FD {}", fd);
n as i64 // pretend it all went well
}; // now result is the value we return back to the program
this.write_scalar(
Expand Down
12 changes: 7 additions & 5 deletions test-cargo-miri/run-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

import sys, subprocess

def fail(msg):
print("TEST FAIL: {}".format(msg))
sys.exit(1)

def test(name, cmd, stdout_ref, stderr_ref):
print("==> Testing `{}` <==".format(name))
## Call `cargo miri`, capture all output
Expand All @@ -25,13 +29,11 @@ def test(name, cmd, stdout_ref, stderr_ref):
print(stderr, end="")
# Test for failures
if p.returncode != 0:
sys.exit(1)
fail("Non-zero exit status")
if stdout != open(stdout_ref).read():
print("stdout does not match reference")
sys.exit(1)
fail("stdout does not match reference")
if stderr != open(stderr_ref).read():
print("stderr does not match reference")
sys.exit(1)
fail("stderr does not match reference")

def test_cargo_miri_run():
test("cargo miri run", ["cargo", "miri", "run", "-q"], "stdout.ref", "stderr.ref")
Expand Down
8 changes: 8 additions & 0 deletions test-cargo-miri/tests/foo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@ fn bar() {
fn baz() {
assert_eq!(5, 5);
}

// A test that won't work on miri
#[cfg(not(feature = "cargo-miri"))]
#[test]
fn does_not_work_on_miri() {
let x = 0u8;
assert!(&x as *const _ as usize % 4 < 4);
}

0 comments on commit d8956f0

Please sign in to comment.