Prechádzať zdrojové kódy

E2E Tests Updated and Unit Test Added

James 2 mesiacov pred
rodič
commit
4b263bf2fb

+ 86 - 42
Tests/EndToEnd/ServiceYamlE2ETests.cs

@@ -12,10 +12,7 @@ public class ServiceYamlE2ETests(TempYamlCliFixture fs, ITestOutputHelper output
         outputHelper.WriteLine($"rpk {string.Join(" ", args)}");
 
         var inputArgs = args.ToArray();
-        var output = await YamlCliTestHost.RunAsync(
-            inputArgs,
-            fs.Root,
-            outputHelper);
+        var output = await YamlCliTestHost.RunAsync(inputArgs, fs.Root, outputHelper);
 
         outputHelper.WriteLine(output);
 
@@ -23,7 +20,7 @@ public class ServiceYamlE2ETests(TempYamlCliFixture fs, ITestOutputHelper output
         return (output, yaml);
     }
 
-      [Fact]
+    [Fact]
     public async Task services_cli_yaml_test()
     {
         await File.WriteAllTextAsync(Path.Combine(fs.Root, "config.yaml"), "");
@@ -40,16 +37,10 @@ public class ServiceYamlE2ETests(TempYamlCliFixture fs, ITestOutputHelper output
                        tags: 
 
                      """, yaml);
-        
+
         // Update system
-        (output, yaml) = await ExecuteAsync(
-            "services", "set", "immich",
-            "--ip", "192.168.10.14",
-            "--port", "80",
-            "--protocol", "TCP",
-            "--url", "http://timmoth.lan:80",
-            "--runs-on", "vm01"
-        );
+        (output, yaml) = await ExecuteAsync("services", "set", "immich", "--ip", "192.168.10.14", "--port", "80",
+            "--protocol", "TCP", "--url", "http://timmoth.lan:80", "--runs-on", "vm01");
 
         Assert.Equal("Service 'immich' updated.\n", output);
 
@@ -73,12 +64,12 @@ public class ServiceYamlE2ETests(TempYamlCliFixture fs, ITestOutputHelper output
                      Service 'immich' deleted.
 
                      """, output);
-        
+
         Assert.Equal("""
                      resources: []
-                     
+
                      """, yaml);
-        
+
         // Ensure list is empty
         (output, yaml) = await ExecuteAsync("services", "list");
         Assert.Equal("""
@@ -86,7 +77,7 @@ public class ServiceYamlE2ETests(TempYamlCliFixture fs, ITestOutputHelper output
 
                      """, output);
     }
-    
+
     [Fact]
     public async Task services_cli_workflow_test()
     {
@@ -98,36 +89,24 @@ public class ServiceYamlE2ETests(TempYamlCliFixture fs, ITestOutputHelper output
 
         (output, yaml) = await ExecuteAsync("systems", "add", "vm01");
         Assert.Equal("System 'vm01' added.\n", output);
-        (output, yaml) = await ExecuteAsync(
-            "systems", "set", "vm01",
-            "--runs-on", "c6400"
-        );
-        
+        (output, yaml) = await ExecuteAsync("systems", "set", "vm01", "--runs-on", "c6400");
+
         (output, yaml) = await ExecuteAsync("servers", "add", "c6400");
         Assert.Equal("Server 'c6400' added.\n", output);
-        
+
         // Update system
-        (output, yaml) = await ExecuteAsync(
-            "services", "set", "immich",
-            "--ip", "192.168.10.14",
-            "--port", "80",
-            "--protocol", "TCP",
-            "--url", "http://timmoth.lan:80",
-            "--runs-on", "vm01"
-        );
+        (output, yaml) = await ExecuteAsync("services", "set", "immich", "--ip", "192.168.10.14", "--port", "80",
+            "--protocol", "TCP", "--url", "http://timmoth.lan:80", "--runs-on", "vm01");
 
         Assert.Equal("Service 'immich' updated.\n", output);
 
         // Get system by name
         (output, yaml) = await ExecuteAsync("services", "get", "immich");
-        Assert.Equal(
-            """
-            immich  Ip: 192.168.10.14, Port: 80, Protocol: TCP, Url: http://timmoth.lan:80, 
-            RunsOn: c6400/vm01
-            
-            """
-            ,
-            output);
+        Assert.Equal("""
+                     immich  Ip: 192.168.10.14, Port: 80, Protocol: TCP, Url: http://timmoth.lan:80, 
+                     RunsOn: c6400/vm01
+
+                     """, output);
 
         // List systems
         (output, yaml) = await ExecuteAsync("services", "list");
@@ -138,7 +117,7 @@ public class ServiceYamlE2ETests(TempYamlCliFixture fs, ITestOutputHelper output
                      │ immich │ 192.168.10.14 │ 80   │ TCP      │ http://timmoth.lan:8 │ c6400/vm01 │
                      │        │               │      │          │ 0                    │            │
                      ╰────────┴───────────────┴──────┴──────────┴──────────────────────┴────────────╯
-                     
+
                      """, output);
 
         // Report systems
@@ -150,7 +129,7 @@ public class ServiceYamlE2ETests(TempYamlCliFixture fs, ITestOutputHelper output
                      │ immich │ 192.168.10.14 │ 80   │ TCP      │ http://timmoth.lan:8 │ c6400/vm01 │
                      │        │               │      │          │ 0                    │            │
                      ╰────────┴───────────────┴──────┴──────────┴──────────────────────┴────────────╯
-                     
+
                      """, output);
 
         // Delete system
@@ -167,4 +146,69 @@ public class ServiceYamlE2ETests(TempYamlCliFixture fs, ITestOutputHelper output
 
                      """, output);
     }
+
+    [Fact]
+    public async Task services_subnets_cli_test()
+    {
+        await File.WriteAllTextAsync(Path.Combine(fs.Root, "config.yaml"), "");
+
+        // Add services
+        var (output, yaml) = await ExecuteAsync("services", "add", "svc1");
+        Assert.Equal("Service 'svc1' added.\n", output);
+
+        (output, yaml) = await ExecuteAsync("services", "add", "svc2");
+        Assert.Equal("Service 'svc2' added.\n", output);
+
+        (output, yaml) = await ExecuteAsync("services", "add", "svc3");
+        Assert.Equal("Service 'svc3' added.\n", output);
+
+        // Add system + server so RunsOn resolves
+        (output, yaml) = await ExecuteAsync("systems", "add", "vm01");
+        Assert.Equal("System 'vm01' added.\n", output);
+
+        (output, yaml) = await ExecuteAsync("servers", "add", "c6400");
+        Assert.Equal("Server 'c6400' added.\n", output);
+
+        (output, yaml) = await ExecuteAsync("systems", "set", "vm01", "--runs-on", "c6400");
+        Assert.Equal("System 'vm01' updated.\n", output);
+
+        // Assign IPs
+        (output, yaml) = await ExecuteAsync("services", "set", "svc1", "--ip", "192.168.10.10", "--port", "80",
+            "--protocol", "TCP", "--runs-on", "vm01");
+        Assert.Equal("Service 'svc1' updated.\n", output);
+
+        (output, yaml) = await ExecuteAsync("services", "set", "svc2", "--ip", "192.168.10.20", "--port", "443",
+            "--protocol", "TCP", "--runs-on", "vm01");
+        Assert.Equal("Service 'svc2' updated.\n", output);
+
+        (output, yaml) = await ExecuteAsync("services", "set", "svc3", "--ip", "10.0.0.5", "--port", "8080",
+            "--protocol", "TCP", "--runs-on", "vm01");
+        Assert.Equal("Service 'svc3' updated.\n", output);
+
+        // -----------------------------
+        // Test CIDR filter mode
+        // -----------------------------
+        (output, yaml) = await ExecuteAsync("services", "subnets", "--cidr", "192.168.10.0/24");
+
+        Assert.Equal("""
+                     Services in 192.168.10.0/24
+                     ╭──────┬───────────────┬─────────╮
+                     │ Name │ IP            │ Runs On │
+                     ├──────┼───────────────┼─────────┤
+                     │ svc1 │ 192.168.10.10 │ vm01    │
+                     │ svc2 │ 192.168.10.20 │ vm01    │
+                     ╰──────┴───────────────┴─────────╯
+
+                     """, output);
+
+        // -----------------------------
+        // Test subnet summary mode
+        // -----------------------------
+        (output, yaml) = await ExecuteAsync("services", "subnets");
+
+        Assert.Contains("Subnet", output);
+        Assert.Contains("Utilization", output);
+        Assert.Contains("192.168.10.0/24", output);
+        Assert.Contains("10.0.0.0/24", output);
+    }
 }

+ 91 - 0
Tests/HardwareResources/Services/ServiceSubnetsCommandTests.cs

@@ -0,0 +1,91 @@
+using NSubstitute;
+using RackPeek.Domain.Resources.Services;
+using RackPeek.Domain.Resources.Services.UseCases;
+
+namespace Tests.HardwareResources.Services;
+
+public class ServiceSubnetsUseCaseTests
+{
+    [Fact]
+    public async Task Filter_mode_returns_services_in_cidr_sorted_by_ip()
+    {
+        var repo = Substitute.For<IServiceRepository>();
+
+        repo.GetAllAsync().Returns(new List<Service>
+        {
+            new()
+            {
+                Name = "svc1",
+                Network = new Network { Ip = "192.168.10.10" },
+                RunsOn = "hostA"
+            },
+            new()
+            {
+                Name = "svc2",
+                Network = new Network { Ip = "192.168.10.20" },
+                RunsOn = "hostB"
+            },
+            new()
+            {
+                Name = "svc3",
+                Network = new Network { Ip = "10.0.0.5" },
+                RunsOn = "hostC"
+            }
+        });
+
+        var sut = new ServiceSubnetsUseCase(repo);
+
+        var result = await sut.ExecuteAsync("192.168.10.0/24", null, CancellationToken.None);
+
+        Assert.False(result.IsInvalidCidr);
+        Assert.Equal("192.168.10.0/24", result.FilteredCidr);
+
+        Assert.Equal(2, result.Services.Count);
+
+        // Sorted by IP
+        Assert.Equal("svc1", result.Services[0].Name);
+        Assert.Equal("svc2", result.Services[1].Name);
+
+        Assert.Equal("192.168.10.10", result.Services[0].Ip);
+        Assert.Equal("192.168.10.20", result.Services[1].Ip);
+    }
+
+    [Fact]
+    public async Task Invalid_cidr_returns_error_result()
+    {
+        var repo = Substitute.For<IServiceRepository>();
+        repo.GetAllAsync().Returns(new List<Service>());
+
+        var sut = new ServiceSubnetsUseCase(repo);
+
+        var result = await sut.ExecuteAsync("not-a-cidr", null, CancellationToken.None);
+
+        Assert.True(result.IsInvalidCidr);
+        Assert.Equal("not-a-cidr", result.InvalidCidrValue);
+    }
+
+    [Fact]
+    public async Task Subnet_discovery_groups_services_by_prefix()
+    {
+        var repo = Substitute.For<IServiceRepository>();
+
+        repo.GetAllAsync().Returns(new List<Service>
+        {
+            new() { Name = "svc1", Network = new Network { Ip = "192.168.1.10" } },
+            new() { Name = "svc2", Network = new Network { Ip = "192.168.1.20" } },
+            new() { Name = "svc3", Network = new Network { Ip = "192.168.2.5" } },
+            new() { Name = "svc4", Network = new Network { Ip = "10.0.0.1" } }
+        });
+
+        var sut = new ServiceSubnetsUseCase(repo);
+
+        var result = await sut.ExecuteAsync(null, 24, CancellationToken.None);
+
+        Assert.False(result.IsInvalidCidr);
+        Assert.Equal(3, result.Subnets.Count);
+
+        Assert.Contains(result.Subnets, s => s.Cidr == "10.0.0.0/24" && s.Count == 1);
+        Assert.Contains(result.Subnets, s => s.Cidr == "192.168.1.0/24" && s.Count == 2);
+        Assert.Contains(result.Subnets, s => s.Cidr == "192.168.2.0/24" && s.Count == 1);
+    }
+}