diff --git a/.travis.yml b/.travis.yml index d56ca04817..e76a2f86cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,13 @@ language: rust rust: - nightly -matrix: - allow_failures: - - rust: nightly before_script: - | pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH script: - | - travis-cargo build && + env RUST_SYSROOT=$HOME/rust travis-cargo build && env RUST_SYSROOT=$HOME/rust travis-cargo test notifications: email: diff --git a/Cargo.lock b/Cargo.lock index 240a214480..d0b785a061 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,7 +3,7 @@ name = "miri" version = "0.1.0" dependencies = [ "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "compiletest_rs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "compiletest_rs 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "log_settings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -24,10 +24,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "compiletest_rs" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -96,6 +97,11 @@ name = "regex-syntax" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc-serialize" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "thread-id" version = "2.0.0" diff --git a/Cargo.toml b/Cargo.toml index 5a8211230f..fea568e244 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,4 +21,4 @@ log = "0.3.6" log_settings = "0.1.1" [dev-dependencies] -compiletest_rs = "0.1.1" +compiletest_rs = "0.2" diff --git a/src/bin/miri.rs b/src/bin/miri.rs index 8ec691dbbb..ac5bf495f4 100644 --- a/src/bin/miri.rs +++ b/src/bin/miri.rs @@ -17,7 +17,7 @@ use miri::{ Frame, }; use rustc::session::Session; -use rustc_driver::{driver, CompilerCalls}; +use rustc_driver::{driver, CompilerCalls, Compilation}; use rustc::ty::{TyCtxt, subst}; use rustc::hir::def_id::DefId; @@ -31,6 +31,7 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls { ) -> driver::CompileController<'a> { let mut control = driver::CompileController::basic(); + control.after_analysis.stop = Compilation::Stop; control.after_analysis.callback = Box::new(|state| { state.session.abort_if_errors(); @@ -70,6 +71,7 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls { } } } + state.session.abort_if_errors(); }); control diff --git a/tests/compiletest.rs b/tests/compiletest.rs index 7ce9636fc0..66b94ad88d 100644 --- a/tests/compiletest.rs +++ b/tests/compiletest.rs @@ -1,43 +1,89 @@ extern crate compiletest_rs as compiletest; -use std::path::PathBuf; +use std::path::{PathBuf, Path}; +use std::io::Write; -fn run_mode(mode: &'static str) { +fn run_mode(dir: &'static str, mode: &'static str, sysroot: &str) { // Disable rustc's new error fomatting. It breaks these tests. std::env::remove_var("RUST_NEW_ERROR_FORMAT"); - - // Taken from https://github.com/Manishearth/rust-clippy/pull/911. - let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME")); - let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN")); - let sysroot = match (home, toolchain) { - (Some(home), Some(toolchain)) => format!("{}/toolchains/{}", home, toolchain), - _ => option_env!("RUST_SYSROOT") - .expect("need to specify RUST_SYSROOT env var or use rustup or multirust") - .to_owned(), - }; let flags = format!("--sysroot {} -Dwarnings", sysroot); - - // FIXME: read directories in sysroot/lib/rustlib and generate the test targets from that - let targets = &["x86_64-unknown-linux-gnu", "i686-unknown-linux-gnu"]; - - for &target in targets { - use std::io::Write; - let stderr = std::io::stderr(); - write!(stderr.lock(), "running tests for target {}", target).unwrap(); + for_all_targets(sysroot, |target| { let mut config = compiletest::default_config(); config.host_rustcflags = Some(flags.clone()); config.mode = mode.parse().expect("Invalid mode"); - config.run_lib_path = format!("{}/lib/rustlib/{}/lib", sysroot, target); + config.run_lib_path = Path::new(sysroot).join("lib").join("rustlib").join(&target).join("lib"); config.rustc_path = "target/debug/miri".into(); - config.src_base = PathBuf::from(format!("tests/{}", mode)); + config.src_base = PathBuf::from(format!("tests/{}", dir)); config.target = target.to_owned(); config.target_rustcflags = Some(flags.clone()); compiletest::run_tests(&config); + }); +} + +fn for_all_targets(sysroot: &str, mut f: F) { + for target in std::fs::read_dir(format!("{}/lib/rustlib/", sysroot)).unwrap() { + let target = target.unwrap(); + if !target.metadata().unwrap().is_dir() { + continue; + } + let target = target.file_name().into_string().unwrap(); + if target == "etc" { + continue; + } + let stderr = std::io::stderr(); + writeln!(stderr.lock(), "running tests for target {}", target).unwrap(); + f(target); } } #[test] fn compile_test() { - run_mode("compile-fail"); - run_mode("run-pass"); + let mut failed = false; + // Taken from https://github.com/Manishearth/rust-clippy/pull/911. + let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME")); + let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN")); + let sysroot = match (home, toolchain) { + (Some(home), Some(toolchain)) => format!("{}/toolchains/{}", home, toolchain), + _ => option_env!("RUST_SYSROOT") + .expect("need to specify RUST_SYSROOT env var or use rustup or multirust") + .to_owned(), + }; + run_mode("compile-fail", "compile-fail", &sysroot); + for_all_targets(&sysroot, |target| { + for file in std::fs::read_dir("tests/run-pass").unwrap() { + let file = file.unwrap(); + if !file.metadata().unwrap().is_file() { + continue; + } + let file = file.path(); + let stderr = std::io::stderr(); + write!(stderr.lock(), "test [miri-pass] {} ", file.to_str().unwrap()).unwrap(); + let mut cmd = std::process::Command::new("target/debug/miri"); + cmd.arg(file); + cmd.arg("-Dwarnings"); + cmd.arg(format!("--target={}", target)); + let libs = Path::new(&sysroot).join("lib"); + let sysroot = libs.join("rustlib").join(&target).join("lib"); + let paths = std::env::join_paths(&[libs, sysroot]).unwrap(); + cmd.env(compiletest::procsrv::dylib_env_var(), paths); + match cmd.output() { + Ok(ref output) if output.status.success() => writeln!(stderr.lock(), "ok").unwrap(), + Ok(output) => { + failed = true; + writeln!(stderr.lock(), "FAILED with exit code {}", output.status.code().unwrap_or(0)).unwrap(); + writeln!(stderr.lock(), "stdout: \n {}", std::str::from_utf8(&output.stdout).unwrap()).unwrap(); + writeln!(stderr.lock(), "stderr: \n {}", std::str::from_utf8(&output.stderr).unwrap()).unwrap(); + } + Err(e) => { + failed = true; + writeln!(stderr.lock(), "FAILED: {}", e).unwrap(); + }, + } + } + let stderr = std::io::stderr(); + writeln!(stderr.lock(), "").unwrap(); + }); + if failed { + panic!("some tests failed"); + } }