2014-05-20 18:15:34 +01:00
|
|
|
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
2012-12-03 16:48:01 -08:00
|
|
|
// 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.
|
|
|
|
|
2014-03-21 18:05:05 -07:00
|
|
|
#![crate_type = "bin"]
|
2015-01-30 12:26:44 -08:00
|
|
|
|
2015-01-08 01:43:32 +01:00
|
|
|
#![feature(box_syntax)]
|
2015-06-10 13:33:52 -07:00
|
|
|
#![feature(dynamic_lib)]
|
|
|
|
#![feature(libc)]
|
|
|
|
#![feature(rustc_private)]
|
2015-03-18 09:14:54 -07:00
|
|
|
#![feature(str_char)]
|
2015-06-10 13:33:52 -07:00
|
|
|
#![feature(test)]
|
2012-01-17 14:40:59 -08:00
|
|
|
|
2014-03-21 18:05:05 -07:00
|
|
|
#![deny(warnings)]
|
2012-06-04 18:34:24 -07:00
|
|
|
|
2015-04-10 13:51:53 -07:00
|
|
|
extern crate libc;
|
2014-02-14 09:49:11 +08:00
|
|
|
extern crate test;
|
2014-02-14 10:10:06 -08:00
|
|
|
extern crate getopts;
|
2014-12-31 20:43:46 -08:00
|
|
|
|
|
|
|
#[macro_use]
|
|
|
|
extern crate log;
|
2014-05-05 22:19:38 +10:00
|
|
|
|
2015-01-27 12:20:58 -08:00
|
|
|
use std::env;
|
2015-02-26 21:00:43 -08:00
|
|
|
use std::fs;
|
|
|
|
use std::path::{Path, PathBuf};
|
2014-02-03 19:14:40 -08:00
|
|
|
use getopts::{optopt, optflag, reqopt};
|
2014-04-16 13:56:39 +09:00
|
|
|
use common::Config;
|
2015-05-24 18:07:52 +02:00
|
|
|
use common::{Pretty, DebugInfoGdb, DebugInfoLldb};
|
2012-11-18 17:56:50 -08:00
|
|
|
use util::logv;
|
|
|
|
|
2013-03-26 19:53:33 -07:00
|
|
|
pub mod procsrv;
|
|
|
|
pub mod util;
|
|
|
|
pub mod header;
|
|
|
|
pub mod runtest;
|
|
|
|
pub mod common;
|
|
|
|
pub mod errors;
|
2015-04-10 10:36:13 -07:00
|
|
|
mod raise_fd_limit;
|
2013-03-26 19:53:33 -07:00
|
|
|
|
2013-01-30 14:10:03 -08:00
|
|
|
pub fn main() {
|
2015-02-11 11:47:53 -08:00
|
|
|
let config = parse_config(env::args().collect());
|
2014-10-09 12:11:37 +13:00
|
|
|
|
|
|
|
if config.valgrind_path.is_none() && config.force_valgrind {
|
2014-10-09 15:17:22 -04:00
|
|
|
panic!("Can't find Valgrind to run Valgrind tests");
|
2014-10-09 12:11:37 +13:00
|
|
|
}
|
|
|
|
|
2013-05-11 22:45:28 -04:00
|
|
|
log_config(&config);
|
|
|
|
run_tests(&config);
|
2012-11-18 17:56:50 -08:00
|
|
|
}
|
|
|
|
|
2014-05-22 16:57:53 -07:00
|
|
|
pub fn parse_config(args: Vec<String> ) -> Config {
|
2013-07-06 00:44:40 -07:00
|
|
|
|
2014-03-05 15:28:08 -08:00
|
|
|
let groups : Vec<getopts::OptGroup> =
|
|
|
|
vec!(reqopt("", "compile-lib-path", "path to host shared libraries", "PATH"),
|
2013-08-30 16:17:32 -04:00
|
|
|
reqopt("", "run-lib-path", "path to target shared libraries", "PATH"),
|
|
|
|
reqopt("", "rustc-path", "path to rustc to use for compiling", "PATH"),
|
2015-04-06 13:48:17 -07:00
|
|
|
reqopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH"),
|
|
|
|
reqopt("", "python", "path to python to use for doc tests", "PATH"),
|
2014-10-09 12:11:37 +13:00
|
|
|
optopt("", "valgrind-path", "path to Valgrind executable for Valgrind tests", "PROGRAM"),
|
|
|
|
optflag("", "force-valgrind", "fail if Valgrind tests cannot be run under Valgrind"),
|
2013-08-30 16:17:32 -04:00
|
|
|
optopt("", "llvm-bin-path", "path to directory holding llvm binaries", "DIR"),
|
|
|
|
reqopt("", "src-base", "directory to scan for test files", "PATH"),
|
|
|
|
reqopt("", "build-base", "directory to deposit test outputs", "PATH"),
|
|
|
|
reqopt("", "aux-base", "directory to find auxiliary test files", "PATH"),
|
|
|
|
reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET"),
|
|
|
|
reqopt("", "mode", "which sort of compile tests to run",
|
2015-02-11 23:09:30 +01:00
|
|
|
"(compile-fail|parse-fail|run-fail|run-pass|run-pass-valgrind|pretty|debug-info)"),
|
2014-02-07 20:08:32 +01:00
|
|
|
optflag("", "ignored", "run tests marked as ignored"),
|
2013-08-30 16:17:32 -04:00
|
|
|
optopt("", "runtool", "supervisor program to run tests under \
|
2013-07-06 00:44:40 -07:00
|
|
|
(eg. emulator, valgrind)", "PROGRAM"),
|
2014-02-11 16:51:08 -05:00
|
|
|
optopt("", "host-rustcflags", "flags to pass to rustc for host", "FLAGS"),
|
|
|
|
optopt("", "target-rustcflags", "flags to pass to rustc for target", "FLAGS"),
|
2013-07-06 00:44:40 -07:00
|
|
|
optflag("", "verbose", "run tests verbosely, showing all output"),
|
|
|
|
optopt("", "logfile", "file to log test execution to", "FILE"),
|
|
|
|
optopt("", "target", "the target to build for", "TARGET"),
|
2014-01-17 10:18:02 -08:00
|
|
|
optopt("", "host", "the host to build for", "HOST"),
|
2014-10-02 11:35:24 +02:00
|
|
|
optopt("", "gdb-version", "the version of GDB used", "VERSION STRING"),
|
|
|
|
optopt("", "lldb-version", "the version of LLDB used", "VERSION STRING"),
|
2014-05-13 14:44:30 -04:00
|
|
|
optopt("", "android-cross-path", "Android NDK standalone path", "PATH"),
|
2013-07-06 00:44:40 -07:00
|
|
|
optopt("", "adb-path", "path to the android debugger", "PATH"),
|
|
|
|
optopt("", "adb-test-dir", "path to tests for the android debugger", "PATH"),
|
2014-04-24 11:35:48 +02:00
|
|
|
optopt("", "lldb-python-dir", "directory containing LLDB's python module", "PATH"),
|
2014-03-05 15:28:08 -08:00
|
|
|
optflag("h", "help", "show this message"));
|
2012-11-18 17:56:50 -08:00
|
|
|
|
2015-07-11 14:34:57 +03:00
|
|
|
let (argv0, args_) = args.split_first().unwrap();
|
2015-10-25 11:48:56 +01:00
|
|
|
if args.len() == 1 || args[1] == "-h" || args[1] == "--help" {
|
2013-09-29 13:18:51 -07:00
|
|
|
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
|
2015-02-01 21:53:25 -05:00
|
|
|
println!("{}", getopts::usage(&message, &groups));
|
2014-01-09 21:06:55 +11:00
|
|
|
println!("");
|
2014-10-09 15:17:22 -04:00
|
|
|
panic!()
|
2013-07-06 00:44:40 -07:00
|
|
|
}
|
|
|
|
|
2012-11-18 17:56:50 -08:00
|
|
|
let matches =
|
2015-02-01 21:53:25 -05:00
|
|
|
&match getopts::getopts(args_, &groups) {
|
2012-11-18 17:56:50 -08:00
|
|
|
Ok(m) => m,
|
2014-12-20 00:09:35 -08:00
|
|
|
Err(f) => panic!("{:?}", f)
|
2012-11-18 17:56:50 -08:00
|
|
|
};
|
|
|
|
|
2013-09-18 03:42:23 +02:00
|
|
|
if matches.opt_present("h") || matches.opt_present("help") {
|
2013-09-29 13:18:51 -07:00
|
|
|
let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
|
2015-02-01 21:53:25 -05:00
|
|
|
println!("{}", getopts::usage(&message, &groups));
|
2014-01-09 21:06:55 +11:00
|
|
|
println!("");
|
2014-10-09 15:17:22 -04:00
|
|
|
panic!()
|
2013-07-06 00:44:40 -07:00
|
|
|
}
|
|
|
|
|
2015-02-26 21:00:43 -08:00
|
|
|
fn opt_path(m: &getopts::Matches, nm: &str) -> PathBuf {
|
2014-12-22 19:02:11 +01:00
|
|
|
match m.opt_str(nm) {
|
2015-03-18 09:14:54 -07:00
|
|
|
Some(s) => PathBuf::from(&s),
|
2014-12-22 19:02:11 +01:00
|
|
|
None => panic!("no option (=path) found for {}", nm),
|
|
|
|
}
|
2012-11-18 17:56:50 -08:00
|
|
|
}
|
2013-08-12 14:15:05 -04:00
|
|
|
|
2014-05-05 22:19:38 +10:00
|
|
|
let filter = if !matches.free.is_empty() {
|
2015-01-20 10:45:29 -08:00
|
|
|
Some(matches.free[0].clone())
|
2014-05-05 22:19:38 +10:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
2014-04-16 13:56:39 +09:00
|
|
|
Config {
|
2014-06-25 07:35:54 +02:00
|
|
|
compile_lib_path: matches.opt_str("compile-lib-path").unwrap(),
|
|
|
|
run_lib_path: matches.opt_str("run-lib-path").unwrap(),
|
2013-05-23 09:39:48 -07:00
|
|
|
rustc_path: opt_path(matches, "rustc-path"),
|
2015-04-06 13:48:17 -07:00
|
|
|
rustdoc_path: opt_path(matches, "rustdoc-path"),
|
|
|
|
python: matches.opt_str("python").unwrap(),
|
2014-10-07 20:00:26 +13:00
|
|
|
valgrind_path: matches.opt_str("valgrind-path"),
|
2014-10-09 12:11:37 +13:00
|
|
|
force_valgrind: matches.opt_present("force-valgrind"),
|
2015-03-18 09:14:54 -07:00
|
|
|
llvm_bin_path: matches.opt_str("llvm-bin-path").map(|s| PathBuf::from(&s)),
|
2013-08-30 16:17:32 -04:00
|
|
|
src_base: opt_path(matches, "src-base"),
|
2013-05-23 09:39:48 -07:00
|
|
|
build_base: opt_path(matches, "build-base"),
|
|
|
|
aux_base: opt_path(matches, "aux-base"),
|
2014-06-25 07:35:54 +02:00
|
|
|
stage_id: matches.opt_str("stage-id").unwrap(),
|
2015-01-27 22:52:32 -08:00
|
|
|
mode: matches.opt_str("mode").unwrap().parse().ok().expect("invalid mode"),
|
2013-09-18 03:42:23 +02:00
|
|
|
run_ignored: matches.opt_present("ignored"),
|
2014-05-05 22:19:38 +10:00
|
|
|
filter: filter,
|
2015-03-18 09:14:54 -07:00
|
|
|
logfile: matches.opt_str("logfile").map(|s| PathBuf::from(&s)),
|
2014-06-25 07:35:54 +02:00
|
|
|
runtool: matches.opt_str("runtool"),
|
|
|
|
host_rustcflags: matches.opt_str("host-rustcflags"),
|
|
|
|
target_rustcflags: matches.opt_str("target-rustcflags"),
|
|
|
|
target: opt_str2(matches.opt_str("target")),
|
|
|
|
host: opt_str2(matches.opt_str("host")),
|
2014-08-20 12:53:50 +02:00
|
|
|
gdb_version: extract_gdb_version(matches.opt_str("gdb-version")),
|
2014-10-02 11:35:24 +02:00
|
|
|
lldb_version: extract_lldb_version(matches.opt_str("lldb-version")),
|
2014-05-13 14:44:30 -04:00
|
|
|
android_cross_path: opt_path(matches, "android-cross-path"),
|
2014-06-25 07:35:54 +02:00
|
|
|
adb_path: opt_str2(matches.opt_str("adb-path")),
|
2015-02-02 17:42:23 +09:00
|
|
|
adb_test_dir: format!("{}/{}",
|
|
|
|
opt_str2(matches.opt_str("adb-test-dir")),
|
|
|
|
opt_str2(matches.opt_str("target"))),
|
2013-05-04 10:35:07 +09:00
|
|
|
adb_device_status:
|
2015-01-22 21:39:06 +09:00
|
|
|
opt_str2(matches.opt_str("target")).contains("android") &&
|
|
|
|
"(none)" != opt_str2(matches.opt_str("adb-test-dir")) &&
|
2014-06-25 07:35:54 +02:00
|
|
|
!opt_str2(matches.opt_str("adb-test-dir")).is_empty(),
|
|
|
|
lldb_python_dir: matches.opt_str("lldb-python-dir"),
|
2014-10-09 12:11:37 +13:00
|
|
|
verbose: matches.opt_present("verbose"),
|
2013-02-21 15:19:40 -08:00
|
|
|
}
|
2012-11-18 17:56:50 -08:00
|
|
|
}
|
|
|
|
|
2014-04-16 13:56:39 +09:00
|
|
|
pub fn log_config(config: &Config) {
|
2012-11-18 17:56:50 -08:00
|
|
|
let c = config;
|
2014-05-27 20:44:58 -07:00
|
|
|
logv(c, format!("configuration:"));
|
2014-12-20 00:09:35 -08:00
|
|
|
logv(c, format!("compile_lib_path: {:?}", config.compile_lib_path));
|
|
|
|
logv(c, format!("run_lib_path: {:?}", config.run_lib_path));
|
|
|
|
logv(c, format!("rustc_path: {:?}", config.rustc_path.display()));
|
2015-04-06 13:48:17 -07:00
|
|
|
logv(c, format!("rustdoc_path: {:?}", config.rustdoc_path.display()));
|
2014-12-20 00:09:35 -08:00
|
|
|
logv(c, format!("src_base: {:?}", config.src_base.display()));
|
|
|
|
logv(c, format!("build_base: {:?}", config.build_base.display()));
|
2014-05-27 20:44:58 -07:00
|
|
|
logv(c, format!("stage_id: {}", config.stage_id));
|
|
|
|
logv(c, format!("mode: {}", config.mode));
|
|
|
|
logv(c, format!("run_ignored: {}", config.run_ignored));
|
|
|
|
logv(c, format!("filter: {}",
|
|
|
|
opt_str(&config.filter
|
|
|
|
.as_ref()
|
2015-09-01 14:43:42 +02:00
|
|
|
.map(|re| re.to_owned()))));
|
2014-05-27 20:44:58 -07:00
|
|
|
logv(c, format!("runtool: {}", opt_str(&config.runtool)));
|
|
|
|
logv(c, format!("host-rustcflags: {}",
|
|
|
|
opt_str(&config.host_rustcflags)));
|
|
|
|
logv(c, format!("target-rustcflags: {}",
|
|
|
|
opt_str(&config.target_rustcflags)));
|
|
|
|
logv(c, format!("target: {}", config.target));
|
|
|
|
logv(c, format!("host: {}", config.host));
|
2014-12-20 00:09:35 -08:00
|
|
|
logv(c, format!("android-cross-path: {:?}",
|
2014-05-27 20:44:58 -07:00
|
|
|
config.android_cross_path.display()));
|
2014-12-20 00:09:35 -08:00
|
|
|
logv(c, format!("adb_path: {:?}", config.adb_path));
|
|
|
|
logv(c, format!("adb_test_dir: {:?}", config.adb_test_dir));
|
2014-05-27 20:44:58 -07:00
|
|
|
logv(c, format!("adb_device_status: {}",
|
|
|
|
config.adb_device_status));
|
|
|
|
logv(c, format!("verbose: {}", config.verbose));
|
|
|
|
logv(c, format!("\n"));
|
2012-11-18 17:56:50 -08:00
|
|
|
}
|
|
|
|
|
2014-05-22 16:57:53 -07:00
|
|
|
pub fn opt_str<'a>(maybestr: &'a Option<String>) -> &'a str {
|
2013-05-11 22:45:28 -04:00
|
|
|
match *maybestr {
|
2013-06-30 19:36:55 -07:00
|
|
|
None => "(none)",
|
2015-02-01 21:53:25 -05:00
|
|
|
Some(ref s) => s,
|
2013-05-11 22:45:28 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-22 16:57:53 -07:00
|
|
|
pub fn opt_str2(maybestr: Option<String>) -> String {
|
2014-05-14 20:47:24 -07:00
|
|
|
match maybestr {
|
2015-09-01 14:43:42 +02:00
|
|
|
None => "(none)".to_owned(),
|
2014-05-14 20:47:24 -07:00
|
|
|
Some(s) => s,
|
|
|
|
}
|
2012-11-18 17:56:50 -08:00
|
|
|
}
|
|
|
|
|
2014-04-16 13:56:39 +09:00
|
|
|
pub fn run_tests(config: &Config) {
|
2015-01-22 21:39:06 +09:00
|
|
|
if config.target.contains("android") {
|
2015-09-01 14:43:42 +02:00
|
|
|
if let DebugInfoGdb = config.mode {
|
|
|
|
println!("{} debug-info test uses tcp 5039 port.\
|
|
|
|
please reserve it", config.target);
|
2013-11-04 15:53:01 +09:00
|
|
|
}
|
2014-02-13 21:17:02 -08:00
|
|
|
|
2015-01-22 21:39:06 +09:00
|
|
|
// android debug-info test uses remote debugger
|
2015-05-09 00:12:29 +09:00
|
|
|
// so, we test 1 thread at once.
|
2014-02-13 21:17:02 -08:00
|
|
|
// also trying to isolate problems with adb_run_wrapper.sh ilooping
|
2015-03-19 15:42:53 -04:00
|
|
|
env::set_var("RUST_TEST_THREADS","1");
|
2013-11-04 15:53:01 +09:00
|
|
|
}
|
|
|
|
|
2014-10-26 10:57:29 +01:00
|
|
|
match config.mode {
|
|
|
|
DebugInfoLldb => {
|
|
|
|
// Some older versions of LLDB seem to have problems with multiple
|
2015-05-09 00:12:29 +09:00
|
|
|
// instances running in parallel, so only run one test thread at a
|
2014-10-26 10:57:29 +01:00
|
|
|
// time.
|
2015-03-19 15:42:53 -04:00
|
|
|
env::set_var("RUST_TEST_THREADS", "1");
|
2014-10-26 10:57:29 +01:00
|
|
|
}
|
|
|
|
_ => { /* proceed */ }
|
|
|
|
}
|
|
|
|
|
2012-11-18 17:56:50 -08:00
|
|
|
let opts = test_opts(config);
|
|
|
|
let tests = make_tests(config);
|
2013-09-02 21:50:50 -07:00
|
|
|
// sadly osx needs some file descriptor limits raised for running tests in
|
|
|
|
// parallel (especially when we have lots and lots of child processes).
|
|
|
|
// For context, see #8904
|
2015-04-10 13:51:53 -07:00
|
|
|
unsafe { raise_fd_limit::raise_fd_limit(); }
|
2015-01-22 03:41:32 +00:00
|
|
|
// Prevent issue #21352 UAC blocking .exe containing 'patch' etc. on Windows
|
|
|
|
// If #11207 is resolved (adding manifest to .exe) this becomes unnecessary
|
2015-01-27 12:20:58 -08:00
|
|
|
env::set_var("__COMPAT_LAYER", "RunAsInvoker");
|
2014-09-14 20:27:36 -07:00
|
|
|
let res = test::run_tests_console(&opts, tests.into_iter().collect());
|
2014-01-30 14:37:10 -08:00
|
|
|
match res {
|
|
|
|
Ok(true) => {}
|
2014-10-09 15:17:22 -04:00
|
|
|
Ok(false) => panic!("Some tests failed"),
|
2014-01-30 14:37:10 -08:00
|
|
|
Err(e) => {
|
2014-12-20 00:09:35 -08:00
|
|
|
println!("I/O failure during tests: {:?}", e);
|
2014-01-30 14:37:10 -08:00
|
|
|
}
|
|
|
|
}
|
2012-11-18 17:56:50 -08:00
|
|
|
}
|
|
|
|
|
2014-04-16 13:56:39 +09:00
|
|
|
pub fn test_opts(config: &Config) -> test::TestOpts {
|
2013-01-22 08:44:24 -08:00
|
|
|
test::TestOpts {
|
2014-05-13 16:44:05 -07:00
|
|
|
filter: match config.filter {
|
|
|
|
None => None,
|
2014-05-05 22:19:38 +10:00
|
|
|
Some(ref filter) => Some(filter.clone()),
|
2014-05-13 16:44:05 -07:00
|
|
|
},
|
2013-01-22 08:44:24 -08:00
|
|
|
run_ignored: config.run_ignored,
|
2013-07-02 12:47:32 -07:00
|
|
|
logfile: config.logfile.clone(),
|
2013-02-13 11:46:14 -08:00
|
|
|
run_tests: true,
|
2015-05-02 13:38:51 +10:00
|
|
|
bench_benchmarks: true,
|
2015-02-15 15:30:09 +01:00
|
|
|
nocapture: env::var("RUST_TEST_NOCAPTURE").is_ok(),
|
2014-06-08 17:10:27 -07:00
|
|
|
color: test::AutoColor,
|
2012-11-18 17:56:50 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-16 13:56:39 +09:00
|
|
|
pub fn make_tests(config: &Config) -> Vec<test::TestDescAndFn> {
|
2014-12-20 00:09:35 -08:00
|
|
|
debug!("making tests from {:?}",
|
2013-09-26 17:21:59 -07:00
|
|
|
config.src_base.display());
|
2014-03-05 15:28:08 -08:00
|
|
|
let mut tests = Vec::new();
|
2015-02-26 21:00:43 -08:00
|
|
|
let dirs = fs::read_dir(&config.src_base).unwrap();
|
|
|
|
for file in dirs {
|
|
|
|
let file = file.unwrap().path();
|
2014-12-20 00:09:35 -08:00
|
|
|
debug!("inspecting file {:?}", file.display());
|
2013-07-21 18:33:29 +01:00
|
|
|
if is_test(config, &file) {
|
2015-05-24 18:07:52 +02:00
|
|
|
tests.push(make_test(config, &file))
|
2012-11-18 17:56:50 -08:00
|
|
|
}
|
|
|
|
}
|
2013-02-15 01:11:38 -08:00
|
|
|
tests
|
2012-11-18 17:56:50 -08:00
|
|
|
}
|
|
|
|
|
2014-04-16 13:56:39 +09:00
|
|
|
pub fn is_test(config: &Config, testfile: &Path) -> bool {
|
2012-11-18 17:56:50 -08:00
|
|
|
// Pretty-printer does not work with .rc files yet
|
|
|
|
let valid_extensions =
|
|
|
|
match config.mode {
|
2015-09-01 14:43:42 +02:00
|
|
|
Pretty => vec!(".rs".to_owned()),
|
|
|
|
_ => vec!(".rc".to_owned(), ".rs".to_owned())
|
2012-11-18 17:56:50 -08:00
|
|
|
};
|
2015-09-01 14:43:42 +02:00
|
|
|
let invalid_prefixes = vec!(".".to_owned(), "#".to_owned(), "~".to_owned());
|
2015-02-26 21:00:43 -08:00
|
|
|
let name = testfile.file_name().unwrap().to_str().unwrap();
|
2012-11-18 17:56:50 -08:00
|
|
|
|
|
|
|
let mut valid = false;
|
|
|
|
|
2015-01-31 12:20:46 -05:00
|
|
|
for ext in &valid_extensions {
|
2015-02-01 21:53:25 -05:00
|
|
|
if name.ends_with(ext) {
|
2014-05-19 23:19:56 -07:00
|
|
|
valid = true;
|
|
|
|
}
|
2012-11-18 17:56:50 -08:00
|
|
|
}
|
|
|
|
|
2015-01-31 12:20:46 -05:00
|
|
|
for pre in &invalid_prefixes {
|
2015-02-01 21:53:25 -05:00
|
|
|
if name.starts_with(pre) {
|
2014-05-19 23:19:56 -07:00
|
|
|
valid = false;
|
|
|
|
}
|
2012-11-18 17:56:50 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return valid;
|
|
|
|
}
|
|
|
|
|
2015-05-24 18:07:52 +02:00
|
|
|
pub fn make_test(config: &Config, testfile: &Path) -> test::TestDescAndFn
|
2015-01-04 22:05:29 -05:00
|
|
|
{
|
2013-01-31 17:12:29 -08:00
|
|
|
test::TestDescAndFn {
|
|
|
|
desc: test::TestDesc {
|
|
|
|
name: make_test_name(config, testfile),
|
|
|
|
ignore: header::is_test_ignored(config, testfile),
|
2015-01-31 15:08:25 -08:00
|
|
|
should_panic: test::ShouldPanic::No,
|
2013-01-31 17:12:29 -08:00
|
|
|
},
|
2015-05-24 18:07:52 +02:00
|
|
|
testfn: make_test_closure(config, &testfile),
|
2012-11-18 17:56:50 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-16 13:56:39 +09:00
|
|
|
pub fn make_test_name(config: &Config, testfile: &Path) -> test::TestName {
|
2013-06-23 01:27:34 -07:00
|
|
|
|
|
|
|
// Try to elide redundant long paths
|
2014-05-22 16:57:53 -07:00
|
|
|
fn shorten(path: &Path) -> String {
|
2015-02-26 21:00:43 -08:00
|
|
|
let filename = path.file_name().unwrap().to_str();
|
|
|
|
let p = path.parent().unwrap();
|
|
|
|
let dir = p.file_name().unwrap().to_str();
|
2014-05-27 20:44:58 -07:00
|
|
|
format!("{}/{}", dir.unwrap_or(""), filename.unwrap_or(""))
|
2013-06-23 01:27:34 -07:00
|
|
|
}
|
2013-06-26 15:34:12 -07:00
|
|
|
|
2014-05-27 20:44:58 -07:00
|
|
|
test::DynTestName(format!("[{}] {}", config.mode, shorten(testfile)))
|
2012-11-18 17:56:50 -08:00
|
|
|
}
|
|
|
|
|
2014-04-16 13:56:39 +09:00
|
|
|
pub fn make_test_closure(config: &Config, testfile: &Path) -> test::TestFn {
|
2013-12-04 16:29:01 -08:00
|
|
|
let config = (*config).clone();
|
2015-02-26 21:00:43 -08:00
|
|
|
let testfile = testfile.to_path_buf();
|
2015-04-01 11:12:30 -04:00
|
|
|
test::DynTestFn(Box::new(move || {
|
2015-02-26 21:00:43 -08:00
|
|
|
runtest::run(config, &testfile)
|
2014-11-26 08:12:18 -05:00
|
|
|
}))
|
2012-11-18 17:56:50 -08:00
|
|
|
}
|
2013-07-15 18:51:20 -07:00
|
|
|
|
2014-08-20 12:53:50 +02:00
|
|
|
fn extract_gdb_version(full_version_line: Option<String>) -> Option<String> {
|
|
|
|
match full_version_line {
|
2014-08-27 15:18:16 +02:00
|
|
|
Some(ref full_version_line)
|
2015-03-24 16:54:09 -07:00
|
|
|
if !full_version_line.trim().is_empty() => {
|
2015-01-26 21:21:15 -05:00
|
|
|
let full_version_line = full_version_line.trim();
|
2014-08-27 15:18:16 +02:00
|
|
|
|
2015-09-24 00:34:20 -04:00
|
|
|
// used to be a regex "(^|[^0-9])([0-9]\.[0-9]+)"
|
2015-01-20 10:45:29 -08:00
|
|
|
for (pos, c) in full_version_line.char_indices() {
|
|
|
|
if !c.is_digit(10) { continue }
|
|
|
|
if pos + 2 >= full_version_line.len() { continue }
|
|
|
|
if full_version_line.char_at(pos + 1) != '.' { continue }
|
|
|
|
if !full_version_line.char_at(pos + 2).is_digit(10) { continue }
|
|
|
|
if pos > 0 && full_version_line.char_at_reverse(pos).is_digit(10) {
|
|
|
|
continue
|
2014-08-27 15:18:16 +02:00
|
|
|
}
|
2015-09-24 00:34:20 -04:00
|
|
|
let mut end = pos + 3;
|
|
|
|
while end < full_version_line.len() &&
|
|
|
|
full_version_line.char_at(end).is_digit(10) {
|
|
|
|
end += 1;
|
2014-08-20 12:53:50 +02:00
|
|
|
}
|
2015-09-24 00:34:20 -04:00
|
|
|
return Some(full_version_line[pos..end].to_owned());
|
2014-08-20 12:53:50 +02:00
|
|
|
}
|
2015-01-20 10:45:29 -08:00
|
|
|
println!("Could not extract GDB version from line '{}'",
|
|
|
|
full_version_line);
|
|
|
|
None
|
2014-08-20 12:53:50 +02:00
|
|
|
},
|
2014-08-27 15:18:16 +02:00
|
|
|
_ => None
|
2014-08-20 12:53:50 +02:00
|
|
|
}
|
2014-09-14 20:27:36 -07:00
|
|
|
}
|
2014-10-02 11:35:24 +02:00
|
|
|
|
|
|
|
fn extract_lldb_version(full_version_line: Option<String>) -> Option<String> {
|
|
|
|
// Extract the major LLDB version from the given version string.
|
|
|
|
// LLDB version strings are different for Apple and non-Apple platforms.
|
|
|
|
// At the moment, this function only supports the Apple variant, which looks
|
|
|
|
// like this:
|
|
|
|
//
|
|
|
|
// LLDB-179.5 (older versions)
|
|
|
|
// lldb-300.2.51 (new versions)
|
|
|
|
//
|
|
|
|
// We are only interested in the major version number, so this function
|
|
|
|
// will return `Some("179")` and `Some("300")` respectively.
|
|
|
|
|
2015-09-01 14:43:42 +02:00
|
|
|
if let Some(ref full_version_line) = full_version_line {
|
|
|
|
if !full_version_line.trim().is_empty() {
|
2015-01-26 21:21:15 -05:00
|
|
|
let full_version_line = full_version_line.trim();
|
2014-10-02 11:35:24 +02:00
|
|
|
|
2015-01-20 10:45:29 -08:00
|
|
|
for (pos, l) in full_version_line.char_indices() {
|
|
|
|
if l != 'l' && l != 'L' { continue }
|
|
|
|
if pos + 5 >= full_version_line.len() { continue }
|
|
|
|
let l = full_version_line.char_at(pos + 1);
|
|
|
|
if l != 'l' && l != 'L' { continue }
|
|
|
|
let d = full_version_line.char_at(pos + 2);
|
|
|
|
if d != 'd' && d != 'D' { continue }
|
|
|
|
let b = full_version_line.char_at(pos + 3);
|
|
|
|
if b != 'b' && b != 'B' { continue }
|
|
|
|
let dash = full_version_line.char_at(pos + 4);
|
|
|
|
if dash != '-' { continue }
|
|
|
|
|
|
|
|
let vers = full_version_line[pos + 5..].chars().take_while(|c| {
|
|
|
|
c.is_digit(10)
|
|
|
|
}).collect::<String>();
|
2015-03-24 16:54:09 -07:00
|
|
|
if !vers.is_empty() { return Some(vers) }
|
2014-10-02 11:35:24 +02:00
|
|
|
}
|
2015-01-20 10:45:29 -08:00
|
|
|
println!("Could not extract LLDB version from line '{}'",
|
|
|
|
full_version_line);
|
2015-09-01 14:43:42 +02:00
|
|
|
}
|
2014-10-02 11:35:24 +02:00
|
|
|
}
|
2015-09-01 14:43:42 +02:00
|
|
|
None
|
2014-10-02 11:35:24 +02:00
|
|
|
}
|