commit c9c1afb4784b1d3daa651f4ac23e4749633cf65b
parent c654f6f8b1ab8033d096b4d2500b56511139e2b0
Author: Asher Morgan <59518073+ashermorgan@users.noreply.github.com>
Date: Mon, 8 Jul 2024 16:34:04 -0700
Hide SCP stdout and add more SSH tests
Diffstat:
4 files changed, 132 insertions(+), 1 deletion(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -3,6 +3,15 @@
version = 3
[[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
name = "anstream"
version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -116,6 +125,7 @@ dependencies = [
"anyhow",
"clap",
"colored",
+ "regex",
"serde",
"serde_yaml",
"shellexpand",
@@ -255,6 +265,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
+name = "memchr"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
+[[package]]
name = "option-ext"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -290,6 +306,35 @@ dependencies = [
]
[[package]]
+name = "regex"
+version = "1.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
+
+[[package]]
name = "rustix"
version = "0.38.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
@@ -11,3 +11,6 @@ serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.9"
shellexpand = "3.0"
tempfile = "3"
+
+[dev-dependencies]
+regex = "1.10.5"
diff --git a/src/ssh.rs b/src/ssh.rs
@@ -16,7 +16,7 @@ use std::env;
use shellexpand::tilde_with_context;
use std::fs::{read_dir, remove_dir_all};
use std::path::{MAIN_SEPARATOR_STR, Path, PathBuf};
-use std::process::Command;
+use std::process::{Command, Stdio};
use super::local::copy_file;
/// Makes a relative path absolute according to a certain base directory
@@ -141,6 +141,7 @@ fn send_dir(src: &str, dst: &str, host: &str) -> Result<()> {
})?.path();
let mut cmd = Command::new("scp");
+ cmd.stdout(Stdio::null());
if env::var("COLIRU_TEST").is_ok() {
cmd.args(["-o", "StrictHostKeyChecking=no", "-P", "2222"]);
@@ -187,6 +188,7 @@ mod tests {
use super::*;
use crate::test_utils::{SSH_HOST, read_file, setup_integration, write_file};
+ use regex::Regex;
use std::fs;
#[test]
@@ -407,6 +409,24 @@ mod tests {
}
#[test]
+ fn test_send_dir_bad_host() {
+ let tmp = setup_integration("test_send_dir_bad_host");
+
+ write_file(&tmp.local.join("foo"), "contents of foo");
+ write_file(&tmp.local.join("bar"), "contents of bar");
+
+ let dst = "~/test_send_dir_bad_host";
+ let bad_host = "fake@coliru.test.internal"; // Will be a DNS error
+
+ let result = send_dir(tmp.local.to_str().unwrap(), dst, bad_host);
+ let expected = Regex::new("SCP terminated unsuccessfully: \
+ exit (status|code): \\d+").unwrap();
+
+ assert_eq!(result.is_ok(), false);
+ assert_eq!(expected.is_match(&result.unwrap_err().to_string()), true);
+ }
+
+ #[test]
#[cfg(target_family = "unix")]
fn test_send_command_basic() {
let tmp = setup_integration("test_send_command_basic");
@@ -421,4 +441,19 @@ mod tests {
assert_eq!(dst_real.exists(), true);
assert_eq!(read_file(&dst_real), "contents of foo\n");
}
+
+ #[test]
+ fn test_send_command_bad_host() {
+ let _tmp = setup_integration("test_send_command_bad_host");
+
+ let cmd = format!("echo Hello World");
+ let bad_host = "fake@coliru.test.internal"; // Will be a DNS error
+
+ let result = send_command(&cmd, bad_host);
+ let expected = Regex::new("SSH terminated unsuccessfully: \
+ exit (status|code): \\d+").unwrap();
+
+ assert_eq!(result.is_ok(), false);
+ assert_eq!(expected.is_match(&result.unwrap_err().to_string()), true);
+ }
}
diff --git a/tests/ssh.rs b/tests/ssh.rs
@@ -5,6 +5,7 @@
mod test_utils;
use test_utils::*;
+use regex::Regex;
use std::fs::remove_file;
#[test]
@@ -282,3 +283,50 @@ foo!
assert_eq!(foo_contents, "foo!\n");
assert_eq!(log_contents, "script.sh called with arg1 linux\n");
}
+
+#[test]
+fn test_ssh_bad_host() {
+ // Use setup_e2e_local instead of setup_e2e_ssh to avoid regular --host
+ let (_dirs, mut cmd) = setup_e2e_local("test_ssh_bad_host");
+ let bad_host = "fake@coliru.test.internal"; // Will be a DNS error
+ cmd.args(["manifest.yml", "-t", "linux", "--host", bad_host]);
+
+ // setup_e2e_local will install to CWD instead of $HOME on Windows:
+ let expected_stdout = Regex::new(&format!("\
+\\[1/3] Copy gitconfig to {bad_host}:~/(.coliru/)?.gitconfig
+\\[2/3] Copy foo to {bad_host}:~/.coliru/foo
+\\[2/3] Copy bashrc to {bad_host}:~/(.coliru/)?.bashrc
+\\[2/3] Copy vimrc to {bad_host}:~/(.coliru/)?.vimrc
+\\[2/3] Copy script.sh to {bad_host}:~/.coliru/script.sh
+\\[2/3] Run sh script.sh arg1 linux on {bad_host}
+")).unwrap();
+ // Exact std output varies significantly across machines;
+ let expected_stderr = Regex::new("\
+ssh: Could not resolve hostname coliru.test.internal: [\\w \\.]+\r?(
+[\\w :]+\r?)?
+ Error: Failed to transfer staged files: SCP terminated unsuccessfully: \
+ exit (status|code): \\d+
+ssh: Could not resolve hostname coliru.test.internal: [\\w \\.]+\r?(
+[\\w :]+\r?)?
+ Error: Failed to transfer staged files: SCP terminated unsuccessfully: \
+ exit (status|code): \\d+
+ssh: Could not resolve hostname coliru.test.internal: [\\w \\.]+\r?(
+[\\w :]+\r?)?
+ Error: Failed to transfer staged files: SCP terminated unsuccessfully: \
+ exit (status|code): \\d+
+ssh: Could not resolve hostname coliru.test.internal: [\\w \\.]+\r?(
+[\\w :]+\r?)?
+ Error: Failed to transfer staged files: SCP terminated unsuccessfully: \
+ exit (status|code): \\d+
+ssh: Could not resolve hostname coliru.test.internal: [\\w \\.]+\r?(
+[\\w :]+\r?)?
+ Error: Failed to transfer staged files: SCP terminated unsuccessfully: \
+ exit (status|code): \\d+
+ssh: Could not resolve hostname coliru.test.internal: [\\w \\.]+\r?
+ Error: SSH terminated unsuccessfully: exit (status|code): \\d+
+").unwrap();
+ let (stdout, stderr, exitcode) = run_command(&mut cmd);
+ assert_eq!(expected_stderr.is_match(&stderr), true);
+ assert_eq!(expected_stdout.is_match(&stdout), true);
+ assert_eq!(exitcode, Some(1));
+}