Преглед изворни кода

Merge pull request #162 from Timmoth/Testing-Improvements

Tim Jones пре 1 месец
родитељ
комит
b3e9577677

+ 54 - 0
Tests/EndToEnd/FirewallTests/FirewallCommandTests.cs

@@ -0,0 +1,54 @@
+using Tests.EndToEnd.Infra;
+using Xunit.Abstractions;
+
+namespace Tests.EndToEnd;
+
+[Collection("Yaml CLI tests")]
+public class FirewallCommandTests(TempYamlCliFixture fs, ITestOutputHelper outputHelper)
+    : IClassFixture<TempYamlCliFixture>
+{
+    private async Task<(string, string)> ExecuteAsync(params string[] args)
+    {
+        var output = await YamlCliTestHost.RunAsync(
+            args,
+            fs.Root,
+            outputHelper,
+            "config.yaml"
+        );
+
+        var yaml = await File.ReadAllTextAsync(Path.Combine(fs.Root, "config.yaml"));
+        return (output, yaml);
+    }
+
+    [Fact]
+    public async Task describe_outputs_expected_information()
+    {
+        await ExecuteAsync("firewalls", "add", "fw01");
+        await ExecuteAsync("firewalls", "set", "fw01", "--Model", "Fortinet FG-60F", "--managed", "true", "--poe", "false");
+
+        var (output, _) = await ExecuteAsync("firewalls", "describe", "fw01");
+
+        Assert.Contains("fw01", output);
+        Assert.Contains("Fortinet FG-60F", output);
+        Assert.Contains("Managed", output);
+        Assert.Contains("PoE", output);
+    }
+
+    [Fact]
+    public async Task help_commands_do_not_throw()
+    {
+        Assert.Contains("Manage firewalls", (await ExecuteAsync("firewalls", "--help")).Item1);
+        Assert.Contains("Add a new firewall", (await ExecuteAsync("firewalls", "add", "--help")).Item1);
+        Assert.Contains("List all firewalls", (await ExecuteAsync("firewalls", "list", "--help")).Item1);
+        Assert.Contains("Retrieve details", (await ExecuteAsync("firewalls", "get", "--help")).Item1);
+        Assert.Contains("Show detailed information", (await ExecuteAsync("firewalls", "describe", "--help")).Item1);
+        Assert.Contains("Update properties", (await ExecuteAsync("firewalls", "set", "--help")).Item1);
+        Assert.Contains("Delete a firewall", (await ExecuteAsync("firewalls", "del", "--help")).Item1);
+
+        // Port help
+        Assert.Contains("Manage ports", (await ExecuteAsync("firewalls", "port", "--help")).Item1);
+        Assert.Contains("Add a port", (await ExecuteAsync("firewalls", "port", "add", "--help")).Item1);
+        Assert.Contains("Update a firewall port", (await ExecuteAsync("firewalls", "port", "set", "--help")).Item1);
+        Assert.Contains("Remove a port", (await ExecuteAsync("firewalls", "port", "del", "--help")).Item1);
+    }
+}

+ 92 - 0
Tests/EndToEnd/FirewallTests/FirewallErrorTests.cs

