public void Password()
        {
            ExecuteResponse result;

            using (new KubeTestManager())
            {
                using (var runner = new ProgramRunner())
                {
                    // Verify that [neon password] returns help/usage text:

                    result = runner.Execute(Program.Main, "password");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Contains("Manages neonKUBE passwords.", result.OutputText);

                    result = runner.Execute(Program.Main, "help", "password");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Contains("Manages neonKUBE passwords.", result.OutputText);

                    // Verify that the "--help" option does the same thing.

                    result = runner.Execute(Program.Main, "password", "--help");

                    Assert.Equal(0, result.ExitCode);
                    Assert.Contains("Manages neonKUBE passwords.", result.OutputText);

                    // Verify that an invalid command fails.

                    result = runner.Execute(Program.Main, "password", "bad");

                    Assert.NotEqual(0, result.ExitCode);
                    Assert.Contains("Unexpected [bad] command.", result.ErrorText);
                }
            }
        }
Beispiel #2
0
        public void VariableInjectEncrypted()
        {
            var orgDirectory = Environment.CurrentDirectory;

            try
            {
                using (var manager = new KubeTestManager())
                {
                    using (var runner = new ProgramRunner())
                    {
                        using (var tempFolder = new TempFolder())
                        {
                            Environment.CurrentDirectory = tempFolder.Path;

                            var vault = new NeonVault(Program.LookupPassword);

                            // Create a test password and a [.password-name] file in the
                            // temp test folder.

                            var result = runner.Execute(Program.Main, $"password", "set", "test");
                            Assert.Equal(0, result.ExitCode);

                            //-------------------------------------------------
                            // Verify that we can inject variables into an
                            // ENCRYPTED file.

                            File.WriteAllText("test.cmd", "type %1 > output.txt");

                            File.WriteAllText("file.txt",
                                              @"
$<<TEST_A>>
$<<TEST_B>>
$<<TEST_C>>
$<<TEST_D>>
");
                            File.WriteAllBytes("file.txt", vault.Encrypt("file.txt", "test"));
                            Assert.True(NeonVault.IsEncrypted("file.txt"));

                            result = runner.Execute(Program.Main, $"run", "--TEST_A=A-VALUE", "--TEST_B=B-VALUE", "--TEST_C=C-VALUE", "--TEST_D=D-VALUE", "--", "test.cmd", "_..file.txt");
                            Assert.Equal(0, result.ExitCode);

                            var output = File.ReadAllText("output.txt");

                            Assert.Contains("A-VALUE", output);
                            Assert.Contains("B-VALUE", output);
                            Assert.Contains("C-VALUE", output);
                            Assert.Contains("D-VALUE", output);
                            File.Delete("output.txt");
                            File.Delete("file.txt");
                        }
                    }
                }
            }
            finally
            {
                Environment.CurrentDirectory = orgDirectory;
            }
        }
        public void PasswordList()
        {
            ExecuteResponse result;

            using (var manager = new KubeTestManager())
            {
                using (var runner = new ProgramRunner())
                {
                    // Verify that [--help] works:

                    result = runner.Execute(Program.Main, "password", "list", "--help");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Contains("Lists passwords.", result.OutputText);

                    // Add a few passwords:

                    result = runner.Execute(Program.Main, "password", "rm", "--force", "*");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.ExecuteWithInput(Program.Main, "one", "password", "set", "pwd-1", "-");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.ExecuteWithInput(Program.Main, "two", "password", "set", "pwd-2", "-");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.ExecuteWithInput(Program.Main, "three", "password", "set", "pwd-3", "-");
                    Assert.Equal(0, result.ExitCode);

                    // Verify that we can list via: list

                    result = runner.Execute(Program.Main, "password", "list");
                    Assert.Equal(0, result.ExitCode);
                    TestHelper.AssertEqualLines(
                        @"pwd-1
pwd-2
pwd-3
",
                        result.OutputText);

                    // Verify that we can list via: ls

                    result = runner.Execute(Program.Main, "password", "ls");
                    Assert.Equal(0, result.ExitCode);
                    TestHelper.AssertEqualLines(
                        @"pwd-1
pwd-2
pwd-3
",
                        result.OutputText);
                }
            }
        }
Beispiel #4
0
        public void Options()
        {
            var orgDirectory = Environment.CurrentDirectory;

            try
            {
                using (var manager = new KubeTestManager())
                {
                    using (var runner = new ProgramRunner())
                    {
                        using (var tempFolder = new TempFolder())
                        {
                            Environment.CurrentDirectory = tempFolder.Path;

                            //-------------------------------------------------
                            // Verify that the [run] command handles command line options correctly.

                            File.WriteAllText("test.cmd", "echo %* > output.txt");

                            var result = runner.Execute(Program.Main, $"run", "--", "test.cmd", "-foo", "--bar=foobar", "--hello", "world");
                            Assert.Equal(0, result.ExitCode);

                            Assert.Contains("-foo --bar=foobar --hello world", File.ReadAllText("output.txt"));
                        }
                    }
                }
            }
            finally
            {
                Environment.CurrentDirectory = orgDirectory;
            }
        }
        public void SourceNamespace()
        {
            using (new KubeTestManager())
            {
                using (var runner = new ProgramRunner())
                {
                    // Verify that all types are generated when no targets
                    // are specified.

                    var result = runner.Execute(Program.Main, "generate", "models", $"--source-namespace={typeof(FooBar.Class4).Namespace}", thisAssemblyPath);
                    Assert.Equal(0, result.ExitCode);

                    var sourceCode = result.OutputText;

                    ModelGenerator.Compile(sourceCode, "test-assembly", references => ModelGenTestHelper.ReferenceHandler(references));

                    Assert.DoesNotContain("class Class1", sourceCode);
                    Assert.DoesNotContain("class Class2", sourceCode);
                    Assert.DoesNotContain("class Class3", sourceCode);
                    Assert.Contains("class Class4", sourceCode);
                    Assert.DoesNotContain("class Service1", sourceCode);
                    Assert.DoesNotContain("class Service2", sourceCode);
                }
            }
        }
Beispiel #6
0
        public void Vault()
        {
            using (var runner = new ProgramRunner())
            {
                var result = runner.Execute(Program.Main, "vault");

                Assert.Equal(0, result.ExitCode);
            }
        }
Beispiel #7
0
        public void Base()
        {
            using (var runner = new ProgramRunner())
            {
                // Verify that base command returns some help.

                var result = runner.Execute(Program.Main);

                Assert.Equal(0, result.ExitCode);
                Assert.Contains("neonKUBE Management Tool: neon", result.OutputText);

                // Verify that we see an error for an unrecognized command.,

                result = runner.Execute(Program.Main, "invalid-command");

                Assert.NotEqual(0, result.ExitCode);
            }
        }
Beispiel #8
0
        public void Run()
        {
            using (var runner = new ProgramRunner())
            {
                // Verify that the help command works.

                var result = runner.Execute(Program.Main, "run", "--help");

                Assert.Equal(0, result.ExitCode);
                Assert.Contains("Runs a sub-command, optionally injecting settings and secrets and/or", result.OutputText);

                // Verify ther error we get when there's no right command line.

                result = runner.Execute(Program.Main, "run");

                Assert.NotEqual(0, result.ExitCode);
                Assert.Contains("*** ERROR: Expected a command after a [--] argument.", result.ErrorText);
            }
        }
        public void Base()
        {
            // Verify that base command returns some help.

            using (var runner = new ProgramRunner())
            {
                var result = runner.Execute(Program.Main, "couchbase");

                Assert.Equal(0, result.ExitCode);
                Assert.Contains("Performs Couchbase related operations.", result.OutputText);
            }
        }
Beispiel #10
0
        public void Execute()
        {
            ExecuteResponse result;

            using (var runner = new ProgramRunner())
            {
                mainExecuted = false;

                result = runner.Execute(Main, "pass");
                Assert.Equal(0, result.ExitCode);
                Assert.Equal("PASS: STDOUT", result.OutputText);
                Assert.Equal("PASS: STDERR", result.ErrorText);
                Assert.True(mainExecuted);

                mainExecuted = false;
                result       = runner.Execute(Main, "fail");
                Assert.Equal(1, result.ExitCode);
                Assert.Equal("FAIL: STDOUT", result.OutputText);
                Assert.Equal("FAIL: STDERR", result.ErrorText);
                Assert.True(mainExecuted);
            }
        }
Beispiel #11
0
        public void VariableOptions()
        {
            var orgDirectory = Environment.CurrentDirectory;

            try
            {
                using (var manager = new KubeTestManager())
                {
                    using (var runner = new ProgramRunner())
                    {
                        using (var tempFolder = new TempFolder())
                        {
                            Environment.CurrentDirectory = tempFolder.Path;

                            var vault = new NeonVault(Program.LookupPassword);

                            //-------------------------------------------------
                            // Verify that we can process [--name=value] run command options.

                            File.WriteAllText("test.cmd", "echo %* > output.txt");

                            var result = runner.Execute(Program.Main, $"run", "--TEST_A=A-VALUE", "--TEST_B=B-VALUE", "--TEST_C=C-VALUE", "--TEST_D=D-VALUE", "--", "test.cmd", "_.TEST_A", "_.TEST_B", "_.TEST_C", "_.TEST_D");
                            Assert.Equal(0, result.ExitCode);

                            var output = File.ReadAllText("output.txt");

                            Assert.Contains("A-VALUE", output);
                            Assert.Contains("B-VALUE", output);
                            Assert.Contains("C-VALUE", output);
                            Assert.Contains("D-VALUE", output);
                            File.Delete("output.txt");
                        }
                    }
                }
            }
            finally
            {
                Environment.CurrentDirectory = orgDirectory;
            }
        }
Beispiel #12
0
        public void StandardFiles()
        {
            // We had a problem with [NeonHelper_Execute] where standard output
            // and standard error streams weren't being relayed back to the
            // corresponding [neon-cli] streams when the sub-process was an
            // actual executable rather than a batch script.  So the unit tests
            // above that ran a script passed.
            //
            // This test verifies that we get output from an actual executable.

            var orgDirectory = Environment.CurrentDirectory;

            try
            {
                using (var manager = new KubeTestManager())
                {
                    using (var runner = new ProgramRunner())
                    {
                        using (var tempFolder = new TempFolder())
                        {
                            Environment.CurrentDirectory = tempFolder.Path;

                            File.WriteAllText("test.txt", "Hello World!");

                            var result = runner.Execute(Program.Main, $"run", "--", "cat", "test.txt");
                            Assert.Equal(0, result.ExitCode);
                            Assert.Contains("Hello World!", result.AllText);
                        }
                    }
                }
            }
            finally
            {
                Environment.CurrentDirectory = orgDirectory;
            }
        }
Beispiel #13
0
        public void Version()
        {
            using (var runner = new ProgramRunner())
            {
                var result = runner.Execute(Program.Main, "version");
                Assert.Equal(0, result.ExitCode);
                Assert.Equal(Build.ProductVersion, result.OutputText.Trim());

                result = runner.Execute(Program.Main, "version", "-n");
                Assert.Equal(0, result.ExitCode);
                Assert.Equal(Build.ProductVersion, result.OutputText.Trim());
                Assert.DoesNotContain('\n', result.OutputText);

                result = runner.Execute(Program.Main, "version", "-n", "--git");
                Assert.Equal(0, result.ExitCode);
                Assert.Equal($"{Build.ProductVersion}/{ThisAssembly.Git.Branch}-{ThisAssembly.Git.Commit}", result.OutputText.Trim());
                Assert.DoesNotContain('\n', result.OutputText);

                result = runner.Execute(Program.Main, "version", $"--minimum={Program.Version}");
                Assert.Equal(0, result.ExitCode);

                result = runner.Execute(Program.Main, "version", $"--minimum=0");
                Assert.Equal(0, result.ExitCode);

                result = runner.Execute(Program.Main, "version", $"--minimum=64000.0.0");
                Assert.NotEqual(0, result.ExitCode);

                var curVersion   = SemanticVersion.Parse(Program.Version);
                var newerVersion = SemanticVersion.Create(curVersion.Major, curVersion.Minor, curVersion.Patch + 1, curVersion.Build, curVersion.Prerelease);

                Assert.True(newerVersion > curVersion);

                result = runner.Execute(Program.Main, "version", $"--minimum={newerVersion}");
                Assert.NotEqual(0, result.ExitCode);
            }
        }
Beispiel #14
0
        public void ReadVariables_Decrypted()
        {
            var orgDirectory = Environment.CurrentDirectory;

            try
            {
                using (var manager = new KubeTestManager())
                {
                    using (var runner = new ProgramRunner())
                    {
                        using (var tempFolder = new TempFolder())
                        {
                            Environment.CurrentDirectory = tempFolder.Path;

                            var vault = new NeonVault(Program.LookupPassword);

                            // Create a test password and a [.password-name] file in the
                            // temp test folder.

                            var result = runner.Execute(Program.Main, $"password", "set", "test");
                            Assert.Equal(0, result.ExitCode);

                            File.WriteAllText(".password-name", "test");

                            //-------------------------------------------------
                            // Verify that we can read variables from a couple of
                            // unencrypted variable files.

                            File.WriteAllText("test.cmd", "echo %* > output.txt");

                            File.WriteAllText("var1.txt",
                                              @"# This is a comment.

TEST_A=A-VALUE
TEST_B=B-VALUE
");

                            File.WriteAllText("var2.txt",
                                              @"# This is a comment.

TEST_C=C-VALUE
TEST_D=D-VALUE
");
                            result = runner.Execute(Program.Main, $"run", "var1.txt", "var2.txt", "--", "test.cmd", "_.TEST_A", "_.TEST_B", "_.TEST_C", "_.TEST_D");
                            Assert.Equal(0, result.ExitCode);

                            var output = File.ReadAllText("output.txt");

                            Assert.Contains("A-VALUE", output);
                            Assert.Contains("B-VALUE", output);
                            Assert.Contains("C-VALUE", output);
                            Assert.Contains("D-VALUE", output);
                            File.Delete("output.txt");
                            File.Delete("var1.txt");
                            File.Delete("var2.txt");
                        }
                    }
                }
            }
            finally
            {
                Environment.CurrentDirectory = orgDirectory;
            }
        }
Beispiel #15
0
        public void VaultCreate()
        {
            using (var manager = new KubeTestManager())
            {
                using (var tempFolder = new TempFolder())
                {
                    var orgDir = Environment.CurrentDirectory;

                    Environment.CurrentDirectory = tempFolder.Path;
                    NeonHelper.OpenEditorHandler = path => File.WriteAllText(path, plainText);

                    try
                    {
                        using (var passwordFile = new TempFile(folder: KubeHelper.PasswordsFolder))
                        {
                            File.WriteAllText(passwordFile.Path, testPassword);

                            var vault = new NeonVault(passwordName => testPassword);

                            using (var runner = new ProgramRunner())
                            {
                                // Verify that the PATH argument is required.

                                var result = runner.Execute(Program.Main, "vault", "create");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: The PATH argument is required.", result.ErrorText);

                                // Verify that the PASSWORD-NAME argument is required when there's
                                // no default [.password-name] file.

                                result = runner.Execute(Program.Main, "vault", "create", "test1.txt");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: A PASSWORD-NAME argument or [.password-name] file is required.", result.ErrorText);

                                // Verify that we can create an encrypted file with an explicitly
                                // named password.

                                result = runner.Execute(Program.Main, "vault", "create", "test2.txt", passwordFile.Name);

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test2.txt", out var passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test2.txt")));

                                // Verify that we see an error for a missing password.

                                result = runner.Execute(Program.Main, "vault", "create", "test3.txt", missingPasswordName);

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains($"*** ERROR: [CryptographicException]: Password named [{missingPasswordName}] not found or is blank or whitespace.", result.ErrorText);

                                // Verify that we see an error for an invalid password.

                                result = runner.Execute(Program.Main, "vault", "create", "test4.txt", badPasswordName);

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains($"*** ERROR: [CryptographicException]: Password name [bad/password] contains invalid characters.  Only ASCII letters, digits, underscores, dashs and dots are allowed.", result.ErrorText);

                                // Verify that a local [.password-name] file is used successfully when we don't
                                // explicitly pass a password name.

                                File.WriteAllText(".password-name", passwordFile.Name);

                                result = runner.Execute(Program.Main, "vault", "create", "test5.txt");
                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test5.txt", out passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test5.txt")));

                                // Verify that a [.password-name] file in the parent directory is used successfully
                                // when we don't explicitly pass a password name.

                                Directory.CreateDirectory("subfolder");
                                Environment.CurrentDirectory = Path.Combine(Environment.CurrentDirectory, "subfolder");

                                result = runner.Execute(Program.Main, "vault", "create", "test6.txt");
                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test6.txt", out passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test6.txt")));
                            }
                        }
                    }
                    finally
                    {
                        Environment.CurrentDirectory = orgDir;
                        NeonHelper.OpenEditorHandler = null;
                    }
                }
            }
        }
        public void PasswordRemove()
        {
            ExecuteResponse result;

            using (var manager = new KubeTestManager())
            {
                using (var runner = new ProgramRunner())
                {
                    // Verify that [--help] works:

                    result = runner.Execute(Program.Main, "password", "remove", "--help");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Contains("Removes a specific named password or all passwords.", result.OutputText);

                    // Add a few passwords:

                    File.WriteAllText(Path.Combine(manager.TestFolder, "pwd-1"), "one");
                    File.WriteAllText(Path.Combine(manager.TestFolder, "pwd-2"), "two");
                    File.WriteAllText(Path.Combine(manager.TestFolder, "pwd-3"), "three");

                    result = runner.Execute(Program.Main, $"password", "set", "pwd-1", Path.Combine(manager.TestFolder, "pwd-1"));
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, $"password", "set", "pwd-2", Path.Combine(manager.TestFolder, "pwd-2"));
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, $"password", "set", "pwd-3", Path.Combine(manager.TestFolder, "pwd-3"));
                    Assert.Equal(0, result.ExitCode);

                    // Verify that we can list the passwords:

                    result = runner.Execute(Program.Main, "password", "ls");
                    Assert.Equal(0, result.ExitCode);
                    TestHelper.AssertEqualLines(
                        @"pwd-1
pwd-2
pwd-3
",
                        result.OutputText);

                    // Verify that we can remove a specific password.

                    result = runner.Execute(Program.Main, "password", "rm", "--force", "pwd-2");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, "password", "ls");
                    Assert.Equal(0, result.ExitCode);
                    TestHelper.AssertEqualLines(
                        @"pwd-1
pwd-3
",
                        result.OutputText);

                    // Verify that we can remove all passwords:

                    result = runner.Execute(Program.Main, "password", "remove", "--force", "*");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, "password", "list");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Empty(result.OutputText);

                    // Verify that we see errors for missing arguments:

                    result = runner.Execute(Program.Main, "password", "rm");
                    Assert.NotEqual(0, result.ExitCode);
                    Assert.Contains("NAME argument is required.", result.ErrorText);

                    // Verify what we see an error when trying to remove a password
                    // that doesn't exist:

                    result = runner.Execute(Program.Main, "password", "rm", "BAD");
                    Assert.NotEqual(0, result.ExitCode);
                    Assert.Contains("does not exist", result.ErrorText);
                }
            }
        }
        public void PasswordGenerate()
        {
            ExecuteResponse result;

            using (var manager = new KubeTestManager())
            {
                using (var runner = new ProgramRunner())
                {
                    //// Verify that [--help] works:

                    result = runner.Execute(Program.Main, "password", "generate", "--help");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Contains("Generates a cryptographically secure password.", result.OutputText);

                    // Verify that we can generate a password with the default length.

                    result = runner.Execute(Program.Main, "password", "generate");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal(20, result.OutputText.Trim().Length);

                    // Verify that we can generate a password with a specific length.

                    result = runner.Execute(Program.Main, "password", "generate", "30");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal(30, result.OutputText.Trim().Length);

                    result = runner.Execute(Program.Main, "password", "generate", "8");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal(8, result.OutputText.Trim().Length);

                    result = runner.Execute(Program.Main, "password", "generate", "100");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal(100, result.OutputText.Trim().Length);

                    // Verify that invalid password lengths are detected.

                    result = runner.Execute(Program.Main, "password", "generate", "BAD");
                    Assert.NotEqual(0, result.ExitCode);

                    result = runner.Execute(Program.Main, "password", "generate", "0");
                    Assert.NotEqual(0, result.ExitCode);

                    result = runner.Execute(Program.Main, "password", "generate", "7");
                    Assert.NotEqual(0, result.ExitCode);

                    result = runner.Execute(Program.Main, "password", "generate", "101");
                    Assert.NotEqual(0, result.ExitCode);

                    // Verify that we get different passwords when we run this
                    // multiple times.

                    var previousPasswords = new HashSet <string>();

                    for (int i = 0; i < 50; i++)
                    {
                        result = runner.Execute(Program.Main, "password", "generate", "100");
                        Assert.Equal(0, result.ExitCode);

                        var password = result.OutputText.Trim();

                        Assert.DoesNotContain(previousPasswords, p => p == password);
                        previousPasswords.Add(password);
                    }
                }
            }
        }
        public void PasswordSet()
        {
            ExecuteResponse result;

            using (var manager = new KubeTestManager())
            {
                using (var runner = new ProgramRunner())
                {
                    // Verify that [--help] works:

                    result = runner.Execute(Program.Main, "password", "set", "--help");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Contains("Creates or modifies a named password.", result.OutputText);

                    // Add a few passwords via files and verify:

                    File.WriteAllText(Path.Combine(manager.TestFolder, "pwd-1"), "one");
                    File.WriteAllText(Path.Combine(manager.TestFolder, "pwd-2"), "two");
                    File.WriteAllText(Path.Combine(manager.TestFolder, "pwd-3"), "three");

                    result = runner.Execute(Program.Main, $"password", "set", "pwd-1", Path.Combine(manager.TestFolder, "pwd-1"));
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, $"password", "set", "pwd-2", Path.Combine(manager.TestFolder, "pwd-2"));
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, $"password", "set", "pwd-3", Path.Combine(manager.TestFolder, "pwd-3"));
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, "password", "get", "pwd-1");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("one", result.OutputText.Trim());

                    result = runner.Execute(Program.Main, "password", "get", "pwd-2");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("two", result.OutputText.Trim());

                    result = runner.Execute(Program.Main, "password", "get", "pwd-3");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("three", result.OutputText.Trim());

                    // Verify that we can set a password from STDIN:

                    result = runner.Execute(Program.Main, "password", "rm", "--force", "*");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.ExecuteWithInput(Program.Main, "one", "password", "set", "pwd-1", "-");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.ExecuteWithInput(Program.Main, "two", "password", "set", "pwd-2", "-");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.ExecuteWithInput(Program.Main, "three", "password", "set", "pwd-3", "-");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, "password", "get", "pwd-1");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("one", result.OutputText.Trim());

                    result = runner.Execute(Program.Main, "password", "get", "pwd-2");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("two", result.OutputText.Trim());

                    result = runner.Execute(Program.Main, "password", "get", "pwd-3");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("three", result.OutputText.Trim());

                    // Verify that we can update a password.

                    result = runner.Execute(Program.Main, "password", "rm", "--force", "*");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.ExecuteWithInput(Program.Main, "one", "password", "set", "pwd-1", "-");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, "password", "get", "pwd-1");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("one", result.OutputText.Trim());

                    result = runner.ExecuteWithInput(Program.Main, "1", "password", "set", "pwd-1", "-");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, "password", "get", "pwd-1");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("1", result.OutputText.Trim());

                    // Verify that password names with all possible character classes works:

                    result = runner.Execute(Program.Main, "password", "rm", "--force", "*");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.ExecuteWithInput(Program.Main, "password", "password", "set", "a.1_2-3", "-");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, "password", "get", "a.1_2-3");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("password", result.OutputText.Trim());

                    // Verify that a 20 character password is generated when no PATH argument is passed:

                    result = runner.ExecuteWithInput(Program.Main, "password", "password", "set", "abc");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, "password", "get", "abc");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal(20, result.OutputText.Trim().Length);

                    // Verify that we see errors for missing arguments:

                    result = runner.ExecuteWithInput(Program.Main, "password", "password", "set");
                    Assert.NotEqual(0, result.ExitCode);
                    Assert.Contains("NAME argument is required.", result.ErrorText);

                    // Verify that password name error checking works:

                    result = runner.Execute(Program.Main, "password", "rm", "--force", "*");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.ExecuteWithInput(Program.Main, "", "password", "set", "pwd@1", "-");
                    Assert.NotEqual(0, result.ExitCode);

                    result = runner.ExecuteWithInput(Program.Main, "", $"password", "set", $"{new string('a', 101)}", "-");
                    Assert.NotEqual(0, result.ExitCode);

                    // Verify that password length error checking works:

                    result = runner.Execute(Program.Main, "password", "rm", "--force", "*");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.ExecuteWithInput(Program.Main, "", "password", "set", "pwd-1", "-");
                    Assert.NotEqual(0, result.ExitCode);
                }
            }
        }
        public async Task Query()
        {
            // Verify that the query commands work.

            var endpoint   = bucket.Configuration.GetEndPoint();
            var bucketName = bucket.Configuration.BucketName;

            // Insert a couple documents into the database.

            var jack = new Person()
            {
                Id   = 0,
                Name = "Jack",
                Age  = 10,
                Data = new byte[] { 0, 1, 2, 3, 4 }
            };

            var jill = new Person()
            {
                Id   = 1,
                Name = "Jill",
                Age  = 11,
                Data = new byte[] { 5, 6, 7, 8, 9 }
            };

            await bucket.InsertSafeAsync(jack, persistTo : PersistTo.One);

            await bucket.InsertSafeAsync(jill, persistTo : PersistTo.One);

            await bucket.WaitForIndexerAsync();

            bucket.Query <dynamic>($"select count(*) from `{bucket.Name}`;");

            using (var runner = new ProgramRunner())
            {
                // Query using the [http://...] target format and passing the query on the command line.

                var result = runner.Execute(Program.Main,
                                            "couchbase",
                                            "query",
                                            $"http://{endpoint.Address}:{endpoint.Port}@{username}:{password}:{bucketName}",
                                            $"select * from `{bucket.Name}`;");

                Assert.Equal(0, result.ExitCode);
                Assert.Contains("Jack", result.OutputText);
                Assert.Contains("Jill", result.OutputText);

                // Query again, but using the using the [couchbase://...] target format.

                result = runner.Execute(Program.Main,
                                        "couchbase",
                                        "query",
                                        $"couchbase://{endpoint.Address}:{endpoint.Port}@{username}:{password}:{bucketName}",
                                        $"select * from `{bucket.Name}`;");

                Assert.Equal(0, result.ExitCode);
                Assert.Contains("Jack", result.OutputText);
                Assert.Contains("Jill", result.OutputText);

                // Pass the query as a file.

                using (var tempFile = new TempFile())
                {
                    File.WriteAllText(tempFile.Path, $"select * from `{bucket.Name}`;");

                    result = runner.Execute(Program.Main,
                                            "couchbase",
                                            "query",
                                            $"couchbase://{endpoint.Address}:{endpoint.Port}@{username}:{password}:{bucketName}",
                                            $"@{tempFile.Path}");

                    Assert.Equal(0, result.ExitCode);
                    Assert.Contains("Jack", result.OutputText);
                    Assert.Contains("Jill", result.OutputText);
                }

                // Pass the query as STDIN.

                result = runner.ExecuteWithInput(Program.Main, $"select * from `{bucket.Name}`;",
                                                 "couchbase",
                                                 "query",
                                                 $"couchbase://{endpoint.Address}:{endpoint.Port}@{username}:{password}:{bucketName}",
                                                 "-");

                Assert.Equal(0, result.ExitCode);
                Assert.Contains("Jack", result.OutputText);
                Assert.Contains("Jill", result.OutputText);
            }
        }
        public async Task Upsert()
        {
            ExecuteResponse result;

            // $todo(jeff.lill):
            //
            // I'm not testing the document key generation features yet.

            // Verify that the query commands work.

            var endpoint   = bucket.Configuration.GetEndPoint();
            var bucketName = bucket.Configuration.BucketName;

            // Generate a string with a couple of JSON documents (one per line)
            // that we'll use for our tests.

            var jack = new Person()
            {
                Id   = 0,
                Name = "Jack",
                Age  = 10,
                Data = new byte[] { 0, 1, 2, 3, 4 }
            };

            var jill = new Person()
            {
                Id   = 1,
                Name = "Jill",
                Age  = 11,
                Data = new byte[] { 5, 6, 7, 8, 9 }
            };

            var sb = new StringBuilder();

            sb.AppendLine(jack.ToString(indented: false));
            sb.AppendLine(jill.ToString(indented: false));

            using (var runner = new ProgramRunner())
            {
                // Upsert using the [http://...] target format and passing the documents as a file.

                using (var tempFile = new TempFile())
                {
                    File.WriteAllText(tempFile.Path, sb.ToString());

                    result = runner.Execute(Program.Main,
                                            "couchbase",
                                            "upsert",
                                            $"http://{endpoint.Address}:{endpoint.Port}@{username}:{password}:{bucketName}",
                                            tempFile.Path);

                    Assert.Equal(0, result.ExitCode);

                    await bucket.WaitForIndexerAsync();

                    // Verify that the documents were written.

                    result = runner.ExecuteWithInput(Program.Main, $"select * from `{bucket.Name}`;",
                                                     "couchbase",
                                                     "query",
                                                     $"couchbase://{endpoint.Address}:{endpoint.Port}@{username}:{password}:{bucketName}",
                                                     "-");

                    Assert.Equal(0, result.ExitCode);
                    Assert.Contains("Jack", result.OutputText);
                    Assert.Contains("Jill", result.OutputText);
                }

                // Generate a couple more documents and test this again but this time passing the
                // JSON documents as STDIN.

                var howard = new Person()
                {
                    Id   = 2,
                    Name = "Howard",
                    Age  = 10,
                    Data = new byte[] { 0, 1, 2, 3, 4 }
                };

                var john = new Person()
                {
                    Id   = 3,
                    Name = "John",
                    Age  = 11,
                    Data = new byte[] { 5, 6, 7, 8, 9 }
                };

                sb.Clear();
                sb.AppendLine(howard.ToString(indented: false));
                sb.AppendLine(john.ToString(indented: false));

                result = runner.ExecuteWithInput(Program.Main, sb.ToString(),
                                                 "couchbase",
                                                 "upsert",
                                                 $"couchbase://{endpoint.Address}:{endpoint.Port}@{username}:{password}:{bucketName}",
                                                 "-");

                await bucket.WaitForIndexerAsync();

                Assert.Equal(0, result.ExitCode);

                // Verify that the documents were written.

                result = runner.ExecuteWithInput(Program.Main, $"select * from `{bucket.Name}`;",
                                                 "couchbase",
                                                 "query",
                                                 $"couchbase://{endpoint.Address}:{endpoint.Port}@{username}:{password}:{bucketName}",
                                                 "-");

                Assert.Equal(0, result.ExitCode);
                Assert.Contains("Howard", result.OutputText);
                Assert.Contains("John", result.OutputText);
            }
        }
