diff --git a/CHANGELOG.md b/CHANGELOG.md index fceb17b608..8a625614b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ From 2019 onwards, all notable changes to tarpaulin will be documented in this file. +## [0.31.5] 2025-01-16 +### Changed +- ASLR detection was slightly broken - although it wouldn't break anything unless setting was broken as well. +- Detect the libdir path by rustc and link to it to enable proc-macro test binaries to run without error #1642 + ## [0.31.4] 2024-12-31 ### Added - Added `--include-files` argument to only display coverage for the mentioned files (#1667) diff --git a/Cargo.lock b/Cargo.lock index 0ddc958f0a..c35477c6f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -173,14 +173,13 @@ dependencies = [ [[package]] name = "cargo-tarpaulin" -version = "0.31.4" +version = "0.31.5" dependencies = [ "cargo_metadata", "cfg-if", "chrono", "clap", "coveralls-api", - "fallible-iterator", "gimli 0.31.1", "git2", "glob", @@ -522,9 +521,9 @@ dependencies = [ [[package]] name = "git2" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" +checksum = "3fda788993cc341f69012feba8bf45c0ba4f3291fcc08e214b4d5a7332d88aff" dependencies = [ "bitflags 2.5.0", "libc", @@ -805,9 +804,9 @@ checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libgit2-sys" -version = "0.17.0+1.8.1" +version = "0.18.0+1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" +checksum = "e1a117465e7e1597e8febea8bb0c410f1c7fb93b1e1cddf34363f8390367ffec" dependencies = [ "cc", "libc", @@ -1127,9 +1126,9 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "proc-macro2" -version = "1.0.92" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] @@ -1410,9 +1409,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.134" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" dependencies = [ "itoa", "memchr", diff --git a/Cargo.toml b/Cargo.toml index 2aec2c56d6..7bc0ad5a05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cargo-tarpaulin" -version = "0.31.4" +version = "0.31.5" authors = ["Daniel McKenna "] description = "Cargo-Tarpaulin is a tool to determine code coverage achieved via tests" repository = "https://github.com/xd009642/tarpaulin" @@ -25,9 +25,8 @@ cfg-if = "1.0.0" chrono = "0.4" clap = { version = "4.4.0", features = ["derive"] } coveralls-api = { version = "0.6.0", optional = true } -fallible-iterator = "0.3.0" gimli = "0.31.1" -git2 = { version = "0.19", optional = true } +git2 = { version = "0.20", optional = true } humantime-serde = "1" indexmap = { version = "~1.8", features = ["serde-1"] } lazy_static = "1.5" diff --git a/src/cargo.rs b/src/cargo.rs index d68be5e8dc..8c7ea1e410 100644 --- a/src/cargo.rs +++ b/src/cargo.rs @@ -278,7 +278,10 @@ fn run_cargo( trace!("Running command {:?}", cmd); let mut child = cmd.spawn().map_err(|e| RunError::Cargo(e.to_string()))?; let update_from = result.test_binaries.len(); - let mut paths = vec![]; + let mut paths = match get_libdir(ty) { + Some(path) => vec![path], + None => vec![], + }; if ty != Some(RunType::Doctests) { let mut package_ids = vec![None; result.test_binaries.len()]; @@ -514,7 +517,7 @@ fn find_str_in_file(file: &Path, value: &str) -> io::Result> { Ok(lines) } -fn create_command(manifest_path: &str, config: &Config, ty: Option) -> Command { +fn start_cargo_command(ty: Option) -> Command { let mut test_cmd = Command::new("cargo"); let bootstrap = matches!(env::var("RUSTC_BOOTSTRAP").as_deref(), Ok("1")); let override_toolchain = if cfg!(windows) { @@ -541,13 +544,37 @@ fn create_command(manifest_path: &str, config: &Config, ty: Option) -> test_cmd.args(["+nightly"]); } } - test_cmd.args(["test"]); } else { if override_toolchain { if let Ok(toolchain) = env::var("RUSTUP_TOOLCHAIN") { test_cmd.arg(format!("+{toolchain}")); } } + } + test_cmd +} + +fn get_libdir(ty: Option) -> Option { + let mut test_cmd = start_cargo_command(ty); + test_cmd.env("RUSTC_BOOTSTRAP", "1"); + test_cmd.args(["rustc", "-Z", "unstable-options", "--print=target-libdir"]); + + let output = match test_cmd.output() { + Ok(output) => String::from_utf8_lossy(&output.stdout).trim().to_string(), + Err(e) => { + debug!("Unable to run cargo rustc command: {}", e); + warn!("Unable to get target libdir proc macro crates in the workspace may not work. Consider adding `--exclude` to remove them from compilation"); + return None; + } + }; + Some(PathBuf::from(output)) +} + +fn create_command(manifest_path: &str, config: &Config, ty: Option) -> Command { + let mut test_cmd = start_cargo_command(ty); + if ty == Some(RunType::Doctests) { + test_cmd.args(["test"]); + } else { if config.command == Mode::Test { test_cmd.args(["test", "--no-run"]); } else { @@ -913,6 +940,12 @@ mod tests { use super::*; use toml::toml; + #[test] + fn can_get_libdir() { + let path = get_libdir(Some(RunType::Tests)).unwrap(); + assert!(path.exists(), "{} doesn't exist", path.display()); + } + #[test] #[cfg(not(windows))] fn check_dead_code_flags() { diff --git a/src/process_handling/linux.rs b/src/process_handling/linux.rs index b2c0e4d636..81c906e580 100644 --- a/src/process_handling/linux.rs +++ b/src/process_handling/linux.rs @@ -11,7 +11,6 @@ use nix::sys::personality; use nix::unistd::*; use std::ffi::{CStr, CString}; use std::path::Path; -use std::process::Command; use tracing::{info, warn}; lazy_static! { @@ -63,17 +62,9 @@ fn disable_aslr() -> nix::Result<()> { } fn is_aslr_enabled() -> bool { - // Create a Command instance with the 'cat' command and the path to the file as arguments - let output = Command::new("cat") - .arg("/proc/sys/kernel/random/boot_random") - .output() - .unwrap(); - - // Convert the output to a String and store it in a variable - let output_str = String::from_utf8(output.stdout).unwrap(); - - // Check if the output string is not '0' (case-insensitive) and return the result - output_str.trim().to_lowercase() != "0" + !personality::get() + .map(|x| x.contains(personality::Persona::ADDR_NO_RANDOMIZE)) + .unwrap_or(true) } pub fn limit_affinity() -> nix::Result<()> { @@ -120,3 +111,15 @@ pub fn execute( unreachable!(); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn can_disable_aslr() { + assert!(is_aslr_enabled()); + disable_aslr().unwrap(); + assert!(!is_aslr_enabled()); + } +} diff --git a/src/process_handling/mod.rs b/src/process_handling/mod.rs index ed205eddec..7eb91c71e9 100644 --- a/src/process_handling/mod.rs +++ b/src/process_handling/mod.rs @@ -236,21 +236,14 @@ fn execute_test( argv.push("--color".to_string()); argv.push(config.color.to_string().to_ascii_lowercase()); } - let no_test_env = if let Ok(threads) = env::var("RUST_TEST_THREADS") { + if let Ok(threads) = env::var("RUST_TEST_THREADS") { envars.push(("RUST_TEST_THREADS".to_string(), threads)); - false - } else { - true - }; - - if no_test_env - && test.is_test_type() + } else if test.is_test_type() && !config.implicit_test_threads && !config.varargs.iter().any(|x| x.contains("--test-threads")) { if let Some(threads) = num_threads { - argv.push("--test-threads".to_string()); - argv.push(threads.to_string()); + envars.push(("RUST_TEST_THREADS".to_string(), threads.to_string())); } } diff --git a/src/report/cobertura.rs b/src/report/cobertura.rs index 74aec5b9c9..b183dcf5a8 100644 --- a/src/report/cobertura.rs +++ b/src/report/cobertura.rs @@ -362,6 +362,8 @@ fn render_class(config: &Config, traces: &TraceMap, file: &Path) -> Option, } -fn render_methods() -> Vec { - unimplemented!() -} - -fn render_method() -> Method { - unimplemented!() -} - #[derive(Debug)] enum Line { Plain { diff --git a/tarpaulin.toml b/tarpaulin.toml index f7feec5647..1b5ca183fb 100644 --- a/tarpaulin.toml +++ b/tarpaulin.toml @@ -98,14 +98,14 @@ target-dir = "./target" # Run the tests without accessing the network (offline mode). offline = false -# Cargo subcommand to run; options are "test" or "build". -command = "test" +# Cargo subcommand to run; options are "Test" or "Build". +command = "Test" -# Types of tests to collect coverage for. For example: ["unit", "integration"] -run-types = ["unit"] +# Types of tests to collect coverage for. For example: ["Lib", "AllTargets", "Benchmarks", "Bins", "Examples", "Doctests", "Tests"] +run-types = ["AllTargets"] # List of packages to include when building the target project. -packages = ["my_package"] +packages = [] # List of packages to exclude from testing. exclude = [] @@ -156,7 +156,7 @@ no-fail-fast = false avoid-cfg-tarpaulin = false # Colouring of logs in the terminal output (e.g., "auto", "always", "never"). -color = "auto" +color = "Auto" # Follow traced executables down through function calls. follow-exec = true @@ -189,4 +189,4 @@ profraw-folder = "./target/profraw" fail-immediately = false # Log to stderr instead of the default output. -stderr = false \ No newline at end of file +stderr = false