Skip to content
This repository was archived by the owner on May 17, 2021. It is now read-only.

Add lang_tester framework for Miri tests #38

Closed
Closed
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
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@ name = "gc_tests"
path = "gc_tests/run_tests.rs"
harness = false

[[test]]
name = "miri_tests"
path = "gc_tests/run_miri_tests.rs"
harness = false

[workspace]
20 changes: 20 additions & 0 deletions gc_tests/miri_test_setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/sh
set -e;

PROJECTDIR=$1
TMPDIR=$2

# Miri deps cause breakages when used with non-miri targets. So we copy gcmalloc
# sources over to a tempdir to compile with miri flags so we can nuke it
# afterwards.
rsync -a --partial --info=progress2 --exclude .git --exclude target --exclude gc_tests $PROJECTDIR/ $TMPDIR
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rsync?!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could probably be cp now. I used rsync while developing because there was a lot of trial-and-error testing and I wanted to speed up transfer of targets. I'm curious, is the "?!" a comment on the overkill or poor platform compatibility. If the latter, I'm afraid there's plenty more where that came from with this approach to getting Miri running.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, cp is more portable than rsync, and given that we copy to a fresh directory each time, I think cp is sufficient.


mkdir -p "$TMPDIR/src/bin/"

# Running this dummy binary forces cargo-miri to compile gcmalloc with miri
# flags as a dependency.
echo "extern crate gcmalloc; fn main() {}" > $TMPDIR/src/bin/miri.rs
(cd $TMPDIR && cargo-miri miri setup)
(cd $TMPDIR && cargo-miri miri run -- -Zmiri-ignore-leaks)

rm $TMPDIR/src/bin/miri.rs
78 changes: 78 additions & 0 deletions gc_tests/run_miri_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use std::{
env,
path::{Path, PathBuf},
process::Command,
};

use lang_tester::LangTester;
use tempdir::TempDir;

fn proj_dir() -> Box<Path> {
let mut p = PathBuf::new();
p.push(env::var("CARGO_MANIFEST_DIR").unwrap());
p.into_boxed_path()
}

fn test_dir() -> Box<Path> {
let mut p = PathBuf::new();
p.push(env::var("CARGO_MANIFEST_DIR").unwrap());
p.push("gc_tests");
p.push("tests");
p.push(".");
p.into_boxed_path()
}

fn main() {
let projd = proj_dir();
let testsd = test_dir();

let tmpd = TempDir::new("miri_tests").unwrap();
let mut binsd = PathBuf::new();
binsd.push(tmpd.path());
binsd.push("src");
binsd.push("bin");

let mut setup = Command::new("./gc_tests/miri_test_setup.sh")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wondered if it would be better to inline what miri_test_setup.sh does into Rust? But perhaps that's overkill.

.args(&[&*projd, tmpd.path()])
.spawn()
.unwrap();

if !setup.wait().unwrap().success() {
panic!("Miri setup failed");
}

::std::env::set_current_dir(&tmpd).expect("Couldn't change dir");

LangTester::new()
.test_dir(testsd.to_str().unwrap())
.test_file_filter(|p| {
p.extension().unwrap().to_str().unwrap() == "rs"
&& p.file_stem().unwrap().to_str().unwrap().starts_with("miri")
})
.test_extract(|s| {
Some(
s.lines()
.take_while(|l| l.starts_with("//"))
.map(|l| &l[2..])
.collect::<Vec<_>>()
.join("\n"),
)
})
.test_cmds(move |p| {
let mut cp = Command::new("cp");
cp.args(&[p, binsd.as_path()]);

let mut runtime = Command::new("cargo-miri");
runtime.args(&["miri", "run", "--", "-Zmiri-ignore-leaks"]);

let mut rm_path = PathBuf::new();
rm_path.push(&binsd);
rm_path.push(p.file_name().unwrap().to_str().unwrap());

let mut rm = Command::new("rm");
rm.args(&[rm_path.to_str().unwrap()]);

vec![("cp", cp), ("Miri", runtime), ("rm", rm)]
})
.run();
}
11 changes: 11 additions & 0 deletions gc_tests/tests/miri_hello_world.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Miri:
// status: success

extern crate gcmalloc;

use gcmalloc::Gc;

fn main() {
let hello = Gc::new("Hello World");
println!("{}", hello)
}