Skip to content

Commit 3cb12b4

Browse files
authored
Merge pull request #283 from oli-obk/miri
Various changes needed for miri
2 parents 71a3fa8 + d84336e commit 3cb12b4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1658
-1297
lines changed

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313

1414
### Changed
1515

16+
## [0.27.0] - 2024-10-07
17+
18+
### Added
19+
20+
* debug status emitter for when you have problems with ui_test
21+
* cargo features to disable gha or CLI refreshing
22+
23+
### Fixed
24+
25+
* CLI refreshing is now reliable and not leaving around fragments
26+
* Can run multiple `Config`s that test the same files in parallel.
27+
28+
### Changed
29+
1630
* `only`/`ignore` filters now only accept integers, alphabetic characters, `-` and `_`
1731
* `only`/ `ignore` filters allow comments by ignoring everything from an `#` onwards
32+
* `OutputConflictHandling` has been replaced by `error_on_output_conflict`, `bless_output_files`,
33+
and `ignore_output_conflict` functions. Custom functions can now be used to implement special
34+
handling of output conflicts.
35+
* `Run` now forwards env vars passed to the compiler to the executable, too
1836

1937
### Removed
2038

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ui_test"
3-
version = "0.26.5"
3+
version = "0.27.0"
44
edition = "2021"
55
license = "MIT OR Apache-2.0"
66
description = "A test framework for testing rustc diagnostics output"
@@ -23,7 +23,7 @@ rustfix = "0.8.1"
2323
cargo-platform = { version = "0.1.2", optional = true }
2424
comma = "1.0.0"
2525
anyhow = "1.0.6"
26-
indicatif = "0.17.6"
26+
indicatif = { version = "0.17.6", optional = true }
2727
prettydiff = { version = "0.7", default-features = false }
2828
annotate-snippets = { version = "0.11.2" }
2929
levenshtein = "1.0.5"
@@ -52,5 +52,6 @@ name = "build_std"
5252
test = false
5353

5454
[features]
55-
default = ["rustc"]
55+
default = ["rustc", "indicatif", "gha"]
56+
gha = []
5657
rustc = ["dep:cargo-platform", "dep:cargo_metadata"]

examples/rustc_basic.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::sync::atomic::Ordering;
44
use ui_test::{run_tests, Config};
55

