From f66a23487381d23ef37f1df405529488b61ef14c Mon Sep 17 00:00:00 2001 From: Chip Senkbeil Date: Sun, 29 Aug 2021 21:04:09 -0500 Subject: [PATCH] Unfinished tests for proc-run cli --- scripts/test/echo_args_to_stderr.sh | 3 + scripts/test/echo_args_to_stdout.sh | 3 + scripts/test/echo_stdin_to_stdout.sh | 3 + scripts/test/exit_code.sh | 3 + src/subcommand/action.rs | 5 +- tests/cli/action/metadata.rs | 4 +- tests/cli/action/mod.rs | 1 + tests/cli/action/proc_run.rs | 151 +++++++++++++++++++++++++++ 8 files changed, 170 insertions(+), 3 deletions(-) create mode 100755 scripts/test/echo_args_to_stderr.sh create mode 100755 scripts/test/echo_args_to_stdout.sh create mode 100755 scripts/test/echo_stdin_to_stdout.sh create mode 100755 scripts/test/exit_code.sh create mode 100644 tests/cli/action/proc_run.rs diff --git a/scripts/test/echo_args_to_stderr.sh b/scripts/test/echo_args_to_stderr.sh new file mode 100755 index 0000000..dc9ee53 --- /dev/null +++ b/scripts/test/echo_args_to_stderr.sh @@ -0,0 +1,3 @@ +#/usr/bin/env bash + +printf "%s" "$@" 1>&2 diff --git a/scripts/test/echo_args_to_stdout.sh b/scripts/test/echo_args_to_stdout.sh new file mode 100755 index 0000000..ae3ace5 --- /dev/null +++ b/scripts/test/echo_args_to_stdout.sh @@ -0,0 +1,3 @@ +#/usr/bin/env bash + +printf "%s" "$@" diff --git a/scripts/test/echo_stdin_to_stdout.sh b/scripts/test/echo_stdin_to_stdout.sh new file mode 100755 index 0000000..c22cb1f --- /dev/null +++ b/scripts/test/echo_stdin_to_stdout.sh @@ -0,0 +1,3 @@ +#/usr/bin/env bash + +while IFS= read; do echo "$REPLY"; done diff --git a/scripts/test/exit_code.sh b/scripts/test/exit_code.sh new file mode 100755 index 0000000..6411de8 --- /dev/null +++ b/scripts/test/exit_code.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +exit "$1" diff --git a/src/subcommand/action.rs b/src/subcommand/action.rs index 6685dc3..612a61e 100644 --- a/src/subcommand/action.rs +++ b/src/subcommand/action.rs @@ -27,7 +27,10 @@ pub enum Error { impl ExitCodeError for Error { fn is_silent(&self) -> bool { - matches!(self, Self::OperationFailed) + match self { + Self::BadProcessExit(_) | Self::OperationFailed => true, + _ => false, + } } fn to_exit_code(&self) -> ExitCode { diff --git a/tests/cli/action/metadata.rs b/tests/cli/action/metadata.rs index 9a33f59..3bb6e40 100644 --- a/tests/cli/action/metadata.rs +++ b/tests/cli/action/metadata.rs @@ -24,7 +24,7 @@ fn should_output_metadata_for_file(mut action_cmd: Command) { let file = temp.child("file"); file.write_str(FILE_CONTENTS).unwrap(); - // distant action metdata {path} + // distant action metadata {path} action_cmd .args(&["metadata", file.to_str().unwrap()]) .assert() @@ -70,7 +70,7 @@ fn should_support_including_a_canonicalized_path(mut action_cmd: Command) { let file = temp.child("file"); file.touch().unwrap(); - // distant action metdata --canonicalize {path} + // distant action metadata --canonicalize {path} action_cmd .args(&["metadata", "--canonicalize", file.to_str().unwrap()]) .assert() diff --git a/tests/cli/action/mod.rs b/tests/cli/action/mod.rs index 302b8d8..d543f67 100644 --- a/tests/cli/action/mod.rs +++ b/tests/cli/action/mod.rs @@ -9,5 +9,6 @@ mod file_read_text; mod file_write; mod file_write_text; mod metadata; +mod proc_run; mod remove; mod rename; diff --git a/tests/cli/action/proc_run.rs b/tests/cli/action/proc_run.rs new file mode 100644 index 0000000..32fea6d --- /dev/null +++ b/tests/cli/action/proc_run.rs @@ -0,0 +1,151 @@ +use crate::cli::{ + fixtures::*, + utils::{random_tenant, regex_pred, FAILURE_LINE}, +}; +use assert_cmd::Command; +use distant::ExitCode; +use distant_core::{ + data::{Error, ErrorKind}, + Request, RequestData, Response, ResponseData, +}; +use rstest::*; +use std::path::PathBuf; + +lazy_static::lazy_static! { + static ref SCRIPT_DIR: PathBuf = + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("scripts").join("test"); + + static ref ECHO_ARGS_TO_STDOUT_SH: PathBuf = SCRIPT_DIR.join("echo_args_to_stdout.sh"); + static ref ECHO_ARGS_TO_STDERR_SH: PathBuf = SCRIPT_DIR.join("echo_args_to_stderr.sh"); + static ref ECHO_STDIN_TO_STDOUT_SH: PathBuf = SCRIPT_DIR.join("echo_stdin_to_stdout.sh"); + static ref EXIT_CODE_SH: PathBuf = SCRIPT_DIR.join("exit_code.sh"); + + static ref DOES_NOT_EXIST_BIN: PathBuf = SCRIPT_DIR.join("does_not_exist_bin"); +} + +#[rstest] +fn should_execute_program_and_return_exit_status(mut action_cmd: Command) { + // distant action proc-run -- {cmd} [args] + action_cmd + .args(&["proc-run", "--"]) + .arg(EXIT_CODE_SH.to_str().unwrap()) + .arg("0") + .assert() + .success() + .stdout("") + .stderr(""); +} + +#[rstest] +fn should_capture_and_print_stdout(mut action_cmd: Command) { + // distant action proc-run {cmd} [args] + action_cmd + .args(&["proc-run", "--"]) + .arg(ECHO_ARGS_TO_STDOUT_SH.to_str().unwrap()) + .arg("hello world") + .assert() + .success() + .stdout("hello world") + .stderr(""); +} + +#[rstest] +fn should_capture_and_print_stderr(mut action_cmd: Command) { + // distant action proc-run {cmd} [args] + action_cmd + .args(&["proc-run", "--"]) + .arg(ECHO_ARGS_TO_STDERR_SH.to_str().unwrap()) + .arg("hello world") + .assert() + .success() + .stdout("") + .stderr("hello world"); +} + +#[rstest] +fn should_forward_stdin_to_remote_process(mut action_cmd: Command) { + // distant action proc-run {cmd} [args] + action_cmd + .args(&["proc-run", "--"]) + .arg(ECHO_STDIN_TO_STDOUT_SH.to_str().unwrap()) + .write_stdin("hello world\n") + .assert() + .success() + .stdout("hello world\n") + .stderr(""); +} + +#[rstest] +fn yield_an_error_when_fails(mut action_cmd: Command) { + // distant action proc-run {cmd} [args] + action_cmd + .args(&["proc-run", "--"]) + .arg(EXIT_CODE_SH.to_str().unwrap()) + .arg("3") + .assert() + .code(3) + .stdout("") + .stderr(""); +} + +#[rstest] +fn should_support_json_to_execute_program_and_return_exit_status(mut action_cmd: Command) { + let req = Request { + id: rand::random(), + tenant: random_tenant(), + payload: vec![RequestData::ProcRun { + cmd: ECHO_ARGS_TO_STDOUT_SH.to_str().unwrap().to_string(), + args: Vec::new(), + }], + }; + + // distant action --format json --interactive + let cmd = action_cmd + .args(&["--format", "json"]) + .arg("--interactive") + .write_stdin(format!("{}\n", serde_json::to_string(&req).unwrap())) + .assert() + .success() + .stderr(""); + + let res: Response = serde_json::from_slice(&cmd.get_output().stdout).unwrap(); + assert!( + matches!(res.payload[0], ResponseData::ProcStart { .. }), + "Unexpected response: {:?}", + res.payload[0], + ); +} + +#[rstest] +fn should_support_json_output_for_error(mut action_cmd: Command) { + let req = Request { + id: rand::random(), + tenant: random_tenant(), + payload: vec![RequestData::ProcRun { + cmd: DOES_NOT_EXIST_BIN.to_str().unwrap().to_string(), + args: Vec::new(), + }], + }; + + // distant action --format json --interactive + let cmd = action_cmd + .args(&["--format", "json"]) + .arg("--interactive") + .write_stdin(format!("{}\n", serde_json::to_string(&req).unwrap())) + .assert() + .success() + .stderr(""); + + let res: Response = serde_json::from_slice(&cmd.get_output().stdout).unwrap(); + assert!( + matches!( + res.payload[0], + ResponseData::Error(Error { + kind: ErrorKind::NotFound, + .. + }) + ), + "Unexpected response: {:?}", + res.payload[0] + ); +}