diff options
| author | bors <bors@rust-lang.org> | 2020-02-06 09:19:29 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-02-06 09:19:29 +0000 |
| commit | c1f8be074edaa702c5b4ca52a9d44bba2b46946c (patch) | |
| tree | a872d8ad3b0d94385cf46777a6dea6ba5023d196 | |
| parent | a7b3b9f553f58974bd14ee28ba857e3e703fb8c1 (diff) | |
| parent | c4b4dd200ce1b9f6862e866bc8354832910d57ec (diff) | |
| download | rust-c1f8be074edaa702c5b4ca52a9d44bba2b46946c.tar.gz rust-c1f8be074edaa702c5b4ca52a9d44bba2b46946c.zip | |
Auto merge of #5121 - lzutao:comptest, r=flip1995
Improve compile_test and dogfood tests * Hopefully this finally resolves the "multiple matching crates" error, e.g. #4015 * This handle some convenient CARGO env like CARGO_TARGET_DIR and CARGO_BUILD_TARGET changelog: none
| -rw-r--r-- | tests/cargo/mod.rs | 75 | ||||
| -rw-r--r-- | tests/compile-test.rs | 102 | ||||
| -rw-r--r-- | tests/dogfood.rs | 30 |
3 files changed, 124 insertions, 83 deletions
diff --git a/tests/cargo/mod.rs b/tests/cargo/mod.rs new file mode 100644 index 00000000000..5b2de05cb17 --- /dev/null +++ b/tests/cargo/mod.rs @@ -0,0 +1,75 @@ +use cargo_metadata::{Message::CompilerArtifact, MetadataCommand}; +use std::env; +use std::ffi::OsStr; +use std::mem; +use std::path::PathBuf; +use std::process::Command; + +pub struct BuildInfo { + cargo_target_dir: PathBuf, +} + +impl BuildInfo { + pub fn new() -> Self { + let data = MetadataCommand::new().exec().unwrap(); + Self { + cargo_target_dir: data.target_directory, + } + } + + pub fn host_lib(&self) -> PathBuf { + if let Some(path) = option_env!("HOST_LIBS") { + PathBuf::from(path) + } else { + self.cargo_target_dir.join(env!("PROFILE")) + } + } + + pub fn target_lib(&self) -> PathBuf { + if let Some(path) = option_env!("TARGET_LIBS") { + path.into() + } else { + let mut dir = self.cargo_target_dir.clone(); + if let Some(target) = env::var_os("CARGO_BUILD_TARGET") { + dir.push(target); + } + dir.push(env!("PROFILE")); + dir + } + } + + pub fn clippy_driver_path(&self) -> PathBuf { + if let Some(path) = option_env!("CLIPPY_DRIVER_PATH") { + PathBuf::from(path) + } else { + self.target_lib().join("clippy-driver") + } + } + + // When we'll want to use `extern crate ..` for a dependency that is used + // both by the crate and the compiler itself, we can't simply pass -L flags + // as we'll get a duplicate matching versions. Instead, disambiguate with + // `--extern dep=path`. + // See https://github.com/rust-lang/rust-clippy/issues/4015. + pub fn third_party_crates() -> Vec<(&'static str, PathBuf)> { + const THIRD_PARTY_CRATES: [&str; 4] = ["serde", "serde_derive", "regex", "clippy_lints"]; + let cargo = env::var_os("CARGO"); + let cargo = cargo.as_deref().unwrap_or_else(|| OsStr::new("cargo")); + let output = Command::new(cargo) + .arg("build") + .arg("--test=compile-test") + .arg("--message-format=json") + .output() + .unwrap(); + + let mut crates = Vec::with_capacity(THIRD_PARTY_CRATES.len()); + for message in cargo_metadata::parse_messages(output.stdout.as_slice()) { + if let CompilerArtifact(mut artifact) = message.unwrap() { + if let Some(&krate) = THIRD_PARTY_CRATES.iter().find(|&&krate| krate == artifact.target.name) { + crates.push((krate, mem::take(&mut artifact.filenames[0]))); + } + } + } + crates + } +} diff --git a/tests/compile-test.rs b/tests/compile-test.rs index 5c05e74dcb6..7cfbfcf16a9 100644 --- a/tests/compile-test.rs +++ b/tests/compile-test.rs @@ -1,36 +1,15 @@ #![feature(test)] use compiletest_rs as compiletest; -extern crate tester as test; +use compiletest_rs::common::Mode as TestMode; -use std::env::{set_var, var}; +use std::env::{self, set_var}; use std::ffi::OsStr; use std::fs; use std::io; use std::path::{Path, PathBuf}; -#[must_use] -fn clippy_driver_path() -> PathBuf { - if let Some(path) = option_env!("CLIPPY_DRIVER_PATH") { - PathBuf::from(path) - } else { - PathBuf::from(concat!("target/", env!("PROFILE"), "/clippy-driver")) - } -} - -#[must_use] -fn host_libs() -> PathBuf { - if let Some(path) = option_env!("HOST_LIBS") { - PathBuf::from(path) - } else { - Path::new("target").join(env!("PROFILE")) - } -} - -#[must_use] -fn target_libs() -> Option<PathBuf> { - option_env!("TARGET_LIBS").map(PathBuf::from) -} +mod cargo; #[must_use] fn rustc_test_suite() -> Option<PathBuf> { @@ -42,73 +21,52 @@ fn rustc_lib_path() -> PathBuf { option_env!("RUSTC_LIB_PATH").unwrap().into() } -fn config(mode: &str, dir: PathBuf) -> compiletest::Config { +fn default_config() -> compiletest::Config { + let build_info = cargo::BuildInfo::new(); let mut config = compiletest::Config::default(); - let cfg_mode = mode.parse().expect("Invalid mode"); - if let Ok(name) = var::<&str>("TESTNAME") { - config.filter = Some(name) + if let Ok(name) = env::var("TESTNAME") { + config.filter = Some(name); } if rustc_test_suite().is_some() { - config.run_lib_path = rustc_lib_path(); - config.compile_lib_path = rustc_lib_path(); + let path = rustc_lib_path(); + config.run_lib_path = path.clone(); + config.compile_lib_path = path; } - // When we'll want to use `extern crate ..` for a dependency that is used - // both by the crate and the compiler itself, we can't simply pass -L flags - // as we'll get a duplicate matching versions. Instead, disambiguate with - // `--extern dep=path`. - // See https://github.com/rust-lang/rust-clippy/issues/4015. - let needs_disambiguation = ["serde", "regex", "clippy_lints"]; - // This assumes that deps are compiled (they are for Cargo integration tests). - let deps = fs::read_dir(target_libs().unwrap_or_else(host_libs).join("deps")).unwrap(); - let disambiguated = deps - .filter_map(|dep| { - let path = dep.ok()?.path(); - let name = path.file_name()?.to_string_lossy(); - // NOTE: This only handles a single dep - // https://github.com/laumann/compiletest-rs/issues/101 - needs_disambiguation.iter().find_map(|dep| { - if name.starts_with(&format!("lib{}-", dep)) && name.ends_with(".rlib") { - Some(format!("--extern {}={}", dep, path.display())) - } else { - None - } - }) - }) - .collect::<Vec<_>>(); + let disambiguated: Vec<_> = cargo::BuildInfo::third_party_crates() + .iter() + .map(|(krate, path)| format!("--extern {}={}", krate, path.display())) + .collect(); config.target_rustcflags = Some(format!( - "-L {0} -L {0}/deps {1} -Dwarnings -Zui-testing {2}", - host_libs().display(), - target_libs().map_or_else(String::new, |path| format!("-L {0} -L {0}/deps", path.display())), + "-L {0} -L {1} -Dwarnings -Zui-testing {2}", + build_info.host_lib().join("deps").display(), + build_info.target_lib().join("deps").display(), disambiguated.join(" ") )); - config.mode = cfg_mode; config.build_base = if rustc_test_suite().is_some() { // we don't need access to the stderr files on travis let mut path = PathBuf::from(env!("OUT_DIR")); path.push("test_build_base"); path } else { - let mut path = std::env::current_dir().unwrap(); - path.push("target/debug/test_build_base"); - path + build_info.host_lib().join("test_build_base") }; - config.src_base = dir; - config.rustc_path = clippy_driver_path(); + config.rustc_path = build_info.clippy_driver_path(); config } -fn run_mode(mode: &str, dir: PathBuf) { - let cfg = config(mode, dir); +fn run_mode(cfg: &mut compiletest::Config) { + cfg.mode = TestMode::Ui; + cfg.src_base = Path::new("tests").join("ui"); compiletest::run_tests(&cfg); } #[allow(clippy::identity_conversion)] -fn run_ui_toml_tests(config: &compiletest::Config, mut tests: Vec<test::TestDescAndFn>) -> Result<bool, io::Error> { +fn run_ui_toml_tests(config: &compiletest::Config, mut tests: Vec<tester::TestDescAndFn>) -> Result<bool, io::Error> { let mut result = true; let opts = compiletest::test_opts(config); for dir in fs::read_dir(&config.src_base)? { @@ -137,15 +95,16 @@ fn run_ui_toml_tests(config: &compiletest::Config, mut tests: Vec<test::TestDesc .iter() .position(|test| test.desc.name == test_name) .expect("The test should be in there"); - result &= test::run_tests_console(&opts, vec![tests.swap_remove(index)])?; + result &= tester::run_tests_console(&opts, vec![tests.swap_remove(index)])?; } } Ok(result) } -fn run_ui_toml() { - let path = PathBuf::from("tests/ui-toml").canonicalize().unwrap(); - let config = config("ui", path); +fn run_ui_toml(config: &mut compiletest::Config) { + config.mode = TestMode::Ui; + config.src_base = Path::new("tests").join("ui-toml").canonicalize().unwrap(); + let tests = compiletest::make_tests(&config); let res = run_ui_toml_tests(&config, tests); @@ -167,6 +126,7 @@ fn prepare_env() { #[test] fn compile_test() { prepare_env(); - run_mode("ui", "tests/ui".into()); - run_ui_toml(); + let mut config = default_config(); + run_mode(&mut config); + run_ui_toml(&mut config); } diff --git a/tests/dogfood.rs b/tests/dogfood.rs index 944f3c2c013..5458143ab1c 100644 --- a/tests/dogfood.rs +++ b/tests/dogfood.rs @@ -1,16 +1,26 @@ +use lazy_static::lazy_static; +use std::path::PathBuf; +use std::process::Command; + +#[allow(dead_code)] +mod cargo; + +lazy_static! { + static ref CLIPPY_PATH: PathBuf = { + let build_info = cargo::BuildInfo::new(); + build_info.target_lib().join("cargo-clippy") + }; +} + #[test] fn dogfood_clippy() { // run clippy on itself and fail the test if lint warnings are reported if option_env!("RUSTC_TEST_SUITE").is_some() || cfg!(windows) { return; } - let root_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let clippy_binary = std::path::Path::new(&root_dir) - .join("target") - .join(env!("PROFILE")) - .join("cargo-clippy"); + let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let output = std::process::Command::new(clippy_binary) + let output = Command::new(&*CLIPPY_PATH) .current_dir(root_dir) .env("CLIPPY_DOGFOOD", "1") .env("CARGO_INCREMENTAL", "0") @@ -37,11 +47,7 @@ fn dogfood_subprojects() { if option_env!("RUSTC_TEST_SUITE").is_some() || cfg!(windows) { return; } - let root_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let clippy_binary = std::path::Path::new(&root_dir) - .join("target") - .join(env!("PROFILE")) - .join("cargo-clippy"); + let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); for d in &[ "clippy_workspace_tests", @@ -51,7 +57,7 @@ fn dogfood_subprojects() { "clippy_dev", "rustc_tools_util", ] { - let output = std::process::Command::new(&clippy_binary) + let output = Command::new(&*CLIPPY_PATH) .current_dir(root_dir.join(d)) .env("CLIPPY_DOGFOOD", "1") .env("CARGO_INCREMENTAL", "0") |
