mirror of
https://github.com/sharkdp/hyperfine.git
synced 2026-11-01 08:50:19 +00:00
Fix panic on --runs 0 (#923)
* fix: reject --runs/--max-runs 0, clamp --min-runs to 1 * Validate positive run counts with clap --------- Co-authored-by: VXNCXNX <VXNCXNX@users.noreply.github.com> Co-authored-by: David Peter <mail@david-peter.de>
This commit is contained in:
3 files changed
+37
-14
No files matched your search
@@ -41,6 +41,7 @@ fn build_command() -> Command {
|
||||
.short('w')
|
||||
.value_name("NUM")
|
||||
.action(ArgAction::Set)
|
||||
.value_parser(clap::value_parser!(u64))
|
||||
.help(
|
||||
"Perform NUM warmup runs before the actual benchmark. This can be used \
|
||||
to fill (disk) caches for I/O-heavy programs.",
|
||||
@@ -52,6 +53,7 @@ fn build_command() -> Command {
|
||||
.short('m')
|
||||
.action(ArgAction::Set)
|
||||
.value_name("NUM")
|
||||
.value_parser(clap::value_parser!(u64).range(1..))
|
||||
.help("Perform at least NUM runs for each command (default: 10)."),
|
||||
)
|
||||
.arg(
|
||||
@@ -60,6 +62,7 @@ fn build_command() -> Command {
|
||||
.short('M')
|
||||
.action(ArgAction::Set)
|
||||
.value_name("NUM")
|
||||
.value_parser(clap::value_parser!(u64).range(1..))
|
||||
.help("Perform at most NUM runs for each command. By default, there is no limit."),
|
||||
)
|
||||
.arg(
|
||||
@@ -69,6 +72,7 @@ fn build_command() -> Command {
|
||||
.short('r')
|
||||
.action(ArgAction::Set)
|
||||
.value_name("NUM")
|
||||
.value_parser(clap::value_parser!(u64).range(1..))
|
||||
.help("Perform exactly NUM runs for each command. If this option is not specified, \
|
||||
hyperfine automatically determines the number of runs."),
|
||||
)
|
||||
|
||||
+7
-14
@@ -275,22 +275,15 @@ impl Default for Options {
|
||||
impl Options {
|
||||
pub fn from_cli_arguments<'a>(matches: &ArgMatches) -> Result<Self, OptionsError<'a>> {
|
||||
let mut options = Self::default();
|
||||
let param_to_u64 = |param| {
|
||||
matches
|
||||
.get_one::<String>(param)
|
||||
.map(|n| {
|
||||
n.parse::<u64>()
|
||||
.map_err(|e| OptionsError::IntParsingError(param, e))
|
||||
})
|
||||
.transpose()
|
||||
};
|
||||
options.warmup_count = matches
|
||||
.get_one::<u64>("warmup")
|
||||
.copied()
|
||||
.unwrap_or(options.warmup_count);
|
||||
|
||||
options.warmup_count = param_to_u64("warmup")?.unwrap_or(options.warmup_count);
|
||||
let mut min_runs = matches.get_one::<u64>("min-runs").copied();
|
||||
let mut max_runs = matches.get_one::<u64>("max-runs").copied();
|
||||
|
||||
let mut min_runs = param_to_u64("min-runs")?;
|
||||
let mut max_runs = param_to_u64("max-runs")?;
|
||||
|
||||
if let Some(runs) = param_to_u64("runs")? {
|
||||
if let Some(&runs) = matches.get_one::<u64>("runs") {
|
||||
min_runs = Some(runs);
|
||||
max_runs = Some(runs);
|
||||
}
|
||||
|
||||
@@ -74,6 +74,32 @@ fn exits_quietly_when_stdout_is_closed() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fails_with_zero_runs() {
|
||||
for option in ["--runs", "--min-runs", "--max-runs"] {
|
||||
hyperfine()
|
||||
.arg(option)
|
||||
.arg("0")
|
||||
.arg("echo dummy benchmark")
|
||||
.assert()
|
||||
.code(2)
|
||||
.stderr(predicate::str::contains(format!(
|
||||
"invalid value '0' for '{option} <NUM>'"
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn min_runs_of_one_still_performs_one_run() {
|
||||
hyperfine_debug()
|
||||
.arg("--min-runs=1")
|
||||
.arg("--warmup=0")
|
||||
.arg("sleep 4")
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(predicate::str::contains("Time (abs ≡)"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_run_commands_without_a_shell() {
|
||||
hyperfine()
|
||||
|
||||
Reference in new issue
Block a user