Auto merge of #2884 - oli-obk:ui_test, r=RalfJung,oli-obk

Update to latest ui_test crate version.

Also stops using github actions groups that conflict with our groups as github does not nest them
This commit is contained in:
bors 2023-05-09 15:34:23 +00:00
commit 84f80f1fc9
40 changed files with 118 additions and 64 deletions

View File

@ -820,9 +820,9 @@ dependencies = [
[[package]] [[package]]
name = "ui_test" name = "ui_test"
version = "0.6.2" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e10f5f88ce8c331a388deda1e6e2bd533c73ca89cc5f539a3df02ed35c8efba" checksum = "95033b0e41b8018013d99a6f1486c1ae5bd080378ced60c5f797e93842423b33"
dependencies = [ dependencies = [
"bstr", "bstr",
"cargo-platform", "cargo-platform",

View File

@ -39,7 +39,7 @@ libloading = "0.7"
[dev-dependencies] [dev-dependencies]
colored = "2" colored = "2"
ui_test = "0.6.2" ui_test = "0.9"
rustc_version = "0.4" rustc_version = "0.4"
# Features chosen to match those required by env_logger, to avoid rebuilds # Features chosen to match those required by env_logger, to avoid rebuilds
regex = { version = "1.5.5", default-features = false, features = ["perf", "std"] } regex = { version = "1.5.5", default-features = false, features = ["perf", "std"] }

View File

@ -2,6 +2,8 @@ use colored::*;
use regex::bytes::Regex; use regex::bytes::Regex;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::{env, process::Command}; use std::{env, process::Command};
use ui_test::status_emitter::StatusEmitter;
use ui_test::CommandBuilder;
use ui_test::{color_eyre::Result, Config, Match, Mode, OutputConflictHandling}; use ui_test::{color_eyre::Result, Config, Match, Mode, OutputConflictHandling};
fn miri_path() -> PathBuf { fn miri_path() -> PathBuf {
@ -44,17 +46,9 @@ fn build_so_for_c_ffi_tests() -> PathBuf {
} }
fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> Result<()> { fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> Result<()> {
let mut config = Config { // Miri is rustc-like, so we create a default builder for rustc and modify it
target: Some(target.to_owned()), let mut program = CommandBuilder::rustc();
stderr_filters: STDERR.clone(), program.program = miri_path();
stdout_filters: STDOUT.clone(),
root_dir: PathBuf::from(path),
mode,
program: miri_path(),
quiet: false,
edition: Some("2021".into()),
..Config::default()
};
let in_rustc_test_suite = option_env!("RUSTC_STAGE").is_some(); let in_rustc_test_suite = option_env!("RUSTC_STAGE").is_some();
@ -62,22 +56,20 @@ fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> R
if in_rustc_test_suite { if in_rustc_test_suite {
// Less aggressive warnings to make the rustc toolstate management less painful. // 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.) // (We often get warnings when e.g. a feature gets stabilized or some lint gets added/improved.)
config.args.push("-Astable-features".into()); program.args.push("-Astable-features".into());
config.args.push("-Aunused".into()); program.args.push("-Aunused".into());
} else { } else {
config.args.push("-Dwarnings".into()); program.args.push("-Dwarnings".into());
config.args.push("-Dunused".into()); program.args.push("-Dunused".into());
} }
if let Ok(extra_flags) = env::var("MIRIFLAGS") { if let Ok(extra_flags) = env::var("MIRIFLAGS") {
for flag in extra_flags.split_whitespace() { for flag in extra_flags.split_whitespace() {
config.args.push(flag.into()); program.args.push(flag.into());
} }
} }
config.args.push("-Zui-testing".into()); program.args.push("-Zui-testing".into());
if let Some(target) = &config.target { program.args.push("--target".into());
config.args.push("--target".into()); program.args.push(target.into());
config.args.push(target.into());
}
// If we're on linux, and we're testing the extern-so functionality, // If we're on linux, and we're testing the extern-so functionality,
// then build the shared object file for testing external C function calls // then build the shared object file for testing external C function calls
@ -86,18 +78,31 @@ fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> R
let so_file_path = build_so_for_c_ffi_tests(); let so_file_path = build_so_for_c_ffi_tests();
let mut flag = std::ffi::OsString::from("-Zmiri-extern-so-file="); let mut flag = std::ffi::OsString::from("-Zmiri-extern-so-file=");
flag.push(so_file_path.into_os_string()); flag.push(so_file_path.into_os_string());
config.args.push(flag); program.args.push(flag);
} }
let skip_ui_checks = env::var_os("MIRI_SKIP_UI_CHECKS").is_some(); let skip_ui_checks = env::var_os("MIRI_SKIP_UI_CHECKS").is_some();
config.output_conflict_handling = match (env::var_os("MIRI_BLESS").is_some(), skip_ui_checks) { let output_conflict_handling = match (env::var_os("MIRI_BLESS").is_some(), skip_ui_checks) {
(false, false) => OutputConflictHandling::Error, (false, false) => OutputConflictHandling::Error,
(true, false) => OutputConflictHandling::Bless, (true, false) => OutputConflictHandling::Bless,
(false, true) => OutputConflictHandling::Ignore, (false, true) => OutputConflictHandling::Ignore,
(true, true) => panic!("cannot use MIRI_BLESS and MIRI_SKIP_UI_CHECKS at the same time"), (true, true) => panic!("cannot use MIRI_BLESS and MIRI_SKIP_UI_CHECKS at the same time"),
}; };
let mut config = Config {
target: Some(target.to_owned()),
stderr_filters: STDERR.clone(),
stdout_filters: STDOUT.clone(),
root_dir: PathBuf::from(path),
mode,
program,
output_conflict_handling,
quiet: false,
edition: Some("2021".into()),
..Config::default()
};
// Handle command-line arguments. // Handle command-line arguments.
let mut after_dashdash = false; let mut after_dashdash = false;
config.path_filter.extend(std::env::args().skip(1).filter(|arg| { config.path_filter.extend(std::env::args().skip(1).filter(|arg| {
@ -135,7 +140,14 @@ fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> R
"run".into(), // There is no `cargo miri build` so we just use `cargo miri run`. "run".into(), // There is no `cargo miri build` so we just use `cargo miri run`.
]; ];
} }
ui_test::run_tests(config) ui_test::run_tests_generic(
config,
// The files we're actually interested in (all `.rs` files).
|path| path.extension().is_some_and(|ext| ext == "rs"),
// This could be used to overwrite the `Config` on a per-test basis.
|_, _| None,
TextAndGha,
)
} }
macro_rules! regexes { macro_rules! regexes {
@ -235,3 +247,45 @@ fn main() -> Result<()> {
Ok(()) Ok(())
} }
/// This is a custom renderer for `ui_test` output that does not emit github actions
/// `group`s, while still producing regular github actions messages on test failures.
struct TextAndGha;
impl StatusEmitter for TextAndGha {
fn failed_test<'a>(
&'a self,
revision: &'a str,
path: &'a Path,
cmd: &'a Command,
stderr: &'a [u8],
) -> Box<dyn std::fmt::Debug + 'a> {
Box::new((
ui_test::status_emitter::Gha::<false>.failed_test(revision, path, cmd, stderr),
ui_test::status_emitter::Text.failed_test(revision, path, cmd, stderr),
))
}
fn run_tests(&self, _config: &Config) -> Box<dyn ui_test::status_emitter::DuringTestRun> {
Box::new(TextAndGha)
}
fn finalize(
&self,
failures: usize,
succeeded: usize,
ignored: usize,
filtered: usize,
) -> Box<dyn ui_test::status_emitter::Summary> {
Box::new((
ui_test::status_emitter::Gha::<false>.finalize(failures, succeeded, ignored, filtered),
ui_test::status_emitter::Text.finalize(failures, succeeded, ignored, filtered),
))
}
}
impl ui_test::status_emitter::DuringTestRun for TextAndGha {
fn test_result(&mut self, path: &Path, revision: &str, result: &ui_test::TestResult) {
ui_test::status_emitter::Text.test_result(path, revision, result);
ui_test::status_emitter::Gha::<false>.test_result(path, revision, result);
}
}

View File

@ -1,6 +1,6 @@
use std::alloc::{alloc, dealloc, Layout}; use std::alloc::{alloc, dealloc, Layout};
//@error-pattern: has size 1 and alignment 1, but gave size 1 and alignment 2 //@error-in-other-file: has size 1 and alignment 1, but gave size 1 and alignment 2
fn main() { fn main() {
unsafe { unsafe {

View File

@ -1,6 +1,6 @@
use std::alloc::{alloc, dealloc, Layout}; use std::alloc::{alloc, dealloc, Layout};
//@error-pattern: has size 1 and alignment 1, but gave size 2 and alignment 1 //@error-in-other-file: has size 1 and alignment 1, but gave size 2 and alignment 1
fn main() { fn main() {
unsafe { unsafe {

View File

@ -1,6 +1,6 @@
use std::alloc::{alloc, dealloc, Layout}; use std::alloc::{alloc, dealloc, Layout};
//@error-pattern: dereferenced after this allocation got freed //@error-in-other-file: dereferenced after this allocation got freed
fn main() { fn main() {
unsafe { unsafe {

View File

@ -1,6 +1,6 @@
// Make sure we detect when the `Global` and `System` allocators are mixed // Make sure we detect when the `Global` and `System` allocators are mixed
// (even when the default `Global` uses `System`). // (even when the default `Global` uses `System`).
//@error-pattern: /deallocating .*, which is Rust heap memory, using .* heap deallocation operation/ //@error-in-other-file: /deallocating .*, which is Rust heap memory, using .* heap deallocation operation/
//@normalize-stderr-test: "using [A-Za-z]+ heap deallocation operation" -> "using PLATFORM heap deallocation operation" //@normalize-stderr-test: "using [A-Za-z]+ heap deallocation operation" -> "using PLATFORM heap deallocation operation"
//@normalize-stderr-test: "\| +\^+" -> "| ^" //@normalize-stderr-test: "\| +\^+" -> "| ^"

View File

@ -1,6 +1,6 @@
use std::alloc::{alloc, realloc, Layout}; use std::alloc::{alloc, realloc, Layout};
//@error-pattern: has size 1 and alignment 1, but gave size 2 and alignment 1 //@error-in-other-file: has size 1 and alignment 1, but gave size 2 and alignment 1
fn main() { fn main() {
unsafe { unsafe {

View File

@ -1,6 +1,6 @@
use std::alloc::{alloc, dealloc, realloc, Layout}; use std::alloc::{alloc, dealloc, realloc, Layout};
//@error-pattern: dereferenced after this allocation got freed //@error-in-other-file: dereferenced after this allocation got freed
fn main() { fn main() {
unsafe { unsafe {

View File

@ -1,7 +1,7 @@
// Validation/SB changes why we fail // Validation/SB changes why we fail
//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows //@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows
//@error-pattern: /deallocating .*, which is stack variable memory, using Rust heap deallocation operation/ //@error-in-other-file: /deallocating .*, which is stack variable memory, using Rust heap deallocation operation/
fn main() { fn main() {
let x = 42; let x = 42;

View File

@ -1,5 +1,5 @@
//@ignore-target-windows: No libc on Windows //@ignore-target-windows: No libc on Windows
//@error-pattern: the main thread terminated without waiting for all remaining threads //@error-in-other-file: the main thread terminated without waiting for all remaining threads
// Check that we terminate the program when the main thread terminates. // Check that we terminate the program when the main thread terminates.

View File

@ -1,5 +1,5 @@
//@only-target-windows: Uses win32 api functions //@only-target-windows: Uses win32 api functions
//@error-pattern: Undefined Behavior: trying to join a detached thread //@error-in-other-file: Undefined Behavior: trying to join a detached thread
// Joining a detached thread is undefined behavior. // Joining a detached thread is undefined behavior.

View File

@ -1,4 +1,4 @@
//@error-pattern: miri cannot be run on programs that fail compilation //@error-in-other-file: miri cannot be run on programs that fail compilation
#![deny(warnings)] #![deny(warnings)]

View File

@ -1,4 +1,4 @@
//@error-pattern: cannot be represented in target type `i32` //@error-in-other-file: cannot be represented in target type `i32`
#![feature(portable_simd)] #![feature(portable_simd)]
use std::simd::*; use std::simd::*;

View File

@ -1,4 +1,4 @@
//@error-pattern: pointer to 1 byte starting at offset 9 is out-of-bounds //@error-in-other-file: pointer to 1 byte starting at offset 9 is out-of-bounds
#![feature(portable_simd)] #![feature(portable_simd)]
use std::simd::*; use std::simd::*;

View File

@ -1,4 +1,4 @@
//@error-pattern: pointer to 1 byte starting at offset 9 is out-of-bounds //@error-in-other-file: pointer to 1 byte starting at offset 9 is out-of-bounds
#![feature(portable_simd)] #![feature(portable_simd)]
use std::simd::*; use std::simd::*;

View File

@ -1,4 +1,4 @@
//@error-pattern: a cycle occurred during layout computation //@error-in-other-file: a cycle occurred during layout computation
//~^ ERROR: cycle detected when computing layout of //~^ ERROR: cycle detected when computing layout of
use std::mem; use std::mem;

View File

@ -1,4 +1,4 @@
//@error-pattern: memory leaked //@error-in-other-file: memory leaked
//@normalize-stderr-test: ".*│.*" -> "$$stripped$$" //@normalize-stderr-test: ".*│.*" -> "$$stripped$$"
fn main() { fn main() {

View File

@ -1,5 +1,5 @@
//@compile-flags: -Zmiri-disable-leak-backtraces //@compile-flags: -Zmiri-disable-leak-backtraces
//@error-pattern: the evaluated program leaked memory //@error-in-other-file: the evaluated program leaked memory
//@normalize-stderr-test: ".*│.*" -> "$$stripped$$" //@normalize-stderr-test: ".*│.*" -> "$$stripped$$"
fn main() { fn main() {

View File

@ -1,4 +1,4 @@
//@error-pattern: memory leaked //@error-in-other-file: memory leaked
//@stderr-per-bitwidth //@stderr-per-bitwidth
//@normalize-stderr-test: ".*│.*" -> "$$stripped$$" //@normalize-stderr-test: ".*│.*" -> "$$stripped$$"

View File

@ -1,2 +1,2 @@
//@error-pattern: miri can only run programs that have a main function //@error-in-other-file: miri can only run programs that have a main function
#![no_main] #![no_main]

View File

@ -1,4 +1,4 @@
//@error-pattern: the program aborted //@error-in-other-file: the program aborted
//@normalize-stderr-test: "\| +\^+" -> "| ^" //@normalize-stderr-test: "\| +\^+" -> "| ^"
//@normalize-stderr-test: "unsafe \{ libc::abort\(\) \}|crate::intrinsics::abort\(\);" -> "ABORT();" //@normalize-stderr-test: "unsafe \{ libc::abort\(\) \}|crate::intrinsics::abort\(\);" -> "ABORT();"
//@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "$1" //@normalize-stderr-test: "\n +[0-9]+:[^\n]+" -> "$1"

View File

@ -1,4 +1,4 @@
//@error-pattern: the program aborted execution //@error-in-other-file: the program aborted execution
//@normalize-stderr-test: "\| +\^+" -> "| ^" //@normalize-stderr-test: "\| +\^+" -> "| ^"
//@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();" //@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();"
//@compile-flags: -C panic=abort //@compile-flags: -C panic=abort

View File

@ -1,4 +1,4 @@
//@error-pattern: the program aborted execution //@error-in-other-file: the program aborted execution
//@normalize-stderr-test: "\| +\^+" -> "| ^" //@normalize-stderr-test: "\| +\^+" -> "| ^"
//@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();" //@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();"
//@compile-flags: -C panic=abort //@compile-flags: -C panic=abort

View File

@ -1,4 +1,4 @@
//@error-pattern: the program aborted execution //@error-in-other-file: the program aborted execution
//@normalize-stderr-test: "\| +\^+" -> "| ^" //@normalize-stderr-test: "\| +\^+" -> "| ^"
//@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();" //@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();"
//@compile-flags: -C panic=abort //@compile-flags: -C panic=abort

View File

@ -1,4 +1,4 @@
//@error-pattern: the program aborted execution //@error-in-other-file: the program aborted execution
//@normalize-stderr-test: "\| +\^+" -> "| ^" //@normalize-stderr-test: "\| +\^+" -> "| ^"
//@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();" //@normalize-stderr-test: "libc::abort\(\);|core::intrinsics::abort\(\);" -> "ABORT();"
//@compile-flags: -C panic=abort //@compile-flags: -C panic=abort

View File

@ -1,5 +1,5 @@
//@ignore-target-windows: File handling is not implemented yet //@ignore-target-windows: File handling is not implemented yet
//@error-pattern: `open` not available when isolation is enabled //@error-in-other-file: `open` not available when isolation is enabled
fn main() { fn main() {
let _file = std::fs::File::open("file.txt").unwrap(); let _file = std::fs::File::open("file.txt").unwrap();

View File

@ -1,4 +1,4 @@
//@error-pattern: /deallocating while item \[Unique for .*\] is strongly protected/ //@error-in-other-file: /deallocating while item \[Unique for .*\] is strongly protected/
fn inner(x: &mut i32, f: fn(&mut i32)) { fn inner(x: &mut i32, f: fn(&mut i32)) {
// `f` may mutate, but it may not deallocate! // `f` may mutate, but it may not deallocate!

View File

@ -1,7 +1,7 @@
//! Test that drop_in_place mutably retags the entire place, even for a type that does not need //! Test that drop_in_place mutably retags the entire place, even for a type that does not need
//! dropping, ensuring among other things that it is writeable //! dropping, ensuring among other things that it is writeable
//@error-pattern: /retag .* for Unique permission .* only grants SharedReadOnly permission/ //@error-in-other-file: /retag .* for Unique permission .* only grants SharedReadOnly permission/
fn main() { fn main() {
unsafe { unsafe {

View File

@ -1,4 +1,4 @@
//@error-pattern: /deallocation .* tag does not exist in the borrow stack/ //@error-in-other-file: /deallocation .* tag does not exist in the borrow stack/
use std::alloc::{alloc, dealloc, Layout}; use std::alloc::{alloc, dealloc, Layout};
fn main() { fn main() {

View File

@ -1,4 +1,4 @@
//@error-pattern: pointer to 4 bytes starting at offset 0 is out-of-bounds //@error-in-other-file: pointer to 4 bytes starting at offset 0 is out-of-bounds
fn main() { fn main() {
unsafe { unsafe {

View File

@ -1,4 +1,4 @@
//@error-pattern: is a dangling pointer //@error-in-other-file: is a dangling pointer
use std::ptr::NonNull; use std::ptr::NonNull;
fn main() { fn main() {

View File

@ -1,4 +1,4 @@
//@error-pattern: which is strongly protected //@error-in-other-file: which is strongly protected
struct Newtype<'a>(&'a mut i32, i32); struct Newtype<'a>(&'a mut i32, i32);
fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) { fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) {

View File

@ -1,4 +1,4 @@
//@error-pattern: which is strongly protected //@error-in-other-file: which is strongly protected
struct Newtype<'a>(&'a mut i32); struct Newtype<'a>(&'a mut i32);
fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) { fn dealloc_while_running(_n: Newtype<'_>, dealloc: impl FnOnce()) {

View File

@ -1,5 +1,5 @@
//@compile-flags: -Zmiri-strict-provenance //@compile-flags: -Zmiri-strict-provenance
//@error-pattern: /retag .* tag does not exist in the borrow stack/ //@error-in-other-file: /retag .* tag does not exist in the borrow stack/
fn main() { fn main() {
unsafe { unsafe {

View File

@ -1,6 +1,6 @@
//@compile-flags: -Zmiri-permissive-provenance -Zmiri-backtrace=full //@compile-flags: -Zmiri-permissive-provenance -Zmiri-backtrace=full
//@only-target-x86_64-unknown-linux: support for tokio only on linux and x86 //@only-target-x86_64-unknown-linux: support for tokio only on linux and x86
//@error-pattern: returning ready events from epoll_wait is not yet implemented //@error-in-other-file: returning ready events from epoll_wait is not yet implemented
//@normalize-stderr-test: " += note:.*\n" -> "" //@normalize-stderr-test: " += note:.*\n" -> ""
use tokio::time::{sleep, Duration, Instant}; use tokio::time::{sleep, Duration, Instant};

View File

@ -1,5 +1,5 @@
//@compile-flags: -Zmiri-tree-borrows //@compile-flags: -Zmiri-tree-borrows
//@error-pattern: /deallocation through .* is forbidden/ //@error-in-other-file: /deallocation through .* is forbidden/
fn inner(x: &mut i32, f: fn(&mut i32)) { fn inner(x: &mut i32, f: fn(&mut i32)) {
// `f` may mutate, but it may not deallocate! // `f` may mutate, but it may not deallocate!

View File

@ -13,7 +13,7 @@ struct PartialDrop {
b: u8, b: u8,
} }
//@error-pattern: /alignment 2 is required/ //@error-in-other-file: /alignment 2 is required/
fn main() { fn main() {
unsafe { unsafe {
// Create an unaligned pointer // Create an unaligned pointer

View File

@ -1,4 +1,4 @@
//@error-pattern: memory is uninitialized at [0x4..0x10] //@error-in-other-file: memory is uninitialized at [0x4..0x10]
use std::alloc::{alloc, dealloc, Layout}; use std::alloc::{alloc, dealloc, Layout};
use std::slice::from_raw_parts; use std::slice::from_raw_parts;

View File

@ -1,4 +1,4 @@
//@error-pattern: memory is uninitialized at [0x4..0x8] //@error-in-other-file: memory is uninitialized at [0x4..0x8]
//@normalize-stderr-test: "a[0-9]+" -> "ALLOC" //@normalize-stderr-test: "a[0-9]+" -> "ALLOC"
#![feature(strict_provenance)] #![feature(strict_provenance)]