Beispiel #21
0
        public void VaultPasswordName()
        {
            using (var manager = new KubeTestManager())
            {
                using (var tempFolder = new TempFolder())
                {
                    var orgDir = Environment.CurrentDirectory;

                    Environment.CurrentDirectory = tempFolder.Path;
                    NeonHelper.OpenEditorHandler = path => File.WriteAllText(path, plainText);

                    try
                    {
                        using (var passwordFile = new TempFile(folder: KubeHelper.PasswordsFolder))
                        {
                            File.WriteAllText(passwordFile.Path, testPassword);

                            var vault = new NeonVault(passwordName => testPassword);

                            using (var runner = new ProgramRunner())
                            {
                                // Verify that the PATH argument is required.

                                var result = runner.Execute(Program.Main, "vault", "password-name");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: The PATH argument is required.", result.ErrorText);

                                // Verify that we can create an encrypted file with an explicitly
                                // named password.

                                result = runner.Execute(Program.Main, "vault", "create", "test1.txt", passwordFile.Name);

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test1.txt", out var passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test1.txt")));

                                // Verify that we can get the password with a line ending.

                                result = runner.Execute(Program.Main, "vault", "password-name", "test1.txt", passwordFile.Name);

                                Assert.Equal(0, result.ExitCode);
                                Assert.Contains(passwordFile.Name, result.OutputText);
                                Assert.Contains("\n", result.OutputText);

                                // Verify that we can get the password without a line ending.

                                result = runner.Execute(Program.Main, "vault", "password-name", "-n", "test1.txt", passwordFile.Name);

                                Assert.Equal(0, result.ExitCode);
                                Assert.Equal(passwordFile.Name, result.OutputText);
                            }
                        }
                    }
                    finally
                    {
                        Environment.CurrentDirectory = orgDir;
                        NeonHelper.OpenEditorHandler = null;
                    }
                }
            }
        }
        public void PasswordImportExport()
        {
            const string zipPassword = "******";

            ExecuteResponse result;

            using (var manager = new KubeTestManager())
            {
                using (var runner = new ProgramRunner())
                {
                    // Verify that [import --help] works:

                    result = runner.Execute(Program.Main, "password", "import", "--help");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Contains("Imports passwords from an encrypted ZIP file.", result.OutputText);

                    // Verify that [import] checks the PATH argument.

                    result = runner.Execute(Program.Main, "password", "import");
                    Assert.NotEqual(0, result.ExitCode);
                    Assert.Contains("PATH argument is required.", result.ErrorText);

                    // Verify that [export --help] works:

                    result = runner.Execute(Program.Main, "password", "export", "--help");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Contains("Exports selected passwords to an encrypted ZIP file.", result.OutputText);

                    // Verify that [export] checks the PATH argument.

                    result = runner.Execute(Program.Main, "password", "export");
                    Assert.NotEqual(0, result.ExitCode);
                    Assert.Contains("PATH argument is required.", result.ErrorText);

                    // Verify that [export] checks the NAME argument.

                    result = runner.Execute(Program.Main, "password", "export", "test.zip");
                    Assert.NotEqual(0, result.ExitCode);
                    Assert.Contains("At least one NAME argument is required.", result.ErrorText);

                    // Add a few passwords:

                    result = runner.Execute(Program.Main, "password", "rm", "--force", "*");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.ExecuteWithInput(Program.Main, "one", "password", "set", "pwd-1", "-");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.ExecuteWithInput(Program.Main, "two", "password", "set", "pwd-2", "-");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.ExecuteWithInput(Program.Main, "three", "password", "set", "pwd-3", "-");
                    Assert.Equal(0, result.ExitCode);

                    // Export all passwords to a ZIP file:

                    var zipPath = Path.Combine(manager.TestFolder, "passwords.zip");

                    result = runner.ExecuteWithInput(Program.Main, zipPassword, "password", "export", "--stdin", zipPath, "*");
                    Assert.Equal(0, result.ExitCode);
                    Assert.True(File.Exists(zipPath));

                    // Remove all passwords, import the passwords using a zip password file, and verify.

                    result = runner.Execute(Program.Main, "password", "rm", "--force", "*");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.ExecuteWithInput(Program.Main, zipPassword, "password", "import", "--stdin", zipPath);
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, "password", "get", "pwd-1");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("one", result.OutputText.Trim());

                    result = runner.Execute(Program.Main, "password", "get", "pwd-2");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("two", result.OutputText.Trim());

                    result = runner.Execute(Program.Main, "password", "get", "pwd-3");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("three", result.OutputText.Trim());

                    // Export two of the three passwords to a ZIP file:

                    result = runner.ExecuteWithInput(Program.Main, zipPassword, "password", "export", "--stdin", zipPath, "pwd-1", "pwd-2");
                    Assert.Equal(0, result.ExitCode);
                    Assert.True(File.Exists(zipPath));

                    // Remove all passwords, import the passwords using a zip password file, and verify.

                    result = runner.Execute(Program.Main, "password", "rm", "--force", "*");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.ExecuteWithInput(Program.Main, zipPassword, "password", "import", "--stdin", zipPath);
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, "password", "get", "pwd-1");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("one", result.OutputText.Trim());

                    result = runner.Execute(Program.Main, "password", "get", "pwd-2");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("two", result.OutputText.Trim());

                    result = runner.Execute(Program.Main, "password", "get", "pwd-3");
                    Assert.NotEqual(0, result.ExitCode);    // This one wasn't exported.
                }
            }
        }