@@ -0,0 +1,92 @@
+using Tests.EndToEnd.Infra;
+using Xunit.Abstractions;
+
+namespace Tests.EndToEnd;
+
+[Collection("Yaml CLI tests")]
+public class FirewallErrorTests(TempYamlCliFixture fs, ITestOutputHelper outputHelper)
+    : IClassFixture<TempYamlCliFixture>
+{
+    private async Task<(string, string)> ExecuteAsync(params string[] args)
+    {
+        var output = await YamlCliTestHost.RunAsync(
+            args,
+            fs.Root,
+            outputHelper,
+            "config.yaml"
+        );
+
+        var yaml = await File.ReadAllTextAsync(Path.Combine(fs.Root, "config.yaml"));
+        return (output, yaml);
+    }
+
+    [Fact]
+    public async Task adding_duplicate_firewall_returns_error()
+    {
+        await ExecuteAsync("firewalls", "add", "fw01");
+        var (output, _) = await ExecuteAsync("firewalls", "add", "fw01");
+        Assert.Contains("already exists", output, StringComparison.OrdinalIgnoreCase);
+    }
+
+    [Fact]
+    public async Task get_missing_firewall_returns_error()
+    {
+        var (output, _) = await ExecuteAsync("firewalls", "get", "ghost");
+        Assert.Contains("not found", output, StringComparison.OrdinalIgnoreCase);
+    }
+
+    [Fact]
+    public async Task set_missing_firewall_returns_error()
+    {
+        var (output, _) = await ExecuteAsync("firewalls", "set", "ghost", "--Model", "X");
+        Assert.Contains("not found", output, StringComparison.OrdinalIgnoreCase);
+    }
+
+    [Fact]
+    public async Task delete_missing_firewall_returns_error()
+    {
+        var (output, _) = await ExecuteAsync("firewalls", "del", "ghost");
+        Assert.Contains("not found", output, StringComparison.OrdinalIgnoreCase);
+    }
+
+    // Port errors
+    [Fact]
+    public async Task port_add_missing_firewall_returns_error()
+    {
+        var (output, _) = await ExecuteAsync(
+            "firewalls", "port", "add", "ghost",
+            "--type", "rj45",
+            "--speed", "1",
+            "--count", "8"
+        );
+
+        Assert.Contains("not found", output, StringComparison.OrdinalIgnoreCase);
+    }
+
+    [Fact]
+    public async Task port_set_invalid_index_returns_error()
+    {
+        await ExecuteAsync("firewalls", "add", "fw01");
+
+        var (output, _) = await ExecuteAsync(
+            "firewalls", "port", "set", "fw01",
+            "--index", "5",
+            "--type", "rj45"
+        );
+
+        Assert.Contains("not found", output, StringComparison.OrdinalIgnoreCase);
+    }
+
+    [Fact]
+    public async Task port_del_invalid_index_returns_error()
+    {
+        await ExecuteAsync("firewalls", "add", "fw01");
+
+        var (output, _) = await ExecuteAsync(
+            "firewalls", "port", "del", "fw01",
+            "--index", "3"
+        );
+
+        Assert.Contains("not found", output, StringComparison.OrdinalIgnoreCase);
+    }
+}

+ 131 - 0
Tests/EndToEnd/FirewallTests/FirewallWorkflowTests.cs

