Improve command error messages and unit test coverage

This commit is contained in:
Leonard Steppy 2024-12-18 11:35:38 +01:00
parent b6002b635d
commit 0c56e837d4
4 changed files with 40 additions and 9 deletions

View File

@ -78,3 +78,7 @@ Once you have that installed, just run
cargo build --release cargo build --release
``` ```
and you will find an executable in `target/release`. and you will find an executable in `target/release`.
### Unit tests
In order for the unit tests to pass, you will need `python3`

View File

@ -3,6 +3,7 @@ use crate::logger::{LogLevel, Logger};
use std::error::Error; use std::error::Error;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::io; use std::io;
use std::iter::once;
use std::process::{Command, ExitStatus, Stdio}; use std::process::{Command, ExitStatus, Stdio};
pub trait LogRunnable { pub trait LogRunnable {
@ -47,12 +48,20 @@ impl Display for SpecificExecutionError<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!( write!(
f, f,
"Failed to execute command {:?}: {}", "Failed to execute command '{}': {}",
self.command, self.error command_to_string(self.command),
self.error
) )
} }
} }
fn command_to_string(command: &Command) -> String {
once(command.get_program().to_string_lossy())
.chain(command.get_args().map(|arg| arg.to_string_lossy()))
.collect::<Vec<_>>()
.join(" ")
}
impl Error for SpecificExecutionError<'_> {} impl Error for SpecificExecutionError<'_> {}
#[derive(Debug)] #[derive(Debug)]
@ -76,9 +85,9 @@ impl From<ExitStatus> for ExecutionError {
impl Display for ExecutionError { impl Display for ExecutionError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self { match self {
ExecutionError::StartError(e) => write!(f, "failed to start command: {}", e), ExecutionError::StartError(e) => write!(f, "Failed to start command: {}", e),
ExecutionError::BadExitStatus(status) => { ExecutionError::BadExitStatus(status) => {
write!(f, "command failed with exit status: {}", status) write!(f, "Command failed with {}", status)
} }
} }
} }
@ -90,23 +99,40 @@ impl Error for ExecutionError {}
mod test { mod test {
use crate::command::{ExecutionError, LogRunnable, SpecificExecutionError}; use crate::command::{ExecutionError, LogRunnable, SpecificExecutionError};
use crate::logger::Logger; use crate::logger::Logger;
use std::path::PathBuf;
use std::process::Command; use std::process::Command;
#[test] #[test]
fn test_unknown_command() { fn test_unknown_command() {
let mut command = Command::new("a_command_which_def_doesnt_exist"); let mut command = Command::new("python7");
let Err( let Err(
e @ SpecificExecutionError { e @ SpecificExecutionError {
error: ExecutionError::StartError(_), error: ExecutionError::StartError(_),
.. ..
}, },
) = command.args(["foo", "bar"]).run(&Logger::default()) ) = command
.args([PathBuf::from("test-ressources/python/exit_1.py")])
.run(&Logger::default())
else { else {
panic!("command shouldn't exist"); panic!("command shouldn't exist");
}; };
println!("{e}"); assert_eq!(e.to_string(), "Failed to execute command 'python7': Failed to start command: No such file or directory (os error 2)");
} }
#[test] #[test]
fn test_error() {} fn test_error() {
let mut command = Command::new("python3");
let Err(
e @ SpecificExecutionError {
error: ExecutionError::BadExitStatus(_),
..
},
) = command
.arg("test-ressources/python/exit_1.py")
.run(&Logger::default())
else {
panic!("command should return exit-code 1")
};
assert_eq!(e.to_string(), "Failed to execute command 'python3 test-ressources/python/exit_1.py': Command failed with exit status: 1");
}
} }

View File

@ -39,7 +39,7 @@ macro_rules! log {
$logger.$level(format!($($args)*)); $logger.$level(format!($($args)*));
}; };
($logger:expr, $($args:tt)*) => { ($logger:expr, $($args:tt)*) => {
log!($logger, info, $($args)*); log!($logger, info, $($args)*); //TODO better use default level with log function instead of assuming info as default
} }
} }

View File

@ -0,0 +1 @@
exit(1)