Beispiel #23
0
        public void DecryptFile()
        {
            var orgDirectory = Environment.CurrentDirectory;

            try
            {
                using (var manager = new KubeTestManager())
                {
                    using (var runner = new ProgramRunner())
                    {
                        using (var tempFolder = new TempFolder())
                        {
                            Environment.CurrentDirectory = tempFolder.Path;

                            var vault = new NeonVault(Program.LookupPassword);

                            // Create a test password and a [.password-name] file in the
                            // temp test folder.

                            var result = runner.Execute(Program.Main, $"password", "set", "test");
                            Assert.Equal(0, result.ExitCode);

                            //-------------------------------------------------
                            // Verify that we can decrypt a file.

                            File.WriteAllText("test.cmd", "type %1 > output.txt");

                            const string plainText = "The quick brown fox jumped over the lazy dog.";

                            File.WriteAllText("file.txt", plainText);
                            File.WriteAllBytes("file.txt", vault.Encrypt("file.txt", "test"));
                            Assert.True(NeonVault.IsEncrypted("file.txt"));

                            result = runner.Execute(Program.Main, $"run", "--", "test.cmd", "_...file.txt");
                            Assert.Equal(0, result.ExitCode);

                            var output = File.ReadAllText("output.txt");

                            Assert.Contains(plainText, output);
                            File.Delete("output.txt");
                            File.Delete("file.txt");

                            //-------------------------------------------------
                            // Try this again calling a command directly (batch files seem to have different behavior).

                            File.WriteAllText("type", "%1");

                            File.WriteAllText("file.txt", plainText);
                            File.WriteAllBytes("file.txt", vault.Encrypt("file.txt", "test"));
                            Assert.True(NeonVault.IsEncrypted("file.txt"));

                            result = runner.Execute(Program.Main, $"run", "--", "cat", "_...file.txt");
                            Assert.Equal(0, result.ExitCode);

                            Assert.Contains(plainText, result.OutputText);
                            File.Delete("output.txt");
                            File.Delete("file.txt");
                        }
                    }
                }
            }
            finally
            {
                Environment.CurrentDirectory = orgDirectory;
            }
        }
        public void PasswordBasics()
        {
            ExecuteResponse result;

            // Verify basic password operations: get, set, list|ls, and remove|rm:

            using (var manager = new KubeTestManager())
            {
                using (var runner = new ProgramRunner())
                {
                    // We should start out with no passwords:

                    result = runner.Execute(Program.Main, "password", "list");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Empty(result.OutputText.Trim());

                    result = runner.Execute(Program.Main, "password", "ls");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Empty(result.OutputText.Trim());

                    // Add a few passwords via files and verify:

                    File.WriteAllText(Path.Combine(manager.TestFolder, "pwd-1"), "one");
                    File.WriteAllText(Path.Combine(manager.TestFolder, "pwd-2"), "two");
                    File.WriteAllText(Path.Combine(manager.TestFolder, "pwd-3"), "three");

                    result = runner.Execute(Program.Main, $"password", "set", "pwd-1", Path.Combine(manager.TestFolder, "pwd-1"));
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, $"password", "set", "pwd-2", Path.Combine(manager.TestFolder, "pwd-2"));
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, $"password", "set", "pwd-3", Path.Combine(manager.TestFolder, "pwd-3"));
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, "password", "get", "pwd-1");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("one", result.OutputText.Trim());

                    result = runner.Execute(Program.Main, "password", "get", "pwd-2");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("two", result.OutputText.Trim());

                    result = runner.Execute(Program.Main, "password", "get", "pwd-3");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Equal("three", result.OutputText.Trim());

                    // Verify that we can list the passwords:

                    result = runner.Execute(Program.Main, "password", "ls");
                    Assert.Equal(0, result.ExitCode);
                    TestHelper.AssertEqualLines(
                        @"pwd-1
pwd-2
pwd-3
",
                        result.OutputText);

                    // Verify that we can remove a specific password.

                    result = runner.Execute(Program.Main, "password", "rm", "--force", "pwd-2");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, "password", "ls");
                    Assert.Equal(0, result.ExitCode);
                    TestHelper.AssertEqualLines(
                        @"pwd-1
pwd-3
",
                        result.OutputText);

                    // Verify that we can remove all passwords:

                    result = runner.Execute(Program.Main, "password", "rm", "--force", "*");
                    Assert.Equal(0, result.ExitCode);

                    result = runner.Execute(Program.Main, "password", "ls");
                    Assert.Equal(0, result.ExitCode);
                    Assert.Empty(result.OutputText);
                }
            }
        }
