// Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. #[crate_type = "bin"]; #[no_core]; #[allow(vecs_implicitly_copyable)]; #[allow(non_camel_case_types)]; #[allow(deprecated_mode)]; #[allow(deprecated_pattern)]; extern mod core(vers = "0.6"); extern mod std(vers = "0.6"); use core::*; pub mod procsrv; pub mod util; pub mod header; pub mod runtest; pub mod common; pub mod errors; use std::getopts; use std::test; use core::result::{Ok, Err}; use common::config; use common::mode_run_pass; use common::mode_run_fail; use common::mode_compile_fail; use common::mode_pretty; use common::mode_debug_info; use common::mode; use util::logv; pub fn main() { let args = os::args(); let config = parse_config(args); log_config(config); run_tests(config); } pub fn parse_config(args: ~[~str]) -> config { let opts = ~[getopts::reqopt(~"compile-lib-path"), getopts::reqopt(~"run-lib-path"), getopts::reqopt(~"rustc-path"), getopts::reqopt(~"src-base"), getopts::reqopt(~"build-base"), getopts::reqopt(~"aux-base"), getopts::reqopt(~"stage-id"), getopts::reqopt(~"mode"), getopts::optflag(~"ignored"), getopts::optopt(~"runtool"), getopts::optopt(~"rustcflags"), getopts::optflag(~"verbose"), getopts::optopt(~"logfile"), getopts::optflag(~"jit")]; fail_unless!(!args.is_empty()); let args_ = vec::tail(args); let matches = &match getopts::getopts(args_, opts) { Ok(m) => m, Err(f) => fail!(getopts::fail_str(f)) }; fn opt_path(m: &getopts::Matches, nm: ~str) -> Path { Path(getopts::opt_str(m, nm)) } config { compile_lib_path: getopts::opt_str(matches, ~"compile-lib-path"), run_lib_path: getopts::opt_str(matches, ~"run-lib-path"), rustc_path: opt_path(matches, ~"rustc-path"), src_base: opt_path(matches, ~"src-base"), build_base: opt_path(matches, ~"build-base"), aux_base: opt_path(matches, ~"aux-base"), stage_id: getopts::opt_str(matches, ~"stage-id"), mode: str_mode(getopts::opt_str(matches, ~"mode")), run_ignored: getopts::opt_present(matches, ~"ignored"), filter: if vec::len(matches.free) > 0u { option::Some(matches.free[0]) } else { option::None }, logfile: option::map(&getopts::opt_maybe_str(matches, ~"logfile"), |s| Path(*s)), runtool: getopts::opt_maybe_str(matches, ~"runtool"), rustcflags: getopts::opt_maybe_str(matches, ~"rustcflags"), jit: getopts::opt_present(matches, ~"jit"), verbose: getopts::opt_present(matches, ~"verbose") } } pub fn log_config(config: config) { let c = config; logv(c, fmt!("configuration:")); logv(c, fmt!("compile_lib_path: %s", config.compile_lib_path)); logv(c, fmt!("run_lib_path: %s", config.run_lib_path)); logv(c, fmt!("rustc_path: %s", config.rustc_path.to_str())); logv(c, fmt!("src_base: %s", config.src_base.to_str())); logv(c, fmt!("build_base: %s", config.build_base.to_str())); logv(c, fmt!("stage_id: %s", config.stage_id)); logv(c, fmt!("mode: %s", mode_str(config.mode))); logv(c, fmt!("run_ignored: %b", config.run_ignored)); logv(c, fmt!("filter: %s", opt_str(config.filter))); logv(c, fmt!("runtool: %s", opt_str(config.runtool))); logv(c, fmt!("rustcflags: %s", opt_str(config.rustcflags))); logv(c, fmt!("jit: %b", config.jit)); logv(c, fmt!("verbose: %b", config.verbose)); logv(c, fmt!("\n")); } pub fn opt_str(maybestr: Option<~str>) -> ~str { match maybestr { option::Some(s) => s, option::None => ~"(none)" } } pub fn str_opt(maybestr: ~str) -> Option<~str> { if maybestr != ~"(none)" { option::Some(maybestr) } else { option::None } } pub fn str_mode(s: ~str) -> mode { match s { ~"compile-fail" => mode_compile_fail, ~"run-fail" => mode_run_fail, ~"run-pass" => mode_run_pass, ~"pretty" => mode_pretty, ~"debug-info" => mode_debug_info, _ => fail!(~"invalid mode") } } pub fn mode_str(mode: mode) -> ~str { match mode { mode_compile_fail => ~"compile-fail", mode_run_fail => ~"run-fail", mode_run_pass => ~"run-pass", mode_pretty => ~"pretty", mode_debug_info => ~"debug-info", } } pub fn run_tests(config: config) { let opts = test_opts(config); let tests = make_tests(config); let res = test::run_tests_console(&opts, tests); if !res { fail!(~"Some tests failed"); } } pub fn test_opts(config: config) -> test::TestOpts { test::TestOpts { filter: config.filter, run_ignored: config.run_ignored, logfile: copy config.logfile, run_tests: true, run_benchmarks: false, save_results: option::None, compare_results: option::None } } pub fn make_tests(config: config) -> ~[test::TestDescAndFn] { debug!("making tests from %s", config.src_base.to_str()); let mut tests = ~[]; for os::list_dir_path(&config.src_base).each |file| { let file = copy *file; debug!("inspecting file %s", file.to_str()); if is_test(config, file) { tests.push(make_test(config, file)) } } tests } pub fn is_test(config: config, testfile: &Path) -> bool { // Pretty-printer does not work with .rc files yet let valid_extensions = match config.mode { mode_pretty => ~[~".rs"], _ => ~[~".rc", ~".rs"] }; let invalid_prefixes = ~[~".", ~"#", ~"~"]; let name = testfile.filename().get(); let mut valid = false; for valid_extensions.each |ext| { if str::ends_with(name, *ext) { valid = true; } } for invalid_prefixes.each |pre| { if str::starts_with(name, *pre) { valid = false; } } return valid; } pub fn make_test(config: config, testfile: &Path) -> test::TestDescAndFn { test::TestDescAndFn { desc: test::TestDesc { name: make_test_name(config, testfile), ignore: header::is_test_ignored(config, testfile), should_fail: false }, testfn: make_test_closure(config, testfile), } } pub fn make_test_name(config: config, testfile: &Path) -> test::TestName { test::DynTestName(fmt!("[%s] %s", mode_str(config.mode), testfile.to_str())) } pub fn make_test_closure(config: config, testfile: &Path) -> test::TestFn { let testfile = testfile.to_str(); test::DynTestFn(|| runtest::run(config, testfile)) } // Local Variables: // fill-column: 78; // indent-tabs-mode: nil // c-basic-offset: 4 // buffer-file-coding-system: utf-8-unix // End: