From 615f70ca94aa621a6639698734c6f2e2134c6163 Mon Sep 17 00:00:00 2001 From: Sam Vente Date: Mon, 4 Oct 2021 11:59:00 +0200 Subject: [PATCH] add timeout functionality for bisecting hangs using the GNU coreutils timeout --- src/main.rs | 7 +++++++ src/toolchains.rs | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index eec9009..fec607b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -114,6 +114,13 @@ struct Opts { )] prompt: bool, + #[structopt( + long = "timeout", + short = "t", + help = "Assume failure after specified number of seconds (for bisecting hangs)" + )] + timeout: Option, + #[structopt(short = "v", long = "verbose", parse(from_occurrences))] verbosity: usize, diff --git a/src/toolchains.rs b/src/toolchains.rs index d7ecd54..2312f23 100644 --- a/src/toolchains.rs +++ b/src/toolchains.rs @@ -317,14 +317,15 @@ impl Toolchain { .join(&format!("target-{}", self.rustup_name())), ); } - let mut cmd = match cfg.args.script { - Some(ref script) => { + + let mut cmd = match (cfg.args.script.as_ref(), cfg.args.timeout) { + (Some(script), None) => { let mut cmd = Command::new(script); cmd.env("RUSTUP_TOOLCHAIN", self.rustup_name()); cmd.args(&cfg.args.command_args); cmd } - None => { + (None, None) => { let mut cmd = Command::new("cargo"); cmd.arg(&format!("+{}", self.rustup_name())); if cfg.args.command_args.is_empty() { @@ -334,6 +335,26 @@ impl Toolchain { } cmd } + (Some(script), Some(timeout)) => { + let mut cmd = Command::new("timeout"); + cmd.arg(timeout.to_string()); + cmd.arg(script); + cmd.args(&cfg.args.command_args); + cmd.env("RUSTUP_TOOLCHAIN", self.rustup_name()); + cmd + } + (None, Some(timeout)) => { + let mut cmd = Command::new("timeout"); + cmd.arg(timeout.to_string()); + cmd.arg("cargo"); + cmd.arg(format!("+{}", self.rustup_name())); + if cfg.args.command_args.is_empty() { + cmd.arg("build"); + } else { + cmd.args(&cfg.args.command_args); + } + cmd + } }; cmd.current_dir(&cfg.args.test_dir); cmd.env("CARGO_TARGET_DIR", format!("target-{}", self.rustup_name())); @@ -377,6 +398,14 @@ impl Toolchain { let output = self.run_test(cfg); let status = output.status; + //timeout returns exit code 124 on expiration + if status.code() == Some(124) { + match cfg.args.timeout { + Some(_) => break TestOutcome::Regressed, + None => panic!("Process timed out but no timeout was specified. Please check host configuration for timeouts and try again.") + } + } + eprintln!("\n\n{} finished with exit code {:?}.", self, status.code()); eprintln!("please select an action to take:");