Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cargo miri tweaks and test that we can exclude tests #580

Merged
merged 8 commits into from
Dec 19, 2018
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
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);
}