commit 5e1672a6ae69184e24aacd3e147039dd63fa7324
parent ef67865a71a4d6d529eb0f63bbdf0dface3c7f6f
Author: Asher Morgan <59518073+ashermorgan@users.noreply.github.com>
Date: Fri, 28 Jun 2024 11:22:25 -0700
Add --host arg and initialize ssh tests
Diffstat:
| M | src/cli.rs | | | 8 | ++++++-- |
| M | src/core.rs | | | 55 | +++++++++++++++++++++++++++++++++++++------------------ |
| M | tests/basic.rs | | | 392 | ++++--------------------------------------------------------------------------- |
| M | tests/common/mod.rs | | | 30 | ++++++++++++++++++++++++++++++ |
| A | tests/local.rs | | | 349 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | tests/ssh.rs | | | 243 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
6 files changed, 681 insertions(+), 396 deletions(-)
diff --git a/src/cli.rs b/src/cli.rs
@@ -21,12 +21,16 @@ struct Args {
/// Do a trial run without any permanent changes
#[arg(short = 'n', long)]
pub dry_run: bool,
+
+ /// Install dotfiles on another machine via SSH
+ #[arg(long, default_value="", hide_default_value=true)]
+ pub host: String,
}
/// Runs the coliru CLI
pub fn run() {
let args = Args::parse();
let manifest_path = Path::new(&args.manifest);
- execute_manifest_file(&manifest_path, args.tag_rules, args.dry_run,
- args.copy);
+ execute_manifest_file(&manifest_path, args.tag_rules, &args.host,
+ args.dry_run, args.copy);
}
diff --git a/src/core.rs b/src/core.rs
@@ -6,17 +6,18 @@ use super::tags::tags_match;
use super::utils::{copy_file, link_file, run_script};
/// Execute the steps in a coliru manifest file according to a set of tag rules
-pub fn execute_manifest_file(path: &Path, tag_rules: Vec<String>, dry_run: bool,
- copy: bool) {
+pub fn execute_manifest_file(path: &Path, tag_rules: Vec<String>, host: &str,
+ dry_run: bool, copy: bool) {
match parse_manifest_file(path) {
- Ok(manifest) => execute_manifest(manifest, tag_rules, dry_run, copy),
+ Ok(manifest) => execute_manifest(manifest, tag_rules, host, dry_run,
+ copy),
Err(why) => eprintln!("Error: {}", why),
};
}
/// Execute the steps in a coliru manifest according to a set of tag rules
-fn execute_manifest(manifest: Manifest, tag_rules: Vec<String>, dry_run: bool,
- copy: bool) {
+fn execute_manifest(manifest: Manifest, tag_rules: Vec<String>, host: &str,
+ dry_run: bool, copy: bool) {
if let Err(why) = set_current_dir(manifest.base_dir) {
eprintln!("Error: {}", why);
return;
@@ -27,20 +28,25 @@ fn execute_manifest(manifest: Manifest, tag_rules: Vec<String>, dry_run: bool,
let step_str = format!("[{}/{}]", i+1, manifest.steps.len());
- execute_copies(&step.copy, dry_run, &step_str);
- if copy {
- execute_copies(&step.link, dry_run, &step_str);
+ execute_copies(&step.copy, host, dry_run, &step_str);
+ if copy || host != "" {
+ execute_copies(&step.link, host, dry_run, &step_str);
} else {
execute_links(&step.link, dry_run, &step_str);
}
- execute_runs(&step.run, &tag_rules, dry_run, &step_str);
+ execute_runs(&step.run, &tag_rules, host, dry_run, &step_str);
}
}
/// Execute the copy commands specified in a coliru manifest step
-fn execute_copies(copies: &[CopyLinkOptions], dry_run: bool, step_str: &str) {
+fn execute_copies(copies: &[CopyLinkOptions], host: &str, dry_run: bool,
+ step_str: &str) {
for copy in copies {
- print!("{} Copy {} to {}", step_str, copy.src, copy.dst);
+ if host == "" {
+ print!("{} Copy {} to {}", step_str, copy.src, copy.dst);
+ } else {
+ print!("{} Send {} to {}:{}", step_str, copy.src, host, copy.dst);
+ }
if dry_run {
println!(" (DRY RUN)");
@@ -48,8 +54,12 @@ fn execute_copies(copies: &[CopyLinkOptions], dry_run: bool, step_str: &str) {
}
println!("");
- if let Err(why) = copy_file(©.src, ©.dst) {
- eprintln!(" Error: {}", why);
+ if host == "" {
+ if let Err(why) = copy_file(©.src, ©.dst) {
+ eprintln!(" Error: {}", why);
+ }
+ } else {
+ eprintln!(" Error: not implemented");
}
}
}
@@ -72,12 +82,17 @@ fn execute_links(links: &[CopyLinkOptions], dry_run: bool, step_str: &str) {
}
/// Execute the run commands specified in a coliru manifest step
-fn execute_runs(runs: &[RunOptions], tag_rules: &[String], dry_run: bool,
- step_str: &str) {
+fn execute_runs(runs: &[RunOptions], tag_rules: &[String], host: &str,
+ dry_run: bool, step_str: &str) {
for run in runs {
let postfix = run.postfix.replace("$COLIRU_RULES", &tag_rules.join(" "));
- print!("{} Run {} {} {}", step_str, run.prefix, run.src, postfix);
+ if host == "" {
+ print!("{} Run {} {} {}", step_str, run.prefix, run.src, postfix);
+ } else {
+ print!("{} Run {} {} {} on {}", step_str, run.prefix, run.src,
+ postfix, host);
+ }
if dry_run {
println!(" (DRY RUN)");
@@ -85,8 +100,12 @@ fn execute_runs(runs: &[RunOptions], tag_rules: &[String], dry_run: bool,
}
println!("");
- if let Err(why) = run_script(&run.src, &run.prefix, &postfix) {
- eprintln!(" Error: {}", why);
+ if host == "" {
+ if let Err(why) = run_script(&run.src, &run.prefix, &postfix) {
+ eprintln!(" Error: {}", why);
+ }
+ } else {
+ eprintln!(" Error: not implemented");
}
}
}
diff --git a/tests/basic.rs b/tests/basic.rs
@@ -1,33 +1,14 @@
+/// End to end tests that do not test general CLI behavior rather than specific
+/// installation behavior
+
mod common;
use common::*;
-use std::env::{current_exe, consts::EXE_SUFFIX};
-use std::fs::{copy, remove_file};
-use std::path::Path;
-
-/// Create a basic manifest file and its associated dotfiles in a directory
-fn manifest_1(dir: &Path) {
- // Copy files from examples
- let examples = current_exe().unwrap().parent().unwrap().to_path_buf()
- .join("../../../examples");
- let copy_file = |name: &str| {
- copy(examples.join(name), &dir.join(name)).unwrap();
- };
- copy_file("script.bat");
- copy_file("script.sh");
- copy_file("manifest.yml");
- copy_file("manifest-windows-test.yml");
-
- // Create simplified config files
- write_file(&dir.join("bashrc"), "bash #1");
- write_file(&dir.join("gitconfig"), "git #1");
- write_file(&dir.join("vimrc"), "vim #1");
-
-}
+use std::env::consts::EXE_SUFFIX;
#[test]
-fn test_help() {
- let (_dir, mut cmd) = setup_e2e("test_help");
+fn test_basic_help() {
+ let (_dir, mut cmd) = setup_e2e("test_basic_help");
cmd.arg("--help");
let expected = format!("\
A minimal, flexible, dotfile installer
@@ -41,6 +22,7 @@ Options:
-t, --tag-rules [<TAG_RULES>...] The set of tag rules to enforce
-c, --copy Interpret link commands as copy commands
-n, --dry-run Do a trial run without any permanent changes
+ --host <HOST> Install dotfiles on another machine via SSH
-h, --help Print help
-V, --version Print version
");
@@ -49,350 +31,8 @@ Options:
}
#[test]
-#[cfg(target_family = "unix")]
-fn test_standard() {
- let (dir, mut cmd) = setup_e2e("test_standard");
- cmd.args(["manifest.yml", "-t", "linux"]);
- manifest_1(&dir.dir);
-
- let expected = "\
-[1/3] Copy gitconfig to ~/.gitconfig.coliru
-[2/3] Link bashrc to ~/.bashrc.coliru
-[2/3] Link vimrc to ~/.vimrc.coliru
-[2/3] Run sh script.sh arg1 linux
-script.sh called with arg1 linux
-";
- assert_eq!(&stdout_to_string(&mut cmd), expected);
- assert_eq!(&stderr_to_string(&mut cmd), "");
-
- // Assert files are correctly copied/linked/run
- write_file(&dir.dir.join("bashrc"), "bash #2");
- write_file(&dir.dir.join("gitconfig"), "git #2");
- write_file(&dir.dir.join("vimrc"), "vim #2");
- let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
- let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
- let vim1_contents = read_file(&dir.dir.join(".vimrc.coliru"));
- let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
- let log_contents = read_file(&dir.dir.join("log.txt"));
- assert_eq!(bash_contents, "bash #2");
- assert_eq!(git_contents, "git #1");
- assert_eq!(vim1_contents, "vim #2");
- assert_eq!(vim2_exists, false);
- assert_eq!(log_contents, "script.sh called with arg1 linux\n");
-}
-
-#[test]
-#[cfg(target_family = "windows")]
-fn test_standard() {
- let (dir, mut cmd) = setup_e2e("test_standard");
- cmd.args(["manifest-windows-test.yml", "-t", "windows"]);
- manifest_1(&dir.dir);
-
- let expected = "\
-[1/3] Copy gitconfig to .gitconfig.coliru
-[3/3] Link vimrc to _vimrc.coliru
-[3/3] Run script.bat arg1 windows
-script.bat called with arg1 windows\r
-";
- assert_eq!(&stdout_to_string(&mut cmd), expected);
- assert_eq!(&stderr_to_string(&mut cmd), "");
-
- // Assert files are correctly copied/linked/run
- write_file(&dir.dir.join("gitconfig"), "git #2");
- write_file(&dir.dir.join("vimrc"), "vim #2");
- let bash_exists = dir.dir.join(".bashrc.coliru").exists();
- let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
- let vim1_exists = dir.dir.join(".vimrc.coliru").exists();
- let vim2_contents = read_file(&dir.dir.join("_vimrc.coliru"));
- let log_contents = read_file(&dir.dir.join("log.txt"));
- assert_eq!(bash_exists, false);
- assert_eq!(git_contents, "git #1");
- assert_eq!(vim1_exists, false);
- assert_eq!(vim2_contents, "vim #2");
- assert_eq!(log_contents, "script.bat called with arg1 windows \r\n");
-}
-
-#[test]
-#[cfg(target_family = "unix")]
-fn test_run_alternate_tag_rules_1() {
- let (dir, mut cmd) = setup_e2e("test_run_alternate_tag_rules_1");
- cmd.args(["manifest.yml", "-t", "linux", "^windows"]);
- manifest_1(&dir.dir);
-
- let expected = "\
-[2/3] Link bashrc to ~/.bashrc.coliru
-[2/3] Link vimrc to ~/.vimrc.coliru
-[2/3] Run sh script.sh arg1 linux ^windows
-script.sh called with arg1 linux ^windows
-";
- assert_eq!(&stdout_to_string(&mut cmd), expected);
- assert_eq!(&stderr_to_string(&mut cmd), "");
-
- // Assert files are correctly copied/linked/run
- write_file(&dir.dir.join("bashrc"), "bash #2");
- write_file(&dir.dir.join("vimrc"), "vim #2");
- let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
- let git_exists = dir.dir.join(".gitconfig.coliru").exists();
- let vim1_contents = read_file(&dir.dir.join(".vimrc.coliru"));
- let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
- let log_contents = read_file(&dir.dir.join("log.txt"));
- assert_eq!(bash_contents, "bash #2");
- assert_eq!(git_exists, false);
- assert_eq!(vim1_contents, "vim #2");
- assert_eq!(vim2_exists, false);
- assert_eq!(log_contents, "script.sh called with arg1 linux ^windows\n");
-}
-
-#[test]
-#[cfg(target_family = "unix")]
-fn test_run_alternate_tag_rules_2() {
- let (dir, mut cmd) = setup_e2e("test_run_alternate_tag_rules_2");
- cmd.args(["manifest.yml", "-t", "macos"]);
- manifest_1(&dir.dir);
-
- let expected = "\
-[1/3] Copy gitconfig to ~/.gitconfig.coliru
-[2/3] Link bashrc to ~/.bashrc.coliru
-[2/3] Link vimrc to ~/.vimrc.coliru
-[2/3] Run sh script.sh arg1 macos
-script.sh called with arg1 macos
-";
- assert_eq!(&stdout_to_string(&mut cmd), expected);
- assert_eq!(&stderr_to_string(&mut cmd), "");
-
- // Assert files are correctly copied/linked/run
- write_file(&dir.dir.join("bashrc"), "bash #2");
- write_file(&dir.dir.join("gitconfig"), "git #2");
- write_file(&dir.dir.join("vimrc"), "vim #2");
- let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
- let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
- let vim1_contents = read_file(&dir.dir.join(".vimrc.coliru"));
- let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
- let log_contents = read_file(&dir.dir.join("log.txt"));
- assert_eq!(bash_contents, "bash #2");
- assert_eq!(git_contents, "git #1");
- assert_eq!(vim1_contents, "vim #2");
- assert_eq!(vim2_exists, false);
- assert_eq!(log_contents, "script.sh called with arg1 macos\n");
-}
-
-#[test]
-fn test_dry_run() {
- let (dir, mut cmd) = setup_e2e("test_dry_run");
- cmd.args(["manifest.yml", "--dry-run", "-t", "linux"]);
- manifest_1(&dir.dir);
-
- let expected = "\
-[1/3] Copy gitconfig to ~/.gitconfig.coliru (DRY RUN)
-[2/3] Link bashrc to ~/.bashrc.coliru (DRY RUN)
-[2/3] Link vimrc to ~/.vimrc.coliru (DRY RUN)
-[2/3] Run sh script.sh arg1 linux (DRY RUN)
-";
- assert_eq!(&stdout_to_string(&mut cmd), expected);
- assert_eq!(&stderr_to_string(&mut cmd), "");
-
- // Assert files are correctly copied/linked/run
- let bash_exists = dir.dir.join(".bashrc.coliru").exists();
- let git_exists = dir.dir.join(".gitconfig.coliru").exists();
- let vim1_exists = dir.dir.join(".vimrc.coliru").exists();
- let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
- let log_exists = dir.dir.join("log.txt").exists();
- assert_eq!(bash_exists, false);
- assert_eq!(git_exists, false);
- assert_eq!(vim1_exists, false);
- assert_eq!(vim2_exists, false);
- assert_eq!(log_exists, false);
-}
-
-#[test]
-#[cfg(target_family = "unix")]
-fn test_copy() {
- let (dir, mut cmd) = setup_e2e("test_copy");
- cmd.args(["manifest.yml", "--copy", "-t", "linux"]);
- manifest_1(&dir.dir);
-
- let expected = "\
-[1/3] Copy gitconfig to ~/.gitconfig.coliru
-[2/3] Copy bashrc to ~/.bashrc.coliru
-[2/3] Copy vimrc to ~/.vimrc.coliru
-[2/3] Run sh script.sh arg1 linux
-script.sh called with arg1 linux
-";
- assert_eq!(&stdout_to_string(&mut cmd), expected);
- assert_eq!(&stderr_to_string(&mut cmd), "");
-
- // Assert files are correctly copied/linked/run
- write_file(&dir.dir.join("bashrc"), "bash #2");
- write_file(&dir.dir.join("gitconfig"), "git #2");
- write_file(&dir.dir.join("vimrc"), "vim #2");
- let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
- let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
- let vim1_contents = read_file(&dir.dir.join(".vimrc.coliru"));
- let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
- let log_contents = read_file(&dir.dir.join("log.txt"));
- assert_eq!(bash_contents, "bash #1");
- assert_eq!(git_contents, "git #1");
- assert_eq!(vim1_contents, "vim #1");
- assert_eq!(vim2_exists, false);
- assert_eq!(log_contents, "script.sh called with arg1 linux\n");
-}
-
-#[test]
-#[cfg(target_family = "windows")]
-fn test_copy() {
- let (dir, mut cmd) = setup_e2e("test_copy");
- cmd.args(["manifest-windows-test.yml", "--copy", "-t", "windows"]);
- manifest_1(&dir.dir);
-
- let expected = "\
-[1/3] Copy gitconfig to .gitconfig.coliru
-[3/3] Copy vimrc to _vimrc.coliru
-[3/3] Run script.bat arg1 windows
-script.bat called with arg1 windows\r
-";
- assert_eq!(&stdout_to_string(&mut cmd), expected);
- assert_eq!(&stderr_to_string(&mut cmd), "");
-
- // Assert files are correctly copied/linked/run
- write_file(&dir.dir.join("gitconfig"), "git #2");
- write_file(&dir.dir.join("vimrc"), "vim #2");
- let bash_exists = dir.dir.join(".bashrc.coliru").exists();
- let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
- let vim1_exists = dir.dir.join(".vimrc.coliru").exists();
- let vim2_contents = read_file(&dir.dir.join("_vimrc.coliru"));
- let log_contents = read_file(&dir.dir.join("log.txt"));
- assert_eq!(bash_exists, false);
- assert_eq!(git_contents, "git #1");
- assert_eq!(vim1_exists, false);
- assert_eq!(vim2_contents, "vim #1");
- assert_eq!(log_contents, "script.bat called with arg1 windows \r\n");
-}
-
-#[test]
-#[cfg(target_family = "unix")]
-fn test_run_failure() {
- let (dir, mut cmd) = setup_e2e("test_run_failure");
- cmd.args(["manifest.yml", "-t", "linux"]);
- manifest_1(&dir.dir);
- write_file(&dir.dir.join("script.sh"), "exit 1");
-
- let expected_stdout = "\
-[1/3] Copy gitconfig to ~/.gitconfig.coliru
-[2/3] Link bashrc to ~/.bashrc.coliru
-[2/3] Link vimrc to ~/.vimrc.coliru
-[2/3] Run sh script.sh arg1 linux
-";
- let expected_stderr = " Error: Process exited with exit status: 1\n";
- assert_eq!(&stdout_to_string(&mut cmd), expected_stdout);
- assert_eq!(&stderr_to_string(&mut cmd), expected_stderr);
-
- // Assert files are correctly copied/linked/run
- write_file(&dir.dir.join("bashrc"), "bash #2");
- write_file(&dir.dir.join("gitconfig"), "git #2");
- write_file(&dir.dir.join("vimrc"), "vim #2");
- let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
- let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
- let vim1_contents = read_file(&dir.dir.join(".vimrc.coliru"));
- let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
- assert_eq!(bash_contents, "bash #2");
- assert_eq!(git_contents, "git #1");
- assert_eq!(vim1_contents, "vim #2");
- assert_eq!(vim2_exists, false);
-}
-
-#[test]
-#[cfg(target_family = "windows")]
-fn test_run_failure() {
- let (dir, mut cmd) = setup_e2e("test_run_failure");
- cmd.args(["manifest-windows-test.yml", "-t", "windows"]);
- manifest_1(&dir.dir);
- write_file(&dir.dir.join("script.bat"), "@echo off\r\nexit 1");
-
- let expected_stdout = "\
-[1/3] Copy gitconfig to .gitconfig.coliru
-[3/3] Link vimrc to _vimrc.coliru
-[3/3] Run script.bat arg1 windows
-";
- let expected_stderr = " Error: Process exited with exit code: 1\n";
- assert_eq!(&stdout_to_string(&mut cmd), expected_stdout);
- assert_eq!(&stderr_to_string(&mut cmd), expected_stderr);
-
- // Assert files are correctly copied/linked/run
- write_file(&dir.dir.join("gitconfig"), "git #2");
- write_file(&dir.dir.join("vimrc"), "vim #2");
- let bash_exists = dir.dir.join(".bashrc.coliru").exists();
- let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
- let vim1_exists = dir.dir.join(".vimrc.coliru").exists();
- let vim2_contents = read_file(&dir.dir.join("_vimrc.coliru"));
- assert_eq!(bash_exists, false);
- assert_eq!(git_contents, "git #1");
- assert_eq!(vim1_exists, false);
- assert_eq!(vim2_contents, "vim #2");
-}
-
-#[test]
-#[cfg(target_family = "unix")]
-fn test_missing_file() {
- let (dir, mut cmd) = setup_e2e("test_missing_file");
- cmd.args(["manifest.yml", "-t", "linux"]);
- manifest_1(&dir.dir);
- remove_file(&dir.dir.join("vimrc")).unwrap();
-
- let expected_stdout = "\
-[1/3] Copy gitconfig to ~/.gitconfig.coliru
-[2/3] Link bashrc to ~/.bashrc.coliru
-[2/3] Link vimrc to ~/.vimrc.coliru
-[2/3] Run sh script.sh arg1 linux
-script.sh called with arg1 linux
-";
- let expected_stderr = " Error: No such file or directory \
- (os error 2)\n";
- assert_eq!(&stdout_to_string(&mut cmd), expected_stdout);
- assert_eq!(&stderr_to_string(&mut cmd), expected_stderr);
-
- // Assert files are correctly copied/linked/run
- write_file(&dir.dir.join("bashrc"), "bash #2");
- write_file(&dir.dir.join("gitconfig"), "git #2");
- let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
- let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
- let log_contents = read_file(&dir.dir.join("log.txt"));
- assert_eq!(bash_contents, "bash #2");
- assert_eq!(git_contents, "git #1");
- assert_eq!(log_contents, "script.sh called with arg1 linux\n");
-}
-
-#[test]
-#[cfg(target_family = "windows")]
-fn test_missing_file() {
- let (dir, mut cmd) = setup_e2e("test_missing_file");
- cmd.args(["manifest-windows-test.yml", "-t", "windows"]);
- manifest_1(&dir.dir);
- remove_file(&dir.dir.join("vimrc")).unwrap();
-
- let expected_stdout = "\
-[1/3] Copy gitconfig to .gitconfig.coliru
-[3/3] Link vimrc to _vimrc.coliru
-[3/3] Run script.bat arg1 windows
-script.bat called with arg1 windows\r
-";
- let expected_stderr = " Error: The system cannot find the file specified. \
- (os error 2)\n";
- assert_eq!(&stdout_to_string(&mut cmd), expected_stdout);
- assert_eq!(&stderr_to_string(&mut cmd), expected_stderr);
-
- // Assert files are correctly copied/linked/run
- write_file(&dir.dir.join("gitconfig"), "git #2");
- let bash_exists = dir.dir.join(".bashrc.coliru").exists();
- let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
- let log_contents = read_file(&dir.dir.join("log.txt"));
- assert_eq!(bash_exists, false);
- assert_eq!(git_contents, "git #1");
- assert_eq!(log_contents, "script.bat called with arg1 windows \r\n");
-}
-
-#[test]
-fn test_empty_manifest() {
- let (dir, mut cmd) = setup_e2e("test_empty_manifest");
+fn test_basic_empty_manifest() {
+ let (dir, mut cmd) = setup_e2e("test_basic_empty_manifest");
cmd.args(["manifest.yml"]);
write_file(&dir.dir.join("manifest.yml"), "");
@@ -403,8 +43,8 @@ fn test_empty_manifest() {
#[test]
#[cfg(target_family = "unix")]
-fn test_missing_manifest() {
- let (_dir, mut cmd) = setup_e2e("test_missing_manifest");
+fn test_basic_missing_manifest() {
+ let (_dir, mut cmd) = setup_e2e("test_basic_missing_manifest");
cmd.args(["missing.yml"]);
let expected = "Error: No such file or directory (os error 2)\n";
@@ -414,8 +54,8 @@ fn test_missing_manifest() {
#[test]
#[cfg(target_family = "windows")]
-fn test_missing_manifest() {
- let (_dir, mut cmd) = setup_e2e("test_missing_manifest");
+fn test_basic_missing_manifest() {
+ let (_dir, mut cmd) = setup_e2e("test_basic_missing_manifest");
cmd.args(["missing.yml"]);
let expected = "Error: The system cannot find the file specified. \
@@ -425,11 +65,11 @@ fn test_missing_manifest() {
}
#[test]
-fn test_absolute_manifest() {
- let (dir, mut cmd) = setup_e2e("test_absolute_manifest");
+fn test_basic_absolute_manifest() {
+ let (dir, mut cmd) = setup_e2e("test_basic_absolute_manifest");
let manifest_path = dir.dir.join("manifest.yml");
cmd.args([&manifest_path.to_str().unwrap(), "--dry-run", "-t", "linux"]);
- manifest_1(&dir.dir);
+ copy_manifest(&dir.dir);
let expected = "\
[1/3] Copy gitconfig to ~/.gitconfig.coliru (DRY RUN)
diff --git a/tests/common/mod.rs b/tests/common/mod.rs
@@ -6,6 +6,8 @@ use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::Command;
+pub const SSH_HOST: &str = "test@localhost:2222";
+
/// Stores the path to a temporary directory that is automatically deleted
/// when the value is dropped.
///
@@ -61,6 +63,34 @@ pub fn setup_e2e(name: &str) -> (TempDir, Command) {
(dir, cmd)
}
+/// Prepares a temporary directory and a new Command for an e2e test, with the
+/// --host argument already provided
+pub fn setup_e2e_ssh(name: &str) -> (TempDir, Command) {
+ let (dir, mut cmd) = setup_e2e(name);
+ cmd.args(["--host", SSH_HOST]);
+ (dir, cmd)
+}
+
+/// Create a basic manifest file and its associated dotfiles in a directory
+pub fn copy_manifest(dir: &Path) {
+ // Copy files from examples
+ let examples = env::current_exe().unwrap().parent().unwrap().to_path_buf()
+ .join("../../../examples");
+ let copy_file = |name: &str| {
+ fs::copy(examples.join(name), &dir.join(name)).unwrap();
+ };
+ copy_file("script.bat");
+ copy_file("script.sh");
+ copy_file("manifest.yml");
+ copy_file("manifest-windows-test.yml");
+
+ // Create simplified config files
+ write_file(&dir.join("bashrc"), "bash #1");
+ write_file(&dir.join("gitconfig"), "git #1");
+ write_file(&dir.join("vimrc"), "vim #1");
+
+}
+
/// Writes a string to a file, overwriting it if it already exists.
pub fn write_file(path: &Path, contents: &str) {
let mut file = fs::File::create(path).unwrap();
diff --git a/tests/local.rs b/tests/local.rs
@@ -0,0 +1,349 @@
+/// End to end tests that test specific installation behavior on the local file
+/// system
+
+mod common;
+
+use common::*;
+use std::fs::remove_file;
+
+#[test]
+#[cfg(target_family = "unix")]
+fn test_local_standard() {
+ let (dir, mut cmd) = setup_e2e("test_local_standard");
+ cmd.args(["manifest.yml", "-t", "linux"]);
+ copy_manifest(&dir.dir);
+
+ let expected = "\
+[1/3] Copy gitconfig to ~/.gitconfig.coliru
+[2/3] Link bashrc to ~/.bashrc.coliru
+[2/3] Link vimrc to ~/.vimrc.coliru
+[2/3] Run sh script.sh arg1 linux
+script.sh called with arg1 linux
+";
+ assert_eq!(&stdout_to_string(&mut cmd), expected);
+ assert_eq!(&stderr_to_string(&mut cmd), "");
+
+ // Assert files are correctly copied/linked/run
+ write_file(&dir.dir.join("bashrc"), "bash #2");
+ write_file(&dir.dir.join("gitconfig"), "git #2");
+ write_file(&dir.dir.join("vimrc"), "vim #2");
+ let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
+ let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
+ let vim1_contents = read_file(&dir.dir.join(".vimrc.coliru"));
+ let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
+ let log_contents = read_file(&dir.dir.join("log.txt"));
+ assert_eq!(bash_contents, "bash #2");
+ assert_eq!(git_contents, "git #1");
+ assert_eq!(vim1_contents, "vim #2");
+ assert_eq!(vim2_exists, false);
+ assert_eq!(log_contents, "script.sh called with arg1 linux\n");
+}
+
+#[test]
+#[cfg(target_family = "windows")]
+fn test_local_standard() {
+ let (dir, mut cmd) = setup_e2e("test_local_standard");
+ cmd.args(["manifest-windows-test.yml", "-t", "windows"]);
+ copy_manifest(&dir.dir);
+
+ let expected = "\
+[1/3] Copy gitconfig to .gitconfig.coliru
+[3/3] Link vimrc to _vimrc.coliru
+[3/3] Run script.bat arg1 windows
+script.bat called with arg1 windows\r
+";
+ assert_eq!(&stdout_to_string(&mut cmd), expected);
+ assert_eq!(&stderr_to_string(&mut cmd), "");
+
+ // Assert files are correctly copied/linked/run
+ write_file(&dir.dir.join("gitconfig"), "git #2");
+ write_file(&dir.dir.join("vimrc"), "vim #2");
+ let bash_exists = dir.dir.join(".bashrc.coliru").exists();
+ let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
+ let vim1_exists = dir.dir.join(".vimrc.coliru").exists();
+ let vim2_contents = read_file(&dir.dir.join("_vimrc.coliru"));
+ let log_contents = read_file(&dir.dir.join("log.txt"));
+ assert_eq!(bash_exists, false);
+ assert_eq!(git_contents, "git #1");
+ assert_eq!(vim1_exists, false);
+ assert_eq!(vim2_contents, "vim #2");
+ assert_eq!(log_contents, "script.bat called with arg1 windows \r\n");
+}
+
+#[test]
+#[cfg(target_family = "unix")]
+fn test_local_run_alternate_tag_rules_1() {
+ let (dir, mut cmd) = setup_e2e("test_local_run_alternate_tag_rules_1");
+ cmd.args(["manifest.yml", "-t", "linux", "^windows"]);
+ copy_manifest(&dir.dir);
+
+ let expected = "\
+[2/3] Link bashrc to ~/.bashrc.coliru
+[2/3] Link vimrc to ~/.vimrc.coliru
+[2/3] Run sh script.sh arg1 linux ^windows
+script.sh called with arg1 linux ^windows
+";
+ assert_eq!(&stdout_to_string(&mut cmd), expected);
+ assert_eq!(&stderr_to_string(&mut cmd), "");
+
+ // Assert files are correctly copied/linked/run
+ write_file(&dir.dir.join("bashrc"), "bash #2");
+ write_file(&dir.dir.join("vimrc"), "vim #2");
+ let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
+ let git_exists = dir.dir.join(".gitconfig.coliru").exists();
+ let vim1_contents = read_file(&dir.dir.join(".vimrc.coliru"));
+ let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
+ let log_contents = read_file(&dir.dir.join("log.txt"));
+ assert_eq!(bash_contents, "bash #2");
+ assert_eq!(git_exists, false);
+ assert_eq!(vim1_contents, "vim #2");
+ assert_eq!(vim2_exists, false);
+ assert_eq!(log_contents, "script.sh called with arg1 linux ^windows\n");
+}
+
+#[test]
+#[cfg(target_family = "unix")]
+fn test_local_run_alternate_tag_rules_2() {
+ let (dir, mut cmd) = setup_e2e("test_local_run_alternate_tag_rules_2");
+ cmd.args(["manifest.yml", "-t", "macos"]);
+ copy_manifest(&dir.dir);
+
+ let expected = "\
+[1/3] Copy gitconfig to ~/.gitconfig.coliru
+[2/3] Link bashrc to ~/.bashrc.coliru
+[2/3] Link vimrc to ~/.vimrc.coliru
+[2/3] Run sh script.sh arg1 macos
+script.sh called with arg1 macos
+";
+ assert_eq!(&stdout_to_string(&mut cmd), expected);
+ assert_eq!(&stderr_to_string(&mut cmd), "");
+
+ // Assert files are correctly copied/linked/run
+ write_file(&dir.dir.join("bashrc"), "bash #2");
+ write_file(&dir.dir.join("gitconfig"), "git #2");
+ write_file(&dir.dir.join("vimrc"), "vim #2");
+ let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
+ let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
+ let vim1_contents = read_file(&dir.dir.join(".vimrc.coliru"));
+ let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
+ let log_contents = read_file(&dir.dir.join("log.txt"));
+ assert_eq!(bash_contents, "bash #2");
+ assert_eq!(git_contents, "git #1");
+ assert_eq!(vim1_contents, "vim #2");
+ assert_eq!(vim2_exists, false);
+ assert_eq!(log_contents, "script.sh called with arg1 macos\n");
+}
+
+#[test]
+fn test_local_dry_run() {
+ let (dir, mut cmd) = setup_e2e("test_local_dry_run");
+ cmd.args(["manifest.yml", "--dry-run", "-t", "linux"]);
+ copy_manifest(&dir.dir);
+
+ let expected = "\
+[1/3] Copy gitconfig to ~/.gitconfig.coliru (DRY RUN)
+[2/3] Link bashrc to ~/.bashrc.coliru (DRY RUN)
+[2/3] Link vimrc to ~/.vimrc.coliru (DRY RUN)
+[2/3] Run sh script.sh arg1 linux (DRY RUN)
+";
+ assert_eq!(&stdout_to_string(&mut cmd), expected);
+ assert_eq!(&stderr_to_string(&mut cmd), "");
+
+ // Assert files are correctly copied/linked/run
+ let bash_exists = dir.dir.join(".bashrc.coliru").exists();
+ let git_exists = dir.dir.join(".gitconfig.coliru").exists();
+ let vim1_exists = dir.dir.join(".vimrc.coliru").exists();
+ let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
+ let log_exists = dir.dir.join("log.txt").exists();
+ assert_eq!(bash_exists, false);
+ assert_eq!(git_exists, false);
+ assert_eq!(vim1_exists, false);
+ assert_eq!(vim2_exists, false);
+ assert_eq!(log_exists, false);
+}
+
+#[test]
+#[cfg(target_family = "unix")]
+fn test_local_copy() {
+ let (dir, mut cmd) = setup_e2e("test_local_copy");
+ cmd.args(["manifest.yml", "--copy", "-t", "linux"]);
+ copy_manifest(&dir.dir);
+
+ let expected = "\
+[1/3] Copy gitconfig to ~/.gitconfig.coliru
+[2/3] Copy bashrc to ~/.bashrc.coliru
+[2/3] Copy vimrc to ~/.vimrc.coliru
+[2/3] Run sh script.sh arg1 linux
+script.sh called with arg1 linux
+";
+ assert_eq!(&stdout_to_string(&mut cmd), expected);
+ assert_eq!(&stderr_to_string(&mut cmd), "");
+
+ // Assert files are correctly copied/linked/run
+ write_file(&dir.dir.join("bashrc"), "bash #2");
+ write_file(&dir.dir.join("gitconfig"), "git #2");
+ write_file(&dir.dir.join("vimrc"), "vim #2");
+ let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
+ let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
+ let vim1_contents = read_file(&dir.dir.join(".vimrc.coliru"));
+ let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
+ let log_contents = read_file(&dir.dir.join("log.txt"));
+ assert_eq!(bash_contents, "bash #1");
+ assert_eq!(git_contents, "git #1");
+ assert_eq!(vim1_contents, "vim #1");
+ assert_eq!(vim2_exists, false);
+ assert_eq!(log_contents, "script.sh called with arg1 linux\n");
+}
+
+#[test]
+#[cfg(target_family = "windows")]
+fn test_local_copy() {
+ let (dir, mut cmd) = setup_e2e("test_local_copy");
+ cmd.args(["manifest-windows-test.yml", "--copy", "-t", "windows"]);
+ copy_manifest(&dir.dir);
+
+ let expected = "\
+[1/3] Copy gitconfig to .gitconfig.coliru
+[3/3] Copy vimrc to _vimrc.coliru
+[3/3] Run script.bat arg1 windows
+script.bat called with arg1 windows\r
+";
+ assert_eq!(&stdout_to_string(&mut cmd), expected);
+ assert_eq!(&stderr_to_string(&mut cmd), "");
+
+ // Assert files are correctly copied/linked/run
+ write_file(&dir.dir.join("gitconfig"), "git #2");
+ write_file(&dir.dir.join("vimrc"), "vim #2");
+ let bash_exists = dir.dir.join(".bashrc.coliru").exists();
+ let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
+ let vim1_exists = dir.dir.join(".vimrc.coliru").exists();
+ let vim2_contents = read_file(&dir.dir.join("_vimrc.coliru"));
+ let log_contents = read_file(&dir.dir.join("log.txt"));
+ assert_eq!(bash_exists, false);
+ assert_eq!(git_contents, "git #1");
+ assert_eq!(vim1_exists, false);
+ assert_eq!(vim2_contents, "vim #1");
+ assert_eq!(log_contents, "script.bat called with arg1 windows \r\n");
+}
+
+#[test]
+#[cfg(target_family = "unix")]
+fn test_local_run_failure() {
+ let (dir, mut cmd) = setup_e2e("test_local_run_failure");
+ cmd.args(["manifest.yml", "-t", "linux"]);
+ copy_manifest(&dir.dir);
+ write_file(&dir.dir.join("script.sh"), "exit 1");
+
+ let expected_stdout = "\
+[1/3] Copy gitconfig to ~/.gitconfig.coliru
+[2/3] Link bashrc to ~/.bashrc.coliru
+[2/3] Link vimrc to ~/.vimrc.coliru
+[2/3] Run sh script.sh arg1 linux
+";
+ let expected_stderr = " Error: Process exited with exit status: 1\n";
+ assert_eq!(&stdout_to_string(&mut cmd), expected_stdout);
+ assert_eq!(&stderr_to_string(&mut cmd), expected_stderr);
+
+ // Assert files are correctly copied/linked/run
+ write_file(&dir.dir.join("bashrc"), "bash #2");
+ write_file(&dir.dir.join("gitconfig"), "git #2");
+ write_file(&dir.dir.join("vimrc"), "vim #2");
+ let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
+ let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
+ let vim1_contents = read_file(&dir.dir.join(".vimrc.coliru"));
+ let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
+ assert_eq!(bash_contents, "bash #2");
+ assert_eq!(git_contents, "git #1");
+ assert_eq!(vim1_contents, "vim #2");
+ assert_eq!(vim2_exists, false);
+}
+
+#[test]
+#[cfg(target_family = "windows")]
+fn test_local_run_failure() {
+ let (dir, mut cmd) = setup_e2e("test_local_run_failure");
+ cmd.args(["manifest-windows-test.yml", "-t", "windows"]);
+ copy_manifest(&dir.dir);
+ write_file(&dir.dir.join("script.bat"), "@echo off\r\nexit 1");
+
+ let expected_stdout = "\
+[1/3] Copy gitconfig to .gitconfig.coliru
+[3/3] Link vimrc to _vimrc.coliru
+[3/3] Run script.bat arg1 windows
+";
+ let expected_stderr = " Error: Process exited with exit code: 1\n";
+ assert_eq!(&stdout_to_string(&mut cmd), expected_stdout);
+ assert_eq!(&stderr_to_string(&mut cmd), expected_stderr);
+
+ // Assert files are correctly copied/linked/run
+ write_file(&dir.dir.join("gitconfig"), "git #2");
+ write_file(&dir.dir.join("vimrc"), "vim #2");
+ let bash_exists = dir.dir.join(".bashrc.coliru").exists();
+ let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
+ let vim1_exists = dir.dir.join(".vimrc.coliru").exists();
+ let vim2_contents = read_file(&dir.dir.join("_vimrc.coliru"));
+ assert_eq!(bash_exists, false);
+ assert_eq!(git_contents, "git #1");
+ assert_eq!(vim1_exists, false);
+ assert_eq!(vim2_contents, "vim #2");
+}
+
+#[test]
+#[cfg(target_family = "unix")]
+fn test_local_missing_file() {
+ let (dir, mut cmd) = setup_e2e("test_local_missing_file");
+ cmd.args(["manifest.yml", "-t", "linux"]);
+ copy_manifest(&dir.dir);
+ remove_file(&dir.dir.join("vimrc")).unwrap();
+
+ let expected_stdout = "\
+[1/3] Copy gitconfig to ~/.gitconfig.coliru
+[2/3] Link bashrc to ~/.bashrc.coliru
+[2/3] Link vimrc to ~/.vimrc.coliru
+[2/3] Run sh script.sh arg1 linux
+script.sh called with arg1 linux
+";
+ let expected_stderr = " Error: No such file or directory \
+ (os error 2)\n";
+ assert_eq!(&stdout_to_string(&mut cmd), expected_stdout);
+ assert_eq!(&stderr_to_string(&mut cmd), expected_stderr);
+
+ // Assert files are correctly copied/linked/run
+ write_file(&dir.dir.join("bashrc"), "bash #2");
+ write_file(&dir.dir.join("gitconfig"), "git #2");
+ let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
+ let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
+ let log_contents = read_file(&dir.dir.join("log.txt"));
+ assert_eq!(bash_contents, "bash #2");
+ assert_eq!(git_contents, "git #1");
+ assert_eq!(log_contents, "script.sh called with arg1 linux\n");
+}
+
+#[test]
+#[cfg(target_family = "windows")]
+fn test_local_missing_file() {
+ let (dir, mut cmd) = setup_e2e("test_local_missing_file");
+ cmd.args(["manifest-windows-test.yml", "-t", "windows"]);
+ copy_manifest(&dir.dir);
+ remove_file(&dir.dir.join("vimrc")).unwrap();
+
+ let expected_stdout = "\
+[1/3] Copy gitconfig to .gitconfig.coliru
+[3/3] Link vimrc to _vimrc.coliru
+[3/3] Run script.bat arg1 windows
+script.bat called with arg1 windows\r
+";
+ let expected_stderr = " Error: The system cannot find the file specified. \
+ (os error 2)\n";
+ assert_eq!(&stdout_to_string(&mut cmd), expected_stdout);
+ assert_eq!(&stderr_to_string(&mut cmd), expected_stderr);
+
+ // Assert files are correctly copied/linked/run
+ write_file(&dir.dir.join("gitconfig"), "git #2");
+ let bash_exists = dir.dir.join(".bashrc.coliru").exists();
+ let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
+ let log_contents = read_file(&dir.dir.join("log.txt"));
+ assert_eq!(bash_exists, false);
+ assert_eq!(git_contents, "git #1");
+ assert_eq!(log_contents, "script.bat called with arg1 windows \r\n");
+}
diff --git a/tests/ssh.rs b/tests/ssh.rs
@@ -0,0 +1,243 @@
+/// End to end tests that test specific installation behavior on a remote
+/// machine via SSH
+
+mod common;
+
+use common::*;
+use std::fs::remove_file;
+
+#[test]
+fn test_ssh_standard() {
+ let (dir, mut cmd) = setup_e2e_ssh("test_ssh_standard");
+ cmd.args(["manifest.yml", "-t", "linux"]);
+ copy_manifest(&dir.dir);
+
+ let expected_stdout = format!("\
+[1/3] Send gitconfig to {SSH_HOST}:~/.gitconfig.coliru
+[2/3] Send bashrc to {SSH_HOST}:~/.bashrc.coliru
+[2/3] Send vimrc to {SSH_HOST}:~/.vimrc.coliru
+[2/3] Run sh script.sh arg1 linux on {SSH_HOST}
+");
+ let expected_stderr = " Error: not implemented
+ Error: not implemented
+ Error: not implemented
+ Error: not implemented
+";
+ assert_eq!(stdout_to_string(&mut cmd), expected_stdout);
+ assert_eq!(&stderr_to_string(&mut cmd), expected_stderr);
+
+ // Assert files are correctly copied/linked/run
+ // write_file(&dir.dir.join("bashrc"), "bash #2");
+ // write_file(&dir.dir.join("gitconfig"), "git #2");
+ // write_file(&dir.dir.join("vimrc"), "vim #2");
+ // let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
+ // let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
+ // let vim1_contents = read_file(&dir.dir.join(".vimrc.coliru"));
+ // let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
+ // let log_contents = read_file(&dir.dir.join("log.txt"));
+ // assert_eq!(bash_contents, "bash #2");
+ // assert_eq!(git_contents, "git #1");
+ // assert_eq!(vim1_contents, "vim #2");
+ // assert_eq!(vim2_exists, false);
+ // assert_eq!(log_contents, "script.sh called with arg1 linux\n");
+}
+
+#[test]
+fn test_ssh_run_alternate_tag_rules_1() {
+ let (dir, mut cmd) = setup_e2e_ssh("test_ssh_run_alternate_tag_rules_1");
+ cmd.args(["manifest.yml", "-t", "linux", "^windows"]);
+ copy_manifest(&dir.dir);
+
+ let expected_stdout = format!("\
+[2/3] Send bashrc to {SSH_HOST}:~/.bashrc.coliru
+[2/3] Send vimrc to {SSH_HOST}:~/.vimrc.coliru
+[2/3] Run sh script.sh arg1 linux ^windows on {SSH_HOST}
+");
+ let expected_stderr = " Error: not implemented
+ Error: not implemented
+ Error: not implemented
+";
+ assert_eq!(stdout_to_string(&mut cmd), expected_stdout);
+ assert_eq!(&stderr_to_string(&mut cmd), expected_stderr);
+
+ // Assert files are correctly copied/linked/run
+ // write_file(&dir.dir.join("bashrc"), "bash #2");
+ // write_file(&dir.dir.join("vimrc"), "vim #2");
+ // let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
+ // let git_exists = dir.dir.join(".gitconfig.coliru").exists();
+ // let vim1_contents = read_file(&dir.dir.join(".vimrc.coliru"));
+ // let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
+ // let log_contents = read_file(&dir.dir.join("log.txt"));
+ // assert_eq!(bash_contents, "bash #2");
+ // assert_eq!(git_exists, false);
+ // assert_eq!(vim1_contents, "vim #2");
+ // assert_eq!(vim2_exists, false);
+ // assert_eq!(log_contents, "script.sh called with arg1 linux ^windows\n");
+}
+
+#[test]
+fn test_ssh_run_alternate_tag_rules_2() {
+ let (dir, mut cmd) = setup_e2e_ssh("test_ssh_run_alternate_tag_rules_2");
+ cmd.args(["manifest.yml", "-t", "macos"]);
+ copy_manifest(&dir.dir);
+
+ let expected_stdout = format!("\
+[1/3] Send gitconfig to {SSH_HOST}:~/.gitconfig.coliru
+[2/3] Send bashrc to {SSH_HOST}:~/.bashrc.coliru
+[2/3] Send vimrc to {SSH_HOST}:~/.vimrc.coliru
+[2/3] Run sh script.sh arg1 macos on {SSH_HOST}
+");
+ let expected_stderr = " Error: not implemented
+ Error: not implemented
+ Error: not implemented
+ Error: not implemented
+";
+ assert_eq!(stdout_to_string(&mut cmd), expected_stdout);
+ assert_eq!(&stderr_to_string(&mut cmd), expected_stderr);
+
+ // Assert files are correctly copied/linked/run
+ // write_file(&dir.dir.join("bashrc"), "bash #2");
+ // write_file(&dir.dir.join("gitconfig"), "git #2");
+ // write_file(&dir.dir.join("vimrc"), "vim #2");
+ // let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
+ // let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
+ // let vim1_contents = read_file(&dir.dir.join(".vimrc.coliru"));
+ // let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
+ // let log_contents = read_file(&dir.dir.join("log.txt"));
+ // assert_eq!(bash_contents, "bash #2");
+ // assert_eq!(git_contents, "git #1");
+ // assert_eq!(vim1_contents, "vim #2");
+ // assert_eq!(vim2_exists, false);
+ // assert_eq!(log_contents, "script.sh called with arg1 macos\n");
+}
+
+#[test]
+fn test_ssh_dry_run() {
+ let (dir, mut cmd) = setup_e2e_ssh("test_ssh_dry_run");
+ cmd.args(["manifest.yml", "--dry-run", "-t", "linux"]);
+ copy_manifest(&dir.dir);
+
+ let expected = format!("\
+[1/3] Send gitconfig to {SSH_HOST}:~/.gitconfig.coliru (DRY RUN)
+[2/3] Send bashrc to {SSH_HOST}:~/.bashrc.coliru (DRY RUN)
+[2/3] Send vimrc to {SSH_HOST}:~/.vimrc.coliru (DRY RUN)
+[2/3] Run sh script.sh arg1 linux on {SSH_HOST} (DRY RUN)
+");
+ assert_eq!(stdout_to_string(&mut cmd), expected);
+ assert_eq!(&stderr_to_string(&mut cmd), "");
+
+ // Assert files are correctly copied/linked/run
+ // let bash_exists = dir.dir.join(".bashrc.coliru").exists();
+ // let git_exists = dir.dir.join(".gitconfig.coliru").exists();
+ // let vim1_exists = dir.dir.join(".vimrc.coliru").exists();
+ // let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
+ // let log_exists = dir.dir.join("log.txt").exists();
+ // assert_eq!(bash_exists, false);
+ // assert_eq!(git_exists, false);
+ // assert_eq!(vim1_exists, false);
+ // assert_eq!(vim2_exists, false);
+ // assert_eq!(log_exists, false);
+}
+
+#[test]
+fn test_ssh_copy() {
+ let (dir, mut cmd) = setup_e2e_ssh("test_ssh_copy");
+ cmd.args(["manifest.yml", "--copy", "-t", "linux"]);
+ copy_manifest(&dir.dir);
+
+ let expected_stdout = format!("\
+[1/3] Send gitconfig to {SSH_HOST}:~/.gitconfig.coliru
+[2/3] Send bashrc to {SSH_HOST}:~/.bashrc.coliru
+[2/3] Send vimrc to {SSH_HOST}:~/.vimrc.coliru
+[2/3] Run sh script.sh arg1 linux on {SSH_HOST}
+");
+ let expected_stderr = " Error: not implemented
+ Error: not implemented
+ Error: not implemented
+ Error: not implemented
+";
+ assert_eq!(stdout_to_string(&mut cmd), expected_stdout);
+ assert_eq!(&stderr_to_string(&mut cmd), expected_stderr);
+
+ // Assert files are correctly copied/linked/run
+ // write_file(&dir.dir.join("bashrc"), "bash #2");
+ // write_file(&dir.dir.join("gitconfig"), "git #2");
+ // write_file(&dir.dir.join("vimrc"), "vim #2");
+ // let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
+ // let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
+ // let vim1_contents = read_file(&dir.dir.join(".vimrc.coliru"));
+ // let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
+ // let log_contents = read_file(&dir.dir.join("log.txt"));
+ // assert_eq!(bash_contents, "bash #1");
+ // assert_eq!(git_contents, "git #1");
+ // assert_eq!(vim1_contents, "vim #1");
+ // assert_eq!(vim2_exists, false);
+ // assert_eq!(log_contents, "script.sh called with arg1 linux\n");
+}
+
+#[test]
+fn test_ssh_run_failure() {
+ let (dir, mut cmd) = setup_e2e_ssh("test_ssh_run_failure");
+ cmd.args(["manifest.yml", "-t", "linux"]);
+ copy_manifest(&dir.dir);
+ write_file(&dir.dir.join("script.sh"), "exit 1");
+
+ let expected_stdout = format!("\
+[1/3] Send gitconfig to {SSH_HOST}:~/.gitconfig.coliru
+[2/3] Send bashrc to {SSH_HOST}:~/.bashrc.coliru
+[2/3] Send vimrc to {SSH_HOST}:~/.vimrc.coliru
+[2/3] Run sh script.sh arg1 linux on {SSH_HOST}
+");
+ let expected_stderr = " Error: not implemented
+ Error: not implemented
+ Error: not implemented
+ Error: not implemented
+";
+ assert_eq!(stdout_to_string(&mut cmd), expected_stdout);
+ assert_eq!(&stderr_to_string(&mut cmd), expected_stderr);
+
+ // Assert files are correctly copied/linked/run
+ // write_file(&dir.dir.join("bashrc"), "bash #2");
+ // write_file(&dir.dir.join("gitconfig"), "git #2");
+ // write_file(&dir.dir.join("vimrc"), "vim #2");
+ // let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
+ // let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
+ // let vim1_contents = read_file(&dir.dir.join(".vimrc.coliru"));
+ // let vim2_exists = dir.dir.join("_vimrc.coliru").exists();
+ // assert_eq!(bash_contents, "bash #2");
+ // assert_eq!(git_contents, "git #1");
+ // assert_eq!(vim1_contents, "vim #2");
+ // assert_eq!(vim2_exists, false);
+}
+
+#[test]
+fn test_ssh_missing_file() {
+ let (dir, mut cmd) = setup_e2e_ssh("test_ssh_missing_file");
+ cmd.args(["manifest.yml", "-t", "linux"]);
+ copy_manifest(&dir.dir);
+ remove_file(&dir.dir.join("vimrc")).unwrap();
+
+ let expected_stdout = format!("\
+[1/3] Send gitconfig to {SSH_HOST}:~/.gitconfig.coliru
+[2/3] Send bashrc to {SSH_HOST}:~/.bashrc.coliru
+[2/3] Send vimrc to {SSH_HOST}:~/.vimrc.coliru
+[2/3] Run sh script.sh arg1 linux on {SSH_HOST}
+");
+ let expected_stderr = " Error: not implemented
+ Error: not implemented
+ Error: not implemented
+ Error: not implemented
+";
+ assert_eq!(stdout_to_string(&mut cmd), expected_stdout);
+ assert_eq!(&stderr_to_string(&mut cmd), expected_stderr);
+
+ // Assert files are correctly copied/linked/run
+ // write_file(&dir.dir.join("bashrc"), "bash #2");
+ // write_file(&dir.dir.join("gitconfig"), "git #2");
+ // let bash_contents = read_file(&dir.dir.join(".bashrc.coliru"));
+ // let git_contents = read_file(&dir.dir.join(".gitconfig.coliru"));
+ // let log_contents = read_file(&dir.dir.join("log.txt"));
+ // assert_eq!(bash_contents, "bash #2");
+ // assert_eq!(git_contents, "git #1");
+ // assert_eq!(log_contents, "script.sh called with arg1 linux\n");
+}