Skip to content

Commit caeebd6

Browse files
committed
Auto merge of rust-lang#8374 - Alexendoo:bless-revisions, r=camsteffen
Support `cargo dev bless` for tests with revisions changelog: internal: Support `cargo dev bless` for tests with revisions Previously bless wouldn't pick up the saved stderr from `target/debug/tests/manual_assert.stage-id.edition2021.stderr` or `target/debug/tests/manual_assert.stage-id.edition2018.stderr` due to there being multiple revisions of the test output This tweaks compile-test so the built files end up in e.g. `target/debug/tests/ui`, `target/debug/tests/ui-cargo` rather than share the `tests` dir. `cargo dev bless` then uses that to update all the `.stdout/stdout/fixed` files it can find Also removes an empty file I found, and the logic to remove empty outputs as compiletest doesn't produce empty `.stdout/stderr` files
2 parents 2590701 + 04dce4a commit caeebd6

File tree

3 files changed

+56
-90
lines changed

3 files changed

+56
-90
lines changed

clippy_dev/src/bless.rs

+18-47
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ use std::ffi::OsStr;
55
use std::fs;
66
use std::lazy::SyncLazy;
77
use std::path::{Path, PathBuf};
8-
use walkdir::WalkDir;
9-
10-
use crate::clippy_project_root;
8+
use walkdir::{DirEntry, WalkDir};
119

1210
#[cfg(not(windows))]
1311
static CARGO_CLIPPY_EXE: &str = "cargo-clippy";
@@ -24,43 +22,25 @@ static CLIPPY_BUILD_TIME: SyncLazy<Option<std::time::SystemTime>> = SyncLazy::ne
2422
///
2523
/// Panics if the path to a test file is broken
2624
pub fn bless(ignore_timestamp: bool) {
27-
let test_suite_dirs = [
28-
clippy_project_root().join("tests").join("ui"),
29-
clippy_project_root().join("tests").join("ui-internal"),
30-
clippy_project_root().join("tests").join("ui-toml"),
31-
clippy_project_root().join("tests").join("ui-cargo"),
32-
];
33-
for test_suite_dir in &test_suite_dirs {
34-
WalkDir::new(test_suite_dir)
35-
.into_iter()
36-
.filter_map(Result::ok)
37-
.filter(|f| f.path().extension() == Some(OsStr::new("rs")))
38-
.for_each(|f| {
39-
let test_name = f.path().strip_prefix(test_suite_dir).unwrap();
40-
for &ext in &["stdout", "stderr", "fixed"] {
41-
let test_name_ext = format!("stage-id.{}", ext);
42-
update_reference_file(
43-
f.path().with_extension(ext),
44-
test_name.with_extension(test_name_ext),
45-
ignore_timestamp,
46-
);
47-
}
48-
});
49-
}
25+
let extensions = ["stdout", "stderr", "fixed"].map(OsStr::new);
26+
27+
WalkDir::new(build_dir())
28+
.into_iter()
29+
.map(Result::unwrap)
30+
.filter(|entry| entry.path().extension().map_or(false, |ext| extensions.contains(&ext)))
31+
.for_each(|entry| update_reference_file(&entry, ignore_timestamp));
5032
}
5133

