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

Add compile-pass tests #25

Merged
merged 2 commits into from
Jul 1, 2016
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
6 changes: 5 additions & 1 deletion src/bin/mir2wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ extern { }
use mir2wasm::trans;
use rustc::session::Session;
use rustc_driver::{driver, CompilerCalls};
use std::process;

struct MiriCompilerCalls;

Expand Down Expand Up @@ -42,5 +43,8 @@ fn main() {

let mut args: Vec<String> = std::env::args().collect();
args.push("--target=arm-unknown-linux-gnueabi".to_string());
rustc_driver::run_compiler(&args, &mut MiriCompilerCalls);
match rustc_driver::run_compiler(&args, &mut MiriCompilerCalls) {
(Ok(_), _) => process::exit(0),
(Err(code), _) => process::exit(code as i32)
}
}
3 changes: 3 additions & 0 deletions tests/compile-pass/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
These are tests that make it through the compiler but do not necessarily
run. These should be equivalent to the run-pass tests, but we aren't quite there
yet.
24 changes: 24 additions & 0 deletions tests/compile-pass/enum.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// xfail

#![feature(lang_items, no_core)]
#![allow(dead_code)]
#![no_core]

#[lang="sized"]
trait Sized {}

#[lang="copy"]
trait Copy {}

enum Tag {
A(isize),
B(isize)
}

fn main() {
let a = Tag::A(5);
match a {
Tag::A(i) => i,
Tag::B(i) => i,
};
}
7 changes: 7 additions & 0 deletions tests/compile-pass/trivial.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#![feature(lang_items, no_core)]
#![no_core]

#[lang="sized"]
trait Sized {}

fn main() {}
141 changes: 106 additions & 35 deletions tests/compiletest.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
extern crate compiletest_rs as compiletest;

use std::fs::File;
use std::io::{Read, Write};
use std::path::{PathBuf, Path};
use std::io::Write;

fn compile_fail(sysroot: &str) {
#[test] #[ignore]
fn compile_fail() {
let sysroot = &find_sysroot();
let flags = format!("--sysroot {} -Dwarnings", sysroot);
for_all_targets(sysroot, |target| {
let mut config = compiletest::default_config();
Expand All @@ -18,48 +21,82 @@ fn compile_fail(sysroot: &str) {
});
}

fn run_pass() {
let mut config = compiletest::default_config();
config.mode = "run-pass".parse().expect("Invalid mode");
config.src_base = PathBuf::from("tests/run-pass".to_string());
compiletest::run_tests(&config);
fn should_ignore(filename: &Path) -> bool {
let mut file = File::open(filename).expect("could not open file");
let mut source = String::new();

file.read_to_string(&mut source).expect("could not read file");

return source.contains("xfail")
}

fn for_all_targets<F: FnMut(String)>(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;
#[test]
fn compile_pass() {
let sysroot = find_sysroot();
for_all_targets(&sysroot, |target| {
let (mut pass, mut fail, mut ignored) = (0, 0, 0);

for file in std::fs::read_dir("tests/compile-pass").unwrap() {
let file = file.unwrap();
let path = file.path();

if !file.metadata().unwrap().is_file() || !path.to_str().unwrap().ends_with(".rs") {
continue;
}

if should_ignore(&path) {
ignored += 1;
continue;
}

let stderr = std::io::stderr();
write!(stderr.lock(), "test [compile-pass] {} ... ", path.display()).unwrap();
let mut cmd = std::process::Command::new("target/debug/mir2wasm");
cmd.arg(path);
cmd.arg("-Dwarnings");
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();
pass += 1;
}
Ok(output) => {
writeln!(stderr.lock(), "FAILED with exit code {:?}", output.status.code()).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();
fail += 1;
}
Err(e) => {
writeln!(stderr.lock(), "FAILED: {}", e).unwrap();
fail += 1;
},
}
}
let stderr = std::io::stderr();
writeln!(stderr.lock(), "running tests for target {}", target).unwrap();
f(target);
}
writeln!(stderr.lock(),
"[compile-pass] {} passed; {} failed; {} ignored",
pass, fail, ignored).unwrap();
if fail > 0 {
panic!("some compile-pass tests failed")
}
});
}

#[test]
fn empty_test() {
// show the test harness is running by getting at least one
// successful test.
fn run_pass() {
let mut config = compiletest::default_config();
config.mode = "run-pass".parse().expect("Invalid mode");
config.src_base = PathBuf::from("tests/run-pass".to_string());
compiletest::run_tests(&config);
}

#[test] #[ignore]
fn compile_test() {
// 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(),
};
compile_fail(&sysroot);
run_pass();
fn miri_run_pass() {
let sysroot = find_sysroot();
for_all_targets(&sysroot, |target| {
for file in std::fs::read_dir("tests/run-pass").unwrap() {
let file = file.unwrap();
Expand All @@ -71,7 +108,7 @@ fn compile_test() {

let stderr = std::io::stderr();
write!(stderr.lock(), "test [miri-pass] {} ... ", path.display()).unwrap();
let mut cmd = std::process::Command::new("target/debug/miri");
let mut cmd = std::process::Command::new("target/debug/mir2wasm");
cmd.arg(path);
cmd.arg("-Dwarnings");
cmd.arg(format!("--target={}", target));
Expand All @@ -98,3 +135,37 @@ fn compile_test() {
writeln!(stderr.lock(), "").unwrap();
});
}

fn for_all_targets<F: FnMut(String)>(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 empty_test() {
// show the test harness is running by getting at least one
// successful test.
}

fn find_sysroot() -> String {
// 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"));
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(),
}
}