thin-provisioning-tools/tests/common/process.rs
2021-10-20 20:23:27 +08:00

118 lines
3.2 KiB
Rust

use anyhow::Result;
use std::ffi::OsString;
use std::fmt;
use std::process;
//------------------------------------------
#[macro_export]
macro_rules! args {
( $( $arg: expr ),* ) => {
{
use std::ffi::OsStr;
let args = [$( OsStr::new($arg) ),*];
args
}
};
}
/// Holds a set of arguments for a shell command
#[derive(Debug)]
pub struct Command {
program: OsString,
args: Vec<OsString>,
}
#[macro_export]
macro_rules! cmd {
( $program:expr $(, $arg:expr )* $(,)? ) => {
{
// use std::ffi::OsString;
let args: &[OsString] = &[$( Into::<OsString>::into($arg) ),*];
Command::new($program, args)
}
};
}
impl Command {
pub fn new(program: OsString, args: Vec<OsString>) -> Self {
Command { program, args }
}
fn to_expr(&self) -> duct::Expression {
duct::cmd(&self.program, &self.args)
}
}
impl fmt::Display for Command {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.program.clone().into_string().unwrap())?;
for a in &self.args {
write!(f, " {}", a.clone().into_string().unwrap())?;
}
Ok(())
}
}
fn log_output(output: &process::Output) {
use std::str::from_utf8;
if !output.stdout.is_empty() {
eprintln!("stdout: \n{}<<END>>", from_utf8(&output.stdout).unwrap());
}
if !output.stderr.is_empty() {
eprintln!("stderr: \n{}<<END>>", from_utf8(&output.stderr).unwrap());
}
}
// Returns stdout. The command must return zero.
pub fn run_ok(command: Command) -> Result<String> {
eprintln!("run_ok: {}", command);
let command = command.to_expr().stdout_capture().stderr_capture();
let output = command.run()?;
log_output(&output);
assert!(output.status.success());
let stdout = std::str::from_utf8(&output.stdout[..])
.unwrap()
.trim_end_matches(|c| c == '\n' || c == '\r')
.to_string();
Ok(stdout)
}
// Returns the entire output. The command must return zero.
pub fn run_ok_raw(command: Command) -> Result<std::process::Output> {
eprintln!("run_ok_raw: {}", command);
let command = command.to_expr().stdout_capture().stderr_capture();
let output = command.run()?;
log_output(&output);
assert!(output.status.success());
Ok(output)
}
// Returns stderr, a non zero status must be returned
pub fn run_fail(command: Command) -> Result<String> {
eprintln!("run_fail: {}", command);
let command = command.to_expr().stdout_capture().stderr_capture();
let output = command.unchecked().run()?;
log_output(&output);
assert!(!output.status.success());
let stderr = std::str::from_utf8(&output.stderr[..]).unwrap().to_string();
Ok(stderr)
}
// Returns the entire output, a non zero status must be returned
pub fn run_fail_raw(command: Command) -> Result<std::process::Output> {
eprintln!("run_fail_raw: {}", command);
let command = command.to_expr().stdout_capture().stderr_capture();
let output = command.unchecked().run()?;
log_output(&output);
assert!(!output.status.success());
Ok(output)
}
//------------------------------------------