Adding timeout to local run
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
+use std::time::Duration;
+
use anyhow::Result;
-use clap::{App, SubCommand};
+use clap::{App, Arg, SubCommand};
+use tokio::time::timeout;
use crate::local::{
common::add_common_config, generic_analysis, generic_crash_report, generic_generator,
@@ -22,7 +25,12 @@ const GENERIC_GENERATOR: &str = "generator";
const GENERIC_ANALYSIS: &str = "analysis";
const GENERIC_TEST_INPUT: &str = "test-input";
+const TIMEOUT: &str = "timeout";
+
pub async fn run(args: &clap::ArgMatches<'_>) -> Result<()> {
+ let running_duration = value_t!(args, TIMEOUT, u64).ok();
+
+ let run = async {
match args.subcommand() {
(RADAMSA, Some(sub)) => radamsa::run(sub).await,
(LIBFUZZER, Some(sub)) => libfuzzer::run(sub).await,
@@ -39,11 +47,30 @@ pub async fn run(args: &clap::ArgMatches<'_>) -> Result<()> {
anyhow::bail!("missing subcommand\nUSAGE: {}", args.usage());
}
}
+ };
+
+ if let Some(minutes) = running_duration {
+ if let Ok(run) = timeout(Duration::from_secs(minutes * 60), run).await {
+ run
+ } else {
+ info!("The running timeout period has elapsed");
+ Ok(())
+ }
+ } else {
+ run.await
+ }
}
pub fn args(name: &str) -> App<'static, 'static> {
SubCommand::with_name(name)
.about("pre-release local fuzzing")
+ .arg(
+ Arg::with_name(TIMEOUT)
+ .long(TIMEOUT)
+ .help("The maximum running time in minutes")
+ .takes_value(true)
+ .required(false),
+ )
.subcommand(add_common_config(radamsa::args(RADAMSA)))
.subcommand(add_common_config(libfuzzer::args(LIBFUZZER)))
.subcommand(add_common_config(libfuzzer_fuzz::args(LIBFUZZER_FUZZ)))
