Skip to content

Commit

Permalink
Improve error message when run_command_async fails to find a command (
Browse files Browse the repository at this point in the history
#1831)

Co-authored-by: Lucas Kent <[email protected]>
  • Loading branch information
alleyshairu and rukai authored Nov 22, 2024
1 parent 8dffbdf commit 63a8dcd
Showing 1 changed file with 61 additions and 1 deletion.
62 changes: 61 additions & 1 deletion test-helpers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub mod mock_cassandra;
pub mod shotover_process;
mod test_tracing;

use anyhow::{anyhow, Result};
use anyhow::{anyhow, Error, Result};
use std::path::Path;
use subprocess::{Exec, Redirection};

Expand Down Expand Up @@ -38,16 +38,76 @@ pub fn run_command(command: &str, args: &[&str]) -> Result<String> {
}
}

fn command_not_found_error(command: &str, args: &[&str]) -> Error {
// Maps a command to its associated dependency; however, if the name of the command and dependency is the same, we just use the command name.
// Currently, the only use case is mapping `npm` to its dependency `nodejs`.
let dependency = match command {
"npm" => "nodejs",
_ => command,
};

let args_part = if !args.is_empty() {
format!(" {}", args.join(" "))
} else {
String::new()
};

anyhow!(
"Attempted to run the command `{}{}` but {} does not exist. Have you installed {}?",
command,
args_part,
command,
dependency
)
}

pub async fn run_command_async(current_dir: &Path, command: &str, args: &[&str]) {
let output = tokio::process::Command::new(command)
.args(args)
.current_dir(current_dir)
.kill_on_drop(true)
.status()
.await
.map_err(|e| {
if e.kind() == std::io::ErrorKind::NotFound {
return command_not_found_error(command, args);
}

anyhow!(e)
})
.unwrap();

if !output.success() {
panic!("command {command} {args:?} failed. See above output.")
}
}

#[cfg(test)]
mod tests {
use super::*;
use futures_util::FutureExt;

#[tokio::test]
async fn test_run_command_async_not_found_message() {
let dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let command = "shotover_non_existent_command";
let args = &["arg1", "arg2"];
let result = std::panic::AssertUnwindSafe(run_command_async(dir, command, args))
.catch_unwind()
.await;

assert!(result.is_err(), "Expected a panic but none occurred");

if let Err(panic_info) = result {
if let Some(error_message) = panic_info.downcast_ref::<String>() {
assert!(
error_message.contains("Attempted to run the command `shotover_non_existent_command arg1 arg2` but shotover_non_existent_command does not exist. Have you installed shotover_non_existent_command?"),
"Error message did not contain the expected NotFound error got: {}",
error_message
);
} else {
panic!("Panic payload was not a string: {:?}", panic_info);
}
}
}
}

0 comments on commit 63a8dcd

Please sign in to comment.