66
#[cfg(feature = "rustc")]
7+
#[cfg_attr(test, test)]
78
fn main() -> ui_test::color_eyre::Result<()> {
89
let config = Config::rustc("examples_tests/rustc_basic");
910
let abort_check = config.abort_check.clone();
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#[cfg(feature = "rustc")]
2+
use std::sync::atomic::Ordering;
3+
#[cfg(feature = "rustc")]
4+
use ui_test::{
5+
default_file_filter, default_per_file_config, run_tests_generic, status_emitter, Config,
6+
};
7+
8+
#[cfg(feature = "rustc")]
9+
#[cfg_attr(test, test)]
10+
fn main() -> ui_test::color_eyre::Result<()> {
11+
let config = Config::rustc("examples_tests/rustc_basic");
12+
let abort_check = config.abort_check.clone();
13+
ctrlc::set_handler(move || abort_check.store(true, Ordering::Relaxed))?;
14+
15+
// Compile all `.rs` files in the given directory (relative to your
16+
// Cargo.toml) and compare their output against the corresponding
17+
// `.stderr` files.
18+
run_tests_generic(
19+
vec![config.clone(), config],
20+
default_file_filter,
21+
default_per_file_config,
22+
status_emitter::Text::verbose(),
23+
)
24+
}
25+
26+
#[cfg(not(feature = "rustc"))]
27+
fn main() -> ui_test::color_eyre::Result<()> {
28+
Ok(())
29+
}

examples_tests/rustc_basic/aux_derive.stderr

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ error[E0384]: cannot assign twice to immutable variable `x`
2020
--> examples_tests/rustc_basic/aux_derive.rs:8:5
2121
|
2222
7 | let x = Foo;
23-
| -
24-
| |
25-
| first assignment to `x`
26-
| help: consider making this binding mutable: `mut x`
23+
| - first assignment to `x`
2724
8 | x = Foo;
2825
| ^^^^^^^ cannot assign twice to immutable variable
26+
|
27+
help: consider making this binding mutable
28+
|
29+
7 | let mut x = Foo;
30+
| +++
2931

3032
error: aborting due to 1 previous error; 2 warnings emitted
3133

examples_tests/rustc_basic/executable.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//@run
2+
//@revisions: a b c d e f g h i j k l m n
23

34
fn main() {
45
std::thread::sleep(std::time::Duration::from_secs(5));

examples_tests/rustc_basic/filtered_out.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//@[foo] only-target-asdfasdf
1+
//@[foo] only-target: asdfasdf
22

33
//@ revisions: foo bar
44

src/aux_builds.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
//! Everything needed to build auxilary files with rustc
22
// lol we can't name this file `aux.rs` on windows
33

4-
use bstr::ByteSlice;
5-
use spanned::Spanned;
6-
use std::{ffi::OsString, path::PathBuf, process::Command, sync::Arc};
7-
84
use crate::{
95
build_manager::{Build, BuildManager},
106
custom_flags::Flag,
@@ -13,6 +9,9 @@ use crate::{
139
status_emitter::SilentStatus,
1410
CrateType, Error, Errored,
1511
};
12+
use bstr::ByteSlice;
13+
use spanned::Spanned;
14+
use std::{ffi::OsString, path::PathBuf, process::Command, sync::Arc};
1615

1716
impl Flag for AuxBuilder {
1817
fn must_be_unique(&self) -> bool {

src/build_manager.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
//! Auxiliary and dependency builder. Extendable to custom builds.
22
3-
use std::{
4-
collections::{hash_map::Entry, HashMap},
5-
ffi::OsString,
6-
sync::{Arc, OnceLock, RwLock},
7-
};
8-
9-
use color_eyre::eyre::Result;
10-
use crossbeam_channel::{bounded, Sender};
11-
123
use crate::{
134
status_emitter::{RevisionStyle, TestStatus},
145
test_result::TestRun,
156
Config, Errored,
167
};
8+
use color_eyre::eyre::Result;
9+
use crossbeam_channel::{bounded, Sender};
10+
use std::{
11+
collections::{hash_map::Entry, HashMap},
12+
ffi::OsString,
13+
sync::{Arc, OnceLock, RwLock},
14+
};
1715

1816
/// A build shared between all tests of the same `BuildManager`
1917
pub trait Build {

src/cmd.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1+
use crate::display;
12
use std::{
23
ffi::OsString,
34
path::{Path, PathBuf},
45
process::Command,
56
};
67

7-
use crate::display;
8-
98
#[derive(Debug, Clone)]
109
/// A command, its args and its environment. Used for
1110
/// the main command, the dependency builder and the cfg-reader.

src/config.rs

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
use regex::bytes::Regex;
2-
use spanned::Spanned;
3-
41
#[cfg(feature = "rustc")]
52
use crate::{
63
aux_builds::AuxBuilder, custom_flags::run::Run, custom_flags::rustfix::RustfixMode,
@@ -10,10 +7,12 @@ use crate::{
107
diagnostics::Diagnostics,
118
parser::CommandParserFunc,
129
per_test_config::{Comments, Condition},
13-
CommandBuilder,
10+
CommandBuilder, Error, Errors,
1411
};
1512
pub use color_eyre;
1613
use color_eyre::eyre::Result;
14+
use regex::bytes::Regex;
15+
use spanned::Spanned;
1716
use std::{
1817
collections::BTreeMap,
1918
num::NonZeroUsize,
@@ -40,7 +39,7 @@ pub struct Config {
4039
/// The recommended command to bless failing tests.
4140
pub bless_command: Option<String>,
4241
/// Where to dump files like the binaries compiled from tests.
43-
/// Defaults to `target/ui` in the current directory.
42+
/// Defaults to `target/ui/index_of_config` in the current directory.
4443
pub out_dir: PathBuf,
4544
/// Skip test files whose names contain any of these entries.
4645
pub skip_files: Vec<String>,
@@ -68,6 +67,9 @@ pub struct Config {
6867
pub abort_check: Arc<AtomicBool>,
6968
}
7069

70+
/// Function that performs the actual output conflict handling.
71+
pub type OutputConflictHandling = fn(&Path, Vec<u8>, &mut Errors, &Config);
72+
7173
impl Config {
7274
/// Create a blank configuration that doesn't do anything interesting
7375
pub fn dummy() -> Self {
@@ -78,7 +80,7 @@ impl Config {
7880
target: Default::default(),
7981
root_dir: Default::default(),
8082
program: CommandBuilder::cmd(""),
81-
output_conflict_handling: OutputConflictHandling::Error,
83+
output_conflict_handling: error_on_output_conflict,
8284
bless_command: Default::default(),
8385
out_dir: Default::default(),
8486
skip_files: Default::default(),
@@ -117,7 +119,12 @@ impl Config {
117119
fn clone_inner(&self) -> Box<dyn Flag> {
118120
Box::new(NeedsAsmSupport)
119121
}
120-
fn test_condition(&self, config: &Config) -> bool {
122+
fn test_condition(
123+
&self,
124+
config: &Config,
125+
_comments: &Comments,
126+
_revision: &str,
127+
) -> bool {
121128
let target = config.target.as_ref().unwrap();
122129
static ASM_SUPPORTED_ARCHS: &[&str] = &[
123130
"x86", "x86_64", "arm", "aarch64", "riscv32",
@@ -154,7 +161,7 @@ impl Config {
154161
target: None,
155162
root_dir: root_dir.into(),
156163
program: CommandBuilder::rustc(),
157-
output_conflict_handling: OutputConflictHandling::Error,
164+
output_conflict_handling: error_on_output_conflict,
158165
bless_command: None,
159166
out_dir: std::env::var_os("CARGO_TARGET_DIR")
160167
.map(PathBuf::from)
@@ -194,7 +201,14 @@ impl Config {
194201

195202
config.custom_comments.insert("run", |parser, args, span| {
196203
let set = |exit_code| {
197-
parser.set_custom_once("run", Run { exit_code }, args.span());
204+
parser.set_custom_once(
205+
"run",
206+
Run {
207+
exit_code,
208+
output_conflict_handling: None,
209+
},
210+
args.span(),
211+
);
198212
parser.exit_status = Spanned::new(0, span.clone()).into();
199213
parser.require_annotations = Spanned::new(false, span.clone()).into();
200214

@@ -268,9 +282,9 @@ impl Config {
268282
self.list = list;
269283

270284
if check {
271-
self.output_conflict_handling = OutputConflictHandling::Error;
285+
self.output_conflict_handling = error_on_output_conflict;
272286
} else if bless {
273-
self.output_conflict_handling = OutputConflictHandling::Bless;
287+
self.output_conflict_handling = bless_output_files;
274288
}
275289
}
276290

@@ -411,9 +425,12 @@ impl Config {
411425
return self.run_only_ignored;
412426
}
413427
if comments.for_revision(revision).any(|r| {
414-
r.custom
415-
.values()
416-
.any(|flags| flags.content.iter().any(|flag| flag.test_condition(self)))
428+
r.custom.values().any(|flags| {
429+
flags
430+
.content
431+
.iter()
432+
.any(|flag| flag.test_condition(self, comments, revision))
433+
})
417434
}) {
418435
return self.run_only_ignored;
419436
}
@@ -429,16 +446,41 @@ impl Config {
429446
}
430447
}
431448

432-
#[derive(Debug, Clone)]
433-
/// The different options for what to do when stdout/stderr files differ from the actual output.
434-
pub enum OutputConflictHandling {
435-
/// Fail the test when mismatches are found, if provided the command string
436-
/// in [`Config::bless_command`] will be suggested as a way to bless the
437-
/// test.
438-
Error,
439-
/// Ignore mismatches in the stderr/stdout files.
440-
Ignore,
441-
/// Instead of erroring if the stderr/stdout differs from the expected
442-
/// automatically replace it with the found output (after applying filters).
443-
Bless,
449+
/// Fail the test when mismatches are found, if provided the command string
450+
/// in [`Config::bless_command`] will be suggested as a way to bless the
451+
/// test.
452+
pub fn error_on_output_conflict(
453+
path: &Path,
454+
actual: Vec<u8>,
455+
errors: &mut Errors,
456+
config: &Config,
457+
) {
458+
let expected = std::fs::read(path).unwrap_or_default();
459+
if actual != expected {
460+
errors.push(Error::OutputDiffers {
461+
path: path.to_path_buf(),
462+
actual,
463+
expected,
464+
bless_command: config.bless_command.clone(),
465+
});
466+
}
467+
}
468+
469+
/// Ignore mismatches in the stderr/stdout files.
470+
pub fn ignore_output_conflict(
471+
_path: &Path,
472+
_actual: Vec<u8>,
473+
_errors: &mut Errors,
474+
_config: &Config,
475+
) {
476+
}
477+
478+
/// Instead of erroring if the stderr/stdout differs from the expected
479+
/// automatically replace it with the found output (after applying filters).
480+
pub fn bless_output_files(path: &Path, actual: Vec<u8>, _errors: &mut Errors, _config: &Config) {
481+
if actual.is_empty() {
482+
let _ = std::fs::remove_file(path);
483+
} else {
484+
std::fs::write(path, &actual).unwrap();
485+
}
444486
}

src/config/args.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
//! Default argument processing when `ui_test` is used
22
//! as a test driver.
33
4-
use std::{borrow::Cow, num::NonZeroUsize};
5-
64
use color_eyre::eyre::{bail, ensure, Result};
5+
use std::{borrow::Cow, num::NonZeroUsize};
76

87
/// Plain arguments if `ui_test` is used as a binary.
98
#[derive(Debug, Default)]

src/custom_flags.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
//! Define custom test flags not natively supported by ui_test
22
3+
use crate::{
4+
build_manager::BuildManager, parser::Comments, per_test_config::TestConfig, Config, Errored,
5+
};
36
use std::{
47
panic::{RefUnwindSafe, UnwindSafe},
58
process::{Command, Output},
69
};
710

8-
use crate::{build_manager::BuildManager, per_test_config::TestConfig, Config, Errored};
9-
1011
#[cfg(feature = "rustc")]
1112
pub mod edition;
1213
#[cfg(feature = "rustc")]
@@ -29,7 +30,7 @@ pub trait Flag: Send + Sync + UnwindSafe + RefUnwindSafe + std::fmt::Debug {
2930
}
3031

3132
/// Whether this flag causes a test to be filtered out
32-
fn test_condition(&self, _config: &Config) -> bool {
33+
fn test_condition(&self, _config: &Config, _comments: &Comments, _revision: &str) -> bool {
3334
false
3435
}
3536

0 commit comments

Comments
 (0)