use std::{
ffi::OsString,
path::PathBuf,
process::{Command, ExitStatus},
thread::{self, JoinHandle},
time::Duration,
};
const MILTERTEST: &str = "miltertest";
pub fn test_name(test_file_name: &str) -> OsString {
PathBuf::from(test_file_name)
.as_path()
.file_stem()
.expect("no file stem")
.to_os_string()
}
pub fn spawn_miltertest_runner(test_file_name: &str) -> JoinHandle<ExitStatus> {
let _timeout_thread = thread::spawn(|| {
thread::sleep(Duration::from_secs(15));
eprintln!("miltertest runner timed out");
milter::shutdown();
});
let file_name = to_miltertest_file_name(test_file_name);
thread::spawn(move || {
thread::sleep(Duration::from_millis(100));
let output = Command::new(MILTERTEST)
.arg("-s")
.arg(&file_name)
.output()
.expect("miltertest execution failed");
print_output_stream("STDOUT", output.stdout);
print_output_stream("STDERR", output.stderr);
milter::shutdown();
output.status
})
}
fn to_miltertest_file_name(file_name: &str) -> OsString {
let mut path = PathBuf::from(file_name);
path.set_extension("lua");
path.into_os_string()
}
fn print_output_stream(name: &str, output: Vec<u8>) {
if !output.is_empty() {
let output = String::from_utf8(output).unwrap();
eprintln!("{}:", name);
if output.ends_with('\n') {
eprint!("{}", &output)
} else {
eprintln!("{}", &output)
}
}
}