summaryrefslogtreecommitdiffstats
path: root/src/tools/compiletest/src/runtest.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/compiletest/src/runtest.rs')
-rw-r--r--src/tools/compiletest/src/runtest.rs119
1 files changed, 89 insertions, 30 deletions
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 41c23ff86..7f0b894f5 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -30,6 +30,7 @@ use std::iter;
use std::path::{Path, PathBuf};
use std::process::{Child, Command, ExitStatus, Output, Stdio};
use std::str;
+use std::sync::Arc;
use glob::glob;
use once_cell::sync::Lazy;
@@ -49,8 +50,10 @@ const FAKE_SRC_BASE: &str = "fake-test-src-base";
#[cfg(windows)]
fn disable_error_reporting<F: FnOnce() -> R, R>(f: F) -> R {
use std::sync::Mutex;
- use winapi::um::errhandlingapi::SetErrorMode;
- use winapi::um::winbase::SEM_NOGPFAULTERRORBOX;
+
+ use windows::Win32::System::Diagnostics::Debug::{
+ SetErrorMode, SEM_NOGPFAULTERRORBOX, THREAD_ERROR_MODE,
+ };
static LOCK: Mutex<()> = Mutex::new(());
@@ -62,6 +65,7 @@ fn disable_error_reporting<F: FnOnce() -> R, R>(f: F) -> R {
// termination by design. This mode is inherited by all child processes.
unsafe {
let old_mode = SetErrorMode(SEM_NOGPFAULTERRORBOX); // read inherited flags
+ let old_mode = THREAD_ERROR_MODE(old_mode);
SetErrorMode(old_mode | SEM_NOGPFAULTERRORBOX);
let r = f();
SetErrorMode(old_mode);
@@ -93,7 +97,7 @@ pub fn get_lib_name(lib: &str, dylib: bool) -> String {
}
}
-pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) {
+pub fn run(config: Arc<Config>, testpaths: &TestPaths, revision: Option<&str>) {
match &*config.target {
"arm-linux-androideabi"
| "armv7-linux-androideabi"
@@ -278,13 +282,15 @@ impl<'test> TestCx<'test> {
Incremental => {
let revision =
self.revision.expect("incremental tests require a list of revisions");
- if revision.starts_with("rpass") || revision.starts_with("rfail") {
+ if revision.starts_with("cpass")
+ || revision.starts_with("rpass")
+ || revision.starts_with("rfail")
+ {
true
} else if revision.starts_with("cfail") {
- // FIXME: would be nice if incremental revs could start with "cpass"
pm.is_some()
} else {
- panic!("revision name must begin with rpass, rfail, or cfail");
+ panic!("revision name must begin with cpass, rpass, rfail, or cfail");
}
}
mode => panic!("unimplemented for mode {:?}", mode),
@@ -304,7 +310,9 @@ impl<'test> TestCx<'test> {
);
}
- self.check_correct_failure_status(proc_res);
+ if !self.props.dont_check_failure_status {
+ self.check_correct_failure_status(proc_res);
+ }
}
}
@@ -384,6 +392,20 @@ impl<'test> TestCx<'test> {
}
}
+ fn run_cpass_test(&self) {
+ let emit_metadata = self.should_emit_metadata(self.pass_mode());
+ let proc_res = self.compile_test(WillExecute::No, emit_metadata);
+
+ if !proc_res.status.success() {
+ self.fatal_proc_rec("compilation failed!", &proc_res);
+ }
+
+ // FIXME(#41968): Move this check to tidy?
+ if !errors::load_errors(&self.testpaths.file, self.revision).is_empty() {
+ self.fatal("compile-pass tests with expected warnings should be moved to ui/");
+ }
+ }
+
fn run_rpass_test(&self) {
let emit_metadata = self.should_emit_metadata(self.pass_mode());
let should_run = self.run_if_enabled();
@@ -393,17 +415,15 @@ impl<'test> TestCx<'test> {
self.fatal_proc_rec("compilation failed!", &proc_res);
}
+ // FIXME(#41968): Move this check to tidy?
+ if !errors::load_errors(&self.testpaths.file, self.revision).is_empty() {
+ self.fatal("run-pass tests with expected warnings should be moved to ui/");
+ }
+
if let WillExecute::Disabled = should_run {
return;
}
- // FIXME(#41968): Move this check to tidy?
- let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
- assert!(
- expected_errors.is_empty(),
- "run-pass tests with expected warnings should be moved to ui/"
- );
-
let proc_res = self.exec_compiled_test();
if !proc_res.status.success() {
self.fatal_proc_rec("test run failed!", &proc_res);
@@ -983,7 +1003,12 @@ impl<'test> TestCx<'test> {
&["-quiet".as_ref(), "-batch".as_ref(), "-nx".as_ref(), &debugger_script];
let mut gdb = Command::new(self.config.gdb.as_ref().unwrap());
- gdb.args(debugger_opts).env("PYTHONPATH", rust_pp_module_abs_path);
+ let pythonpath = if let Ok(pp) = std::env::var("PYTHONPATH") {
+ format!("{pp}:{rust_pp_module_abs_path}")
+ } else {
+ rust_pp_module_abs_path
+ };
+ gdb.args(debugger_opts).env("PYTHONPATH", pythonpath);
debugger_run_result =
self.compose_and_run(gdb, self.config.run_lib_path.to_str().unwrap(), None, None);
@@ -1149,13 +1174,18 @@ impl<'test> TestCx<'test> {
) -> ProcRes {
// Prepare the lldb_batchmode which executes the debugger script
let lldb_script_path = rust_src_root.join("src/etc/lldb_batchmode.py");
+ let pythonpath = if let Ok(pp) = std::env::var("PYTHONPATH") {
+ format!("{pp}:{}", self.config.lldb_python_dir.as_ref().unwrap())
+ } else {
+ self.config.lldb_python_dir.as_ref().unwrap().to_string()
+ };
self.cmd2procres(
Command::new(&self.config.python)
.arg(&lldb_script_path)
.arg(test_executable)
.arg(debugger_script)
.env("PYTHONUNBUFFERED", "1") // Help debugging #78665
- .env("PYTHONPATH", self.config.lldb_python_dir.as_ref().unwrap()),
+ .env("PYTHONPATH", pythonpath),
)
}
@@ -1540,7 +1570,7 @@ impl<'test> TestCx<'test> {
rustdoc.arg("--output-format").arg("json").arg("-Zunstable-options");
}
- if let Some(ref linker) = self.config.linker {
+ if let Some(ref linker) = self.config.target_linker {
rustdoc.arg(format!("-Clinker={}", linker));
}
@@ -1583,8 +1613,13 @@ impl<'test> TestCx<'test> {
test_client
.args(&["run", &support_libs.len().to_string(), &prog])
.args(support_libs)
- .args(args)
- .envs(env.clone());
+ .args(args);
+
+ for key in &self.props.unset_exec_env {
+ test_client.env_remove(key);
+ }
+ test_client.envs(env.clone());
+
self.compose_and_run(
test_client,
self.config.run_lib_path.to_str().unwrap(),
@@ -1596,7 +1631,13 @@ impl<'test> TestCx<'test> {
let aux_dir = self.aux_output_dir_name();
let ProcArgs { prog, args } = self.make_run_args();
let mut wr_run = Command::new("wr-run");
- wr_run.args(&[&prog]).args(args).envs(env.clone());
+ wr_run.args(&[&prog]).args(args);
+
+ for key in &self.props.unset_exec_env {
+ wr_run.env_remove(key);
+ }
+ wr_run.envs(env.clone());
+
self.compose_and_run(
wr_run,
self.config.run_lib_path.to_str().unwrap(),
@@ -1608,7 +1649,13 @@ impl<'test> TestCx<'test> {
let aux_dir = self.aux_output_dir_name();
let ProcArgs { prog, args } = self.make_run_args();
let mut program = Command::new(&prog);
- program.args(args).current_dir(&self.output_base_dir()).envs(env.clone());
+ program.args(args).current_dir(&self.output_base_dir());
+
+ for key in &self.props.unset_exec_env {
+ program.env_remove(key);
+ }
+ program.envs(env.clone());
+
self.compose_and_run(
program,
self.config.run_lib_path.to_str().unwrap(),
@@ -2053,10 +2100,15 @@ impl<'test> TestCx<'test> {
if self.props.force_host {
self.maybe_add_external_args(&mut rustc, &self.config.host_rustcflags);
+ if !is_rustdoc {
+ if let Some(ref linker) = self.config.host_linker {
+ rustc.arg(format!("-Clinker={}", linker));
+ }
+ }
} else {
self.maybe_add_external_args(&mut rustc, &self.config.target_rustcflags);
if !is_rustdoc {
- if let Some(ref linker) = self.config.linker {
+ if let Some(ref linker) = self.config.target_linker {
rustc.arg(format!("-Clinker={}", linker));
}
}
@@ -2105,7 +2157,7 @@ impl<'test> TestCx<'test> {
if let Some(ref p) = self.config.nodejs {
args.push(p.clone());
} else {
- self.fatal("no NodeJS binary found (--nodejs)");
+ self.fatal("emscripten target requested and no NodeJS binary found (--nodejs)");
}
// If this is otherwise wasm, then run tests under nodejs with our
// shim
@@ -2113,7 +2165,7 @@ impl<'test> TestCx<'test> {
if let Some(ref p) = self.config.nodejs {
args.push(p.clone());
} else {
- self.fatal("no NodeJS binary found (--nodejs)");
+ self.fatal("wasm32 target requested and no NodeJS binary found (--nodejs)");
}
let src = self
@@ -2903,10 +2955,11 @@ impl<'test> TestCx<'test> {
fn run_incremental_test(&self) {
// Basic plan for a test incremental/foo/bar.rs:
// - load list of revisions rpass1, cfail2, rpass3
- // - each should begin with `rpass`, `cfail`, or `rfail`
- // - if `rpass`, expect compile and execution to succeed
+ // - each should begin with `cpass`, `rpass`, `cfail`, or `rfail`
+ // - if `cpass`, expect compilation to succeed, don't execute
+ // - if `rpass`, expect compilation and execution to succeed
// - if `cfail`, expect compilation to fail
- // - if `rfail`, expect execution to fail
+ // - if `rfail`, expect compilation to succeed and execution to fail
// - create a directory build/foo/bar.incremental
// - compile foo/bar.rs with -C incremental=.../foo/bar.incremental and -C rpass1
// - because name of revision starts with "rpass", expect success
@@ -2930,7 +2983,12 @@ impl<'test> TestCx<'test> {
print!("revision={:?} props={:#?}", revision, self.props);
}
- if revision.starts_with("rpass") {
+ if revision.starts_with("cpass") {
+ if self.props.should_ice {
+ self.fatal("can only use should-ice in cfail tests");
+ }
+ self.run_cpass_test();
+ } else if revision.starts_with("rpass") {
if self.props.should_ice {
self.fatal("can only use should-ice in cfail tests");
}
@@ -2943,7 +3001,7 @@ impl<'test> TestCx<'test> {
} else if revision.starts_with("cfail") {
self.run_cfail_test();
} else {
- self.fatal("revision name must begin with rpass, rfail, or cfail");
+ self.fatal("revision name must begin with cpass, rpass, rfail, or cfail");
}
}
@@ -2963,6 +3021,7 @@ impl<'test> TestCx<'test> {
|| host.contains("freebsd")
|| host.contains("netbsd")
|| host.contains("openbsd")
+ || host.contains("aix")
{
"gmake"
} else {
@@ -3002,7 +3061,7 @@ impl<'test> TestCx<'test> {
cmd.env("NODE", node);
}
- if let Some(ref linker) = self.config.linker {
+ if let Some(ref linker) = self.config.target_linker {
cmd.env("RUSTC_LINKER", linker);
}