use anyhow::{Context, Result}; use arpx::BinCommand; use std::{ collections::HashMap, env::temp_dir, fs::{write, File}, io::{BufRead, BufReader}, process::{Command, Stdio}, time::{SystemTime, UNIX_EPOCH}, }; pub struct TC { datetime: String, profile_path: String, pub envs: HashMap, pub name: String, pub opts: String, pub profile: String, } impl TC { pub fn new(name: &str) -> Self { Self { datetime: Self::datetime(), envs: HashMap::new(), name: name.to_owned(), opts: String::new(), profile: String::new(), profile_path: String::new(), } } #[allow(dead_code)] pub fn env(mut self, key: &str, value: &str) -> Self { self.envs.insert(key.to_string(), value.to_string()); self } pub fn profile(mut self, input: &str) -> Self { self.profile.push_str(input); let mut dir = temp_dir(); dir.push(format!("{}_{}.yaml", self.name, self.datetime)); self.profile_path = dir.as_path().display().to_string(); File::create(dir) .context("Test profile creation failed") .unwrap(); write(&self.profile_path, &self.profile).unwrap(); self } pub fn opts(mut self, input: &str) -> Self { self.opts.push_str(input); self } pub fn run(self) -> Result<(Vec, Vec)> { let BinCommand { bin, mut args } = BinCommand::system_default(); let test_command = format!( "{} -f {} {}", env!("CARGO_BIN_EXE_arpx"), self.profile_path, self.opts ); args.push(test_command); let output = Command::new(bin) .args(args) .envs(self.envs) .current_dir(String::from(env!("CARGO_MANIFEST_DIR"))) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn() .context("Failed to spawn test command")? .wait_with_output() .context("Failed to wait test command")?; let out = BufReader::new(&*output.stdout) .lines() .map(|l| l.expect("!parse")) .collect(); let err = BufReader::new(&*output.stderr) .lines() .map(|l| l.expect("!parse")) .collect(); Ok((out, err)) } fn datetime() -> String { SystemTime::now() .duration_since(UNIX_EPOCH) .expect("Time went backwards") .as_millis() .to_string() } }