From ce286fe1bc8c5fe5711e6a635502ed49653165d1 Mon Sep 17 00:00:00 2001 From: not-matthias Date: Mon, 2 Feb 2026 17:55:03 +0100 Subject: [PATCH] fix(runner): check benchmark URIs rather than memtrack events Memory profiling can be empty, if the benchmark has no allocations. We shouldn't fail in those cases. --- crates/runner-shared/src/artifacts/mod.rs | 11 +++++++-- src/executor/memory/executor.rs | 27 +++++++++++------------ 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/crates/runner-shared/src/artifacts/mod.rs b/crates/runner-shared/src/artifacts/mod.rs index 7a95ebca..6df5ff35 100644 --- a/crates/runner-shared/src/artifacts/mod.rs +++ b/crates/runner-shared/src/artifacts/mod.rs @@ -1,6 +1,8 @@ +use std::io::BufReader; + use libc::pid_t; use log::debug; -use serde::Serialize; +use serde::{Deserialize, Serialize}; mod execution_timestamps; mod memtrack; @@ -10,7 +12,7 @@ pub use memtrack::*; pub trait ArtifactExt where - Self: Sized + Serialize, + Self: Sized + Serialize + for<'de> Deserialize<'de>, { /// WARNING: This doesn't support generic types fn name() -> &'static str { @@ -25,6 +27,11 @@ where } } + fn decode_from_reader(reader: R) -> anyhow::Result { + let reader = BufReader::new(reader); + rmp_serde::from_read(reader).map_err(anyhow::Error::from) + } + fn encode_to_writer(&self, mut writer: W) -> anyhow::Result<()> { let encoded = rmp_serde::to_vec_named(self)?; writer.write_all(&encoded)?; diff --git a/src/executor/memory/executor.rs b/src/executor/memory/executor.rs index 388f7193..53688db0 100644 --- a/src/executor/memory/executor.rs +++ b/src/executor/memory/executor.rs @@ -16,7 +16,7 @@ use async_trait::async_trait; use ipc_channel::ipc; use memtrack::MemtrackIpcClient; use memtrack::MemtrackIpcServer; -use runner_shared::artifacts::{ArtifactExt, ExecutionTimestamps, MemtrackArtifact}; +use runner_shared::artifacts::{ArtifactExt, ExecutionTimestamps}; use runner_shared::fifo::Command as FifoCommand; use runner_shared::fifo::IntegrationMode; use semver::Version; @@ -121,28 +121,27 @@ impl Executor for MemoryExecutor { } async fn teardown(&self, execution_context: &ExecutionContext) -> Result<()> { - let files: Vec<_> = std::fs::read_dir(execution_context.profile_folder.join("results"))? + let results_dir = execution_context.profile_folder.join("results"); + let has_benchmarks = std::fs::read_dir(&results_dir)? .filter_map(Result::ok) - // Filter out non-memtrack files: + // Filter out non-ExecutionTimestamps files: .filter(|entry| { entry .file_name() .to_string_lossy() - .contains(MemtrackArtifact::name()) + .contains(ExecutionTimestamps::name()) }) - .flat_map(|f| std::fs::File::open(f.path())) - .filter(|file| !MemtrackArtifact::is_empty(file)) - .collect(); + .filter_map(|entry| { + let file = std::fs::File::open(entry.path()).ok()?; + ExecutionTimestamps::decode_from_reader(file).ok() + }) + .any(|artifact| !artifact.uri_by_ts.is_empty()); - if files.is_empty() { + if !has_benchmarks { if !execution_context.config.allow_empty { - bail!( - "No memtrack artifact files found. Does the integration support memory profiling?" - ); + bail!("No memory results found in profile folder: {results_dir:?}."); } else { - info!( - "No memtrack artifact files found. Does the integration support memory profiling?" - ); + info!("No memory results found in profile folder: {results_dir:?}."); } }