diff --git a/Cargo.lock b/Cargo.lock index 07fa5ac4..600eee7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -337,6 +337,7 @@ dependencies = [ "rstest", "rstest_reuse", "runner-shared", + "semver", "serde", "serde_json", "serde_yaml", diff --git a/Cargo.toml b/Cargo.toml index f7770a32..d136ec1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ lazy_static = "1.4.0" log = "0.4.20" rand = "0.8.5" regex = "1.10.2" +semver = "1.0" reqwest = { version = "0.11.22", features = [ "json", "stream", diff --git a/src/main.rs b/src/main.rs index 27099496..dac5832c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,18 +13,20 @@ use console::style; use lazy_static::lazy_static; use local_logger::clean_logger; use prelude::*; +use semver::Version; use log::log_enabled; pub const VERSION: &str = env!("CARGO_PKG_VERSION"); pub const MONGODB_TRACER_VERSION: &str = "cs-mongo-tracer-v0.2.0"; -const VALGRIND_CODSPEED_BASE_VERSION: &str = "3.24.0"; +pub const VALGRIND_CODSPEED_VERSION: Version = Version::new(3, 25, 1); +pub const VALGRIND_CODSPEED_DEB_REVISION_SUFFIX: &str = "3codspeed2"; lazy_static! { - pub static ref VALGRIND_CODSPEED_VERSION: String = - format!("{VALGRIND_CODSPEED_BASE_VERSION}.codspeed"); + pub static ref VALGRIND_CODSPEED_VERSION_STRING: String = + format!("{VALGRIND_CODSPEED_VERSION}.codspeed"); pub static ref VALGRIND_CODSPEED_DEB_VERSION: String = - format!("{VALGRIND_CODSPEED_BASE_VERSION}-0codspeed1"); + format!("{VALGRIND_CODSPEED_VERSION}-{VALGRIND_CODSPEED_DEB_REVISION_SUFFIX}"); } #[tokio::main(flavor = "current_thread")] diff --git a/src/run/runner/valgrind/setup.rs b/src/run/runner/valgrind/setup.rs index 1c08e636..e7b25080 100644 --- a/src/run/runner/valgrind/setup.rs +++ b/src/run/runner/valgrind/setup.rs @@ -1,6 +1,10 @@ use crate::run::runner::helpers::apt; use crate::{VALGRIND_CODSPEED_DEB_VERSION, run::check_system::SystemInfo}; -use crate::{VALGRIND_CODSPEED_VERSION, prelude::*, run::helpers::download_file}; +use crate::{ + VALGRIND_CODSPEED_VERSION, VALGRIND_CODSPEED_VERSION_STRING, prelude::*, + run::helpers::download_file, +}; +use semver::Version; use std::{env, path::Path, process::Command}; use url::Url; @@ -25,6 +29,28 @@ fn get_codspeed_valgrind_filename(system_info: &SystemInfo) -> Result { )) } +/// Parse a valgrind version string and extract the semantic version. +/// Expected format: "valgrind-3.25.1.codspeed" or "3.25.1.codspeed" +/// Returns Some(Version) if parsing succeeds, None otherwise. +fn parse_valgrind_codspeed_version(version_str: &str) -> Option { + let version_str = version_str.trim(); + + // Extract the version numbers before .codspeed + let version_part = if let Some(codspeed_idx) = version_str.find(".codspeed") { + &version_str[..codspeed_idx] + } else { + return None; + }; + + // Remove "valgrind-" prefix if present + let version_part = version_part + .strip_prefix("valgrind-") + .unwrap_or(version_part); + + // Parse using semver + Version::parse(version_part).ok() +} + fn is_valgrind_installed() -> bool { let is_valgrind_installed = Command::new("which") .arg("valgrind") @@ -35,28 +61,55 @@ fn is_valgrind_installed() -> bool { return false; } - if let Ok(version_output) = Command::new("valgrind").arg("--version").output() { - if !version_output.status.success() { - debug!( - "Failed to get valgrind version. stderr: {}", - String::from_utf8_lossy(&version_output.stderr) - ); - return false; - } - - let version = String::from_utf8_lossy(&version_output.stdout); - let result = version.contains(VALGRIND_CODSPEED_VERSION.as_str()); - if !result { - warn!( - "Valgrind is installed but the version is not the expected one. expecting {} but found installed: {}", - VALGRIND_CODSPEED_VERSION.as_str(), - version - ); - } - result - } else { - false + let Ok(version_output) = Command::new("valgrind").arg("--version").output() else { + return false; + }; + + if !version_output.status.success() { + debug!( + "Failed to get valgrind version. stderr: {}", + String::from_utf8_lossy(&version_output.stderr) + ); + return false; + } + + let version = String::from_utf8_lossy(&version_output.stdout); + + // Check if it's a codspeed version + if !version.contains(".codspeed") { + warn!( + "Valgrind is installed but is not a CodSpeed version. expecting {} but found installed: {}", + VALGRIND_CODSPEED_VERSION_STRING.as_str(), + version.trim() + ); + return false; + } + + // Parse the installed version + let Some(installed_version) = parse_valgrind_codspeed_version(&version) else { + warn!( + "Could not parse valgrind version. expecting {} but found installed: {}", + VALGRIND_CODSPEED_VERSION_STRING.as_str(), + version.trim() + ); + return false; + }; + if installed_version < VALGRIND_CODSPEED_VERSION { + warn!( + "Valgrind is installed but the version is too old. expecting {} or higher but found installed: {}", + VALGRIND_CODSPEED_VERSION_STRING.as_str(), + version.trim() + ); + return false; } + if installed_version > VALGRIND_CODSPEED_VERSION { + warn!( + "Using experimental valgrind version {}.codspeed. The recommended version is {}", + installed_version, + VALGRIND_CODSPEED_VERSION_STRING.as_str() + ); + } + true } pub async fn install_valgrind( @@ -103,7 +156,7 @@ mod tests { }; assert_snapshot!( get_codspeed_valgrind_filename(&system_info).unwrap(), - @"valgrind_3.24.0-0codspeed1_ubuntu-22.04_amd64.deb" + @"valgrind_3.25.1-3codspeed2_ubuntu-22.04_amd64.deb" ); } @@ -117,7 +170,7 @@ mod tests { }; assert_snapshot!( get_codspeed_valgrind_filename(&system_info).unwrap(), - @"valgrind_3.24.0-0codspeed1_ubuntu-24.04_amd64.deb" + @"valgrind_3.25.1-3codspeed2_ubuntu-24.04_amd64.deb" ); } @@ -131,7 +184,7 @@ mod tests { }; assert_snapshot!( get_codspeed_valgrind_filename(&system_info).unwrap(), - @"valgrind_3.24.0-0codspeed1_ubuntu-22.04_amd64.deb" + @"valgrind_3.25.1-3codspeed2_ubuntu-22.04_amd64.deb" ); } @@ -145,7 +198,44 @@ mod tests { }; assert_snapshot!( get_codspeed_valgrind_filename(&system_info).unwrap(), - @"valgrind_3.24.0-0codspeed1_ubuntu-22.04_arm64.deb" + @"valgrind_3.25.1-3codspeed2_ubuntu-22.04_arm64.deb" + ); + } + + #[test] + fn test_parse_valgrind_codspeed_version_with_prefix() { + let version = parse_valgrind_codspeed_version("valgrind-3.25.1.codspeed").unwrap(); + assert_eq!(version, Version::new(3, 25, 1)); + } + + #[test] + fn test_parse_valgrind_codspeed_version_without_prefix() { + let version = parse_valgrind_codspeed_version("3.25.1.codspeed").unwrap(); + assert_eq!(version, Version::new(3, 25, 1)); + } + + #[test] + fn test_parse_valgrind_codspeed_version_higher_patch() { + let version = parse_valgrind_codspeed_version("valgrind-3.25.2.codspeed").unwrap(); + assert_eq!(version, Version::new(3, 25, 2)); + } + + #[test] + fn test_parse_valgrind_codspeed_version_with_newline() { + let version = parse_valgrind_codspeed_version("valgrind-3.25.1.codspeed\n").unwrap(); + assert_eq!(version, Version::new(3, 25, 1)); + } + + #[test] + fn test_parse_valgrind_codspeed_version_without_codspeed_suffix() { + assert_eq!(parse_valgrind_codspeed_version("valgrind-3.25.1"), None); + } + + #[test] + fn test_parse_valgrind_codspeed_version_invalid_format() { + assert_eq!( + parse_valgrind_codspeed_version("valgrind-3.25.codspeed"), + None ); } }