@@ -0,0 +1,131 @@
+using Tests.EndToEnd.Infra;
+using Xunit.Abstractions;
+
+namespace Tests.EndToEnd;
+
+[Collection("Yaml CLI tests")]
+public class FirewallWorkflowTests(TempYamlCliFixture fs, ITestOutputHelper outputHelper)
+    : IClassFixture<TempYamlCliFixture>
+{
+    private async Task<(string, string)> ExecuteAsync(params string[] args)
+    {
+        outputHelper.WriteLine($"rpk {string.Join(" ", args)}");
+
+        var output = await YamlCliTestHost.RunAsync(
+            args,
+            fs.Root,
+            outputHelper,
+            "config.yaml"
+        );
+
+        outputHelper.WriteLine(output);
+
+        var yaml = await File.ReadAllTextAsync(Path.Combine(fs.Root, "config.yaml"));
+        return (output, yaml);
+    }
+
+    [Fact]
+    public async Task firewalls_cli_workflow_test()
+    {
+        await File.WriteAllTextAsync(Path.Combine(fs.Root, "config.yaml"), "");
+
+        // Add firewall
+        var (output, yaml) = await ExecuteAsync("firewalls", "add", "fw01");
+        Assert.Equal("Firewall 'fw01' added.\n", output);
+        Assert.Contains("name: fw01", yaml);
+
+        // Update firewall
+        (output, yaml) = await ExecuteAsync(
+            "firewalls", "set", "fw01",
+            "--Model", "Fortinet FG-60F",
+            "--managed", "true",
+            "--poe", "false"
+        );
+        Assert.Equal("Firewall 'fw01' updated.\n", output);
+
+        Assert.Equal("""
+                     version: 1
+                     resources:
+                     - kind: Firewall
+                       model: Fortinet FG-60F
+                       managed: true
+                       poe: false
+                       name: fw01
+
+                     """, yaml);
+
+        // Add second firewall
+        (output, yaml) = await ExecuteAsync("firewalls", "add", "fw02");
+        Assert.Equal("Firewall 'fw02' added.\n", output);
+
+        (output, yaml) = await ExecuteAsync(
+            "firewalls", "set", "fw02",
+            "--Model", "Ubiquiti UXG-Lite",
+            "--managed", "false",
+            "--poe", "false"
+        );
+        Assert.Equal("Firewall 'fw02' updated.\n", output);
+
+        Assert.Equal("""
+                     version: 1
+                     resources:
+                     - kind: Firewall
+                       model: Fortinet FG-60F
+                       managed: true
+                       poe: false
+                       name: fw01
+                     - kind: Firewall
+                       model: Ubiquiti UXG-Lite
+                       managed: false
+                       poe: false
+                       name: fw02
+
+                     """, yaml);
+
+        // Get firewall
+        (output, yaml) = await ExecuteAsync("firewalls", "get", "fw01");
+        Assert.Equal("fw01  Model: Fortinet FG-60F, Managed: Yes, PoE: No\n", output);
+
+        // List firewalls
+        (output, yaml) = await ExecuteAsync("firewalls", "list");
+        Assert.Equal("""
+                     ╭──────┬───────────────────┬─────────┬─────┬───────┬──────────────╮
+                     │ Name │ Model             │ Managed │ PoE │ Ports │ Port Summary │
+                     ├──────┼───────────────────┼─────────┼─────┼───────┼──────────────┤
+                     │ fw01 │ Fortinet FG-60F   │ yes     │ no  │ 0     │ Unknown      │
+                     │ fw02 │ Ubiquiti UXG-Lite │ no      │ no  │ 0     │ Unknown      │
+                     ╰──────┴───────────────────┴─────────┴─────┴───────┴──────────────╯
+
+                     """, output);
+
+        // Summary
+        (output, yaml) = await ExecuteAsync("firewalls", "summary");
+        Assert.Equal("""
+                     ╭──────┬───────────────────┬─────────┬─────┬───────┬───────────┬──────────────╮
+                     │ Name │ Model             │ Managed │ PoE │ Ports │ Max Speed │ Port Summary │
+                     ├──────┼───────────────────┼─────────┼─────┼───────┼───────────┼──────────────┤
+                     │ fw01 │ Fortinet FG-60F   │ yes     │ no  │ 0     │ 0G        │ Unknown      │
+                     │ fw02 │ Ubiquiti UXG-Lite │ no      │ no  │ 0     │ 0G        │ Unknown      │
+                     ╰──────┴───────────────────┴─────────┴─────┴───────┴───────────┴──────────────╯
+
+                     """, output);
+
+        // Delete firewall
+        (output, yaml) = await ExecuteAsync("firewalls", "del", "fw02");
+        Assert.Equal("""
+                     Firewall 'fw02' deleted.
+
+                     """, output);
+
+        // List again
+        (output, yaml) = await ExecuteAsync("firewalls", "list");
+        Assert.Equal("""
+                     ╭──────┬─────────────────┬─────────┬─────┬───────┬──────────────╮
+                     │ Name │ Model           │ Managed │ PoE │ Ports │ Port Summary │
+                     ├──────┼─────────────────┼─────────┼─────┼───────┼──────────────┤
+                     │ fw01 │ Fortinet FG-60F │ yes     │ no  │ 0     │ Unknown      │
+                     ╰──────┴─────────────────┴─────────┴─────┴───────┴──────────────╯
+
+                     """, output);
+    }
+}

+ 50 - 0
Tests/EndToEnd/SystemTests/SystemCommandTests.cs

