Run all tests manually

Running a test per thread really doesn't play well with QEMU emulation, so just
make it easy on ourselves and don't run threads.
This commit is contained in:
Alex Crichton 2015-09-13 23:33:33 -07:00
parent 1e6056e573
commit 5a28433bb1
3 changed files with 45 additions and 11 deletions

View File

@ -15,3 +15,7 @@ gcc = { git = "https://github.com/alexcrichton/gcc-rs" }
name = "libc_test"
test = false
doctest = false
[[test]]
name = "all"
harness = false

View File

@ -32,6 +32,7 @@ struct TestGenerator<'a> {
sh: &'a SpanHandler,
structs: HashSet<String>,
abi: Abi,
tests: Vec<String>,
}
struct StructFinder {
@ -253,6 +254,7 @@ fn main() {
sh: &sess.span_diagnostic,
structs: HashSet::new(),
abi: Abi::C,
tests: Vec::new(),
};
// Parse the libc crate
@ -299,6 +301,7 @@ fn main() {
// Walk the crate, emitting test cases for everything found
visit::walk_crate(&mut tg, &krate);
tg.emit_run_all();
// Compile our C shim to be linked into tests
let mut cfg = gcc::Config::new();
@ -336,9 +339,10 @@ impl<'a> TestGenerator<'a> {
let cty = self.rust_ty_to_c_ty(ty);
self.test_size_align(ty, &cty);
self.tests.push(format!("field_offset_size_{}", ty));
t!(writeln!(self.rust, r#"
#[test]
fn field_offset_size_{ty}() {{
println!("verifying struct {ty}");
"#, ty = ty));
for field in s.fields.iter() {
let name = match field.node.kind {
@ -385,20 +389,21 @@ impl<'a> TestGenerator<'a> {
uint64_t __test_align_{ty}(void) {{ return alignof({cty}); }}
"#, ty = rust, cty = c));
t!(writeln!(self.rust, r#"
#[test]
fn size_align_{ty}() {{
extern {{
fn __test_size_{ty}() -> u64;
fn __test_align_{ty}() -> u64;
}}
println!("verifying type {ty} align/size");
unsafe {{
same(mem::size_of::<{ty}>() as u64,
__test_size_{ty}(), "size");
__test_size_{ty}(), "{ty} size");
same(align::<{ty}>() as u64,
__test_align_{ty}(), "align");
__test_align_{ty}(), "{ty} align");
}}
}}
"#, ty = rust));
self.tests.push(format!("size_align_{}", rust));
}
fn rust_ty_to_c_ty(&self, mut rust_ty: &str) -> String {
@ -440,21 +445,22 @@ impl<'a> TestGenerator<'a> {
}}
"#, name = name, cast = cast, cty = cty));
t!(writeln!(self.rust, r#"
#[test]
fn const_{name}() {{
extern {{
fn __test_const_{name}(out: *mut {ty}) -> c_int;
}}
println!("verifying const {name} value");
unsafe {{
let mut o = mem::zeroed();
if __test_const_{name}(&mut o) == 0 {{
panic!("not defined");
panic!("{name} not defined");
}} else {{
same({name}, o, "value");
same({name}, o, "{name} value");
}}
}}
}}
"#, ty = rust_ty, name = name));
self.tests.push(format!("const_{}", name));
}
fn test_extern_fn(&mut self, name: &str, cname: &str,
@ -495,18 +501,19 @@ impl<'a> TestGenerator<'a> {
}}
"#, name = name, cname = cname, args = args, ret = cret, abi = abi));
t!(writeln!(self.rust, r#"
#[test]
#[cfg_attr(windows, ignore)] // FIXME -- dllimport weirdness?
fn fn_{name}() {{
extern {{
fn __test_fn_{name}() -> size_t;
}}
println!("verifying function {name} pointer");
unsafe {{
same({name} as usize,
__test_fn_{name}() as usize, "function pointer");
__test_fn_{name}() as usize,
"{name} function pointer");
}}
}}
"#, name = name));
self.tests.push(format!("fn_{}", name));
}
fn assert_no_generics(&self, _i: ast::Ident, generics: &ast::Generics) {
@ -550,6 +557,24 @@ impl<'a> TestGenerator<'a> {
};
(ret, args, decl.variadic)
}
fn emit_run_all(&mut self) {
t!(writeln!(self.rust, "
fn run_all() {{
"));
for test in self.tests.iter() {
if test.starts_with("fn_") {
// FIXME: weird dllimport issues with windows?
t!(writeln!(self.rust, "if cfg!(not(windows)) {{ {}(); }}",
test));
} else {
t!(writeln!(self.rust, "{}();", test));
}
}
t!(writeln!(self.rust, "
}}
"));
}
}
impl<'a, 'v> Visitor<'v> for TestGenerator<'a> {

View File

@ -55,5 +55,10 @@ macro_rules! offset_of {
)
}
#[cfg(test)]
include!(concat!(env!("OUT_DIR"), "/all.rs"));
fn main() {
println!("RUNNING ALL TESTS");
run_all();
println!("PASSED");
}