Skip to content

Commit 7c5e040

Browse files
committed
refactor(valgrind): parse codspeed iteration from version string
Return a ValgrindVersion { semver, codspeed_iteration } from parse_valgrind_codspeed_version so the runner can distinguish between codspeed iterations of the same upstream valgrind version (e.g. 3.26.0.codspeed1 vs 3.26.0.codspeed2). The legacy `.codspeed` form (no iteration) is still accepted and yields codspeed_iteration: None. Refs COD-2674.
1 parent 873caf0 commit 7c5e040

1 file changed

Lines changed: 51 additions & 22 deletions

File tree

src/executor/valgrind/setup.rs

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53,26 +53,38 @@ pub(super) fn is_codspeed_valgrind_installation_supported(system_info: &SystemIn
5353
get_codspeed_valgrind_target(system_info).is_ok()
5454
}
5555

56-
/// Parse a valgrind version string and extract the semantic version.
57-
/// Expected format: "valgrind-3.25.1.codspeed" or "3.25.1.codspeed"
58-
/// Returns Some(Version) if parsing succeeds, None otherwise.
59-
fn parse_valgrind_codspeed_version(version_str: &str) -> Option<Version> {
60-
let version_str = version_str.trim();
61-
62-
// Extract the version numbers before .codspeed
63-
let version_part = if let Some(codspeed_idx) = version_str.find(".codspeed") {
64-
&version_str[..codspeed_idx]
65-
} else {
66-
return None;
67-
};
56+
#[derive(Debug, Clone, PartialEq, Eq)]
57+
struct ValgrindVersion {
58+
semver: Version,
59+
codspeed_iteration: Option<u32>,
60+
}
6861

69-
// Remove "valgrind-" prefix if present
70-
let version_part = version_part
62+
/// Parse a valgrind version string and extract the upstream semver plus the
63+
/// optional CodSpeed iteration number.
64+
///
65+
/// Accepted formats:
66+
/// - `valgrind-3.25.1.codspeed` (legacy, no iteration)
67+
/// - `valgrind-3.25.1.codspeed2` (with iteration)
68+
/// - same forms without the `valgrind-` prefix
69+
fn parse_valgrind_codspeed_version(version_str: &str) -> Option<ValgrindVersion> {
70+
let stripped = version_str
71+
.trim()
7172
.strip_prefix("valgrind-")
72-
.unwrap_or(version_part);
73+
.unwrap_or(version_str.trim());
74+
75+
let (semver_part, iteration_part) = stripped.split_once(".codspeed")?;
76+
let semver = Version::parse(semver_part).ok()?;
77+
78+
let codspeed_iteration = if iteration_part.is_empty() {
79+
None
80+
} else {
81+
Some(iteration_part.parse::<u32>().ok()?)
82+
};
7383

74-
// Parse using semver
75-
Version::parse(version_part).ok()
84+
Some(ValgrindVersion {
85+
semver,
86+
codspeed_iteration,
87+
})
7688
}
7789

7890
const TOOL_NAME: &str = "valgrind";
@@ -136,7 +148,7 @@ pub fn get_valgrind_status() -> ToolStatus {
136148
};
137149
};
138150

139-
if installed_version < VALGRIND_CODSPEED_VERSION {
151+
if installed_version.semver < VALGRIND_CODSPEED_VERSION {
140152
return ToolStatus {
141153
tool_name,
142154
status: ToolInstallStatus::IncorrectVersion {
@@ -275,32 +287,49 @@ mod tests {
275287
#[test]
276288
fn test_parse_valgrind_codspeed_version_with_prefix() {
277289
let version = parse_valgrind_codspeed_version("valgrind-3.25.1.codspeed").unwrap();
278-
assert_eq!(version, Version::new(3, 25, 1));
290+
assert_eq!(version.semver, Version::new(3, 25, 1));
291+
assert_eq!(version.codspeed_iteration, None);
279292
}
280293

281294
#[test]
282295
fn test_parse_valgrind_codspeed_version_without_prefix() {
283296
let version = parse_valgrind_codspeed_version("3.25.1.codspeed").unwrap();
284-
assert_eq!(version, Version::new(3, 25, 1));
297+
assert_eq!(version.semver, Version::new(3, 25, 1));
298+
assert_eq!(version.codspeed_iteration, None);
285299
}
286300

287301
#[test]
288302
fn test_parse_valgrind_codspeed_version_higher_patch() {
289303
let version = parse_valgrind_codspeed_version("valgrind-3.25.2.codspeed").unwrap();
290-
assert_eq!(version, Version::new(3, 25, 2));
304+
assert_eq!(version.semver, Version::new(3, 25, 2));
291305
}
292306

293307
#[test]
294308
fn test_parse_valgrind_codspeed_version_with_newline() {
295309
let version = parse_valgrind_codspeed_version("valgrind-3.25.1.codspeed\n").unwrap();
296-
assert_eq!(version, Version::new(3, 25, 1));
310+
assert_eq!(version.semver, Version::new(3, 25, 1));
297311
}
298312

299313
#[test]
300314
fn test_parse_valgrind_codspeed_version_without_codspeed_suffix() {
301315
assert_eq!(parse_valgrind_codspeed_version("valgrind-3.25.1"), None);
302316
}
303317

318+
#[test]
319+
fn test_parse_valgrind_codspeed_version_iterations_are_differentiated() {
320+
let legacy = parse_valgrind_codspeed_version("valgrind-3.26.0.codspeed").unwrap();
321+
let v1 = parse_valgrind_codspeed_version("valgrind-3.26.0.codspeed1").unwrap();
322+
let v2 = parse_valgrind_codspeed_version("valgrind-3.26.0.codspeed2").unwrap();
323+
324+
assert_eq!(legacy.semver, v1.semver);
325+
assert_eq!(legacy.codspeed_iteration, None);
326+
assert_eq!(v1.codspeed_iteration, Some(1));
327+
assert_eq!(v2.codspeed_iteration, Some(2));
328+
329+
assert_ne!(legacy, v1);
330+
assert_ne!(v1, v2);
331+
}
332+
304333
#[test]
305334
fn test_parse_valgrind_codspeed_version_invalid_format() {
306335
assert_eq!(

0 commit comments

Comments
 (0)