@@ -0,0 +1,50 @@
+using Tests.EndToEnd.Infra;
+using Xunit.Abstractions;
+
+namespace Tests.EndToEnd;
+
+[Collection("Yaml CLI tests")]
+public class SystemCommandTests(TempYamlCliFixture fs, ITestOutputHelper outputHelper)
+    : IClassFixture<TempYamlCliFixture>
+{
+    private async Task<(string, string)> ExecuteAsync(params string[] args)
+    {
+        var output = await YamlCliTestHost.RunAsync(
+            args,
+            fs.Root,
+            outputHelper,
+            "config.yaml"
+        );
+
+        var yaml = await File.ReadAllTextAsync(Path.Combine(fs.Root, "config.yaml"));
+        return (output, yaml);
+    }
+
+    [Fact]
+    public async Task describe_outputs_expected_information()
+    {
+        await ExecuteAsync("systems", "add", "sys01");
+        await ExecuteAsync("systems", "set", "sys01", "--type", "vm", "--os", "ubuntu", "--cores", "4", "--ram", "16");
+
+        var (output, _) = await ExecuteAsync("systems", "describe", "sys01");
+
+        Assert.Contains("sys01", output);
+        Assert.Contains("vm", output);
+        Assert.Contains("ubuntu", output);
+        Assert.Contains("Cores", output);
+        Assert.Contains("RAM", output);
+    }
+
+    [Fact]
+    public async Task help_commands_do_not_throw()
+    {
+        Assert.Contains("Manage systems", (await ExecuteAsync("systems", "--help")).Item1);
+        Assert.Contains("Add a new system", (await ExecuteAsync("systems", "add", "--help")).Item1);
+        Assert.Contains("List all systems", (await ExecuteAsync("systems", "list", "--help")).Item1);
+        Assert.Contains("Retrieve a system", (await ExecuteAsync("systems", "get", "--help")).Item1);
+        Assert.Contains("Display detailed information", (await ExecuteAsync("systems", "describe", "--help")).Item1);
+        Assert.Contains("Update properties", (await ExecuteAsync("systems", "set", "--help")).Item1);
+        Assert.Contains("Delete a system", (await ExecuteAsync("systems", "del", "--help")).Item1);
+        Assert.Contains("Display the dependency tree", (await ExecuteAsync("systems", "tree", "--help")).Item1);
+    }
+}

+ 58 - 0
Tests/EndToEnd/SystemTests/SystemErrorTests.cs

@@ -0,0 +1,58 @@
+using Tests.EndToEnd.Infra;
+using Xunit.Abstractions;
+
+namespace Tests.EndToEnd;
+
+[Collection("Yaml CLI tests")]
+public class SystemErrorTests(TempYamlCliFixture fs, ITestOutputHelper outputHelper)
+    : IClassFixture<TempYamlCliFixture>
+{
+    private async Task<(string, string)> ExecuteAsync(params string[] args)
+    {
+        var output = await YamlCliTestHost.RunAsync(
+            args,
+            fs.Root,
+            outputHelper,
+            "config.yaml"
+        );
+
+        var yaml = await File.ReadAllTextAsync(Path.Combine(fs.Root, "config.yaml"));
+        return (output, yaml);
+    }
+
+    [Fact]
+    public async Task adding_duplicate_system_returns_error()
+    {
+        await ExecuteAsync("systems", "add", "sys01");
+        var (output, _) = await ExecuteAsync("systems", "add", "sys01");
+        Assert.Contains("already exists", output, StringComparison.OrdinalIgnoreCase);
+    }
+
+    [Fact]
+    public async Task get_missing_system_returns_error()
+    {
+        var (output, _) = await ExecuteAsync("systems", "get", "ghost");
+        Assert.Contains("not found", output, StringComparison.OrdinalIgnoreCase);
+    }
+
+    [Fact]
+    public async Task set_missing_system_returns_error()
+    {
+        var (output, _) = await ExecuteAsync("systems", "set", "ghost", "--type", "vm");
+        Assert.Contains("not found", output, StringComparison.OrdinalIgnoreCase);
+    }
+
+    [Fact]
+    public async Task delete_missing_system_returns_error()
+    {
+        var (output, _) = await ExecuteAsync("systems", "del", "ghost");
+        Assert.Contains("not found", output, StringComparison.OrdinalIgnoreCase);
+    }
+
+    [Fact]
+    public async Task tree_missing_system_returns_error()
+    {
+        var (output, _) = await ExecuteAsync("systems", "tree", "ghost");
+        Assert.Contains("not found", output, StringComparison.OrdinalIgnoreCase);
+    }
+}

+ 113 - 0
Tests/EndToEnd/SystemTests/SystemWorkflowTests.cs

