From 68adbe5da08c9ab88db9aeaf20d771101f77375b Mon Sep 17 00:00:00 2001 From: Guillaume Lagrange Date: Fri, 17 Apr 2026 09:53:49 +0200 Subject: [PATCH 1/2] feat: display a warning when profiling generation failed --- src/api_client.rs | 12 +++++++++++ src/queries/CompareRuns.gql | 5 +++++ src/queries/FetchLocalRun.gql | 3 +++ src/upload/benchmark_display.rs | 9 +++++++++ src/upload/poll_results.rs | 36 +++++++++++++++++++++++++++++++++ 5 files changed, 65 insertions(+) diff --git a/src/api_client.rs b/src/api_client.rs index 58a72e69..c4a40730 100644 --- a/src/api_client.rs +++ b/src/api_client.rs @@ -106,6 +106,14 @@ where s.parse().map_err(de::Error::custom) } +nest! { + #[derive(Debug, Deserialize, Serialize)]* + #[serde(rename_all = "camelCase")]* + pub struct BenchmarkIssues { + pub callgraph_generation_failure: Option, + } +} + nest! { #[derive(Debug, Deserialize, Serialize)]* #[serde(rename_all = "camelCase")]* @@ -119,6 +127,7 @@ nest! { pub name: String, pub executor: ExecutorName, }, + pub issues: Option, pub valgrind: Option, + }>, } } diff --git a/src/queries/CompareRuns.gql b/src/queries/CompareRuns.gql index 9c9b0743..ae4ed364 100644 --- a/src/queries/CompareRuns.gql +++ b/src/queries/CompareRuns.gql @@ -17,6 +17,11 @@ query CompareRuns($owner: String!, $name: String!, $baseRunId: String!, $headRun change category status + result { + issues { + callgraphGenerationFailure + } + } } } } diff --git a/src/queries/FetchLocalRun.gql b/src/queries/FetchLocalRun.gql index 4c211062..f51aaf3b 100644 --- a/src/queries/FetchLocalRun.gql +++ b/src/queries/FetchLocalRun.gql @@ -10,6 +10,9 @@ query FetchLocalRun($owner: String!, $name: String!, $runId: String!) { executor } value + issues { + callgraphGenerationFailure + } valgrind { timeDistribution { ir diff --git a/src/upload/benchmark_display.rs b/src/upload/benchmark_display.rs index 8d1586f5..34c7c41a 100644 --- a/src/upload/benchmark_display.rs +++ b/src/upload/benchmark_display.rs @@ -441,6 +441,7 @@ mod tests { executor: ExecutorName::Valgrind, }, value: 0.001234, + issues: None, valgrind: Some(ValgrindResult { time_distribution: Some(TimeDistribution { ir: 0.001048900, // 85% of 0.001234 @@ -458,6 +459,7 @@ mod tests { executor: ExecutorName::Valgrind, }, value: 0.002567, + issues: None, valgrind: Some(ValgrindResult { time_distribution: Some(TimeDistribution { ir: 0.001796900, // 70% of 0.002567 @@ -476,6 +478,7 @@ mod tests { executor: ExecutorName::WallTime, }, value: 0.150, + issues: None, valgrind: None, walltime: Some(WallTimeResult { iterations: 100.0, @@ -490,6 +493,7 @@ mod tests { executor: ExecutorName::WallTime, }, value: 0.025, + issues: None, valgrind: None, walltime: Some(WallTimeResult { iterations: 500.0, @@ -505,6 +509,7 @@ mod tests { executor: ExecutorName::Memory, }, value: 10485760.0, + issues: None, valgrind: None, walltime: None, memory: Some(MemoryResult { @@ -519,6 +524,7 @@ mod tests { executor: ExecutorName::Memory, }, value: 1048576.0, + issues: None, valgrind: None, walltime: None, memory: Some(MemoryResult { @@ -544,6 +550,7 @@ mod tests { executor: ExecutorName::Valgrind, }, value: 0.001234, // 1.23 ms + issues: None, valgrind: None, walltime: None, memory: None, @@ -562,6 +569,7 @@ mod tests { executor: ExecutorName::WallTime, }, value: 1.5, + issues: None, valgrind: None, walltime: Some(WallTimeResult { iterations: 50.0, @@ -584,6 +592,7 @@ mod tests { executor: ExecutorName::Memory, }, value: 1048576.0, + issues: None, valgrind: None, walltime: None, memory: Some(MemoryResult { diff --git a/src/upload/poll_results.rs b/src/upload/poll_results.rs index 1a0bd560..3c6d0460 100644 --- a/src/upload/poll_results.rs +++ b/src/upload/poll_results.rs @@ -192,6 +192,19 @@ async fn display_single_run_results( } } + let failed: Vec<&str> = response + .run + .results + .iter() + .filter_map(|r| { + r.issues + .as_ref() + .and_then(|i| i.callgraph_generation_failure.as_ref()) + .map(|_| r.benchmark.name.as_str()) + }) + .collect(); + warn_callgraph_failures(&failed); + let run_id = &upload_result.run_id; info!( "\n{} {}", @@ -204,6 +217,16 @@ async fn display_single_run_results( Ok(()) } +fn warn_callgraph_failures(names: &[&str]) { + if names.is_empty() { + return; + } + warn!("We were unable to generate profiling data for the following benchmarks:"); + for name in names { + warn!(" - {name}"); + } +} + fn show_comparison_suggestion(run_id: &str) { info!( "\n{} {}", @@ -269,6 +292,19 @@ async fn display_comparison_results( } } + let failed: Vec<&str> = comparison + .result_comparisons + .iter() + .filter_map(|r| { + r.result + .as_ref() + .and_then(|res| res.issues.as_ref()) + .and_then(|i| i.callgraph_generation_failure.as_ref()) + .map(|_| r.benchmark.name.as_str()) + }) + .collect(); + warn_callgraph_failures(&failed); + info!( "\n{} {}", style("View comparison report:").dim(), From f80b27d5751dd8a897936b2af77c3b7e732f5498 Mon Sep 17 00:00:00 2001 From: Guillaume Lagrange Date: Fri, 17 Apr 2026 10:06:12 +0200 Subject: [PATCH 2/2] feat: do not display the comparison nudge when not in an interactive terminal --- src/upload/poll_results.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/upload/poll_results.rs b/src/upload/poll_results.rs index 3c6d0460..bbe5cda3 100644 --- a/src/upload/poll_results.rs +++ b/src/upload/poll_results.rs @@ -12,7 +12,7 @@ use crate::api_client::{ FetchLocalRunResponse, FetchLocalRunVars, RunStatus, }; use crate::local_logger::icons::Icon; -use crate::local_logger::{start_spinner, stop_spinner}; +use crate::local_logger::{IS_TTY, start_spinner, stop_spinner}; use crate::prelude::*; use super::UploadResult; @@ -228,6 +228,9 @@ fn warn_callgraph_failures(names: &[&str]) { } fn show_comparison_suggestion(run_id: &str) { + if !*IS_TTY { + return; + } info!( "\n{} {}", style("To compare future runs against this one, use:").dim(),