ssh.rs (14695B)
1 #![allow(unused_imports)] 2 3 //! End to end tests that test installation behavior on a remote machine via SSH 4 5 mod test_utils; 6 7 use test_utils::*; 8 use regex::Regex; 9 use std::fs::remove_file; 10 11 #[test] 12 #[cfg(target_family = "unix")] 13 fn test_ssh_standard() { 14 let (dirs, mut cmd) = setup_e2e_ssh("test_ssh_standard"); 15 cmd.args(["manifest.yml", "-t", "linux"]); 16 17 let expected = format!("\ 18 [1/2] Copy gitconfig to {SSH_HOST}:~/test_ssh_standard/.gitconfig 19 [2/2] Copy test_ssh_standard/foo to {SSH_HOST}:~/.coliru/test_ssh_standard/foo 20 [2/2] Copy bashrc to {SSH_HOST}:~/test_ssh_standard/.bashrc 21 [2/2] Copy vimrc to {SSH_HOST}:~/test_ssh_standard/.vimrc 22 [2/2] Copy test_ssh_standard/script.sh to {SSH_HOST}:~/.coliru/test_ssh_standard/script.sh 23 [2/2] Run sh test_ssh_standard/script.sh arg1 linux on {SSH_HOST} 24 foo! 25 "); 26 let (stdout, stderr, exitcode) = run_command(&mut cmd); 27 assert_eq!(&stderr, ""); 28 assert_eq!(&stdout, &expected); 29 assert_eq!(exitcode, Some(0)); 30 31 // Assert files are correctly copied/run 32 let bash_contents = read_file(&dirs.ssh.join(".bashrc")); 33 let git_contents = read_file(&dirs.ssh.join(".gitconfig")); 34 let vim1_contents = read_file(&dirs.ssh.join(".vimrc")); 35 let vim2_exists = dirs.ssh.join("_vimrc").exists(); 36 let foo_contents = read_file(&dirs.ssh_cwd.join("foo")); 37 let log_contents = read_file(&dirs.ssh_cwd.join("log.txt")); 38 assert_eq!(bash_contents, "bash #1\n"); 39 assert_eq!(git_contents, "git #1\n"); 40 assert_eq!(vim1_contents, "vim #1\n"); 41 assert_eq!(vim2_exists, false); 42 assert_eq!(foo_contents, "foo!\n"); 43 assert_eq!(log_contents, "script.sh called with arg1 linux\n"); 44 } 45 46 #[test] 47 #[cfg(target_family = "unix")] 48 fn test_ssh_run_alternate_tag_rules_1() { 49 let (dirs, mut cmd) = setup_e2e_ssh("test_ssh_run_alternate_tag_rules_1"); 50 cmd.args(["manifest.yml", "-t", "linux", "^windows"]); 51 52 let expected = format!("\ 53 [1/1] Copy test_ssh_run_alternate_tag_rules_1/foo to {SSH_HOST}:~/.coliru/test_ssh_run_alternate_tag_rules_1/foo 54 [1/1] Copy bashrc to {SSH_HOST}:~/test_ssh_run_alternate_tag_rules_1/.bashrc 55 [1/1] Copy vimrc to {SSH_HOST}:~/test_ssh_run_alternate_tag_rules_1/.vimrc 56 [1/1] Copy test_ssh_run_alternate_tag_rules_1/script.sh to {SSH_HOST}:~/.coliru/test_ssh_run_alternate_tag_rules_1/script.sh 57 [1/1] Run sh test_ssh_run_alternate_tag_rules_1/script.sh arg1 linux ^windows on {SSH_HOST} 58 foo! 59 "); 60 let (stdout, stderr, exitcode) = run_command(&mut cmd); 61 assert_eq!(&stderr, ""); 62 assert_eq!(&stdout, &expected); 63 assert_eq!(exitcode, Some(0)); 64 65 // Assert files are correctly copied/run 66 let bash_contents = read_file(&dirs.ssh.join(".bashrc")); 67 let git_exists = dirs.ssh.join(".gitconfig").exists(); 68 let vim1_contents = read_file(&dirs.ssh.join(".vimrc")); 69 let vim2_exists = dirs.ssh.join("_vimrc").exists(); 70 let foo_contents = read_file(&dirs.ssh_cwd.join("foo")); 71 let log_contents = read_file(&dirs.ssh_cwd.join("log.txt")); 72 assert_eq!(bash_contents, "bash #1\n"); 73 assert_eq!(git_exists, false); 74 assert_eq!(vim1_contents, "vim #1\n"); 75 assert_eq!(vim2_exists, false); 76 assert_eq!(foo_contents, "foo!\n"); 77 assert_eq!(log_contents, "script.sh called with arg1 linux ^windows\n"); 78 } 79 80 #[test] 81 #[cfg(target_family = "unix")] 82 fn test_ssh_run_alternate_tag_rules_2() { 83 let (dirs, mut cmd) = setup_e2e_ssh("test_ssh_run_alternate_tag_rules_2"); 84 cmd.args(["manifest.yml", "-t", "macos"]); 85 86 let expected = format!("\ 87 [1/2] Copy gitconfig to {SSH_HOST}:~/test_ssh_run_alternate_tag_rules_2/.gitconfig 88 [2/2] Copy test_ssh_run_alternate_tag_rules_2/foo to {SSH_HOST}:~/.coliru/test_ssh_run_alternate_tag_rules_2/foo 89 [2/2] Copy bashrc to {SSH_HOST}:~/test_ssh_run_alternate_tag_rules_2/.bashrc 90 [2/2] Copy vimrc to {SSH_HOST}:~/test_ssh_run_alternate_tag_rules_2/.vimrc 91 [2/2] Copy test_ssh_run_alternate_tag_rules_2/script.sh to {SSH_HOST}:~/.coliru/test_ssh_run_alternate_tag_rules_2/script.sh 92 [2/2] Run sh test_ssh_run_alternate_tag_rules_2/script.sh arg1 macos on {SSH_HOST} 93 foo! 94 "); 95 let (stdout, stderr, exitcode) = run_command(&mut cmd); 96 assert_eq!(&stderr, ""); 97 assert_eq!(&stdout, &expected); 98 assert_eq!(exitcode, Some(0)); 99 100 // Assert files are correctly copied/run 101 let bash_contents = read_file(&dirs.ssh.join(".bashrc")); 102 let git_contents = read_file(&dirs.ssh.join(".gitconfig")); 103 let vim1_contents = read_file(&dirs.ssh.join(".vimrc")); 104 let vim2_exists = dirs.ssh.join("_vimrc").exists(); 105 let foo_contents = read_file(&dirs.ssh_cwd.join("foo")); 106 let log_contents = read_file(&dirs.ssh_cwd.join("log.txt")); 107 assert_eq!(bash_contents, "bash #1\n"); 108 assert_eq!(git_contents, "git #1\n"); 109 assert_eq!(vim1_contents, "vim #1\n"); 110 assert_eq!(vim2_exists, false); 111 assert_eq!(foo_contents, "foo!\n"); 112 assert_eq!(log_contents, "script.sh called with arg1 macos\n"); 113 } 114 115 #[test] 116 fn test_ssh_dry_run() { 117 let (dirs, mut cmd) = setup_e2e_ssh("test_ssh_dry_run"); 118 cmd.args(["manifest.yml", "--dry-run", "-t", "linux"]); 119 120 let expected = format!("\ 121 [1/2] Copy gitconfig to {SSH_HOST}:~/test_ssh_dry_run/.gitconfig (DRY RUN) 122 [2/2] Copy test_ssh_dry_run/foo to {SSH_HOST}:~/.coliru/test_ssh_dry_run/foo (DRY RUN) 123 [2/2] Copy bashrc to {SSH_HOST}:~/test_ssh_dry_run/.bashrc (DRY RUN) 124 [2/2] Copy vimrc to {SSH_HOST}:~/test_ssh_dry_run/.vimrc (DRY RUN) 125 [2/2] Copy test_ssh_dry_run/script.sh to {SSH_HOST}:~/.coliru/test_ssh_dry_run/script.sh (DRY RUN) 126 [2/2] Run sh test_ssh_dry_run/script.sh arg1 linux on {SSH_HOST} (DRY RUN) 127 "); 128 let (stdout, stderr, exitcode) = run_command(&mut cmd); 129 assert_eq!(&stderr, ""); 130 assert_eq!(&stdout, &expected); 131 assert_eq!(exitcode, Some(0)); 132 133 // Assert files are correctly copied/run 134 let bash_exists = dirs.ssh.join(".bashrc").exists(); 135 let git_exists = dirs.ssh.join(".gitconfig").exists(); 136 let vim1_exists = dirs.ssh.join(".vimrc").exists(); 137 let vim2_exists = dirs.ssh.join("_vimrc").exists(); 138 let foo_exists = dirs.ssh_cwd.join("foo").exists(); 139 let log_exists = dirs.ssh_cwd.join("log.txt").exists(); 140 assert_eq!(bash_exists, false); 141 assert_eq!(git_exists, false); 142 assert_eq!(vim1_exists, false); 143 assert_eq!(vim2_exists, false); 144 assert_eq!(foo_exists, false); 145 assert_eq!(log_exists, false); 146 } 147 148 #[test] 149 #[cfg(target_family = "unix")] 150 fn test_ssh_copy() { 151 let (dirs, mut cmd) = setup_e2e_ssh("test_ssh_copy"); 152 cmd.args(["manifest.yml", "--copy", "-t", "linux"]); 153 154 let expected = format!("\ 155 [1/2] Copy gitconfig to {SSH_HOST}:~/test_ssh_copy/.gitconfig 156 [2/2] Copy test_ssh_copy/foo to {SSH_HOST}:~/.coliru/test_ssh_copy/foo 157 [2/2] Copy bashrc to {SSH_HOST}:~/test_ssh_copy/.bashrc 158 [2/2] Copy vimrc to {SSH_HOST}:~/test_ssh_copy/.vimrc 159 [2/2] Copy test_ssh_copy/script.sh to {SSH_HOST}:~/.coliru/test_ssh_copy/script.sh 160 [2/2] Run sh test_ssh_copy/script.sh arg1 linux on {SSH_HOST} 161 foo! 162 "); 163 let (stdout, stderr, exitcode) = run_command(&mut cmd); 164 assert_eq!(&stderr, ""); 165 assert_eq!(&stdout, &expected); 166 assert_eq!(exitcode, Some(0)); 167 168 // Assert files are correctly copied/run 169 let bash_contents = read_file(&dirs.ssh.join(".bashrc")); 170 let git_contents = read_file(&dirs.ssh.join(".gitconfig")); 171 let vim1_contents = read_file(&dirs.ssh.join(".vimrc")); 172 let vim2_exists = dirs.ssh.join("_vimrc").exists(); 173 let foo_contents = read_file(&dirs.ssh_cwd.join("foo")); 174 let log_contents = read_file(&dirs.ssh_cwd.join("log.txt")); 175 assert_eq!(bash_contents, "bash #1\n"); 176 assert_eq!(git_contents, "git #1\n"); 177 assert_eq!(vim1_contents, "vim #1\n"); 178 assert_eq!(vim2_exists, false); 179 assert_eq!(foo_contents, "foo!\n"); 180 assert_eq!(log_contents, "script.sh called with arg1 linux\n"); 181 } 182 183 #[test] 184 #[cfg(target_family = "unix")] 185 fn test_ssh_run_failure() { 186 let (dirs, mut cmd) = setup_e2e_ssh("test_ssh_run_failure"); 187 cmd.args(["manifest.yml", "-t", "linux"]); 188 write_file(&dirs.local.join("test_ssh_run_failure/script.sh"), "exit 1"); 189 190 let expected_stdout = format!("\ 191 [1/2] Copy gitconfig to {SSH_HOST}:~/test_ssh_run_failure/.gitconfig 192 [2/2] Copy test_ssh_run_failure/foo to {SSH_HOST}:~/.coliru/test_ssh_run_failure/foo 193 [2/2] Copy bashrc to {SSH_HOST}:~/test_ssh_run_failure/.bashrc 194 [2/2] Copy vimrc to {SSH_HOST}:~/test_ssh_run_failure/.vimrc 195 [2/2] Copy test_ssh_run_failure/script.sh to {SSH_HOST}:~/.coliru/test_ssh_run_failure/script.sh 196 [2/2] Run sh test_ssh_run_failure/script.sh arg1 linux on {SSH_HOST} 197 "); 198 let expected_stderr = " Error: SSH terminated unsuccessfully: exit status: 1\n"; 199 let (stdout, stderr, exitcode) = run_command(&mut cmd); 200 assert_eq!(&stderr, expected_stderr); 201 assert_eq!(&stdout, &expected_stdout); 202 assert_eq!(exitcode, Some(1)); 203 204 // Assert files are correctly copied/run 205 let bash_contents = read_file(&dirs.ssh.join(".bashrc")); 206 let git_contents = read_file(&dirs.ssh.join(".gitconfig")); 207 let vim1_contents = read_file(&dirs.ssh.join(".vimrc")); 208 let vim2_exists = dirs.ssh.join("_vimrc").exists(); 209 let foo_contents = read_file(&dirs.ssh_cwd.join("foo")); 210 assert_eq!(bash_contents, "bash #1\n"); 211 assert_eq!(git_contents, "git #1\n"); 212 assert_eq!(vim1_contents, "vim #1\n"); 213 assert_eq!(vim2_exists, false); 214 assert_eq!(foo_contents, "foo!\n"); 215 } 216 217 #[test] 218 #[cfg(target_family = "unix")] 219 fn test_ssh_missing_file() { 220 let (dirs, mut cmd) = setup_e2e_ssh("test_ssh_missing_file"); 221 cmd.args(["manifest.yml", "-t", "linux"]); 222 remove_file(&dirs.local.join("vimrc")).unwrap(); 223 224 let expected_stdout = format!("\ 225 [1/2] Copy gitconfig to {SSH_HOST}:~/test_ssh_missing_file/.gitconfig 226 [2/2] Copy test_ssh_missing_file/foo to {SSH_HOST}:~/.coliru/test_ssh_missing_file/foo 227 [2/2] Copy bashrc to {SSH_HOST}:~/test_ssh_missing_file/.bashrc 228 [2/2] Copy vimrc to {SSH_HOST}:~/test_ssh_missing_file/.vimrc 229 [2/2] Copy test_ssh_missing_file/script.sh to {SSH_HOST}:~/.coliru/test_ssh_missing_file/script.sh 230 [2/2] Run sh test_ssh_missing_file/script.sh arg1 linux on {SSH_HOST} 231 foo! 232 "); 233 let expected_stderr = " Error: Failed to copy vimrc to staging directory: \ 234 No such file or directory (os error 2)\n"; 235 let (stdout, stderr, exitcode) = run_command(&mut cmd); 236 assert_eq!(&stderr, expected_stderr); 237 assert_eq!(&stdout, &expected_stdout); 238 assert_eq!(exitcode, Some(1)); 239 240 // Assert files are correctly copied/run 241 let bash_contents = read_file(&dirs.ssh.join(".bashrc")); 242 let git_contents = read_file(&dirs.ssh.join(".gitconfig")); 243 let foo_contents = read_file(&dirs.ssh_cwd.join("foo")); 244 let log_contents = read_file(&dirs.ssh_cwd.join("log.txt")); 245 assert_eq!(bash_contents, "bash #1\n"); 246 assert_eq!(git_contents, "git #1\n"); 247 assert_eq!(foo_contents, "foo!\n"); 248 assert_eq!(log_contents, "script.sh called with arg1 linux\n"); 249 } 250 251 #[test] 252 #[cfg(target_family = "unix")] 253 fn test_ssh_different_cwd() { 254 let (dirs, mut cmd) = setup_e2e_ssh("test_ssh_different_cwd"); 255 cmd.current_dir(&dirs.local.parent().unwrap()); 256 cmd.args(["test_ssh_different_cwd/manifest.yml", "-t", "linux"]); 257 258 let expected = format!("\ 259 [1/2] Copy gitconfig to {SSH_HOST}:~/test_ssh_different_cwd/.gitconfig 260 [2/2] Copy test_ssh_different_cwd/foo to {SSH_HOST}:~/.coliru/test_ssh_different_cwd/foo 261 [2/2] Copy bashrc to {SSH_HOST}:~/test_ssh_different_cwd/.bashrc 262 [2/2] Copy vimrc to {SSH_HOST}:~/test_ssh_different_cwd/.vimrc 263 [2/2] Copy test_ssh_different_cwd/script.sh to {SSH_HOST}:~/.coliru/test_ssh_different_cwd/script.sh 264 [2/2] Run sh test_ssh_different_cwd/script.sh arg1 linux on {SSH_HOST} 265 foo! 266 "); 267 let (stdout, stderr, exitcode) = run_command(&mut cmd); 268 assert_eq!(&stderr, ""); 269 assert_eq!(&stdout, &expected); 270 assert_eq!(exitcode, Some(0)); 271 272 // Assert files are correctly copied/run 273 let bash_contents = read_file(&dirs.ssh.join(".bashrc")); 274 let git_contents = read_file(&dirs.ssh.join(".gitconfig")); 275 let vim1_contents = read_file(&dirs.ssh.join(".vimrc")); 276 let vim2_exists = dirs.ssh.join("_vimrc").exists(); 277 let foo_contents = read_file(&dirs.ssh_cwd.join("foo")); 278 let log_contents = read_file(&dirs.ssh_cwd.join("log.txt")); 279 assert_eq!(bash_contents, "bash #1\n"); 280 assert_eq!(git_contents, "git #1\n"); 281 assert_eq!(vim1_contents, "vim #1\n"); 282 assert_eq!(vim2_exists, false); 283 assert_eq!(foo_contents, "foo!\n"); 284 assert_eq!(log_contents, "script.sh called with arg1 linux\n"); 285 } 286 287 #[test] 288 fn test_ssh_bad_host() { 289 // Use setup_e2e_local instead of setup_e2e_ssh to avoid regular --host 290 let (_dirs, mut cmd) = setup_e2e_local("test_ssh_bad_host"); 291 let bad_host = "fake@coliru.test.internal"; // Will be a DNS error 292 cmd.args(["manifest.yml", "-t", "linux", "--host", bad_host]); 293 294 // setup_e2e_local will install to CWD instead of $HOME on Windows: 295 let expected_stdout = Regex::new(&format!("\ 296 \\[1/2] Copy gitconfig to {bad_host}:~/(.coliru/)?.gitconfig 297 \\[2/2] Copy foo to {bad_host}:~/.coliru/foo 298 \\[2/2] Copy bashrc to {bad_host}:~/(.coliru/)?.bashrc 299 \\[2/2] Copy vimrc to {bad_host}:~/(.coliru/)?.vimrc 300 \\[2/2] Copy script.sh to {bad_host}:~/.coliru/script.sh 301 \\[2/2] Run sh script.sh arg1 linux on {bad_host} 302 ")).unwrap(); 303 // Exact std output varies significantly across machines; 304 let expected_stderr = Regex::new("\ 305 ssh: Could not resolve hostname coliru.test.internal: [\\w \\.]+\r?( 306 [\\w :]+\r?)? 307 Error: Failed to transfer staged files: SCP terminated unsuccessfully: \ 308 exit (status|code): \\d+ 309 ssh: Could not resolve hostname coliru.test.internal: [\\w \\.]+\r?( 310 [\\w :]+\r?)? 311 Error: Failed to transfer staged files: SCP terminated unsuccessfully: \ 312 exit (status|code): \\d+ 313 ssh: Could not resolve hostname coliru.test.internal: [\\w \\.]+\r?( 314 [\\w :]+\r?)? 315 Error: Failed to transfer staged files: SCP terminated unsuccessfully: \ 316 exit (status|code): \\d+ 317 ssh: Could not resolve hostname coliru.test.internal: [\\w \\.]+\r?( 318 [\\w :]+\r?)? 319 Error: Failed to transfer staged files: SCP terminated unsuccessfully: \ 320 exit (status|code): \\d+ 321 ssh: Could not resolve hostname coliru.test.internal: [\\w \\.]+\r?( 322 [\\w :]+\r?)? 323 Error: Failed to transfer staged files: SCP terminated unsuccessfully: \ 324 exit (status|code): \\d+ 325 ssh: Could not resolve hostname coliru.test.internal: [\\w \\.]+\r? 326 Error: SSH terminated unsuccessfully: exit (status|code): \\d+ 327 ").unwrap(); 328 let (stdout, stderr, exitcode) = run_command(&mut cmd); 329 assert_eq!(expected_stderr.is_match(&stderr), true); 330 assert_eq!(expected_stdout.is_match(&stdout), true); 331 assert_eq!(exitcode, Some(1)); 332 }