52-
fn update_reference_file(reference_file_path: PathBuf, test_name: PathBuf, ignore_timestamp: bool) {
53-
let test_output_path = build_dir().join(test_name);
54-
let relative_reference_file_path = reference_file_path.strip_prefix(clippy_project_root()).unwrap();
34+
fn update_reference_file(test_output_entry: &DirEntry, ignore_timestamp: bool) {
35+
let test_output_path = test_output_entry.path();
5536

56-
// If compiletest did not write any changes during the test run,
57-
// we don't have to update anything
58-
if !test_output_path.exists() {
59-
return;
60-
}
37+
let reference_file_name = test_output_entry.file_name().to_str().unwrap().replace(".stage-id", "");
38+
let reference_file_path = Path::new("tests")
39+
.join(test_output_path.strip_prefix(build_dir()).unwrap())
40+
.with_file_name(reference_file_name);
6141

6242
// If the test output was not updated since the last clippy build, it may be outdated
63-
if !ignore_timestamp && !updated_since_clippy_build(&test_output_path).unwrap_or(true) {
43+
if !ignore_timestamp && !updated_since_clippy_build(test_output_entry).unwrap_or(true) {
6444
return;
6545
}
6646

@@ -69,23 +49,14 @@ fn update_reference_file(reference_file_path: PathBuf, test_name: PathBuf, ignor
6949

7050
if test_output_file != reference_file {
7151
// If a test run caused an output file to change, update the reference file
72-
println!("updating {}", &relative_reference_file_path.display());
52+
println!("updating {}", reference_file_path.display());
7353
fs::copy(test_output_path, &reference_file_path).expect("Could not update reference file");
74-
75-
// We need to re-read the file now because it was potentially updated from copying
76-
let reference_file = fs::read(&reference_file_path).unwrap_or_default();
77-
78-
if reference_file.is_empty() {
79-
// If we copied over an empty output file, we remove the now empty reference file
80-
println!("removing {}", &relative_reference_file_path.display());
81-
fs::remove_file(reference_file_path).expect("Could not remove reference file");
82-
}
8354
}
8455
}
8556

86-
fn updated_since_clippy_build(path: &Path) -> Option<bool> {
57+
fn updated_since_clippy_build(entry: &DirEntry) -> Option<bool> {
8758
let clippy_build_time = (*CLIPPY_BUILD_TIME)?;
88-
let modified = fs::metadata(path).ok()?.modified().ok()?;
59+
let modified = entry.metadata().ok()?.modified().ok()?;
8960
Some(modified >= clippy_build_time)
9061
}
9162

tests/compile-test.rs

+38-43
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use std::env::{self, remove_var, set_var, var_os};
1111
use std::ffi::{OsStr, OsString};
1212
use std::fs;
1313
use std::io;
14+
use std::lazy::SyncLazy;
1415
use std::path::{Path, PathBuf};
1516
use test_utils::IS_RUSTC_TEST_SUITE;
1617

@@ -64,11 +65,11 @@ extern crate tokio;
6465
/// dependencies must be added to Cargo.toml at the project root. Test
6566
/// dependencies that are not *directly* used by this test module require an
6667
/// `extern crate` declaration.
67-
fn extern_flags() -> String {
68+
static EXTERN_FLAGS: SyncLazy<String> = SyncLazy::new(|| {
6869
let current_exe_depinfo = {
6970
let mut path = env::current_exe().unwrap();
7071
path.set_extension("d");
71-
std::fs::read_to_string(path).unwrap()
72+
fs::read_to_string(path).unwrap()
7273
};
7374
let mut crates: HashMap<&str, &str> = HashMap::with_capacity(TEST_DEPENDENCIES.len());
7475
for line in current_exe_depinfo.lines() {
@@ -112,24 +113,25 @@ fn extern_flags() -> String {
112113
.into_iter()
113114
.map(|(name, path)| format!(" --extern {}={}", name, path))
114115
.collect()
115-
}
116+
});
116117

117-
fn default_config() -> compiletest::Config {
118+
fn base_config(test_dir: &str) -> compiletest::Config {
118119
let mut config = compiletest::Config {
119120
edition: Some("2021".into()),
121+
mode: TestMode::Ui,
120122
..compiletest::Config::default()
121123
};
122124

123125
if let Ok(filters) = env::var("TESTNAME") {
124-
config.filters = filters.split(',').map(std::string::ToString::to_string).collect();
126+
config.filters = filters.split(',').map(ToString::to_string).collect();
125127
}
126128

127129
if let Some(path) = option_env!("RUSTC_LIB_PATH") {
128130
let path = PathBuf::from(path);
129131
config.run_lib_path = path.clone();
130132
config.compile_lib_path = path;
131133
}
132-
let current_exe_path = std::env::current_exe().unwrap();
134+
let current_exe_path = env::current_exe().unwrap();
133135
let deps_path = current_exe_path.parent().unwrap();
134136
let profile_path = deps_path.parent().unwrap();
135137

@@ -143,10 +145,11 @@ fn default_config() -> compiletest::Config {
143145
"--emit=metadata -Dwarnings -Zui-testing -L dependency={}{}{}",
144146
deps_path.display(),
145147
host_libs,
146-
extern_flags(),
148+
&*EXTERN_FLAGS,
147149
));
148150

149-
config.build_base = profile_path.join("test");
151+
config.src_base = Path::new("tests").join(test_dir);
152+
config.build_base = profile_path.join("test").join(test_dir);
150153
config.rustc_path = profile_path.join(if cfg!(windows) {
151154
"clippy-driver.exe"
152155
} else {
@@ -155,38 +158,31 @@ fn default_config() -> compiletest::Config {
155158
config
156159
}
157160

158-
fn run_ui(cfg: &mut compiletest::Config) {
159-
cfg.mode = TestMode::Ui;
160-
cfg.src_base = Path::new("tests").join("ui");
161+
fn run_ui() {
162+
let config = base_config("ui");
161163
// use tests/clippy.toml
162-
let _g = VarGuard::set("CARGO_MANIFEST_DIR", std::fs::canonicalize("tests").unwrap());
163-
compiletest::run_tests(cfg);
164+
let _g = VarGuard::set("CARGO_MANIFEST_DIR", fs::canonicalize("tests").unwrap());
165+
compiletest::run_tests(&config);
164166
}
165167

166-
fn run_ui_test(cfg: &mut compiletest::Config) {
167-
cfg.mode = TestMode::Ui;
168-
cfg.src_base = Path::new("tests").join("ui_test");
169-
let _g = VarGuard::set("CARGO_MANIFEST_DIR", std::fs::canonicalize("tests").unwrap());
170-
let rustcflags = cfg.target_rustcflags.get_or_insert_with(Default::default);
171-
let len = rustcflags.len();
168+
fn run_ui_test() {
169+
let mut config = base_config("ui_test");
170+
let _g = VarGuard::set("CARGO_MANIFEST_DIR", fs::canonicalize("tests").unwrap());
171+
let rustcflags = config.target_rustcflags.get_or_insert_with(Default::default);
172172
rustcflags.push_str(" --test");
173-
compiletest::run_tests(cfg);
174-
if let Some(ref mut flags) = &mut cfg.target_rustcflags {
175-
flags.truncate(len);
176-
}
173+
compiletest::run_tests(&config);
177174
}
178175

179-
fn run_internal_tests(cfg: &mut compiletest::Config) {
176+
fn run_internal_tests() {
180177
// only run internal tests with the internal-tests feature
181178
if !RUN_INTERNAL_TESTS {
182179
return;
183180
}
184-
cfg.mode = TestMode::Ui;
185-
cfg.src_base = Path::new("tests").join("ui-internal");
186-
compiletest::run_tests(cfg);
181+
let config = base_config("ui-internal");
182+
compiletest::run_tests(&config);
187183
}
188184

189-
fn run_ui_toml(config: &mut compiletest::Config) {
185+
fn run_ui_toml() {
190186
fn run_tests(config: &compiletest::Config, mut tests: Vec<tester::TestDescAndFn>) -> Result<bool, io::Error> {
191187
let mut result = true;
192188
let opts = compiletest::test_opts(config);
@@ -222,12 +218,12 @@ fn run_ui_toml(config: &mut compiletest::Config) {
222218
Ok(result)
223219
}
224220

225-
config.mode = TestMode::Ui;
226-
config.src_base = Path::new("tests").join("ui-toml").canonicalize().unwrap();
221+
let mut config = base_config("ui-toml");
222+
config.src_base = config.src_base.canonicalize().unwrap();
227223

228-
let tests = compiletest::make_tests(config);
224+
let tests = compiletest::make_tests(&config);
229225

230-
let res = run_tests(config, tests);
226+
let res = run_tests(&config, tests);
231227
match res {
232228
Ok(true) => {},
233229
Ok(false) => panic!("Some tests failed"),
@@ -237,7 +233,7 @@ fn run_ui_toml(config: &mut compiletest::Config) {
237233
}
238234
}
239235

240-
fn run_ui_cargo(config: &mut compiletest::Config) {
236+
fn run_ui_cargo() {
241237
fn run_tests(
242238
config: &compiletest::Config,
243239
filters: &[String],
@@ -310,13 +306,13 @@ fn run_ui_cargo(config: &mut compiletest::Config) {
310306
return;
311307
}
312308

313-
config.mode = TestMode::Ui;
314-
config.src_base = Path::new("tests").join("ui-cargo").canonicalize().unwrap();
309+
let mut config = base_config("ui-cargo");
310+
config.src_base = config.src_base.canonicalize().unwrap();
315311

316-
let tests = compiletest::make_tests(config);
312+
let tests = compiletest::make_tests(&config);
317313

318314
let current_dir = env::current_dir().unwrap();
319-
let res = run_tests(config, &config.filters, tests);
315+
let res = run_tests(&config, &config.filters, tests);
320316
env::set_current_dir(current_dir).unwrap();
321317

322318
match res {
@@ -331,12 +327,11 @@ fn run_ui_cargo(config: &mut compiletest::Config) {
331327
#[test]
332328
fn compile_test() {
333329
set_var("CLIPPY_DISABLE_DOCS_LINKS", "true");
334-
let mut config = default_config();
335-
run_ui(&mut config);
336-
run_ui_test(&mut config);
337-
run_ui_toml(&mut config);
338-
run_ui_cargo(&mut config);
339-
run_internal_tests(&mut config);
330+
run_ui();
331+
run_ui_test();
332+
run_ui_toml();
333+
run_ui_cargo();
334+
run_internal_tests();
340335
}
341336

342337
/// Restores an env var on drop

tests/ui/non_expressive_names.stdout

Whitespace-only changes.

0 commit comments

Comments
 (0)