Skip to content

Commit 2412f46

Browse files
committed
Stream Cargo output interactively when compiling runtime benchmarks
This also formats any compilation errors in runtime benchmarks properly and prints them to stdout.
1 parent d386f1e commit 2412f46

File tree

2 files changed

+49
-33
lines changed

2 files changed

+49
-33
lines changed

collector/src/runtime/benchmark.rs

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
use crate::toolchain::LocalToolchain;
12
use benchlib::benchmark::passes_filter;
23
use cargo_metadata::Message;
34
use core::option::Option;
45
use core::option::Option::Some;
56
use core::result::Result::Ok;
7+
use std::io::BufReader;
68
use std::path::{Path, PathBuf};
7-
use std::process::Command;
9+
use std::process::{Child, Command, Stdio};
810

911
/// A binary that defines several benchmarks using the `run_benchmark_group` function from
1012
/// `benchlib`.
@@ -65,10 +67,17 @@ impl BenchmarkFilter {
6567
/// We assume that each binary defines a benchmark suite using `benchlib`.
6668
/// We then execute each benchmark suite with the `list-benchmarks` command to find out its
6769
/// benchmark names.
68-
pub fn discover_benchmarks(cargo_stdout: &[u8]) -> anyhow::Result<BenchmarkSuite> {
70+
pub fn discover_benchmarks(
71+
toolchain: &LocalToolchain,
72+
dir: &Path,
73+
) -> anyhow::Result<BenchmarkSuite> {
74+
log::info!("Compiling runtime benchmarks");
75+
let mut child = start_runtime_benchmarks_compilation(toolchain, dir)?;
76+
6977
let mut groups = vec![];
7078

71-
for message in Message::parse_stream(cargo_stdout) {
79+
let stream = BufReader::new(child.stdout.take().unwrap());
80+
for message in Message::parse_stream(stream) {
7281
let message = message?;
7382
match message {
7483
Message::CompilerArtifact(artifact) => {
@@ -81,23 +90,57 @@ pub fn discover_benchmarks(cargo_stdout: &[u8]) -> anyhow::Result<BenchmarkSuite
8190
path.display()
8291
)
8392
})?;
93+
log::info!("Compiled {}", path.display());
8494
groups.push(BenchmarkGroup {
8595
binary: path,
8696
benchmark_names: benchmarks,
8797
});
8898
}
8999
}
90100
}
91-
_ => {}
101+
Message::TextLine(line) => println!("{}", line),
102+
Message::CompilerMessage(msg) => {
103+
print!("{}", msg.message.rendered.unwrap_or(msg.message.message))
104+
}
105+
_ => {
106+
log::debug!("Cargo metadata output: {:?}", message);
107+
}
92108
}
93109
}
94110

111+
let output = child.wait()?;
112+
if output.success() {
113+
log::info!("Successfully compiled runtime benchmarks");
114+
} else {
115+
return Err(anyhow::anyhow!("Failed to compile runtime benchmarks"));
116+
}
117+
95118
groups.sort_unstable_by(|a, b| a.binary.cmp(&b.binary));
96119
log::debug!("Found binaries: {:?}", groups);
97120

98121
Ok(BenchmarkSuite { groups })
99122
}
100123

124+
/// Compiles all runtime benchmark binaries (groups) and returns the stdout output stream of Cargo.
125+
fn start_runtime_benchmarks_compilation(
126+
toolchain: &LocalToolchain,
127+
dir: &Path,
128+
) -> anyhow::Result<Child> {
129+
let child = Command::new(&toolchain.cargo)
130+
.env("RUSTC", &toolchain.rustc)
131+
.arg("build")
132+
.arg("--release")
133+
.arg("--message-format")
134+
.arg("json-diagnostic-rendered-ansi")
135+
.current_dir(dir)
136+
.stdin(Stdio::null())
137+
.stdout(Stdio::piped())
138+
.stderr(Stdio::null())
139+
.spawn()
140+
.map_err(|error| anyhow::anyhow!("Failed to start cargo: {:?}", error))?;
141+
Ok(child)
142+
}
143+
101144
/// Uses a command from `benchlib` to find the benchmark names from the given
102145
/// benchmark binary.
103146
fn gather_benchmarks(binary: &Path) -> anyhow::Result<Vec<String>> {

collector/src/runtime/mod.rs

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
mod benchmark;
22

33
use crate::benchmark::profile::Profile;
4-
use crate::toolchain::{get_local_toolchain, LocalToolchain};
4+
use crate::toolchain::get_local_toolchain;
55
use benchlib::comm::messages::{BenchmarkMessage, BenchmarkResult, BenchmarkStats};
66
use std::io::{BufRead, BufReader};
77
use std::path::{Path, PathBuf};
@@ -20,8 +20,7 @@ pub fn bench_runtime(
2020
benchmark_dir: PathBuf,
2121
) -> anyhow::Result<()> {
2222
let toolchain = get_local_toolchain(&[Profile::Opt], rustc, None, None, id, "")?;
23-
let output = compile_runtime_benchmark_binaries(&toolchain, &benchmark_dir)?;
24-
let suite = benchmark::discover_benchmarks(&output)?;
23+
let suite = benchmark::discover_benchmarks(&toolchain, &benchmark_dir)?;
2524

2625
let total_benchmark_count = suite.total_benchmark_count();
2726
let filtered = suite.filtered_benchmark_count(&filter);
@@ -92,32 +91,6 @@ fn execute_runtime_benchmark_binary(
9291
Ok(iterator)
9392
}
9493

95-
/// Compiles all runtime benchmark binaries (groups) and returns the stdout output of Cargo.
96-
fn compile_runtime_benchmark_binaries(
97-
toolchain: &LocalToolchain,
98-
dir: &Path,
99-
) -> anyhow::Result<Vec<u8>> {
100-
let result = Command::new(&toolchain.cargo)
101-
.env("RUSTC", &toolchain.rustc)
102-
.arg("build")
103-
.arg("--release")
104-
.arg("--message-format")
105-
.arg("json")
106-
.current_dir(dir)
107-
.output()?;
108-
109-
if !result.status.success() {
110-
anyhow::bail!(
111-
"Failed to compile runtime benchmarks\n{}\n{}",
112-
String::from_utf8_lossy(&result.stdout),
113-
String::from_utf8_lossy(&result.stderr)
114-
);
115-
} else {
116-
log::info!("Successfully compiled runtime benchmarks");
117-
return Ok(result.stdout);
118-
}
119-
}
120-
12194
fn calculate_mean<I: Iterator<Item = f64> + Clone>(iter: I) -> f64 {
12295
let sum: f64 = iter.clone().sum();
12396
let count = iter.count();

0 commit comments

Comments
 (0)