From 8921385fbbd38d3ad237e3884f274284d1d83aab Mon Sep 17 00:00:00 2001 From: Brandon Fish Date: Thu, 27 Dec 2018 01:43:38 -0600 Subject: [PATCH] Update emtests to glob for c/cpp files, use ignores.txt to exclude tests, disable cc out by default --- Cargo.lock | 1 + Cargo.toml | 1 + build/emtests.rs | 122 ++++++++++++++++++++------ build/mod.rs | 1 + emtests/README.md | 15 ++-- emtests/{env.output => env.out} | 0 emtests/env.wasm | Bin 46217 -> 46198 bytes emtests/{printf.output => printf.out} | 0 emtests/printf.wasm | Bin 47042 -> 47023 bytes emtests/{puts.output => puts.out} | 0 emtests/puts.wasm | Bin 23716 -> 23697 bytes src/emtests/_common.rs | 7 +- src/emtests/env.rs | 2 +- src/emtests/printf.rs | 7 +- src/emtests/puts.rs | 7 +- 15 files changed, 115 insertions(+), 48 deletions(-) rename emtests/{env.output => env.out} (100%) rename emtests/{printf.output => printf.out} (100%) rename emtests/{puts.output => puts.out} (100%) diff --git a/Cargo.lock b/Cargo.lock index b874d507b..ff0c21ad7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -888,6 +888,7 @@ dependencies = [ "docopt 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "indicatif 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.44 (git+https://github.com/rust-lang/libc)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 5c09b9f2a..3ab0e0609 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,6 +52,7 @@ console = "0.7.1" [build-dependencies] wabt = "0.7.2" +glob = "0.2.11" # [dev-dependencies] # libffi = "0.6.4" # maplit = "1.0.1" diff --git a/build/emtests.rs b/build/emtests.rs index 2d5306994..43a819402 100644 --- a/build/emtests.rs +++ b/build/emtests.rs @@ -4,36 +4,43 @@ //! - Compile using emcc and get the .wasm from it (wasm) //! - Generate the test that will compare the output of running the .wasm file //! with wasmer with the expected output +use glob::glob; use std::fs; +use std::path::Path; use std::path::PathBuf; use std::process::Command; +use std::fs::File; +use std::io::prelude::*; +use std::io::BufReader; + static BANNER: &str = "// Rust test file autogenerated with cargo build (build/emtests.rs). // Please do NOT modify it by hand, as it will be reseted on next build.\n"; -const TESTS: [&str; 3] = ["emtests/env.c", "emtests/puts.c", "emtests/printf.c"]; +const EXTENSIONS: [&str; 2] = ["c", "cpp"]; +const EXCLUDES: [&str; 1] = ["localtime.c"]; -pub fn compile(file: &str) -> String { +pub fn compile(file: &str, ignores: &Vec) -> Option { let mut output_path = PathBuf::from(file); output_path.set_extension("out"); - let output_str = output_path.to_str().unwrap(); + // let output_str = output_path.to_str().unwrap(); // Compile to .out - Command::new("cc") - .arg(file) - .arg("-o") - .arg(output_str) - .output() - .expect("failed to execute process"); + // Command::new("cc") + // .arg(file) + // .arg("-o") + // .arg(output_str) + // .output() + // .expect("failed to execute process"); // Get the result of .out - let output = Command::new(output_str) - .arg(output_str) - .output() - .expect("failed to execute process"); + // let output = Command::new(output_str) + // .arg(output_str) + // .output() + // .expect("failed to execute process"); // Remove executable - fs::remove_file(output_str).unwrap(); + // fs::remove_file(output_str).unwrap(); let mut output_path = PathBuf::from(file); output_path.set_extension("js"); @@ -54,7 +61,12 @@ pub fn compile(file: &str) -> String { // panic!("{}", output.stderr); // } // Remove js file - fs::remove_file(output_str).unwrap(); + + if Path::new(output_str).is_file() { + fs::remove_file(output_str).unwrap(); + } else { + println!("Output JS not found: {}", output_str); + } let mut output_path = PathBuf::from(file); output_path.set_extension("output"); @@ -65,26 +77,58 @@ pub fn compile(file: &str) -> String { .unwrap() .to_owned(); - let output_str = output_path.to_str().unwrap(); + // + // let output_str = output_path.to_str().unwrap(); // Write the output to file - fs::write(output_str, output.stdout).expect("Unable to write file"); + // fs::write(output_str, output.stdout).expect("Unable to write file"); + let rs_module_name = module_name.to_lowercase(); let rust_test_filepath = format!( concat!(env!("CARGO_MANIFEST_DIR"), "/src/emtests/{}.rs"), - module_name.as_str() + rs_module_name.as_str() ); - let contents = format!("#[test] -fn test_{module_name}() {{ - assert_emscripten_output!(\"../../emtests/{module_name}.wasm\", \"{module_name}\", vec![], \"../../emtests/{module_name}.output\"); + let output_extension = if file.ends_with("c") || module_name.starts_with("test_") { + "out" + } else { + "txt" + }; + + let ignored = if ignores + .iter() + .any(|i| &i.to_lowercase() == &module_name.to_lowercase()) + { + "\n#[ignore]" + } else { + "" + }; + + let module_path = format!("emtests/{}.wasm", module_name); + let test_output_path = format!("emtests/{}.{}", module_name, output_extension); + if !Path::new(&module_path).is_file() { + println!("Path not found to test module: {}", module_path); + None + } else if !Path::new(&test_output_path).is_file() { + println!("Path not found to test output: {}", module_path); + None + } else { + let contents = format!( + "#[test]{ignore} +fn test_{rs_module_name}() {{ + assert_emscripten_output!(\"../../{module_path}\", \"{rs_module_name}\", vec![], \"../../{test_output_path}\"); }} -", module_name=module_name); +", + ignore = ignored, + module_path = module_path, + rs_module_name = rs_module_name, + test_output_path = test_output_path + ); - fs::write(&rust_test_filepath, contents.as_bytes()).unwrap(); - - module_name + fs::write(&rust_test_filepath, contents.as_bytes()).unwrap(); + Some(rs_module_name) + } // panic!("OUTPUT: {:?}", output); } @@ -93,10 +137,26 @@ pub fn build() { let mut modules: Vec = Vec::new(); // modules.reserve_exact(TESTS.len()); - for test in TESTS.iter() { - let moudle_name = compile(test); - modules.push(format!("mod {};", moudle_name)); + + let ignores = read_ignore_list(); + + for ext in EXTENSIONS.iter() { + for entry in glob(&format!("emtests/*.{}", ext)).unwrap() { + match entry { + Ok(path) => { + let test = path.to_str().unwrap(); + if !EXCLUDES.iter().any(|e| test.ends_with(e)) { + if let Some(module_name) = compile(test, &ignores) { + modules.push(format!("mod {};", module_name)); + } + } + } + Err(e) => println!("{:?}", e), + } + } } + assert!(modules.len() > 0, "Expected > 0 modules found"); + modules.insert(0, BANNER.to_string()); modules.insert(1, "// The _common module is not autogenerated, as it provides common macros for the emtests\n#[macro_use]\nmod _common;".to_string()); // We add an empty line @@ -109,3 +169,9 @@ pub fn build() { fs::write(&rust_test_modpath, modfile.as_bytes()).unwrap(); } } + +fn read_ignore_list() -> Vec { + let f = File::open("emtests/ignores.txt").unwrap(); + let f = BufReader::new(f); + f.lines().filter_map(Result::ok).collect() +} diff --git a/build/mod.rs b/build/mod.rs index 392d97413..2bd41a949 100644 --- a/build/mod.rs +++ b/build/mod.rs @@ -1,3 +1,4 @@ +extern crate glob; extern crate wabt; use std::env; diff --git a/emtests/README.md b/emtests/README.md index 92d281ba9..daffe36d6 100644 --- a/emtests/README.md +++ b/emtests/README.md @@ -1,21 +1,24 @@ This directory contains tests for unit testing each of the functions/syscalls that Emscripten will be doing. -If you want to generate the wasm files, you will just need to: +If you want to generate the wasm files, you will just need: + +Have EMCC (version 1.38.21) installed + +Then run: ``` make emtests ``` +**Ignored Tests** +Test names included in `emtests/ignores.txt` will be annotated with `#[ignore]` during test generation. + This process will do something similar to: ``` -cc localtime.c -o localtime.out -# Execute the out file and save its output -./localtime.out > ./localtime.output -rm localtime.out - # Generate the .wasm file emcc localtime.c -o localtime.js # Delte the js file, as we don't need it rm localtime.js ``` + diff --git a/emtests/env.output b/emtests/env.out similarity index 100% rename from emtests/env.output rename to emtests/env.out diff --git a/emtests/env.wasm b/emtests/env.wasm index 0df9e53a585ff3ee61c031b22f089f7fb50ab902..cf10ad39b9f2cbb2acd074d488d77ed8f358400c 100644 GIT binary patch delta 259 zcmeBt$@J|7(}uZBOm?=D=QEj3zRHxx+`uF>*^N0n(StQUH!(AhL4qAf=j7xkGe`ni zskzAol?R&igEv=7Wu7xoU3_LHgAWga1LXP&rxuqaCgo%nX9Sld zCT9m1Bqpaah)q^tvF7)a_V-tmmGSrY=X!RW$#!!Vi=Z5%_v9L-8bt76*mPECSw>B~;5fycM6aI5G%$Z=SBYM32#PvrUL3 pGo#1mu<&A4Mz77MY8HwDshmmTj6kYo@(U1^JJpqM^R~s81puwMRFVJy delta 257 zcmezNf~oT*(}uZBO!jt@=QEiyvQ56il*io1Bs|%bIh)aQ@ZOUmgSp$n_IWEiOq+%E>Iw2rfxX&JHd}OipDG<1Q-A z3&<}n2~I63X7HFS$YRa!FC7q|C@T{X5Ww~7IFsGxXcj>^MxV*KN;Ql=i(e@*GWu+O zt<26S?xT2*Md2QcW4)W=eHMlLEG!NRmstdSCUdHmbNDDeWpQK>@Y&pg9}$mWu7xoU3_LHgDVe$1LV31rxuqaCgo%nX9Sld zCT9m1Bqpaa2u_~HY|Za3=HVeDA@1Sf!FBO0llA5Y%o2)>E|Y(%)G)d%E>mS>blF_4 z#tx(=*Q<*H$*Jn)94?AaSsWPzTsDhnEYV|h+PpJNl9|zQ^X155RYvE{?)3{rfz-<> W;*3CwaoP(I^=i5%-)8Y;s|5jLpia{O delta 246 zcmZ4gp6SqgrVXA$T z09mQI$pw`R&R|w?Y6*i2YkYB1Q8t4sS4w4`Gf-W8W+sCh4}t^ax=$`-7USbCD$NVX zFD?mAEh%PjoZQZA&F>-R=_w;2?&;~tb@eQh&E|{D5{itjlV7RSFuE>IS7l^$-JGGu z4x}a*sEY#0HuZ82SH-6+jtl~>n^`rM=rKBPUKJ+E%;>cFNMx}pqswNC`h}uE>edu- ZMj-WR>I)Ecd%7kcGcyC@X69vU1OYgyOSl~S4KoS2gnpP9*^%Y)zmxq6fNnZ+g>Gh6fP ziy0WmNQfI47;v?3WK`Z<%UmeKs5AM!d<~<{;v5A=MxD*MitLQyI*RvL6z;J&*1IX* vXHmG%!s4KCnMFWna<@`BhmPV?7DomFoy}az9}F0^HvbNu!Mu5TI4>&z#)C4n delta 222 zcmbQZlX1yT#ti~Y@~SF~Ow6pTER4*I3=E7+j0}t{Y|M--j0{ZdjEs!zll7Q#nNKhZ zOrFQ&sISc)pPQOnoLa)5!x~?lRFuu2%au}@=bV_66Q7yMpvQyY0J-{;`IyD{xQj~j z0`iMXf>TS18MG#=FkAB*h#4BnNQfI68gg}SWK`Ll$6P4Gs5|+Ad<~=S;#dVnM%~SE zitLQyx{CK$6z;J&*1IX*XHmG%!s4KCnMFW%a*a|shpysN7DomF-Oaz1J{T}+Z+;Uz PgPEC`fpK$lI3Ftj5zja} diff --git a/src/emtests/_common.rs b/src/emtests/_common.rs index 78b169f54..c279892b0 100644 --- a/src/emtests/_common.rs +++ b/src/emtests/_common.rs @@ -28,6 +28,11 @@ macro_rules! assert_emscripten_output { .unwrap(); let output = capturer.end().unwrap().0; let expected_output = include_str!($expected); - assert_eq!(output, expected_output); + assert!( + output.contains(expected_output), + "Output: `{}` does not contain expected output: `{}`", + output, + expected_output + ); }}; } diff --git a/src/emtests/env.rs b/src/emtests/env.rs index 58b674a3f..b67e176cc 100644 --- a/src/emtests/env.rs +++ b/src/emtests/env.rs @@ -4,6 +4,6 @@ fn test_env() { "../../emtests/env.wasm", "env", vec![], - "../../emtests/env.output" + "../../emtests/env.out" ); } diff --git a/src/emtests/printf.rs b/src/emtests/printf.rs index 4cc250c5f..9114fef3e 100644 --- a/src/emtests/printf.rs +++ b/src/emtests/printf.rs @@ -1,9 +1,4 @@ #[test] fn test_printf() { - assert_emscripten_output!( - "../../emtests/printf.wasm", - "printf", - vec![], - "../../emtests/printf.output" - ); + assert_emscripten_output!("../../emtests/printf.wasm", "printf", vec![], "../../emtests/printf.out"); } diff --git a/src/emtests/puts.rs b/src/emtests/puts.rs index 059d998c4..dae9e2f36 100644 --- a/src/emtests/puts.rs +++ b/src/emtests/puts.rs @@ -1,9 +1,4 @@ #[test] fn test_puts() { - assert_emscripten_output!( - "../../emtests/puts.wasm", - "puts", - vec![], - "../../emtests/puts.output" - ); + assert_emscripten_output!("../../emtests/puts.wasm", "puts", vec![], "../../emtests/puts.out"); }