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 = in_rustc_test_suite || 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"),
53 stderr_filters: STDERR.clone(),
54 stdout_filters: STDOUT.clone(),
55 root_dir: PathBuf::from(path),
58 output_conflict_handling,
60 ui_test::run_tests(config)
63 macro_rules! regexes {
64 ($name:ident: $($regex:expr => $replacement:expr,)*) => {lazy_static::lazy_static! {
65 static ref $name: Vec<(Regex, &'static str)> = vec![
66 $((Regex::new($regex).unwrap(), $replacement),)*
79 // erase line and column info
80 r"\.rs:[0-9]+:[0-9]+" => ".rs:LL:CC",
82 "alloc[0-9]+" => "ALLOC",
83 // erase Stacked Borrows tags
84 "<[0-9]+>" => "<TAG>",
85 // erase whitespace that differs between platforms
86 r" +at (.*\.rs)" => " at $1",
87 // erase generics in backtraces
88 "([0-9]+: .*)::<.*>" => "$1",
89 // erase addresses in backtraces
90 "([0-9]+: ) +0x[0-9a-f]+ - (.*)" => "$1$2",
91 // erase long hexadecimals
92 r"0x[0-9a-fA-F]+[0-9a-fA-F]{2,2}" => "$$HEX",
94 r"VClock\(\[[^\]]+\]\)" => "VClock",
95 // erase specific alignments
96 "alignment [0-9]+" => "alignment ALIGN",
97 // erase thread caller ids
98 r"\(call [0-9]+\)" => "(call ID)",
99 // erase platform module paths
100 "sys::[a-z]+::" => "sys::PLATFORM::",
101 // Windows file paths
103 // erase platform file paths
104 "sys/[a-z]+/" => "sys/PLATFORM/",
105 // erase error annotations in tests
109 fn ui(mode: Mode, path: &str) {
110 let target = get_target();
113 "## Running ui tests in {path} against miri for {}",
114 target.as_deref().unwrap_or("host")
116 eprintln!("{}", msg.green().bold());
118 run_tests(mode, path, target);
121 fn get_target() -> Option<String> {
122 env::var("MIRI_TEST_TARGET").ok()
126 // Add a test env var to do environment communication tests.
127 env::set_var("MIRI_ENV_VAR_TEST", "0");
128 // Let the tests know where to store temp files (they might run for a different target, which can make this hard to find).
129 env::set_var("MIRI_TEMP", env::temp_dir());
131 ui(Mode::Pass, "tests/run-pass");
132 ui(Mode::Panic, "tests/run-fail");
133 ui(Mode::Fail, "tests/compile-fail");