use std::path::PathBuf;
use clap::Parser;
use colored::Colorize;
use rand::RngExt as _;
use crate::CommonOpts;
use crate::cli_wrapper::display_cmd;
use crate::cli_wrapper::*;
#[derive(Parser, Debug)]
pub struct ChaosStressOpts {
#[clap(long, default_value = "100")]
max_iterations_count: i32,
#[clap(value_name = "PROGRAM")]
guest_program: PathBuf,
#[clap(long)]
hermit_arg: Vec<String>,
#[clap(value_name = "ARGS")]
args: Vec<String>,
}
impl ChaosStressOpts {
fn run_hermit(&self, common_args: &CommonOpts) -> anyhow::Result<bool> {
let mut rng = rand::rng();
let random_seed: u16 = rng.random();
let hermit_cli_args = Hermit::new()
.run(self.guest_program.clone(), self.args.clone())
.hermit_args(self.hermit_arg.clone())
.seed(i32::from(random_seed))
.log_level(tracing::Level::WARN)
.into_args();
let mut command = std::process::Command::new("time");
command.arg(&common_args.hermit_bin);
command.args(hermit_cli_args);
println!(" {}", display_cmd(&command).white().bold());
let status = command.status()?;
let status_code = status.code().unwrap_or(0);
println!("Executed command with status: {}", status_code);
Ok(status_code == 0)
}
pub fn run(&self, common_args: &CommonOpts) -> anyhow::Result<bool> {
println!("Run at max {} iterations", self.max_iterations_count);
let mut success_count = 0;
let mut fail_count = 0;
for i in 1..=self.max_iterations_count {
println!("{}", format!(":: Run #{}...", i).yellow().bold());
if self.run_hermit(common_args)? {
success_count += 1;
} else {
fail_count += 1;
}
if success_count > 0 && fail_count > 0 {
return Ok(true);
}
}
Ok(false)
}
}