Beispiel #25
0
        public void VaultEncrypt()
        {
            using (var manager = new KubeTestManager())
            {
                using (var tempFolder = new TempFolder())
                {
                    var orgDir = Environment.CurrentDirectory;

                    Environment.CurrentDirectory = tempFolder.Path;
                    NeonHelper.OpenEditorHandler = path => File.WriteAllText(path, plainText);

                    try
                    {
                        using (var passwordFile = new TempFile(folder: KubeHelper.PasswordsFolder))
                        {
                            File.WriteAllText(passwordFile.Path, testPassword);

                            var vault = new NeonVault(passwordName => testPassword);

                            using (var runner = new ProgramRunner())
                            {
                                // Verify that the PATH argument is required.

                                var result = runner.Execute(Program.Main, "vault", "encrypt");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: The PATH argument is required.", result.ErrorText);

                                // Verify that the TARGET argument is required when [--password-name]
                                // or [--p] is not present.

                                result = runner.Execute(Program.Main, "vault", "decrypt", "source.txt");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: The TARGET argument is required.", result.ErrorText);

                                // Verify that we can encrypt a file in-place, specifying an
                                // explicit password name (using --password-name=NAME).

                                File.WriteAllText("test1.txt", plainText);

                                result = runner.Execute(Program.Main, "vault", "encrypt", "test1.txt", $"--password-name={passwordFile.Name}");

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test1.txt", out var passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test1.txt")));

                                // Verify that we can encrypt a file in-place, specifying an
                                // explicit password name (using --p=NAME).

                                File.WriteAllText("test2.txt", plainText);

                                result = runner.Execute(Program.Main, "vault", "encrypt", "test2.txt", $"-p={passwordFile.Name}");

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test2.txt", out passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test2.txt")));

                                // Verify that we get an error trying to encrypt in-place without a
                                // password name being explicitly specified and also without a
                                // [.password-name] file present.

                                File.WriteAllText("test3.txt", plainText);

                                result = runner.Execute(Program.Main, "vault", "encrypt", "test3.txt");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: A PASSWORD-NAME argument or [.password-name] file is required.", result.ErrorText);

                                // Verify that we get an error trying to encrypt (not in-place) without a
                                // password name being explicitly specified and also without a
                                // [.password-name] file present.

                                File.WriteAllText("test4.txt", plainText);

                                result = runner.Execute(Program.Main, "vault", "encrypt", "test4.txt", "test4.encypted.txt");

                                Assert.NotEqual(0, result.ExitCode);
                                Assert.Contains("*** ERROR: A PASSWORD-NAME argument or [.password-name] file is required.", result.ErrorText);

                                // Verify that we can encrypt a file to another with
                                // and explicit password argument.

                                File.WriteAllText("test5.txt", plainText);

                                result = runner.Execute(Program.Main, "vault", "encrypt", "test5.txt", "test5.encypted.txt", passwordName);

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test5.encypted.txt", out passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test5.encypted.txt")));

                                // Verify that we can encrypt a file to another with
                                // and explicit [--password-name] option.

                                File.WriteAllText("test6.txt", plainText);

                                result = runner.Execute(Program.Main, "vault", "encrypt", "test6.txt", "test6.encypted.txt", $"--password-name={passwordName}");

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test6.encypted.txt", out passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test6.encypted.txt")));

                                // Verify that we can encrypt a file in-place using a [.password-name] file.

                                File.WriteAllText("test7.txt", plainText);
                                File.WriteAllText(".password-name", passwordName);

                                result = runner.Execute(Program.Main, "vault", "encrypt", "test7.txt");

                                Assert.Equal(0, result.ExitCode);
                                Assert.True(NeonVault.IsEncrypted("test7.txt", out passwordName));
                                Assert.Equal(passwordFile.Name, passwordName);
                                Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test7.txt")));

                                // Verify that we can encrypt a file (not in-place) to another where
                                // the source file is located in a different directory from the target
                                // to ensure that we look for the [.password-name] file starting at
                                // the target directory.

                                using (var tempFile = new TempFile())
                                {
                                    File.WriteAllText(tempFile.Path, plainText);

                                    result = runner.Execute(Program.Main, "vault", "encrypt", tempFile.Path, "test8.encrypted.txt");

                                    Assert.Equal(0, result.ExitCode);
                                    Assert.True(NeonVault.IsEncrypted("test8.encrypted.txt", out passwordName));
                                    Assert.Equal(passwordFile.Name, passwordName);
                                    Assert.Equal(plainText, Encoding.UTF8.GetString(vault.Decrypt("test8.encrypted.txt")));
                                }
                            }
                        }
                    }
                    finally
                    {
                        Environment.CurrentDirectory = orgDir;
                        NeonHelper.OpenEditorHandler = null;
                    }
                }
            }
        }