@@ -0,0 +1,113 @@
+using Tests.EndToEnd.Infra;
+using Xunit.Abstractions;
+
+namespace Tests.EndToEnd;
+
+[Collection("Yaml CLI tests")]
+public class SystemWorkflowTests(TempYamlCliFixture fs, ITestOutputHelper outputHelper)
+    : IClassFixture<TempYamlCliFixture>
+{
+    private async Task<(string, string)> ExecuteAsync(params string[] args)
+    {
+        outputHelper.WriteLine($"rpk {string.Join(" ", args)}");
+
+        var output = await YamlCliTestHost.RunAsync(
+            args,
+            fs.Root,
+            outputHelper,
+            "config.yaml"
+        );
+
+        outputHelper.WriteLine(output);
+
+        var yaml = await File.ReadAllTextAsync(Path.Combine(fs.Root, "config.yaml"));
+        return (output, yaml);
+    }
+
+    [Fact]
+    public async Task systems_cli_workflow_test()
+    {
+        await File.WriteAllTextAsync(Path.Combine(fs.Root, "config.yaml"), "");
+        
+        await ExecuteAsync("servers", "add", "proxmox-node01");
+
+        // Add system
+        var (output, yaml) = await ExecuteAsync("systems", "add", "sys01");
+        Assert.Equal("System 'sys01' added.\n", output);
+        Assert.Contains("name: sys01", yaml);
+
+        // Update system
+        (output, yaml) = await ExecuteAsync(
+            "systems", "set", "sys01",
+            "--type", "VM",
+            "--os", "debian-12",
+            "--cores", "2",
+            "--ram", "4",
+            "--runs-on", "proxmox-node01"
+        );
+        Assert.Equal("System 'sys01' updated.\n", output);
+
+        Assert.Equal("""
+                     version: 1
+                     resources:
+                     - kind: Server
+                       name: proxmox-node01
+                     - kind: System
+                       type: vm
+                       os: debian-12
+                       cores: 2
+                       ram: 4
+                       name: sys01
+                       runsOn: proxmox-node01
+
+                     """, yaml);
+
+        // Get system
+        (output, yaml) = await ExecuteAsync("systems", "get", "sys01");
+        Assert.Equal("sys01  Type: vm, OS: debian-12, Cores: 2, RAM: 4GB, Storage: 0GB, RunsOn: \nproxmox-node01\n", output);
+
+        // List systems (strict table)
+        (output, yaml) = await ExecuteAsync("systems", "list");
+        Assert.Equal("""
+                     ╭───────┬──────┬───────────┬───────┬──────────┬──────────────┬────────────────╮
+                     │ Name  │ Type │ OS        │ Cores │ RAM (GB) │ Storage (GB) │ Runs On        │
+                     ├───────┼──────┼───────────┼───────┼──────────┼──────────────┼────────────────┤
+                     │ sys01 │ vm   │ debian-12 │ 2     │ 4        │ 0            │ proxmox-node01 │
+                     ╰───────┴──────┴───────────┴───────┴──────────┴──────────────┴────────────────╯
+
+                     """, output);
+
+        // Summary (strict table)
+        (output, yaml) = await ExecuteAsync("systems", "summary");
+        Assert.Equal("""
+                     ╭───────┬──────┬───────────┬───────┬──────────┬──────────────┬────────────────╮
+                     │ Name  │ Type │ OS        │ Cores │ RAM (GB) │ Storage (GB) │ Runs On        │
+                     ├───────┼──────┼───────────┼───────┼──────────┼──────────────┼────────────────┤
+                     │ sys01 │ vm   │ debian-12 │ 2     │ 4        │ 0            │ proxmox-node01 │
+                     ╰───────┴──────┴───────────┴───────┴──────────┴──────────────┴────────────────╯
+
+                     """, output);
+
+        // Describe (loose)
+        (output, yaml) = await ExecuteAsync("systems", "describe", "sys01");
+        Assert.Contains("sys01", output);
+        Assert.Contains("vm", output);
+        Assert.Contains("debian-12", output);
+        Assert.Contains("Cores", output);
+        Assert.Contains("RAM", output);
+        Assert.Contains("Runs On", output);
+
+        // Tree (loose)
+        (output, yaml) = await ExecuteAsync("systems", "tree", "sys01");
+        Assert.Contains("sys01", output);
+        // ToDo add a service in the workflow to properly test the tree functionality 
+        //Assert.Contains("Service:", output);
+
+        // Delete system
+        (output, yaml) = await ExecuteAsync("systems", "del", "sys01");
+        Assert.Equal("""
+                     System 'sys01' deleted.
+
+                     """, output);
+    }
+}

+ 7 - 0
Tests/Tests.csproj

@@ -26,4 +26,11 @@
         <ProjectReference Include="..\Shared.Rcl\Shared.Rcl.csproj"/>
     </ItemGroup>
 
+    <ItemGroup>
+      <Folder Include="EndToEnd\LaptopTests\" />
+      <Folder Include="EndToEnd\RouterTests\" />
+      <Folder Include="EndToEnd\ServerTests\" />
+      <Folder Include="EndToEnd\ServiceTests\" />
+    </ItemGroup>
+
 </Project>