Support cargo dev bless
for tests with revisions
This commit is contained in:
parent
68b44986de
commit
04dce4aed4
@ -5,9 +5,7 @@ use std::ffi::OsStr;
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::lazy::SyncLazy;
|
use std::lazy::SyncLazy;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use walkdir::WalkDir;
|
use walkdir::{DirEntry, WalkDir};
|
||||||
|
|
||||||
use crate::clippy_project_root;
|
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
static CARGO_CLIPPY_EXE: &str = "cargo-clippy";
|
static CARGO_CLIPPY_EXE: &str = "cargo-clippy";
|
||||||
@ -24,43 +22,25 @@ static CLIPPY_BUILD_TIME: SyncLazy<Option<std::time::SystemTime>> = SyncLazy::ne
|
|||||||
///
|
///
|
||||||
/// Panics if the path to a test file is broken
|
/// Panics if the path to a test file is broken
|
||||||
pub fn bless(ignore_timestamp: bool) {
|
pub fn bless(ignore_timestamp: bool) {
|
||||||
let test_suite_dirs = [
|
let extensions = ["stdout", "stderr", "fixed"].map(OsStr::new);
|
||||||
clippy_project_root().join("tests").join("ui"),
|
|
||||||
clippy_project_root().join("tests").join("ui-internal"),
|
WalkDir::new(build_dir())
|
||||||
clippy_project_root().join("tests").join("ui-toml"),
|
.into_iter()
|
||||||
clippy_project_root().join("tests").join("ui-cargo"),
|
.map(Result::unwrap)
|
||||||
];
|
.filter(|entry| entry.path().extension().map_or(false, |ext| extensions.contains(&ext)))
|
||||||
for test_suite_dir in &test_suite_dirs {
|
.for_each(|entry| update_reference_file(&entry, ignore_timestamp));
|
||||||
WalkDir::new(test_suite_dir)
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(Result::ok)
|
|
||||||
.filter(|f| f.path().extension() == Some(OsStr::new("rs")))
|
|
||||||
.for_each(|f| {
|
|
||||||
let test_name = f.path().strip_prefix(test_suite_dir).unwrap();
|
|
||||||
for &ext in &["stdout", "stderr", "fixed"] {
|
|
||||||
let test_name_ext = format!("stage-id.{}", ext);
|
|
||||||
update_reference_file(
|
|
||||||
f.path().with_extension(ext),
|
|
||||||
test_name.with_extension(test_name_ext),
|
|
||||||
ignore_timestamp,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_reference_file(reference_file_path: PathBuf, test_name: PathBuf, ignore_timestamp: bool) {
|
fn update_reference_file(test_output_entry: &DirEntry, ignore_timestamp: bool) {
|
||||||
let test_output_path = build_dir().join(test_name);
|
let test_output_path = test_output_entry.path();
|
||||||
let relative_reference_file_path = reference_file_path.strip_prefix(clippy_project_root()).unwrap();
|
|
||||||
|
|
||||||
// If compiletest did not write any changes during the test run,
|
let reference_file_name = test_output_entry.file_name().to_str().unwrap().replace(".stage-id", "");
|
||||||
// we don't have to update anything
|
let reference_file_path = Path::new("tests")
|
||||||
if !test_output_path.exists() {
|
.join(test_output_path.strip_prefix(build_dir()).unwrap())
|
||||||
return;
|
.with_file_name(reference_file_name);
|
||||||
}
|
|
||||||
|
|
||||||
// If the test output was not updated since the last clippy build, it may be outdated
|
// If the test output was not updated since the last clippy build, it may be outdated
|
||||||
if !ignore_timestamp && !updated_since_clippy_build(&test_output_path).unwrap_or(true) {
|
if !ignore_timestamp && !updated_since_clippy_build(test_output_entry).unwrap_or(true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,23 +49,14 @@ fn update_reference_file(reference_file_path: PathBuf, test_name: PathBuf, ignor
|
|||||||
|
|
||||||
if test_output_file != reference_file {
|
if test_output_file != reference_file {
|
||||||
// If a test run caused an output file to change, update the reference file
|
// If a test run caused an output file to change, update the reference file
|
||||||
println!("updating {}", &relative_reference_file_path.display());
|
println!("updating {}", reference_file_path.display());
|
||||||
fs::copy(test_output_path, &reference_file_path).expect("Could not update reference file");
|
fs::copy(test_output_path, &reference_file_path).expect("Could not update reference file");
|
||||||
|
|
||||||
// We need to re-read the file now because it was potentially updated from copying
|
|
||||||
let reference_file = fs::read(&reference_file_path).unwrap_or_default();
|
|
||||||
|
|
||||||
if reference_file.is_empty() {
|
|
||||||
// If we copied over an empty output file, we remove the now empty reference file
|
|
||||||
println!("removing {}", &relative_reference_file_path.display());
|
|
||||||
fs::remove_file(reference_file_path).expect("Could not remove reference file");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn updated_since_clippy_build(path: &Path) -> Option<bool> {
|
fn updated_since_clippy_build(entry: &DirEntry) -> Option<bool> {
|
||||||
let clippy_build_time = (*CLIPPY_BUILD_TIME)?;
|
let clippy_build_time = (*CLIPPY_BUILD_TIME)?;
|
||||||
let modified = fs::metadata(path).ok()?.modified().ok()?;
|
let modified = entry.metadata().ok()?.modified().ok()?;
|
||||||
Some(modified >= clippy_build_time)
|
Some(modified >= clippy_build_time)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ use std::env::{self, remove_var, set_var, var_os};
|
|||||||
use std::ffi::{OsStr, OsString};
|
use std::ffi::{OsStr, OsString};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::lazy::SyncLazy;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use test_utils::IS_RUSTC_TEST_SUITE;
|
use test_utils::IS_RUSTC_TEST_SUITE;
|
||||||
|
|
||||||
@ -64,11 +65,11 @@ extern crate tokio;
|
|||||||
/// dependencies must be added to Cargo.toml at the project root. Test
|
/// dependencies must be added to Cargo.toml at the project root. Test
|
||||||
/// dependencies that are not *directly* used by this test module require an
|
/// dependencies that are not *directly* used by this test module require an
|
||||||
/// `extern crate` declaration.
|
/// `extern crate` declaration.
|
||||||
fn extern_flags() -> String {
|
static EXTERN_FLAGS: SyncLazy<String> = SyncLazy::new(|| {
|
||||||
let current_exe_depinfo = {
|
let current_exe_depinfo = {
|
||||||
let mut path = env::current_exe().unwrap();
|
let mut path = env::current_exe().unwrap();
|
||||||
path.set_extension("d");
|
path.set_extension("d");
|
||||||
std::fs::read_to_string(path).unwrap()
|
fs::read_to_string(path).unwrap()
|
||||||
};
|
};
|
||||||
let mut crates: HashMap<&str, &str> = HashMap::with_capacity(TEST_DEPENDENCIES.len());
|
let mut crates: HashMap<&str, &str> = HashMap::with_capacity(TEST_DEPENDENCIES.len());
|
||||||
for line in current_exe_depinfo.lines() {
|
for line in current_exe_depinfo.lines() {
|
||||||
@ -112,16 +113,17 @@ fn extern_flags() -> String {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(name, path)| format!(" --extern {}={}", name, path))
|
.map(|(name, path)| format!(" --extern {}={}", name, path))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
});
|
||||||
|
|
||||||
fn default_config() -> compiletest::Config {
|
fn base_config(test_dir: &str) -> compiletest::Config {
|
||||||
let mut config = compiletest::Config {
|
let mut config = compiletest::Config {
|
||||||
edition: Some("2021".into()),
|
edition: Some("2021".into()),
|
||||||
|
mode: TestMode::Ui,
|
||||||
..compiletest::Config::default()
|
..compiletest::Config::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Ok(filters) = env::var("TESTNAME") {
|
if let Ok(filters) = env::var("TESTNAME") {
|
||||||
config.filters = filters.split(',').map(std::string::ToString::to_string).collect();
|
config.filters = filters.split(',').map(ToString::to_string).collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(path) = option_env!("RUSTC_LIB_PATH") {
|
if let Some(path) = option_env!("RUSTC_LIB_PATH") {
|
||||||
@ -129,7 +131,7 @@ fn default_config() -> compiletest::Config {
|
|||||||
config.run_lib_path = path.clone();
|
config.run_lib_path = path.clone();
|
||||||
config.compile_lib_path = path;
|
config.compile_lib_path = path;
|
||||||
}
|
}
|
||||||
let current_exe_path = std::env::current_exe().unwrap();
|
let current_exe_path = env::current_exe().unwrap();
|
||||||
let deps_path = current_exe_path.parent().unwrap();
|
let deps_path = current_exe_path.parent().unwrap();
|
||||||
let profile_path = deps_path.parent().unwrap();
|
let profile_path = deps_path.parent().unwrap();
|
||||||
|
|
||||||
@ -143,10 +145,11 @@ fn default_config() -> compiletest::Config {
|
|||||||
"--emit=metadata -Dwarnings -Zui-testing -L dependency={}{}{}",
|
"--emit=metadata -Dwarnings -Zui-testing -L dependency={}{}{}",
|
||||||
deps_path.display(),
|
deps_path.display(),
|
||||||
host_libs,
|
host_libs,
|
||||||
extern_flags(),
|
&*EXTERN_FLAGS,
|
||||||
));
|
));
|
||||||
|
|
||||||
config.build_base = profile_path.join("test");
|
config.src_base = Path::new("tests").join(test_dir);
|
||||||
|
config.build_base = profile_path.join("test").join(test_dir);
|
||||||
config.rustc_path = profile_path.join(if cfg!(windows) {
|
config.rustc_path = profile_path.join(if cfg!(windows) {
|
||||||
"clippy-driver.exe"
|
"clippy-driver.exe"
|
||||||
} else {
|
} else {
|
||||||
@ -155,38 +158,31 @@ fn default_config() -> compiletest::Config {
|
|||||||
config
|
config
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_ui(cfg: &mut compiletest::Config) {
|
fn run_ui() {
|
||||||
cfg.mode = TestMode::Ui;
|
let config = base_config("ui");
|
||||||
cfg.src_base = Path::new("tests").join("ui");
|
|
||||||
// use tests/clippy.toml
|
// use tests/clippy.toml
|
||||||
let _g = VarGuard::set("CARGO_MANIFEST_DIR", std::fs::canonicalize("tests").unwrap());
|
let _g = VarGuard::set("CARGO_MANIFEST_DIR", fs::canonicalize("tests").unwrap());
|
||||||
compiletest::run_tests(cfg);
|
compiletest::run_tests(&config);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_ui_test(cfg: &mut compiletest::Config) {
|
fn run_ui_test() {
|
||||||
cfg.mode = TestMode::Ui;
|
let mut config = base_config("ui_test");
|
||||||
cfg.src_base = Path::new("tests").join("ui_test");
|
let _g = VarGuard::set("CARGO_MANIFEST_DIR", fs::canonicalize("tests").unwrap());
|
||||||
let _g = VarGuard::set("CARGO_MANIFEST_DIR", std::fs::canonicalize("tests").unwrap());
|
let rustcflags = config.target_rustcflags.get_or_insert_with(Default::default);
|
||||||
let rustcflags = cfg.target_rustcflags.get_or_insert_with(Default::default);
|
|
||||||
let len = rustcflags.len();
|
|
||||||
rustcflags.push_str(" --test");
|
rustcflags.push_str(" --test");
|
||||||
compiletest::run_tests(cfg);
|
compiletest::run_tests(&config);
|
||||||
if let Some(ref mut flags) = &mut cfg.target_rustcflags {
|
|
||||||
flags.truncate(len);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_internal_tests(cfg: &mut compiletest::Config) {
|
fn run_internal_tests() {
|
||||||
// only run internal tests with the internal-tests feature
|
// only run internal tests with the internal-tests feature
|
||||||
if !RUN_INTERNAL_TESTS {
|
if !RUN_INTERNAL_TESTS {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cfg.mode = TestMode::Ui;
|
let config = base_config("ui-internal");
|
||||||
cfg.src_base = Path::new("tests").join("ui-internal");
|
compiletest::run_tests(&config);
|
||||||
compiletest::run_tests(cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_ui_toml(config: &mut compiletest::Config) {
|
fn run_ui_toml() {
|
||||||
fn run_tests(config: &compiletest::Config, mut tests: Vec<tester::TestDescAndFn>) -> Result<bool, io::Error> {
|
fn run_tests(config: &compiletest::Config, mut tests: Vec<tester::TestDescAndFn>) -> Result<bool, io::Error> {
|
||||||
let mut result = true;
|
let mut result = true;
|
||||||
let opts = compiletest::test_opts(config);
|
let opts = compiletest::test_opts(config);
|
||||||
@ -222,12 +218,12 @@ fn run_ui_toml(config: &mut compiletest::Config) {
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
config.mode = TestMode::Ui;
|
let mut config = base_config("ui-toml");
|
||||||
config.src_base = Path::new("tests").join("ui-toml").canonicalize().unwrap();
|
config.src_base = config.src_base.canonicalize().unwrap();
|
||||||
|
|
||||||
let tests = compiletest::make_tests(config);
|
let tests = compiletest::make_tests(&config);
|
||||||
|
|
||||||
let res = run_tests(config, tests);
|
let res = run_tests(&config, tests);
|
||||||
match res {
|
match res {
|
||||||
Ok(true) => {},
|
Ok(true) => {},
|
||||||
Ok(false) => panic!("Some tests failed"),
|
Ok(false) => panic!("Some tests failed"),
|
||||||
@ -237,7 +233,7 @@ fn run_ui_toml(config: &mut compiletest::Config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_ui_cargo(config: &mut compiletest::Config) {
|
fn run_ui_cargo() {
|
||||||
fn run_tests(
|
fn run_tests(
|
||||||
config: &compiletest::Config,
|
config: &compiletest::Config,
|
||||||
filters: &[String],
|
filters: &[String],
|
||||||
@ -310,13 +306,13 @@ fn run_ui_cargo(config: &mut compiletest::Config) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.mode = TestMode::Ui;
|
let mut config = base_config("ui-cargo");
|
||||||
config.src_base = Path::new("tests").join("ui-cargo").canonicalize().unwrap();
|
config.src_base = config.src_base.canonicalize().unwrap();
|
||||||
|
|
||||||
let tests = compiletest::make_tests(config);
|
let tests = compiletest::make_tests(&config);
|
||||||
|
|
||||||
let current_dir = env::current_dir().unwrap();
|
let current_dir = env::current_dir().unwrap();
|
||||||
let res = run_tests(config, &config.filters, tests);
|
let res = run_tests(&config, &config.filters, tests);
|
||||||
env::set_current_dir(current_dir).unwrap();
|
env::set_current_dir(current_dir).unwrap();
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
@ -331,12 +327,11 @@ fn run_ui_cargo(config: &mut compiletest::Config) {
|
|||||||
#[test]
|
#[test]
|
||||||
fn compile_test() {
|
fn compile_test() {
|
||||||
set_var("CLIPPY_DISABLE_DOCS_LINKS", "true");
|
set_var("CLIPPY_DISABLE_DOCS_LINKS", "true");
|
||||||
let mut config = default_config();
|
run_ui();
|
||||||
run_ui(&mut config);
|
run_ui_test();
|
||||||
run_ui_test(&mut config);
|
run_ui_toml();
|
||||||
run_ui_toml(&mut config);
|
run_ui_cargo();
|
||||||
run_ui_cargo(&mut config);
|
run_internal_tests();
|
||||||
run_internal_tests(&mut config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Restores an env var on drop
|
/// Restores an env var on drop
|
||||||
|
Loading…
x
Reference in New Issue
Block a user