2022-03-17 08:49:10 -05:00
|
|
|
use colored::*;
|
|
|
|
use regex::Regex;
|
2022-07-14 05:03:08 -05:00
|
|
|
use std::path::{Path, PathBuf};
|
|
|
|
use std::{env, ffi::OsString};
|
|
|
|
use ui_test::{color_eyre::Result, Config, DependencyBuilder, Mode, OutputConflictHandling};
|
2017-06-21 16:28:13 -05:00
|
|
|
|
2017-08-08 03:28:05 -05:00
|
|
|
fn miri_path() -> PathBuf {
|
2020-05-21 07:24:41 -05:00
|
|
|
PathBuf::from(option_env!("MIRI").unwrap_or(env!("CARGO_BIN_EXE_miri")))
|
2017-08-08 03:28:05 -05:00
|
|
|
}
|
2017-08-02 11:28:12 -05:00
|
|
|
|
2022-07-06 04:09:53 -05:00
|
|
|
fn run_tests(mode: Mode, path: &str, target: Option<String>) -> Result<()> {
|
2020-05-11 03:37:35 -05:00
|
|
|
let in_rustc_test_suite = option_env!("RUSTC_STAGE").is_some();
|
2022-03-17 08:49:10 -05:00
|
|
|
|
2019-07-31 06:48:15 -05:00
|
|
|
// Add some flags we always want.
|
2022-07-14 05:03:08 -05:00
|
|
|
let mut flags: Vec<OsString> = Vec::new();
|
|
|
|
flags.push("--edition".into());
|
|
|
|
flags.push("2018".into());
|
2019-08-21 02:07:27 -05:00
|
|
|
if in_rustc_test_suite {
|
|
|
|
// Less aggressive warnings to make the rustc toolstate management less painful.
|
|
|
|
// (We often get warnings when e.g. a feature gets stabilized or some lint gets added/improved.)
|
2022-07-14 05:03:08 -05:00
|
|
|
flags.push("-Astable-features".into());
|
|
|
|
flags.push("-Aunused".into());
|
2019-08-21 02:07:27 -05:00
|
|
|
} else {
|
2022-07-14 05:03:08 -05:00
|
|
|
flags.push("-Dwarnings".into());
|
|
|
|
flags.push("-Dunused".into());
|
2019-07-31 06:44:55 -05:00
|
|
|
}
|
2020-10-22 03:36:01 -05:00
|
|
|
if let Ok(extra_flags) = env::var("MIRIFLAGS") {
|
2022-03-17 08:49:10 -05:00
|
|
|
for flag in extra_flags.split_whitespace() {
|
2022-07-14 05:03:08 -05:00
|
|
|
flags.push(flag.into());
|
2022-03-17 08:49:10 -05:00
|
|
|
}
|
|
|
|
}
|
2022-07-14 05:03:08 -05:00
|
|
|
flags.push("-Zui-testing".into());
|
2022-03-17 08:49:10 -05:00
|
|
|
if let Some(target) = &target {
|
2022-07-14 05:03:08 -05:00
|
|
|
flags.push("--target".into());
|
|
|
|
flags.push(target.into());
|
2020-03-18 05:19:01 -05:00
|
|
|
}
|
|
|
|
|
2022-06-02 20:09:10 -05:00
|
|
|
let skip_ui_checks = env::var_os("MIRI_SKIP_UI_CHECKS").is_some();
|
2019-06-09 10:10:04 -05:00
|
|
|
|
2022-03-17 08:49:10 -05:00
|
|
|
let output_conflict_handling = match (env::var_os("MIRI_BLESS").is_some(), skip_ui_checks) {
|
|
|
|
(false, false) => OutputConflictHandling::Error,
|
|
|
|
(true, false) => OutputConflictHandling::Bless,
|
|
|
|
(false, true) => OutputConflictHandling::Ignore,
|
|
|
|
(true, true) => panic!("cannot use MIRI_BLESS and MIRI_SKIP_UI_CHECKS at the same time"),
|
|
|
|
};
|
2018-11-09 04:48:10 -06:00
|
|
|
|
2022-07-18 04:19:20 -05:00
|
|
|
// Pass on all unknown arguments as filters.
|
|
|
|
let mut quiet = false;
|
|
|
|
let path_filter = std::env::args().skip(1).filter(|arg| {
|
|
|
|
match &**arg {
|
|
|
|
"--quiet" => {
|
|
|
|
quiet = true;
|
|
|
|
false
|
|
|
|
}
|
|
|
|
_ => true,
|
|
|
|
}
|
|
|
|
});
|
2022-05-27 06:43:14 -05:00
|
|
|
|
2022-07-14 05:03:08 -05:00
|
|
|
let use_std = env::var_os("MIRI_NO_STD").is_none();
|
|
|
|
|
2022-03-17 08:49:10 -05:00
|
|
|
let config = Config {
|
|
|
|
args: flags,
|
|
|
|
target,
|
|
|
|
stderr_filters: STDERR.clone(),
|
|
|
|
stdout_filters: STDOUT.clone(),
|
|
|
|
root_dir: PathBuf::from(path),
|
|
|
|
mode,
|
2022-05-30 03:27:41 -05:00
|
|
|
path_filter: path_filter.collect(),
|
2022-03-17 08:49:10 -05:00
|
|
|
program: miri_path(),
|
|
|
|
output_conflict_handling,
|
2022-07-14 05:03:08 -05:00
|
|
|
dependencies_crate_manifest_path: use_std
|
|
|
|
.then(|| Path::new("test_dependencies").join("Cargo.toml")),
|
|
|
|
dependency_builder: Some(DependencyBuilder {
|
|
|
|
program: std::env::var_os("CARGO").unwrap().into(),
|
|
|
|
args: vec![
|
|
|
|
"run".into(),
|
|
|
|
"--manifest-path".into(),
|
|
|
|
"cargo-miri/Cargo.toml".into(),
|
|
|
|
"--".into(),
|
|
|
|
"miri".into(),
|
|
|
|
],
|
|
|
|
envs: vec![],
|
|
|
|
}),
|
2022-07-18 04:19:20 -05:00
|
|
|
quiet,
|
2022-03-17 08:49:10 -05:00
|
|
|
};
|
|
|
|
ui_test::run_tests(config)
|
|
|
|
}
|
2018-10-23 06:09:17 -05:00
|
|
|
|
2022-03-17 08:49:10 -05:00
|
|
|
macro_rules! regexes {
|
|
|
|
($name:ident: $($regex:expr => $replacement:expr,)*) => {lazy_static::lazy_static! {
|
|
|
|
static ref $name: Vec<(Regex, &'static str)> = vec![
|
|
|
|
$((Regex::new($regex).unwrap(), $replacement),)*
|
|
|
|
];
|
|
|
|
}};
|
2016-06-15 06:18:35 -05:00
|
|
|
}
|
|
|
|
|
2022-03-17 08:49:10 -05:00
|
|
|
regexes! {
|
|
|
|
STDOUT:
|
|
|
|
// Windows file paths
|
|
|
|
r"\\" => "/",
|
|
|
|
}
|
2018-10-23 06:09:17 -05:00
|
|
|
|
2022-03-17 08:49:10 -05:00
|
|
|
regexes! {
|
|
|
|
STDERR:
|
|
|
|
// erase line and column info
|
2022-05-30 18:21:22 -05:00
|
|
|
r"\.rs:[0-9]+:[0-9]+(: [0-9]+:[0-9]+)?" => ".rs:LL:CC",
|
2022-03-17 08:49:10 -05:00
|
|
|
// erase alloc ids
|
|
|
|
"alloc[0-9]+" => "ALLOC",
|
|
|
|
// erase Stacked Borrows tags
|
|
|
|
"<[0-9]+>" => "<TAG>",
|
|
|
|
// erase whitespace that differs between platforms
|
|
|
|
r" +at (.*\.rs)" => " at $1",
|
|
|
|
// erase generics in backtraces
|
|
|
|
"([0-9]+: .*)::<.*>" => "$1",
|
|
|
|
// erase addresses in backtraces
|
|
|
|
"([0-9]+: ) +0x[0-9a-f]+ - (.*)" => "$1$2",
|
|
|
|
// erase long hexadecimals
|
|
|
|
r"0x[0-9a-fA-F]+[0-9a-fA-F]{2,2}" => "$$HEX",
|
|
|
|
// erase specific alignments
|
|
|
|
"alignment [0-9]+" => "alignment ALIGN",
|
|
|
|
// erase thread caller ids
|
2022-07-11 19:54:31 -05:00
|
|
|
r"call [0-9]+" => "call ID",
|
2022-03-17 08:49:10 -05:00
|
|
|
// erase platform module paths
|
|
|
|
"sys::[a-z]+::" => "sys::PLATFORM::",
|
|
|
|
// Windows file paths
|
|
|
|
r"\\" => "/",
|
2022-05-31 17:23:47 -05:00
|
|
|
// erase Rust stdlib path
|
|
|
|
"[^ `]*/(rust[^/]*|checkout)/library/" => "RUSTLIB/",
|
2022-03-17 08:49:10 -05:00
|
|
|
// erase platform file paths
|
|
|
|
"sys/[a-z]+/" => "sys/PLATFORM/",
|
2022-07-14 05:03:08 -05:00
|
|
|
// erase paths into the crate registry
|
2022-07-21 14:34:32 -05:00
|
|
|
r"[^ ]*/\.?cargo/registry/.*/(.*\.rs)" => "CARGO_REGISTRY/.../$1",
|
2016-12-16 19:10:16 -06:00
|
|
|
}
|
|
|
|
|
2022-07-06 04:09:53 -05:00
|
|
|
fn ui(mode: Mode, path: &str) -> Result<()> {
|
2022-03-17 08:49:10 -05:00
|
|
|
let target = get_target();
|
|
|
|
|
2022-05-25 11:12:54 -05:00
|
|
|
let msg = format!(
|
|
|
|
"## Running ui tests in {path} against miri for {}",
|
|
|
|
target.as_deref().unwrap_or("host")
|
|
|
|
);
|
|
|
|
eprintln!("{}", msg.green().bold());
|
2022-03-17 08:49:10 -05:00
|
|
|
|
2022-07-06 04:09:53 -05:00
|
|
|
run_tests(mode, path, target)
|
2017-07-19 14:52:20 -05:00
|
|
|
}
|
2017-02-07 05:32:39 -06:00
|
|
|
|
2022-03-17 08:49:10 -05:00
|
|
|
fn get_target() -> Option<String> {
|
|
|
|
env::var("MIRI_TEST_TARGET").ok()
|
2018-12-12 04:03:42 -06:00
|
|
|
}
|
2017-07-19 14:52:20 -05:00
|
|
|
|
2022-07-06 04:09:53 -05:00
|
|
|
fn main() -> Result<()> {
|
|
|
|
ui_test::color_eyre::install()?;
|
|
|
|
|
2020-03-18 05:19:01 -05:00
|
|
|
// Add a test env var to do environment communication tests.
|
2020-10-22 03:36:01 -05:00
|
|
|
env::set_var("MIRI_ENV_VAR_TEST", "0");
|
2020-03-23 17:42:03 -05:00
|
|
|
// Let the tests know where to store temp files (they might run for a different target, which can make this hard to find).
|
2020-10-22 03:36:01 -05:00
|
|
|
env::set_var("MIRI_TEMP", env::temp_dir());
|
2019-08-13 12:10:24 -05:00
|
|
|
|
2022-07-06 04:09:53 -05:00
|
|
|
ui(Mode::Pass, "tests/pass")?;
|
|
|
|
ui(Mode::Panic, "tests/panic")?;
|
|
|
|
ui(Mode::Fail, "tests/fail")?;
|
|
|
|
|
|
|
|
Ok(())
|
2018-07-12 08:01:10 -05:00
|
|
|
}
|