Skip to content

Commit a3bafca

Browse files
committed
Add job duration changes stats in post-merge analysis
1 parent ea1da92 commit a3bafca

File tree

2 files changed

+57
-5
lines changed

2 files changed

+57
-5
lines changed

src/ci/citool/src/analysis.rs

+53-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
use std::collections::{BTreeMap, HashMap, HashSet};
21
use std::fmt::Debug;
32

43
use build_helper::metrics::{
54
BuildStep, JsonRoot, TestOutcome, TestSuite, TestSuiteMetadata, escape_step_name,
65
format_build_steps,
76
};
7+
use std::collections::{BTreeMap, HashMap, HashSet};
8+
use std::time::Duration;
89

910
use crate::metrics;
1011
use crate::metrics::{JobMetrics, JobName, get_test_suites};
@@ -184,11 +185,61 @@ fn render_table(suites: BTreeMap<String, TestSuiteRecord>) -> String {
184185
}
185186

186187
/// Outputs a report of test differences between the `parent` and `current` commits.
187-
pub fn output_test_diffs(job_metrics: HashMap<JobName, JobMetrics>) {
188+
pub fn output_test_diffs(job_metrics: &HashMap<JobName, JobMetrics>) {
188189
let aggregated_test_diffs = aggregate_test_diffs(&job_metrics);
189190
report_test_diffs(aggregated_test_diffs);
190191
}
191192

193+
/// Prints the ten largest differences in bootstrap durations.
194+
pub fn output_largest_duration_changes(job_metrics: &HashMap<JobName, JobMetrics>) {
195+
struct Entry<'a> {
196+
job: &'a JobName,
197+
before: Duration,
198+
after: Duration,
199+
change: f64,
200+
}
201+
202+
let mut changes: Vec<Entry> = vec![];
203+
for (job, metrics) in job_metrics {
204+
if let Some(parent) = &metrics.parent {
205+
let duration_before = parent
206+
.invocations
207+
.iter()
208+
.map(|i| BuildStep::from_invocation(i).duration)
209+
.sum::<Duration>();
210+
let duration_after = metrics
211+
.current
212+
.invocations
213+
.iter()
214+
.map(|i| BuildStep::from_invocation(i).duration)
215+
.sum::<Duration>();
216+
let pct_change = duration_after.as_secs_f64() / duration_before.as_secs_f64();
217+
let pct_change = pct_change * 100.0;
218+
// Normalize around 100, to get + for regression and - for improvements
219+
let pct_change = pct_change - 100.0;
220+
changes.push(Entry {
221+
job,
222+
before: duration_before,
223+
after: duration_after,
224+
change: pct_change,
225+
});
226+
}
227+
}
228+
changes.sort_by(|e1, e2| e1.change.partial_cmp(&e2.change).unwrap().reverse());
229+
230+
println!("# Job duration changes");
231+
for (index, entry) in changes.into_iter().take(10).enumerate() {
232+
println!(
233+
"{}. `{}`: {:.1}s -> {:.1}s ({:.1}%)",
234+
index + 1,
235+
entry.job,
236+
entry.before.as_secs_f64(),
237+
entry.after.as_secs_f64(),
238+
entry.change
239+
);
240+
}
241+
}
242+
192243
#[derive(Default)]
193244
struct TestSuiteRecord {
194245
passed: u64,

src/ci/citool/src/main.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use clap::Parser;
1515
use jobs::JobDatabase;
1616
use serde_yaml::Value;
1717

18-
use crate::analysis::output_test_diffs;
18+
use crate::analysis::{output_largest_duration_changes, output_test_diffs};
1919
use crate::cpu_usage::load_cpu_usage;
2020
use crate::datadog::upload_datadog_metric;
2121
use crate::jobs::RunType;
@@ -160,7 +160,7 @@ fn postprocess_metrics(
160160
job_name,
161161
JobMetrics { parent: Some(parent_metrics), current: metrics },
162162
)]);
163-
output_test_diffs(job_metrics);
163+
output_test_diffs(&job_metrics);
164164
return Ok(());
165165
}
166166
Err(error) => {
@@ -180,7 +180,8 @@ fn post_merge_report(db: JobDatabase, current: String, parent: String) -> anyhow
180180
let metrics = download_auto_job_metrics(&db, &parent, &current)?;
181181

182182
println!("\nComparing {parent} (parent) -> {current} (this PR)\n");
183-
output_test_diffs(metrics);
183+
output_test_diffs(&metrics);
184+
output_largest_duration_changes(&metrics);
184185

185186
Ok(())
186187
}

0 commit comments

Comments
 (0)