Skip to content

Commit b14b355

Browse files
committed
add support for benchmarks
1 parent 9388c8e commit b14b355

File tree

1 file changed

+49
-4
lines changed

1 file changed

+49
-4
lines changed

src/bootstrap/render_tests.rs

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ fn run_tests(builder: &Builder<'_>, cmd: &mut Command) -> bool {
5757
struct Renderer<'a> {
5858
stdout: BufReader<ChildStdout>,
5959
failures: Vec<TestOutcome>,
60+
benches: Vec<BenchOutcome>,
6061
builder: &'a Builder<'a>,
6162
tests_count: Option<usize>,
6263
executed_tests: usize,
@@ -67,6 +68,7 @@ impl<'a> Renderer<'a> {
6768
fn new(stdout: ChildStdout, builder: &'a Builder<'a>) -> Self {
6869
Self {
6970
stdout: BufReader::new(stdout),
71+
benches: Vec::new(),
7072
failures: Vec::new(),
7173
builder,
7274
tests_count: None,
@@ -104,7 +106,7 @@ impl<'a> Renderer<'a> {
104106
self.builder.metrics.record_test(
105107
&test.name,
106108
match outcome {
107-
Outcome::Ok => crate::metrics::TestOutcome::Passed,
109+
Outcome::Ok | Outcome::BenchOk => crate::metrics::TestOutcome::Passed,
108110
Outcome::Failed => crate::metrics::TestOutcome::Failed,
109111
Outcome::Ignored { reason } => crate::metrics::TestOutcome::Ignored {
110112
ignore_reason: reason.map(|s| s.to_string()),
@@ -169,6 +171,26 @@ impl<'a> Renderer<'a> {
169171
}
170172
}
171173

174+
if !self.benches.is_empty() {
175+
println!("\nbenchmarks:");
176+
177+
let mut rows = Vec::new();
178+
for bench in &self.benches {
179+
rows.push((
180+
&bench.name,
181+
format!("{:.2?}/iter", Duration::from_nanos(bench.median)),
182+
format!("+/- {:.2?}", Duration::from_nanos(bench.deviation)),
183+
));
184+
}
185+
186+
let max_0 = rows.iter().map(|r| r.0.len()).max().unwrap_or(0);
187+
let max_1 = rows.iter().map(|r| r.1.len()).max().unwrap_or(0);
188+
let max_2 = rows.iter().map(|r| r.2.len()).max().unwrap_or(0);
189+
for row in &rows {
190+
println!(" {:<max_0$} {:>max_1$} {:>max_2$}", row.0, row.1, row.2);
191+
}
192+
}
193+
172194
println!(
173195
"\ntest result: {}. {} passed; {} failed; {} ignored; {} measured; \
174196
{} filtered out; finished in {:.2?}\n",
@@ -196,6 +218,21 @@ impl<'a> Renderer<'a> {
196218
Message::Suite(SuiteMessage::Failed(outcome)) => {
197219
self.render_suite_outcome(Outcome::Failed, &outcome);
198220
}
221+
Message::Bench(outcome) => {
222+
// The formatting for benchmarks doesn't replicate 1:1 the formatting libtest
223+
// outputs, mostly because libtest's formatting is broken in terse mode, which is
224+
// the default used by our monorepo. We use a different formatting instead:
225+
// successful benchmarks are just showed as "benchmarked"/"b", and the details are
226+
// outputted at the bottom like failures.
227+
let fake_test_outcome = TestOutcome {
228+
name: outcome.name.clone(),
229+
exec_time: None,
230+
stdout: None,
231+
reason: None,
232+
};
233+
self.render_test_outcome(Outcome::BenchOk, &fake_test_outcome);
234+
self.benches.push(outcome);
235+
}
199236
Message::Test(TestMessage::Ok(outcome)) => {
200237
self.render_test_outcome(Outcome::Ok, &outcome);
201238
}
@@ -210,13 +247,13 @@ impl<'a> Renderer<'a> {
210247
self.failures.push(outcome);
211248
}
212249
Message::Test(TestMessage::Started) => {} // Not useful
213-
Message::Test(TestMessage::Bench) => todo!("benchmarks are not supported yet"),
214250
}
215251
}
216252
}
217253

218254
enum Outcome<'a> {
219255
Ok,
256+
BenchOk,
220257
Failed,
221258
Ignored { reason: Option<&'a str> },
222259
}
@@ -225,6 +262,7 @@ impl Outcome<'_> {
225262
fn short(&self, builder: &Builder<'_>) -> String {
226263
match self {
227264
Outcome::Ok => builder.color_for_stdout(Color::Green, "."),
265+
Outcome::BenchOk => builder.color_for_stdout(Color::Cyan, "b"),
228266
Outcome::Failed => builder.color_for_stdout(Color::Red, "F"),
229267
Outcome::Ignored { .. } => builder.color_for_stdout(Color::Yellow, "i"),
230268
}
@@ -233,6 +271,7 @@ impl Outcome<'_> {
233271
fn long(&self, builder: &Builder<'_>) -> String {
234272
match self {
235273
Outcome::Ok => builder.color_for_stdout(Color::Green, "ok"),
274+
Outcome::BenchOk => builder.color_for_stdout(Color::Cyan, "benchmarked"),
236275
Outcome::Failed => builder.color_for_stdout(Color::Red, "FAILED"),
237276
Outcome::Ignored { reason: None } => builder.color_for_stdout(Color::Yellow, "ignored"),
238277
Outcome::Ignored { reason: Some(reason) } => {
@@ -247,6 +286,7 @@ impl Outcome<'_> {
247286
enum Message {
248287
Suite(SuiteMessage),
249288
Test(TestMessage),
289+
Bench(BenchOutcome),
250290
}
251291

252292
#[derive(serde_derive::Deserialize)]
@@ -273,11 +313,16 @@ enum TestMessage {
273313
Ok(TestOutcome),
274314
Failed(TestOutcome),
275315
Ignored(TestOutcome),
276-
// Ignored messages:
277-
Bench,
278316
Started,
279317
}
280318

319+
#[derive(serde_derive::Deserialize)]
320+
struct BenchOutcome {
321+
name: String,
322+
median: u64,
323+
deviation: u64,
324+
}
325+
281326
#[derive(serde_derive::Deserialize)]
282327
struct TestOutcome {
283328
name: String,

0 commit comments

Comments
 (0)