Skip to content

Commit 21d01f3

Browse files
committed
Support aggregate bench
1 parent 03aa27a commit 21d01f3

File tree

1 file changed

+121
-1
lines changed

1 file changed

+121
-1
lines changed

spdlog/benches/common/mod.rs

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
use std::{
2-
env, fs,
2+
env,
3+
fmt::Write,
4+
fs,
35
path::{Path, PathBuf},
6+
process::{self, Stdio},
7+
str,
48
};
59

610
use once_cell::sync::Lazy;
@@ -47,3 +51,119 @@ macro_rules! required_multi_thread_feature {
4751
compile_error!("please rerun `cargo bench` with `--features multi-thread`");
4852
};
4953
}
54+
55+
#[macro_export]
56+
macro_rules! aggregate_bench_main {
57+
() => {
58+
fn main() {
59+
common::__aggregate_bench_main_impl(
60+
&std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
61+
.parent()
62+
.unwrap()
63+
.join(file!()),
64+
);
65+
}
66+
};
67+
}
68+
69+
// Some log crates are based on `log` crate, which has only one global logger
70+
// instance, meaning that the logger is only allowed to be configured once. In
71+
// order to bench multiple different configurations, we need multiple child
72+
// processes to bench, and this function is used as a launcher for those child
73+
// processes.
74+
pub fn __aggregate_bench_main_impl(source_file: &Path) {
75+
let args = env::args().collect::<Vec<_>>();
76+
if args.len() != 2 || args.get(1).unwrap() != "--bench" {
77+
eprintln!(
78+
"error: this is an aggregate bench and is supposed to be run only by `cargo bench`"
79+
);
80+
process::exit(1);
81+
}
82+
83+
let current_exe = env::current_exe().unwrap();
84+
let current_dir = current_exe.parent().unwrap();
85+
86+
let name = format!("{}_", env!("CARGO_CRATE_NAME"));
87+
88+
let mut sub_benches = fs::read_dir(current_dir)
89+
.unwrap()
90+
.filter_map(|p| p.ok())
91+
.filter(|p| {
92+
#[cfg(unix)]
93+
let is_executable = p.path().metadata().is_ok_and(|m| {
94+
use std::os::unix::fs::PermissionsExt;
95+
m.is_file() && m.permissions().mode() & 0o111 != 0
96+
});
97+
#[cfg(windows)]
98+
let is_executable = p.path().extension().is_some_and(|ext| ext == "exe");
99+
100+
p.file_name().to_string_lossy().starts_with(&name) && is_executable
101+
// TODO: Test it on Windows
102+
})
103+
.collect::<Vec<_>>();
104+
sub_benches.sort_by_key(|p| p.file_name());
105+
106+
let mut sub_bench_sources = fs::read_dir(Path::new(source_file).parent().unwrap())
107+
.unwrap()
108+
.filter_map(|p| p.ok())
109+
.filter(|p| {
110+
p.file_name()
111+
.to_string_lossy()
112+
.chars()
113+
.next()
114+
.is_some_and(|ch| ch.is_ascii_digit())
115+
&& p.path().extension().is_some_and(|ext| ext == "rs")
116+
})
117+
.collect::<Vec<_>>();
118+
sub_bench_sources.sort_by_key(|p| p.file_name());
119+
120+
fn exit_as_files_mismatch() {
121+
eprintln!(
122+
"error: not all expected sub-benches have been built. try running `cargo bench` directly instead of specifying a `--bench` option."
123+
);
124+
process::exit(1);
125+
}
126+
if sub_benches.len() != sub_bench_sources.len() {
127+
exit_as_files_mismatch();
128+
}
129+
sub_bench_sources
130+
.into_iter()
131+
.zip(sub_benches.iter())
132+
.for_each(|(source, bin)| {
133+
let expected_start = format!(
134+
"{}_{}-",
135+
env!("CARGO_CRATE_NAME"),
136+
source.path().file_stem().unwrap().to_string_lossy()
137+
);
138+
if !bin
139+
.file_name()
140+
.to_string_lossy()
141+
.starts_with(&expected_start)
142+
{
143+
exit_as_files_mismatch();
144+
}
145+
});
146+
147+
let mut captured_stdout = String::new();
148+
for sub_bench in sub_benches {
149+
let output = process::Command::new(sub_bench.path())
150+
.arg("--bench")
151+
.stdout(Stdio::piped())
152+
.stderr(Stdio::inherit())
153+
.output()
154+
.unwrap();
155+
assert!(output.status.success());
156+
157+
captured_stdout
158+
.write_str(str::from_utf8(&output.stdout).unwrap())
159+
.unwrap();
160+
}
161+
162+
let results = captured_stdout
163+
.lines()
164+
.filter(|line| line.contains("test ") && line.contains(" ... "))
165+
.collect::<Vec<_>>()
166+
.join("\n");
167+
168+
println!("{}", results);
169+
}

0 commit comments

Comments
 (0)