4 use std::path::PathBuf;
5 use ui_test::{Config, Mode, OutputConflictHandling};
7 fn miri_path() -> PathBuf {
8 PathBuf::from(option_env!("MIRI").unwrap_or(env!("CARGO_BIN_EXE_miri")))
11 fn run_tests(mode: Mode, path: &str, target: Option<String>) {
12 let in_rustc_test_suite = option_env!("RUSTC_STAGE").is_some();
14 // Add some flags we always want.
15 let mut flags = Vec::new();
16 flags.push("--edition".to_owned());
17 flags.push("2018".to_owned());
18 if in_rustc_test_suite {
19 // Less aggressive warnings to make the rustc toolstate management less painful.
20 // (We often get warnings when e.g. a feature gets stabilized or some lint gets added/improved.)
21 flags.push("-Astable-features".to_owned());
23 flags.push("-Dwarnings".to_owned());
24 flags.push("-Dunused".to_owned()); // overwrite the -Aunused in compiletest-rs
26 if let Ok(sysroot) = env::var("MIRI_SYSROOT") {
27 flags.push("--sysroot".to_string());
30 if let Ok(extra_flags) = env::var("MIRIFLAGS") {
31 for flag in extra_flags.split_whitespace() {
32 flags.push(flag.to_string());
35 flags.push("-Zui-testing".to_string());
36 if let Some(target) = &target {
37 flags.push("--target".to_string());
38 flags.push(target.clone());
41 let skip_ui_checks = env::var_os("MIRI_SKIP_UI_CHECKS").is_some();
43 let output_conflict_handling = match (env::var_os("MIRI_BLESS").is_some(), skip_ui_checks) {
44 (false, false) => OutputConflictHandling::Error,
45 (true, false) => OutputConflictHandling::Bless,
46 (false, true) => OutputConflictHandling::Ignore,
47 (true, true) => panic!("cannot use MIRI_BLESS and MIRI_SKIP_UI_CHECKS at the same time"),
50 // Pass on all arguments as filters.
51 let path_filter = std::env::args().skip(1);
56 stderr_filters: STDERR.clone(),
57 stdout_filters: STDOUT.clone(),
58 root_dir: PathBuf::from(path),
60 path_filter: path_filter.collect(),
62 output_conflict_handling,
64 ui_test::run_tests(config)
67 macro_rules! regexes {
68 ($name:ident: $($regex:expr => $replacement:expr,)*) => {lazy_static::lazy_static! {
69 static ref $name: Vec<(Regex, &'static str)> = vec![
70 $((Regex::new($regex).unwrap(), $replacement),)*
83 // erase line and column info
84 r"\.rs:[0-9]+:[0-9]+(: [0-9]+:[0-9]+)?" => ".rs:LL:CC",
86 "alloc[0-9]+" => "ALLOC",
87 // erase Stacked Borrows tags
88 "<[0-9]+>" => "<TAG>",
89 // erase whitespace that differs between platforms
90 r" +at (.*\.rs)" => " at $1",
91 // erase generics in backtraces
92 "([0-9]+: .*)::<.*>" => "$1",
93 // erase addresses in backtraces
94 "([0-9]+: ) +0x[0-9a-f]+ - (.*)" => "$1$2",
95 // erase long hexadecimals
96 r"0x[0-9a-fA-F]+[0-9a-fA-F]{2,2}" => "$$HEX",
97 // erase specific alignments
98 "alignment [0-9]+" => "alignment ALIGN",
99 // erase thread caller ids
100 r"\(call [0-9]+\)" => "(call ID)",
101 // erase platform module paths
102 "sys::[a-z]+::" => "sys::PLATFORM::",
103 // Windows file paths
105 // erase Rust stdlib path
106 "[^ `]*/(rust[^/]*|checkout)/library/" => "RUSTLIB/",
107 // erase platform file paths
108 "sys/[a-z]+/" => "sys/PLATFORM/",
111 fn ui(mode: Mode, path: &str) {
112 let target = get_target();
115 "## Running ui tests in {path} against miri for {}",
116 target.as_deref().unwrap_or("host")
118 eprintln!("{}", msg.green().bold());
120 run_tests(mode, path, target);
123 fn get_target() -> Option<String> {
124 env::var("MIRI_TEST_TARGET").ok()
128 // Add a test env var to do environment communication tests.
129 env::set_var("MIRI_ENV_VAR_TEST", "0");
130 // Let the tests know where to store temp files (they might run for a different target, which can make this hard to find).
131 env::set_var("MIRI_TEMP", env::temp_dir());
133 ui(Mode::Pass, "tests/pass");
134 ui(Mode::Panic, "tests/panic");
135 ui(Mode::Fail, "tests/fail");