Auto merge of #31749 - nikomatsakis:compiletest-subdir, r=alexcrichton
You can now group tests into directories like `run-pass/borrowck` or `compile-fail/borrowck`. By default, all `.rs` files within any directory are considered tests: to ignore some directory, create a placeholder file called `compiletest-ignore-dir` (I had to do this for several existing directories). r? @alexcrichton cc @brson
This commit is contained in:
commit
15e9a95a4b
31
mk/tests.mk
31
mk/tests.mk
@ -458,21 +458,22 @@ $(foreach host,$(CFG_HOST), \
|
||||
# Rules for the compiletest tests (rpass, rfail, etc.)
|
||||
######################################################################
|
||||
|
||||
RPASS_RS := $(wildcard $(S)src/test/run-pass/*.rs)
|
||||
RPASS_VALGRIND_RS := $(wildcard $(S)src/test/run-pass-valgrind/*.rs)
|
||||
RPASS_FULL_RS := $(wildcard $(S)src/test/run-pass-fulldeps/*.rs)
|
||||
RFAIL_FULL_RS := $(wildcard $(S)src/test/run-fail-fulldeps/*.rs)
|
||||
CFAIL_FULL_RS := $(wildcard $(S)src/test/compile-fail-fulldeps/*.rs)
|
||||
RFAIL_RS := $(wildcard $(S)src/test/run-fail/*.rs)
|
||||
CFAIL_RS := $(wildcard $(S)src/test/compile-fail/*.rs)
|
||||
PFAIL_RS := $(wildcard $(S)src/test/parse-fail/*.rs)
|
||||
PRETTY_RS := $(wildcard $(S)src/test/pretty/*.rs)
|
||||
DEBUGINFO_GDB_RS := $(wildcard $(S)src/test/debuginfo/*.rs)
|
||||
DEBUGINFO_LLDB_RS := $(wildcard $(S)src/test/debuginfo/*.rs)
|
||||
CODEGEN_RS := $(wildcard $(S)src/test/codegen/*.rs)
|
||||
CODEGEN_CC := $(wildcard $(S)src/test/codegen/*.cc)
|
||||
CODEGEN_UNITS_RS := $(wildcard $(S)src/test/codegen-units/*.rs)
|
||||
RUSTDOCCK_RS := $(wildcard $(S)src/test/rustdoc/*.rs)
|
||||
RPASS_RS := $(call rwildcard,$(S)src/test/run-pass/,*.rs)
|
||||
RPASS_VALGRIND_RS := $(call rwildcard,$(S)src/test/run-pass-valgrind/,*.rs)
|
||||
RPASS_FULL_RS := $(call rwildcard,$(S)src/test/run-pass-fulldeps/,*.rs)
|
||||
RFAIL_FULL_RS := $(call rwildcard,$(S)src/test/run-fail-fulldeps/,*.rs)
|
||||
CFAIL_FULL_RS := $(call rwildcard,$(S)src/test/compile-fail-fulldeps/,*.rs)
|
||||
RFAIL_RS := $(call rwildcard,$(S)src/test/run-fail/,*.rs)
|
||||
RFAIL_RS := $(call rwildcard,$(S)src/test/run-fail/,*.rs)
|
||||
CFAIL_RS := $(call rwildcard,$(S)src/test/compile-fail/,*.rs)
|
||||
PFAIL_RS := $(call rwildcard,$(S)src/test/parse-fail/,*.rs)
|
||||
PRETTY_RS := $(call rwildcard,$(S)src/test/pretty/,*.rs)
|
||||
DEBUGINFO_GDB_RS := $(call rwildcard,$(S)src/test/debuginfo/,*.rs)
|
||||
DEBUGINFO_LLDB_RS := $(call rwildcard,$(S)src/test/debuginfo/,*.rs)
|
||||
CODEGEN_RS := $(call rwildcard,$(S)src/test/codegen/,*.rs)
|
||||
CODEGEN_CC := $(call rwildcard,$(S)src/test/codegen/,*.cc)
|
||||
CODEGEN_UNITS_RS := $(call rwildcard,$(S)src/test/codegen-units/,*.rs)
|
||||
RUSTDOCCK_RS := $(call rwildcard,$(S)src/test/rustdoc/,*.rs)
|
||||
|
||||
RPASS_TESTS := $(RPASS_RS)
|
||||
RPASS_VALGRIND_TESTS := $(RPASS_VALGRIND_RS)
|
||||
|
@ -28,10 +28,12 @@ extern crate log;
|
||||
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use getopts::{optopt, optflag, reqopt};
|
||||
use common::Config;
|
||||
use common::{Pretty, DebugInfoGdb, DebugInfoLldb};
|
||||
use test::TestPaths;
|
||||
use util::logv;
|
||||
|
||||
pub mod procsrv;
|
||||
@ -267,15 +269,61 @@ pub fn make_tests(config: &Config) -> Vec<test::TestDescAndFn> {
|
||||
debug!("making tests from {:?}",
|
||||
config.src_base.display());
|
||||
let mut tests = Vec::new();
|
||||
let dirs = fs::read_dir(&config.src_base).unwrap();
|
||||
for file in dirs {
|
||||
let file = file.unwrap().path();
|
||||
debug!("inspecting file {:?}", file.display());
|
||||
if is_test(config, &file) {
|
||||
tests.push(make_test(config, &file))
|
||||
collect_tests_from_dir(config,
|
||||
&config.src_base,
|
||||
&config.src_base,
|
||||
&PathBuf::new(),
|
||||
&mut tests)
|
||||
.unwrap();
|
||||
tests
|
||||
}
|
||||
|
||||
fn collect_tests_from_dir(config: &Config,
|
||||
base: &Path,
|
||||
dir: &Path,
|
||||
relative_dir_path: &Path,
|
||||
tests: &mut Vec<test::TestDescAndFn>)
|
||||
-> io::Result<()> {
|
||||
// Ignore directories that contain a file
|
||||
// `compiletest-ignore-dir`.
|
||||
for file in try!(fs::read_dir(dir)) {
|
||||
let file = try!(file);
|
||||
if file.file_name() == *"compiletest-ignore-dir" {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
tests
|
||||
|
||||
let dirs = try!(fs::read_dir(dir));
|
||||
for file in dirs {
|
||||
let file = try!(file);
|
||||
let file_path = file.path();
|
||||
debug!("inspecting file {:?}", file_path.display());
|
||||
if is_test(config, &file_path) {
|
||||
// If we find a test foo/bar.rs, we have to build the
|
||||
// output directory `$build/foo` so we can write
|
||||
// `$build/foo/bar` into it. We do this *now* in this
|
||||
// sequential loop because otherwise, if we do it in the
|
||||
// tests themselves, they race for the privilege of
|
||||
// creating the directories and sometimes fail randomly.
|
||||
let build_dir = config.build_base.join(&relative_dir_path);
|
||||
fs::create_dir_all(&build_dir).unwrap();
|
||||
|
||||
let paths = TestPaths {
|
||||
file: file_path,
|
||||
base: base.to_path_buf(),
|
||||
relative_dir: relative_dir_path.to_path_buf(),
|
||||
};
|
||||
tests.push(make_test(config, &paths))
|
||||
} else if file_path.is_dir() {
|
||||
let relative_file_path = relative_dir_path.join(file.file_name());
|
||||
try!(collect_tests_from_dir(config,
|
||||
base,
|
||||
&file_path,
|
||||
&relative_file_path,
|
||||
tests));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn is_test(config: &Config, testfile: &Path) -> bool {
|
||||
@ -305,36 +353,33 @@ pub fn is_test(config: &Config, testfile: &Path) -> bool {
|
||||
return valid;
|
||||
}
|
||||
|
||||
pub fn make_test(config: &Config, testfile: &Path) -> test::TestDescAndFn
|
||||
{
|
||||
pub fn make_test(config: &Config, testpaths: &TestPaths) -> test::TestDescAndFn {
|
||||
test::TestDescAndFn {
|
||||
desc: test::TestDesc {
|
||||
name: make_test_name(config, testfile),
|
||||
ignore: header::is_test_ignored(config, testfile),
|
||||
name: make_test_name(config, testpaths),
|
||||
ignore: header::is_test_ignored(config, &testpaths.file),
|
||||
should_panic: test::ShouldPanic::No,
|
||||
},
|
||||
testfn: make_test_closure(config, &testfile),
|
||||
testfn: make_test_closure(config, testpaths),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_test_name(config: &Config, testfile: &Path) -> test::TestName {
|
||||
|
||||
// Try to elide redundant long paths
|
||||
fn shorten(path: &Path) -> String {
|
||||
let filename = path.file_name().unwrap().to_str();
|
||||
let p = path.parent().unwrap();
|
||||
let dir = p.file_name().unwrap().to_str();
|
||||
format!("{}/{}", dir.unwrap_or(""), filename.unwrap_or(""))
|
||||
}
|
||||
|
||||
test::DynTestName(format!("[{}] {}", config.mode, shorten(testfile)))
|
||||
pub fn make_test_name(config: &Config, testpaths: &TestPaths) -> test::TestName {
|
||||
// Convert a complete path to something like
|
||||
//
|
||||
// run-pass/foo/bar/baz.rs
|
||||
let path =
|
||||
PathBuf::from(config.mode.to_string())
|
||||
.join(&testpaths.relative_dir)
|
||||
.join(&testpaths.file.file_name().unwrap());
|
||||
test::DynTestName(format!("[{}] {}", config.mode, path.display()))
|
||||
}
|
||||
|
||||
pub fn make_test_closure(config: &Config, testfile: &Path) -> test::TestFn {
|
||||
let config = (*config).clone();
|
||||
let testfile = testfile.to_path_buf();
|
||||
pub fn make_test_closure(config: &Config, testpaths: &TestPaths) -> test::TestFn {
|
||||
let config = config.clone();
|
||||
let testpaths = testpaths.clone();
|
||||
test::DynTestFn(Box::new(move || {
|
||||
runtest::run(config, &testfile)
|
||||
runtest::run(config, &testpaths)
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ use errors;
|
||||
use header::TestProps;
|
||||
use header;
|
||||
use procsrv;
|
||||
use test::TestPaths;
|
||||
use util::logv;
|
||||
|
||||
use std::env;
|
||||
@ -27,7 +28,7 @@ use std::net::TcpStream;
|
||||
use std::path::{Path, PathBuf, Component};
|
||||
use std::process::{Command, Output, ExitStatus};
|
||||
|
||||
pub fn run(config: Config, testfile: &Path) {
|
||||
pub fn run(config: Config, testpaths: &TestPaths) {
|
||||
match &*config.target {
|
||||
|
||||
"arm-linux-androideabi" | "aarch64-linux-android" => {
|
||||
@ -43,21 +44,21 @@ pub fn run(config: Config, testfile: &Path) {
|
||||
// We're going to be dumping a lot of info. Start on a new line.
|
||||
print!("\n\n");
|
||||
}
|
||||
debug!("running {:?}", testfile.display());
|
||||
let props = header::load_props(&testfile);
|
||||
debug!("running {:?}", testpaths.file.display());
|
||||
let props = header::load_props(&testpaths.file);
|
||||
debug!("loaded props");
|
||||
match config.mode {
|
||||
CompileFail => run_cfail_test(&config, &props, &testfile),
|
||||
ParseFail => run_cfail_test(&config, &props, &testfile),
|
||||
RunFail => run_rfail_test(&config, &props, &testfile),
|
||||
RunPass => run_rpass_test(&config, &props, &testfile),
|
||||
RunPassValgrind => run_valgrind_test(&config, &props, &testfile),
|
||||
Pretty => run_pretty_test(&config, &props, &testfile),
|
||||
DebugInfoGdb => run_debuginfo_gdb_test(&config, &props, &testfile),
|
||||
DebugInfoLldb => run_debuginfo_lldb_test(&config, &props, &testfile),
|
||||
Codegen => run_codegen_test(&config, &props, &testfile),
|
||||
Rustdoc => run_rustdoc_test(&config, &props, &testfile),
|
||||
CodegenUnits => run_codegen_units_test(&config, &props, &testfile),
|
||||
CompileFail => run_cfail_test(&config, &props, &testpaths),
|
||||
ParseFail => run_cfail_test(&config, &props, &testpaths),
|
||||
RunFail => run_rfail_test(&config, &props, &testpaths),
|
||||
RunPass => run_rpass_test(&config, &props, &testpaths),
|
||||
RunPassValgrind => run_valgrind_test(&config, &props, &testpaths),
|
||||
Pretty => run_pretty_test(&config, &props, &testpaths),
|
||||
DebugInfoGdb => run_debuginfo_gdb_test(&config, &props, &testpaths),
|
||||
DebugInfoLldb => run_debuginfo_lldb_test(&config, &props, &testpaths),
|
||||
Codegen => run_codegen_test(&config, &props, &testpaths),
|
||||
Rustdoc => run_rustdoc_test(&config, &props, &testpaths),
|
||||
CodegenUnits => run_codegen_units_test(&config, &props, &testpaths),
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,8 +70,8 @@ fn get_output(props: &TestProps, proc_res: &ProcRes) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
fn run_cfail_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
let proc_res = compile_test(config, props, testfile);
|
||||
fn run_cfail_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
|
||||
let proc_res = compile_test(config, props, testpaths);
|
||||
|
||||
if proc_res.status.success() {
|
||||
fatal_proc_rec(&format!("{} test compiled successfully!", config.mode)[..],
|
||||
@ -84,27 +85,27 @@ fn run_cfail_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
}
|
||||
|
||||
let output_to_check = get_output(props, &proc_res);
|
||||
let expected_errors = errors::load_errors(testfile);
|
||||
let expected_errors = errors::load_errors(&testpaths.file);
|
||||
if !expected_errors.is_empty() {
|
||||
if !props.error_patterns.is_empty() {
|
||||
fatal("both error pattern and expected errors specified");
|
||||
}
|
||||
check_expected_errors(expected_errors, testfile, &proc_res);
|
||||
check_expected_errors(expected_errors, testpaths, &proc_res);
|
||||
} else {
|
||||
check_error_patterns(props, testfile, &output_to_check, &proc_res);
|
||||
check_error_patterns(props, testpaths, &output_to_check, &proc_res);
|
||||
}
|
||||
check_no_compiler_crash(&proc_res);
|
||||
check_forbid_output(props, &output_to_check, &proc_res);
|
||||
}
|
||||
|
||||
fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
let proc_res = compile_test(config, props, testfile);
|
||||
fn run_rfail_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
|
||||
let proc_res = compile_test(config, props, testpaths);
|
||||
|
||||
if !proc_res.status.success() {
|
||||
fatal_proc_rec("compilation failed!", &proc_res);
|
||||
}
|
||||
|
||||
let proc_res = exec_compiled_test(config, props, testfile);
|
||||
let proc_res = exec_compiled_test(config, props, testpaths);
|
||||
|
||||
// The value our Makefile configures valgrind to return on failure
|
||||
const VALGRIND_ERR: i32 = 100;
|
||||
@ -114,7 +115,7 @@ fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
|
||||
let output_to_check = get_output(props, &proc_res);
|
||||
check_correct_failure_status(&proc_res);
|
||||
check_error_patterns(props, testfile, &output_to_check, &proc_res);
|
||||
check_error_patterns(props, testpaths, &output_to_check, &proc_res);
|
||||
}
|
||||
|
||||
fn check_correct_failure_status(proc_res: &ProcRes) {
|
||||
@ -128,27 +129,27 @@ fn check_correct_failure_status(proc_res: &ProcRes) {
|
||||
}
|
||||
}
|
||||
|
||||
fn run_rpass_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
let proc_res = compile_test(config, props, testfile);
|
||||
fn run_rpass_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
|
||||
let proc_res = compile_test(config, props, testpaths);
|
||||
|
||||
if !proc_res.status.success() {
|
||||
fatal_proc_rec("compilation failed!", &proc_res);
|
||||
}
|
||||
|
||||
let proc_res = exec_compiled_test(config, props, testfile);
|
||||
let proc_res = exec_compiled_test(config, props, testpaths);
|
||||
|
||||
if !proc_res.status.success() {
|
||||
fatal_proc_rec("test run failed!", &proc_res);
|
||||
}
|
||||
}
|
||||
|
||||
fn run_valgrind_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
fn run_valgrind_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
|
||||
if config.valgrind_path.is_none() {
|
||||
assert!(!config.force_valgrind);
|
||||
return run_rpass_test(config, props, testfile);
|
||||
return run_rpass_test(config, props, testpaths);
|
||||
}
|
||||
|
||||
let mut proc_res = compile_test(config, props, testfile);
|
||||
let mut proc_res = compile_test(config, props, testpaths);
|
||||
|
||||
if !proc_res.status.success() {
|
||||
fatal_proc_rec("compilation failed!", &proc_res);
|
||||
@ -156,14 +157,14 @@ fn run_valgrind_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
|
||||
let mut new_config = config.clone();
|
||||
new_config.runtool = new_config.valgrind_path.clone();
|
||||
proc_res = exec_compiled_test(&new_config, props, testfile);
|
||||
proc_res = exec_compiled_test(&new_config, props, testpaths);
|
||||
|
||||
if !proc_res.status.success() {
|
||||
fatal_proc_rec("test run failed!", &proc_res);
|
||||
}
|
||||
}
|
||||
|
||||
fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
fn run_pretty_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
|
||||
if props.pp_exact.is_some() {
|
||||
logv(config, "testing for exact pretty-printing".to_owned());
|
||||
} else {
|
||||
@ -174,7 +175,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
match props.pp_exact { Some(_) => 1, None => 2 };
|
||||
|
||||
let mut src = String::new();
|
||||
File::open(testfile).unwrap().read_to_string(&mut src).unwrap();
|
||||
File::open(&testpaths.file).unwrap().read_to_string(&mut src).unwrap();
|
||||
let mut srcs = vec!(src);
|
||||
|
||||
let mut round = 0;
|
||||
@ -182,7 +183,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
logv(config, format!("pretty-printing round {}", round));
|
||||
let proc_res = print_source(config,
|
||||
props,
|
||||
testfile,
|
||||
testpaths,
|
||||
srcs[round].to_owned(),
|
||||
&props.pretty_mode);
|
||||
|
||||
@ -198,7 +199,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
|
||||
let mut expected = match props.pp_exact {
|
||||
Some(ref file) => {
|
||||
let filepath = testfile.parent().unwrap().join(file);
|
||||
let filepath = testpaths.file.parent().unwrap().join(file);
|
||||
let mut s = String::new();
|
||||
File::open(&filepath).unwrap().read_to_string(&mut s).unwrap();
|
||||
s
|
||||
@ -220,7 +221,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
if props.pretty_compare_only { return; }
|
||||
|
||||
// Finally, let's make sure it actually appears to remain valid code
|
||||
let proc_res = typecheck_source(config, props, testfile, actual);
|
||||
let proc_res = typecheck_source(config, props, testpaths, actual);
|
||||
|
||||
if !proc_res.status.success() {
|
||||
fatal_proc_rec("pretty-printed source does not typecheck", &proc_res);
|
||||
@ -228,13 +229,13 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
if !props.pretty_expanded { return }
|
||||
|
||||
// additionally, run `--pretty expanded` and try to build it.
|
||||
let proc_res = print_source(config, props, testfile, srcs[round].clone(), "expanded");
|
||||
let proc_res = print_source(config, props, testpaths, srcs[round].clone(), "expanded");
|
||||
if !proc_res.status.success() {
|
||||
fatal_proc_rec("pretty-printing (expanded) failed", &proc_res);
|
||||
}
|
||||
|
||||
let ProcRes{ stdout: expanded_src, .. } = proc_res;
|
||||
let proc_res = typecheck_source(config, props, testfile, expanded_src);
|
||||
let proc_res = typecheck_source(config, props, testpaths, expanded_src);
|
||||
if !proc_res.status.success() {
|
||||
fatal_proc_rec("pretty-printed source (expanded) does not typecheck",
|
||||
&proc_res);
|
||||
@ -244,15 +245,15 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
|
||||
fn print_source(config: &Config,
|
||||
props: &TestProps,
|
||||
testfile: &Path,
|
||||
testpaths: &TestPaths,
|
||||
src: String,
|
||||
pretty_type: &str) -> ProcRes {
|
||||
let aux_dir = aux_output_dir_name(config, testfile);
|
||||
let aux_dir = aux_output_dir_name(config, testpaths);
|
||||
compose_and_run(config,
|
||||
testfile,
|
||||
testpaths,
|
||||
make_pp_args(config,
|
||||
props,
|
||||
testfile,
|
||||
testpaths,
|
||||
pretty_type.to_owned()),
|
||||
props.exec_env.clone(),
|
||||
&config.compile_lib_path,
|
||||
@ -262,9 +263,9 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
|
||||
fn make_pp_args(config: &Config,
|
||||
props: &TestProps,
|
||||
testfile: &Path,
|
||||
testpaths: &TestPaths,
|
||||
pretty_type: String) -> ProcArgs {
|
||||
let aux_dir = aux_output_dir_name(config, testfile);
|
||||
let aux_dir = aux_output_dir_name(config, testpaths);
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
let mut args = vec!("-".to_owned(),
|
||||
"-Zunstable-options".to_owned(),
|
||||
@ -300,13 +301,13 @@ actual:\n\
|
||||
}
|
||||
|
||||
fn typecheck_source(config: &Config, props: &TestProps,
|
||||
testfile: &Path, src: String) -> ProcRes {
|
||||
let args = make_typecheck_args(config, props, testfile);
|
||||
compose_and_run_compiler(config, props, testfile, args, Some(src))
|
||||
testpaths: &TestPaths, src: String) -> ProcRes {
|
||||
let args = make_typecheck_args(config, props, testpaths);
|
||||
compose_and_run_compiler(config, props, testpaths, args, Some(src))
|
||||
}
|
||||
|
||||
fn make_typecheck_args(config: &Config, props: &TestProps, testfile: &Path) -> ProcArgs {
|
||||
let aux_dir = aux_output_dir_name(config, testfile);
|
||||
fn make_typecheck_args(config: &Config, props: &TestProps, testpaths: &TestPaths) -> ProcArgs {
|
||||
let aux_dir = aux_output_dir_name(config, testpaths);
|
||||
let target = if props.force_host {
|
||||
&*config.host
|
||||
} else {
|
||||
@ -330,7 +331,7 @@ actual:\n\
|
||||
}
|
||||
}
|
||||
|
||||
fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
|
||||
let mut config = Config {
|
||||
target_rustcflags: cleanup_debug_info_options(&config.target_rustcflags),
|
||||
host_rustcflags: cleanup_debug_info_options(&config.host_rustcflags),
|
||||
@ -342,16 +343,16 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
commands,
|
||||
check_lines,
|
||||
breakpoint_lines
|
||||
} = parse_debugger_commands(testfile, "gdb");
|
||||
} = parse_debugger_commands(testpaths, "gdb");
|
||||
let mut cmds = commands.join("\n");
|
||||
|
||||
// compile test file (it should have 'compile-flags:-g' in the header)
|
||||
let compiler_run_result = compile_test(config, props, testfile);
|
||||
let compiler_run_result = compile_test(config, props, testpaths);
|
||||
if !compiler_run_result.status.success() {
|
||||
fatal_proc_rec("compilation failed!", &compiler_run_result);
|
||||
}
|
||||
|
||||
let exe_file = make_exe_name(config, testfile);
|
||||
let exe_file = make_exe_name(config, testpaths);
|
||||
|
||||
let debugger_run_result;
|
||||
match &*config.target {
|
||||
@ -369,8 +370,10 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
config.host, config.target));
|
||||
for line in &breakpoint_lines {
|
||||
script_str.push_str(&format!("break {:?}:{}\n",
|
||||
testfile.file_name().unwrap()
|
||||
.to_string_lossy(),
|
||||
testpaths.file
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_string_lossy(),
|
||||
*line)[..]);
|
||||
}
|
||||
script_str.push_str(&cmds);
|
||||
@ -378,7 +381,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
|
||||
debug!("script_str = {}", script_str);
|
||||
dump_output_file(config,
|
||||
testfile,
|
||||
testpaths,
|
||||
&script_str,
|
||||
"debugger.script");
|
||||
|
||||
@ -441,7 +444,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
None => fatal("cannot find android cross path")
|
||||
};
|
||||
|
||||
let debugger_script = make_out_name(config, testfile, "debugger.script");
|
||||
let debugger_script = make_out_name(config, testpaths, "debugger.script");
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
let debugger_opts =
|
||||
vec!("-quiet".to_owned(),
|
||||
@ -531,7 +534,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
// Add line breakpoints
|
||||
for line in &breakpoint_lines {
|
||||
script_str.push_str(&format!("break '{}':{}\n",
|
||||
testfile.file_name().unwrap()
|
||||
testpaths.file.file_name().unwrap()
|
||||
.to_string_lossy(),
|
||||
*line));
|
||||
}
|
||||
@ -541,7 +544,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
|
||||
debug!("script_str = {}", script_str);
|
||||
dump_output_file(config,
|
||||
testfile,
|
||||
testpaths,
|
||||
&script_str,
|
||||
"debugger.script");
|
||||
|
||||
@ -550,7 +553,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
if cfg!(windows) {"gdb.exe"} else {"gdb"}
|
||||
}
|
||||
|
||||
let debugger_script = make_out_name(config, testfile, "debugger.script");
|
||||
let debugger_script = make_out_name(config, testpaths, "debugger.script");
|
||||
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
let debugger_opts =
|
||||
@ -567,7 +570,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
let environment = vec![("PYTHONPATH".to_owned(), rust_pp_module_abs_path)];
|
||||
|
||||
debugger_run_result = compose_and_run(config,
|
||||
testfile,
|
||||
testpaths,
|
||||
proc_args,
|
||||
environment,
|
||||
&config.run_lib_path,
|
||||
@ -596,7 +599,7 @@ fn find_rust_src_root(config: &Config) -> Option<PathBuf> {
|
||||
return None;
|
||||
}
|
||||
|
||||
fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
|
||||
if config.lldb_python_dir.is_none() {
|
||||
fatal("Can't run LLDB test because LLDB's python path is not set.");
|
||||
}
|
||||
@ -610,12 +613,12 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
|
||||
let config = &mut config;
|
||||
|
||||
// compile test file (it should have 'compile-flags:-g' in the header)
|
||||
let compile_result = compile_test(config, props, testfile);
|
||||
let compile_result = compile_test(config, props, testpaths);
|
||||
if !compile_result.status.success() {
|
||||
fatal_proc_rec("compilation failed!", &compile_result);
|
||||
}
|
||||
|
||||
let exe_file = make_exe_name(config, testfile);
|
||||
let exe_file = make_exe_name(config, testpaths);
|
||||
|
||||
match config.lldb_version {
|
||||
Some(ref version) => {
|
||||
@ -634,7 +637,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
|
||||
check_lines,
|
||||
breakpoint_lines,
|
||||
..
|
||||
} = parse_debugger_commands(testfile, "lldb");
|
||||
} = parse_debugger_commands(testpaths, "lldb");
|
||||
|
||||
// Write debugger script:
|
||||
// We don't want to hang when calling `quit` while the process is still running
|
||||
@ -676,13 +679,14 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
|
||||
// Write the script into a file
|
||||
debug!("script_str = {}", script_str);
|
||||
dump_output_file(config,
|
||||
testfile,
|
||||
testpaths,
|
||||
&script_str,
|
||||
"debugger.script");
|
||||
let debugger_script = make_out_name(config, testfile, "debugger.script");
|
||||
let debugger_script = make_out_name(config, testpaths, "debugger.script");
|
||||
|
||||
// Let LLDB execute the script via lldb_batchmode.py
|
||||
let debugger_run_result = run_lldb(config,
|
||||
testpaths,
|
||||
&exe_file,
|
||||
&debugger_script,
|
||||
&rust_src_root);
|
||||
@ -694,6 +698,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
|
||||
check_debugger_output(&debugger_run_result, &check_lines);
|
||||
|
||||
fn run_lldb(config: &Config,
|
||||
testpaths: &TestPaths,
|
||||
test_executable: &Path,
|
||||
debugger_script: &Path,
|
||||
rust_src_root: &Path)
|
||||
@ -701,7 +706,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
|
||||
// Prepare the lldb_batchmode which executes the debugger script
|
||||
let lldb_script_path = rust_src_root.join("src/etc/lldb_batchmode.py");
|
||||
cmd2procres(config,
|
||||
test_executable,
|
||||
testpaths,
|
||||
Command::new(&config.python)
|
||||
.arg(&lldb_script_path)
|
||||
.arg(test_executable)
|
||||
@ -711,7 +716,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd2procres(config: &Config, test_executable: &Path, cmd: &mut Command)
|
||||
fn cmd2procres(config: &Config, testpaths: &TestPaths, cmd: &mut Command)
|
||||
-> ProcRes {
|
||||
let (status, out, err) = match cmd.output() {
|
||||
Ok(Output { status, stdout, stderr }) => {
|
||||
@ -725,7 +730,7 @@ fn cmd2procres(config: &Config, test_executable: &Path, cmd: &mut Command)
|
||||
}
|
||||
};
|
||||
|
||||
dump_output(config, test_executable, &out, &err);
|
||||
dump_output(config, testpaths, &out, &err);
|
||||
ProcRes {
|
||||
status: Status::Normal(status),
|
||||
stdout: out,
|
||||
@ -740,7 +745,7 @@ struct DebuggerCommands {
|
||||
breakpoint_lines: Vec<usize>,
|
||||
}
|
||||
|
||||
fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
|
||||
fn parse_debugger_commands(testpaths: &TestPaths, debugger_prefix: &str)
|
||||
-> DebuggerCommands {
|
||||
let command_directive = format!("{}-command", debugger_prefix);
|
||||
let check_directive = format!("{}-check", debugger_prefix);
|
||||
@ -749,7 +754,7 @@ fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
|
||||
let mut commands = vec!();
|
||||
let mut check_lines = vec!();
|
||||
let mut counter = 1;
|
||||
let reader = BufReader::new(File::open(file_path).unwrap());
|
||||
let reader = BufReader::new(File::open(&testpaths.file).unwrap());
|
||||
for line in reader.lines() {
|
||||
match line {
|
||||
Ok(line) => {
|
||||
@ -860,11 +865,12 @@ fn check_debugger_output(debugger_run_result: &ProcRes, check_lines: &[String])
|
||||
}
|
||||
|
||||
fn check_error_patterns(props: &TestProps,
|
||||
testfile: &Path,
|
||||
testpaths: &TestPaths,
|
||||
output_to_check: &str,
|
||||
proc_res: &ProcRes) {
|
||||
if props.error_patterns.is_empty() {
|
||||
fatal(&format!("no error pattern specified in {:?}", testfile.display()));
|
||||
fatal(&format!("no error pattern specified in {:?}",
|
||||
testpaths.file.display()));
|
||||
}
|
||||
let mut next_err_idx = 0;
|
||||
let mut next_err_pat = &props.error_patterns[next_err_idx];
|
||||
@ -915,7 +921,7 @@ fn check_forbid_output(props: &TestProps,
|
||||
}
|
||||
|
||||
fn check_expected_errors(expected_errors: Vec<errors::ExpectedError>,
|
||||
testfile: &Path,
|
||||
testpaths: &TestPaths,
|
||||
proc_res: &ProcRes) {
|
||||
|
||||
// true if we found the error in question
|
||||
@ -926,7 +932,9 @@ fn check_expected_errors(expected_errors: Vec<errors::ExpectedError>,
|
||||
}
|
||||
|
||||
let prefixes = expected_errors.iter().map(|ee| {
|
||||
format!("{}:{}:", testfile.display(), ee.line)
|
||||
let expected = format!("{}:{}:", testpaths.file.display(), ee.line);
|
||||
// On windows just translate all '\' path separators to '/'
|
||||
expected.replace(r"\", "/")
|
||||
}).collect::<Vec<String>>();
|
||||
|
||||
let (expect_help, expect_note) =
|
||||
@ -1142,62 +1150,64 @@ impl fmt::Display for Status {
|
||||
}
|
||||
|
||||
fn compile_test(config: &Config, props: &TestProps,
|
||||
testfile: &Path) -> ProcRes {
|
||||
let aux_dir = aux_output_dir_name(config, testfile);
|
||||
testpaths: &TestPaths) -> ProcRes {
|
||||
let aux_dir = aux_output_dir_name(config, testpaths);
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
let link_args = vec!("-L".to_owned(),
|
||||
aux_dir.to_str().unwrap().to_owned());
|
||||
let args = make_compile_args(config,
|
||||
props,
|
||||
link_args,
|
||||
|a, b| TargetLocation::ThisFile(make_exe_name(a, b)), testfile);
|
||||
compose_and_run_compiler(config, props, testfile, args, None)
|
||||
|a, b| TargetLocation::ThisFile(make_exe_name(a, b)), testpaths);
|
||||
compose_and_run_compiler(config, props, testpaths, args, None)
|
||||
}
|
||||
|
||||
fn document(config: &Config, props: &TestProps,
|
||||
testfile: &Path, out_dir: &Path) -> ProcRes {
|
||||
fn document(config: &Config,
|
||||
props: &TestProps,
|
||||
testpaths: &TestPaths,
|
||||
out_dir: &Path)
|
||||
-> ProcRes {
|
||||
if props.build_aux_docs {
|
||||
for rel_ab in &props.aux_builds {
|
||||
let abs_ab = config.aux_base.join(rel_ab);
|
||||
let aux_props = header::load_props(&abs_ab);
|
||||
|
||||
let auxres = document(config, &aux_props, &abs_ab, out_dir);
|
||||
let aux_testpaths = compute_aux_test_paths(config, testpaths, rel_ab);
|
||||
let aux_props = header::load_props(&aux_testpaths.file);
|
||||
let auxres = document(config, &aux_props, &aux_testpaths, out_dir);
|
||||
if !auxres.status.success() {
|
||||
return auxres;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let aux_dir = aux_output_dir_name(config, testfile);
|
||||
let aux_dir = aux_output_dir_name(config, testpaths);
|
||||
let mut args = vec!["-L".to_owned(),
|
||||
aux_dir.to_str().unwrap().to_owned(),
|
||||
"-o".to_owned(),
|
||||
out_dir.to_str().unwrap().to_owned(),
|
||||
testfile.to_str().unwrap().to_owned()];
|
||||
testpaths.file.to_str().unwrap().to_owned()];
|
||||
args.extend(split_maybe_args(&props.compile_flags));
|
||||
let args = ProcArgs {
|
||||
prog: config.rustdoc_path.to_str().unwrap().to_owned(),
|
||||
args: args,
|
||||
};
|
||||
compose_and_run_compiler(config, props, testfile, args, None)
|
||||
compose_and_run_compiler(config, props, testpaths, args, None)
|
||||
}
|
||||
|
||||
fn exec_compiled_test(config: &Config, props: &TestProps,
|
||||
testfile: &Path) -> ProcRes {
|
||||
testpaths: &TestPaths) -> ProcRes {
|
||||
|
||||
let env = props.exec_env.clone();
|
||||
|
||||
match &*config.target {
|
||||
|
||||
"arm-linux-androideabi" | "aarch64-linux-android" => {
|
||||
_arm_exec_compiled_test(config, props, testfile, env)
|
||||
_arm_exec_compiled_test(config, props, testpaths, env)
|
||||
}
|
||||
|
||||
_=> {
|
||||
let aux_dir = aux_output_dir_name(config, testfile);
|
||||
let aux_dir = aux_output_dir_name(config, testpaths);
|
||||
compose_and_run(config,
|
||||
testfile,
|
||||
make_run_args(config, props, testfile),
|
||||
testpaths,
|
||||
make_run_args(config, props, testpaths),
|
||||
env,
|
||||
&config.run_lib_path,
|
||||
Some(aux_dir.to_str().unwrap()),
|
||||
@ -1206,21 +1216,36 @@ fn exec_compiled_test(config: &Config, props: &TestProps,
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_aux_test_paths(config: &Config,
|
||||
testpaths: &TestPaths,
|
||||
rel_ab: &str)
|
||||
-> TestPaths
|
||||
{
|
||||
let abs_ab = config.aux_base.join(rel_ab);
|
||||
TestPaths {
|
||||
file: abs_ab,
|
||||
base: testpaths.base.clone(),
|
||||
relative_dir: Path::new(rel_ab).parent()
|
||||
.map(|p| p.to_path_buf())
|
||||
.unwrap_or_else(|| PathBuf::new())
|
||||
}
|
||||
}
|
||||
|
||||
fn compose_and_run_compiler(config: &Config, props: &TestProps,
|
||||
testfile: &Path, args: ProcArgs,
|
||||
testpaths: &TestPaths, args: ProcArgs,
|
||||
input: Option<String>) -> ProcRes {
|
||||
if !props.aux_builds.is_empty() {
|
||||
ensure_dir(&aux_output_dir_name(config, testfile));
|
||||
ensure_dir(&aux_output_dir_name(config, testpaths));
|
||||
}
|
||||
|
||||
let aux_dir = aux_output_dir_name(config, testfile);
|
||||
let aux_dir = aux_output_dir_name(config, testpaths);
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
let extra_link_args = vec!["-L".to_owned(),
|
||||
aux_dir.to_str().unwrap().to_owned()];
|
||||
|
||||
for rel_ab in &props.aux_builds {
|
||||
let abs_ab = config.aux_base.join(rel_ab);
|
||||
let aux_props = header::load_props(&abs_ab);
|
||||
let aux_testpaths = compute_aux_test_paths(config, testpaths, rel_ab);
|
||||
let aux_props = header::load_props(&aux_testpaths.file);
|
||||
let mut crate_type = if aux_props.no_prefer_dynamic {
|
||||
Vec::new()
|
||||
} else {
|
||||
@ -1247,13 +1272,13 @@ fn compose_and_run_compiler(config: &Config, props: &TestProps,
|
||||
&aux_props,
|
||||
crate_type,
|
||||
|a,b| {
|
||||
let f = make_lib_name(a, b, testfile);
|
||||
let f = make_lib_name(a, &b.file, testpaths);
|
||||
let parent = f.parent().unwrap();
|
||||
TargetLocation::ThisDirectory(parent.to_path_buf())
|
||||
},
|
||||
&abs_ab);
|
||||
&aux_testpaths);
|
||||
let auxres = compose_and_run(config,
|
||||
&abs_ab,
|
||||
&aux_testpaths,
|
||||
aux_args,
|
||||
Vec::new(),
|
||||
&config.compile_lib_path,
|
||||
@ -1262,20 +1287,20 @@ fn compose_and_run_compiler(config: &Config, props: &TestProps,
|
||||
if !auxres.status.success() {
|
||||
fatal_proc_rec(
|
||||
&format!("auxiliary build of {:?} failed to compile: ",
|
||||
abs_ab.display()),
|
||||
aux_testpaths.file.display()),
|
||||
&auxres);
|
||||
}
|
||||
|
||||
match &*config.target {
|
||||
"arm-linux-androideabi" | "aarch64-linux-android" => {
|
||||
_arm_push_aux_shared_library(config, testfile);
|
||||
_arm_push_aux_shared_library(config, testpaths);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
compose_and_run(config,
|
||||
testfile,
|
||||
testpaths,
|
||||
args,
|
||||
Vec::new(),
|
||||
&config.compile_lib_path,
|
||||
@ -1285,16 +1310,17 @@ fn compose_and_run_compiler(config: &Config, props: &TestProps,
|
||||
|
||||
fn ensure_dir(path: &Path) {
|
||||
if path.is_dir() { return; }
|
||||
fs::create_dir(path).unwrap();
|
||||
fs::create_dir_all(path).unwrap();
|
||||
}
|
||||
|
||||
fn compose_and_run(config: &Config, testfile: &Path,
|
||||
fn compose_and_run(config: &Config,
|
||||
testpaths: &TestPaths,
|
||||
ProcArgs{ args, prog }: ProcArgs,
|
||||
procenv: Vec<(String, String)> ,
|
||||
lib_path: &str,
|
||||
aux_path: Option<&str>,
|
||||
input: Option<String>) -> ProcRes {
|
||||
return program_output(config, testfile, lib_path,
|
||||
return program_output(config, testpaths, lib_path,
|
||||
prog, aux_path, args, procenv, input);
|
||||
}
|
||||
|
||||
@ -1307,18 +1333,18 @@ fn make_compile_args<F>(config: &Config,
|
||||
props: &TestProps,
|
||||
extras: Vec<String> ,
|
||||
xform: F,
|
||||
testfile: &Path)
|
||||
testpaths: &TestPaths)
|
||||
-> ProcArgs where
|
||||
F: FnOnce(&Config, &Path) -> TargetLocation,
|
||||
F: FnOnce(&Config, &TestPaths) -> TargetLocation,
|
||||
{
|
||||
let xform_file = xform(config, testfile);
|
||||
let xform_file = xform(config, testpaths);
|
||||
let target = if props.force_host {
|
||||
&*config.host
|
||||
} else {
|
||||
&*config.target
|
||||
};
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
let mut args = vec!(testfile.to_str().unwrap().to_owned(),
|
||||
let mut args = vec!(testpaths.file.to_str().unwrap().to_owned(),
|
||||
"-L".to_owned(),
|
||||
config.build_base.to_str().unwrap().to_owned(),
|
||||
format!("--target={}", target));
|
||||
@ -1350,15 +1376,15 @@ fn make_compile_args<F>(config: &Config,
|
||||
};
|
||||
}
|
||||
|
||||
fn make_lib_name(config: &Config, auxfile: &Path, testfile: &Path) -> PathBuf {
|
||||
fn make_lib_name(config: &Config, auxfile: &Path, testpaths: &TestPaths) -> PathBuf {
|
||||
// what we return here is not particularly important, as it
|
||||
// happens; rustc ignores everything except for the directory.
|
||||
let auxname = output_testname(auxfile);
|
||||
aux_output_dir_name(config, testfile).join(&auxname)
|
||||
aux_output_dir_name(config, testpaths).join(&auxname)
|
||||
}
|
||||
|
||||
fn make_exe_name(config: &Config, testfile: &Path) -> PathBuf {
|
||||
let mut f = output_base_name(config, testfile);
|
||||
fn make_exe_name(config: &Config, testpaths: &TestPaths) -> PathBuf {
|
||||
let mut f = output_base_name(config, testpaths);
|
||||
// FIXME: This is using the host architecture exe suffix, not target!
|
||||
if config.target == "asmjs-unknown-emscripten" {
|
||||
let mut fname = f.file_name().unwrap().to_os_string();
|
||||
@ -1372,7 +1398,7 @@ fn make_exe_name(config: &Config, testfile: &Path) -> PathBuf {
|
||||
f
|
||||
}
|
||||
|
||||
fn make_run_args(config: &Config, props: &TestProps, testfile: &Path)
|
||||
fn make_run_args(config: &Config, props: &TestProps, testpaths: &TestPaths)
|
||||
-> ProcArgs {
|
||||
// If we've got another tool to run under (valgrind),
|
||||
// then split apart its command
|
||||
@ -1383,7 +1409,7 @@ fn make_run_args(config: &Config, props: &TestProps, testfile: &Path)
|
||||
args.push("nodejs".to_owned());
|
||||
}
|
||||
|
||||
let exe_file = make_exe_name(config, testfile);
|
||||
let exe_file = make_exe_name(config, testpaths);
|
||||
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
args.push(exe_file.to_str().unwrap().to_owned());
|
||||
@ -1415,7 +1441,7 @@ fn split_maybe_args(argstr: &Option<String>) -> Vec<String> {
|
||||
}
|
||||
}
|
||||
|
||||
fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: String,
|
||||
fn program_output(config: &Config, testpaths: &TestPaths, lib_path: &str, prog: String,
|
||||
aux_path: Option<&str>, args: Vec<String>,
|
||||
env: Vec<(String, String)>,
|
||||
input: Option<String>) -> ProcRes {
|
||||
@ -1437,7 +1463,7 @@ fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: String
|
||||
&args,
|
||||
env,
|
||||
input).expect(&format!("failed to exec `{}`", prog));
|
||||
dump_output(config, testfile, &out, &err);
|
||||
dump_output(config, testpaths, &out, &err);
|
||||
return ProcRes {
|
||||
status: Status::Normal(status),
|
||||
stdout: out,
|
||||
@ -1463,36 +1489,41 @@ fn make_cmdline(libpath: &str, prog: &str, args: &[String]) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
fn dump_output(config: &Config, testfile: &Path, out: &str, err: &str) {
|
||||
dump_output_file(config, testfile, out, "out");
|
||||
dump_output_file(config, testfile, err, "err");
|
||||
fn dump_output(config: &Config, testpaths: &TestPaths, out: &str, err: &str) {
|
||||
dump_output_file(config, testpaths, out, "out");
|
||||
dump_output_file(config, testpaths, err, "err");
|
||||
maybe_dump_to_stdout(config, out, err);
|
||||
}
|
||||
|
||||
fn dump_output_file(config: &Config, testfile: &Path,
|
||||
out: &str, extension: &str) {
|
||||
let outfile = make_out_name(config, testfile, extension);
|
||||
fn dump_output_file(config: &Config,
|
||||
testpaths: &TestPaths,
|
||||
out: &str,
|
||||
extension: &str) {
|
||||
let outfile = make_out_name(config, testpaths, extension);
|
||||
File::create(&outfile).unwrap().write_all(out.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> PathBuf {
|
||||
output_base_name(config, testfile).with_extension(extension)
|
||||
fn make_out_name(config: &Config, testpaths: &TestPaths, extension: &str) -> PathBuf {
|
||||
output_base_name(config, testpaths).with_extension(extension)
|
||||
}
|
||||
|
||||
fn aux_output_dir_name(config: &Config, testfile: &Path) -> PathBuf {
|
||||
let f = output_base_name(config, testfile);
|
||||
fn aux_output_dir_name(config: &Config, testpaths: &TestPaths) -> PathBuf {
|
||||
let f = output_base_name(config, testpaths);
|
||||
let mut fname = f.file_name().unwrap().to_os_string();
|
||||
fname.push(&format!(".{}.libaux", config.mode));
|
||||
f.with_file_name(&fname)
|
||||
}
|
||||
|
||||
fn output_testname(testfile: &Path) -> PathBuf {
|
||||
PathBuf::from(testfile.file_stem().unwrap())
|
||||
fn output_testname(filepath: &Path) -> PathBuf {
|
||||
PathBuf::from(filepath.file_stem().unwrap())
|
||||
}
|
||||
|
||||
fn output_base_name(config: &Config, testfile: &Path) -> PathBuf {
|
||||
config.build_base
|
||||
.join(&output_testname(testfile))
|
||||
fn output_base_name(config: &Config, testpaths: &TestPaths) -> PathBuf {
|
||||
let dir = config.build_base.join(&testpaths.relative_dir);
|
||||
|
||||
// Note: The directory `dir` is created during `collect_tests_from_dir`
|
||||
dir
|
||||
.join(&output_testname(&testpaths.file))
|
||||
.with_extension(&config.stage_id)
|
||||
}
|
||||
|
||||
@ -1531,10 +1562,10 @@ stderr:\n\
|
||||
|
||||
fn _arm_exec_compiled_test(config: &Config,
|
||||
props: &TestProps,
|
||||
testfile: &Path,
|
||||
testpaths: &TestPaths,
|
||||
env: Vec<(String, String)>)
|
||||
-> ProcRes {
|
||||
let args = make_run_args(config, props, testfile);
|
||||
let args = make_run_args(config, props, testpaths);
|
||||
let cmdline = make_cmdline("",
|
||||
&args.prog,
|
||||
&args.args);
|
||||
@ -1645,7 +1676,7 @@ fn _arm_exec_compiled_test(config: &Config,
|
||||
.expect(&format!("failed to exec `{}`", config.adb_path));
|
||||
|
||||
dump_output(config,
|
||||
testfile,
|
||||
testpaths,
|
||||
&stdout_out,
|
||||
&stderr_out);
|
||||
|
||||
@ -1657,8 +1688,8 @@ fn _arm_exec_compiled_test(config: &Config,
|
||||
}
|
||||
}
|
||||
|
||||
fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) {
|
||||
let tdir = aux_output_dir_name(config, testfile);
|
||||
fn _arm_push_aux_shared_library(config: &Config, testpaths: &TestPaths) {
|
||||
let tdir = aux_output_dir_name(config, testpaths);
|
||||
|
||||
let dirs = fs::read_dir(&tdir).unwrap();
|
||||
for file in dirs {
|
||||
@ -1692,8 +1723,8 @@ fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) {
|
||||
// codegen tests (using FileCheck)
|
||||
|
||||
fn compile_test_and_save_ir(config: &Config, props: &TestProps,
|
||||
testfile: &Path) -> ProcRes {
|
||||
let aux_dir = aux_output_dir_name(config, testfile);
|
||||
testpaths: &TestPaths) -> ProcRes {
|
||||
let aux_dir = aux_output_dir_name(config, testpaths);
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
let mut link_args = vec!("-L".to_owned(),
|
||||
aux_dir.to_str().unwrap().to_owned());
|
||||
@ -1705,34 +1736,34 @@ fn compile_test_and_save_ir(config: &Config, props: &TestProps,
|
||||
|a, b| TargetLocation::ThisDirectory(
|
||||
output_base_name(a, b).parent()
|
||||
.unwrap().to_path_buf()),
|
||||
testfile);
|
||||
compose_and_run_compiler(config, props, testfile, args, None)
|
||||
testpaths);
|
||||
compose_and_run_compiler(config, props, testpaths, args, None)
|
||||
}
|
||||
|
||||
fn check_ir_with_filecheck(config: &Config, testfile: &Path) -> ProcRes {
|
||||
let irfile = output_base_name(config, testfile).with_extension("ll");
|
||||
fn check_ir_with_filecheck(config: &Config, testpaths: &TestPaths) -> ProcRes {
|
||||
let irfile = output_base_name(config, testpaths).with_extension("ll");
|
||||
let prog = config.llvm_bin_path.as_ref().unwrap().join("FileCheck");
|
||||
let proc_args = ProcArgs {
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
prog: prog.to_str().unwrap().to_owned(),
|
||||
args: vec!(format!("-input-file={}", irfile.to_str().unwrap()),
|
||||
testfile.to_str().unwrap().to_owned())
|
||||
testpaths.file.to_str().unwrap().to_owned())
|
||||
};
|
||||
compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
|
||||
compose_and_run(config, testpaths, proc_args, Vec::new(), "", None, None)
|
||||
}
|
||||
|
||||
fn run_codegen_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
fn run_codegen_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
|
||||
|
||||
if config.llvm_bin_path.is_none() {
|
||||
fatal("missing --llvm-bin-path");
|
||||
}
|
||||
|
||||
let mut proc_res = compile_test_and_save_ir(config, props, testfile);
|
||||
let mut proc_res = compile_test_and_save_ir(config, props, testpaths);
|
||||
if !proc_res.status.success() {
|
||||
fatal_proc_rec("compilation failed!", &proc_res);
|
||||
}
|
||||
|
||||
proc_res = check_ir_with_filecheck(config, testfile);
|
||||
proc_res = check_ir_with_filecheck(config, testpaths);
|
||||
if !proc_res.status.success() {
|
||||
fatal_proc_rec("verification with 'FileCheck' failed",
|
||||
&proc_res);
|
||||
@ -1750,30 +1781,30 @@ fn charset() -> &'static str {
|
||||
}
|
||||
}
|
||||
|
||||
fn run_rustdoc_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
let out_dir = output_base_name(config, testfile);
|
||||
fn run_rustdoc_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
|
||||
let out_dir = output_base_name(config, testpaths);
|
||||
let _ = fs::remove_dir_all(&out_dir);
|
||||
ensure_dir(&out_dir);
|
||||
|
||||
let proc_res = document(config, props, testfile, &out_dir);
|
||||
let proc_res = document(config, props, testpaths, &out_dir);
|
||||
if !proc_res.status.success() {
|
||||
fatal_proc_rec("rustdoc failed!", &proc_res);
|
||||
}
|
||||
let root = find_rust_src_root(config).unwrap();
|
||||
|
||||
let res = cmd2procres(config,
|
||||
testfile,
|
||||
testpaths,
|
||||
Command::new(&config.python)
|
||||
.arg(root.join("src/etc/htmldocck.py"))
|
||||
.arg(out_dir)
|
||||
.arg(testfile));
|
||||
.arg(&testpaths.file));
|
||||
if !res.status.success() {
|
||||
fatal_proc_rec("htmldocck failed!", &res);
|
||||
}
|
||||
}
|
||||
|
||||
fn run_codegen_units_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
let proc_res = compile_test(config, props, testfile);
|
||||
fn run_codegen_units_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
|
||||
let proc_res = compile_test(config, props, testpaths);
|
||||
|
||||
if !proc_res.status.success() {
|
||||
fatal_proc_rec("compilation failed!", &proc_res);
|
||||
@ -1790,7 +1821,7 @@ fn run_codegen_units_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
.map(|s| (&s[prefix.len()..]).to_string())
|
||||
.collect();
|
||||
|
||||
let expected: HashSet<String> = errors::load_errors(testfile)
|
||||
let expected: HashSet<String> = errors::load_errors(&testpaths.file)
|
||||
.iter()
|
||||
.map(|e| e.msg.trim().to_string())
|
||||
.collect();
|
||||
|
@ -203,7 +203,12 @@ pub struct TestDesc {
|
||||
pub should_panic: ShouldPanic,
|
||||
}
|
||||
|
||||
unsafe impl Send for TestDesc {}
|
||||
#[derive(Clone)]
|
||||
pub struct TestPaths {
|
||||
pub file: PathBuf, // e.g., compile-test/foo/bar/baz.rs
|
||||
pub base: PathBuf, // e.g., compile-test, auxiliary
|
||||
pub relative_dir: PathBuf, // e.g., foo/bar
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TestDescAndFn {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user