1 //! File tests. 2 //! 3 //! This crate contains the main test driver as well as implementations of the 4 //! available filetest commands. 5 6 #![deny(missing_docs)] 7 8 pub use crate::function_runner::TestFileCompiler; 9 use crate::runner::TestRunner; 10 use cranelift_reader::TestCommand; 11 use std::path::Path; 12 13 mod concurrent; 14 pub mod function_runner; 15 mod match_directive; 16 mod runner; 17 mod runone; 18 mod subtest; 19 20 mod test_alias_analysis; 21 mod test_cat; 22 mod test_compile; 23 mod test_domtree; 24 mod test_interpret; 25 mod test_legalizer; 26 mod test_optimize; 27 mod test_print_cfg; 28 mod test_run; 29 mod test_safepoint; 30 mod test_unwind; 31 mod test_verifier; 32 33 /// Main entry point for `clif-util test`. 34 /// 35 /// Take a list of filenames which can be either `.clif` files or directories. 36 /// 37 /// Files are interpreted as test cases and executed immediately. 38 /// 39 /// Directories are scanned recursively for test cases ending in `.clif`. These test cases are 40 /// executed on background threads. 41 /// 42 pub fn run(verbose: bool, report_times: bool, files: &[String]) -> anyhow::Result<()> { 43 let mut runner = TestRunner::new(verbose, report_times); 44 45 for path in files.iter().map(Path::new) { 46 if path.is_file() { 47 runner.push_test(path); 48 } else { 49 runner.push_dir(path); 50 } 51 } 52 53 runner.start_threads(); 54 runner.run() 55 } 56 57 /// Used for 'pass' subcommand. 58 /// Commands are interpreted as test and executed. 59 /// 60 /// Directories are scanned recursively for test cases ending in `.clif`. 61 /// 62 pub fn run_passes( 63 verbose: bool, 64 report_times: bool, 65 passes: &[String], 66 target: &str, 67 file: &str, 68 ) -> anyhow::Result<()> { 69 let mut runner = TestRunner::new(verbose, report_times); 70 71 let path = Path::new(file); 72 if path == Path::new("-") || path.is_file() { 73 runner.push_test(path); 74 } else { 75 runner.push_dir(path); 76 } 77 78 runner.start_threads(); 79 runner.run_passes(passes, target) 80 } 81 82 /// Create a new subcommand trait object to match `parsed.command`. 83 /// 84 /// This function knows how to create all of the possible `test <foo>` commands that can appear in 85 /// a `.clif` test file. 86 fn new_subtest(parsed: &TestCommand) -> anyhow::Result<Box<dyn subtest::SubTest>> { 87 match parsed.command { 88 "alias-analysis" => test_alias_analysis::subtest(parsed), 89 "cat" => test_cat::subtest(parsed), 90 "compile" => test_compile::subtest(parsed), 91 "domtree" => test_domtree::subtest(parsed), 92 "interpret" => test_interpret::subtest(parsed), 93 "legalizer" => test_legalizer::subtest(parsed), 94 "optimize" => test_optimize::subtest(parsed), 95 "print-cfg" => test_print_cfg::subtest(parsed), 96 "run" => test_run::subtest(parsed), 97 "safepoint" => test_safepoint::subtest(parsed), 98 "unwind" => test_unwind::subtest(parsed), 99 "verifier" => test_verifier::subtest(parsed), 100 _ => anyhow::bail!("unknown test command '{}'", parsed.command), 101 } 102 } 103 104 fn pretty_anyhow_error( 105 func: &cranelift_codegen::ir::Function, 106 err: cranelift_codegen::CodegenError, 107 ) -> anyhow::Error { 108 let s = cranelift_codegen::print_errors::pretty_error(func, err); 109 anyhow::anyhow!("{}", s) 110 } 111