rust/src/compiletest/compiletest.rc
2013-03-29 16:39:08 -07:00

236 lines
7.2 KiB
Plaintext

// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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::*;
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 mod procsrv;
pub mod util;
pub mod header;
pub mod runtest;
pub mod common;
pub mod errors;
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"),
getopts::optflag(~"newrt")];
assert!(!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: getopts::opt_maybe_str(matches, ~"logfile").map(|s| Path(*s)),
runtool: getopts::opt_maybe_str(matches, ~"runtool"),
rustcflags: getopts::opt_maybe_str(matches, ~"rustcflags"),
jit: getopts::opt_present(matches, ~"jit"),
newrt: getopts::opt_present(matches, ~"newrt"),
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!("newrt: %b", config.newrt));
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: