using Tests.EndToEnd.Infra; using Xunit.Abstractions; namespace Tests.EndToEnd; /// /// Comprehensive E2E test covering all CLI commands with varied input data. /// Tests happy paths for CRUD operations, components, labels, and exporters. /// [Collection("Yaml CLI tests")] public class CliCommandsWorkflowTests(TempYamlCliFixture fs, ITestOutputHelper outputHelper) : IClassFixture { 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 comprehensive_cli_workflow_test() { await File.WriteAllTextAsync(Path.Combine(fs.Root, "config.yaml"), ""); // ============================================================ // GLOBAL: Summary command // ============================================================ (var output, _) = await ExecuteAsync("summary"); Assert.Contains("Breakdown", output); // ============================================================ // SERVERS: Full CRUD with components and labels // ============================================================ // Add server with various naming conventions (output, _) = await ExecuteAsync("servers", "add", "srv-prod-web01"); // Set server properties with varied data (output, _) = await ExecuteAsync( "servers", "set", "srv-prod-web01", "--ram", "64", "--ram_mts", "3200", "--ipmi", "True" ); Assert.Contains("updated", output); // Add CPU with bracket format model name (output, _) = await ExecuteAsync( "servers", "cpu", "add", "srv-prod-web01", "--model", "AMD EPYC 7763 [64c]", "--cores", "64", "--threads", "128" ); Assert.Contains("added", output); // Add drive (output, _) = await ExecuteAsync( "servers", "drive", "add", "srv-prod-web01", "--type", "nvme", "--size", "4096" ); Assert.Contains("added", output); // Add GPU with dash format (output, _) = await ExecuteAsync( "servers", "gpu", "add", "srv-prod-web01", "--model", "NVIDIA-RTX-4090", "--vram", "24" ); Assert.Contains("added", output); // Add NIC (output, _) = await ExecuteAsync( "servers", "nic", "add", "srv-prod-web01", "--type", "RJ45", "--speed", "10", "--ports", "2" ); Assert.Contains("added", output); // Add label (output, _) = await ExecuteAsync( "servers", "label", "add", "srv-prod-web01", "--key", "env", "--value", "production" ); Assert.Contains("Label", output); // Get server (output, _) = await ExecuteAsync("servers", "get", "srv-prod-web01"); Assert.Contains("srv-prod-web01", output); Assert.Contains("64 GB", output); // Get server (output, _) = await ExecuteAsync("servers", "get", "srv-prod-web01"); Assert.Contains("srv-prod-web01", output); // Describe (output, _) = await ExecuteAsync("servers", "describe", "srv-prod-web01"); Assert.Contains("srv-prod-web01", output); Assert.Contains("EPYC", output); // Tree (output, _) = await ExecuteAsync("servers", "tree", "srv-prod-web01"); Assert.Contains("srv-prod-web01", output); // ============================================================ // SWITCHES: Full workflow // ============================================================ (output, _) = await ExecuteAsync("switches", "add", "sw-core-01"); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "switches", "set", "sw-core-01", "--model", "Cisco-C9300-48P", "--managed", "true", "--poe", "true" ); Assert.Contains("updated", output); (output, _) = await ExecuteAsync("switches", "port", "add", "sw-core-01", "--type", "SFP+", "--speed", "25", "--ports", "4"); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "switches", "label", "add", "sw-core-01", "--key", "zone", "--value", "core" ); Assert.Contains("added", output); (output, _) = await ExecuteAsync("switches", "get", "sw-core-01"); Assert.Contains("sw-core-01", output); (output, _) = await ExecuteAsync("switches", "list"); Assert.Contains("sw-core-01", output); (output, _) = await ExecuteAsync("switches", "summary"); Assert.Contains("Name", output); (output, _) = await ExecuteAsync("switches", "describe", "sw-core-01"); Assert.Contains("sw-core-01", output); // ============================================================ // ROUTERS: Full workflow // ============================================================ (output, _) = await ExecuteAsync("routers", "add", "rt-edge-01"); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "routers", "set", "rt-edge-01", "--Model", "MikroTik-CCR2004", "--managed", "true", "--poe", "false" ); Assert.Contains("updated", output); (output, _) = await ExecuteAsync("routers", "port", "add", "rt-edge-01", "--type", "SFP", "--speed", "10", "--ports", "8"); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "routers", "label", "add", "rt-edge-01", "--key", "tier", "--value", "edge" ); Assert.Contains("added", output); (output, _) = await ExecuteAsync("routers", "get", "rt-edge-01"); Assert.Contains("rt-edge-01", output); (output, _) = await ExecuteAsync("routers", "list"); Assert.Contains("rt-edge-01", output); (output, _) = await ExecuteAsync("routers", "summary"); Assert.Contains("Name", output); (output, _) = await ExecuteAsync("routers", "describe", "rt-edge-01"); Assert.Contains("rt-edge-01", output); // ============================================================ // FIREWALLS: Full workflow // ============================================================ (output, _) = await ExecuteAsync("firewalls", "add", "fw-perimeter-01"); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "firewalls", "set", "fw-perimeter-01", "--Model", "PaloAlto-PA-5220", "--managed", "true", "--poe", "false" ); Assert.Contains("updated", output); (output, _) = await ExecuteAsync("firewalls", "port", "add", "fw-perimeter-01", "--type", "RJ45", "--speed", "1", "--ports", "10"); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "firewalls", "label", "add", "fw-perimeter-01", "--key", "security", "--value", "dmz" ); Assert.Contains("added", output); (output, _) = await ExecuteAsync("firewalls", "get", "fw-perimeter-01"); Assert.Contains("fw-perimeter-01", output); (output, _) = await ExecuteAsync("firewalls", "list"); Assert.Contains("fw-perimeter-01", output); (output, _) = await ExecuteAsync("firewalls", "summary"); Assert.Contains("Name", output); (output, _) = await ExecuteAsync("firewalls", "describe", "fw-perimeter-01"); Assert.Contains("fw-perimeter-01", output); // ============================================================ // SYSTEMS: Full workflow with tree // ============================================================ (output, _) = await ExecuteAsync("systems", "add", "sys-app-web-01"); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "systems", "set", "sys-app-web-01", "--type", "container", "--os", "ubuntu-22.04", "--cores", "4", "--ram", "16", "--ip", "10.0.1.50", "--runs-on", "srv-prod-web01" ); Assert.Contains("updated", output); (output, _) = await ExecuteAsync( "systems", "label", "add", "sys-app-web-01", "--key", "app", "--value", "web-frontend" ); Assert.Contains("added", output); (output, _) = await ExecuteAsync("systems", "get", "sys-app-web-01"); Assert.Contains("sys-app-web-01", output); (output, _) = await ExecuteAsync("systems", "list"); Assert.Contains("Name", output); (output, _) = await ExecuteAsync("systems", "summary"); Assert.Contains("Name", output); (output, _) = await ExecuteAsync("systems", "describe", "sys-app-web-01"); Assert.Contains("container", output); (output, _) = await ExecuteAsync("systems", "tree", "sys-app-web-01"); Assert.Contains("sys-app-web-01", output); // ============================================================ // ACCESS POINTS: Full workflow // ============================================================ (output, _) = await ExecuteAsync("accesspoints", "add", "ap-floor2-01"); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "accesspoints", "set", "ap-floor2-01", "--model", "Ubiquiti-U6-Pro", "--speed", "2.5" ); Assert.Contains("updated", output); (output, _) = await ExecuteAsync( "accesspoints", "label", "add", "ap-floor2-01", "--key", "location", "--value", "floor-2" ); Assert.Contains("added", output); (output, _) = await ExecuteAsync("accesspoints", "get", "ap-floor2-01"); Assert.Contains("ap-floor2-01", output); Assert.Contains("Ubiquiti", output); (output, _) = await ExecuteAsync("accesspoints", "list"); Assert.Contains("ap-floor2-01", output); (output, _) = await ExecuteAsync("accesspoints", "summary"); Assert.Contains("Name", output); (output, _) = await ExecuteAsync("accesspoints", "describe", "ap-floor2-01"); Assert.Contains("ap-floor2-01", output); // ============================================================ // UPS: Full workflow // ============================================================ (output, _) = await ExecuteAsync("ups", "add", "ups-rack-a-01"); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "ups", "set", "ups-rack-a-01", "--model", "APC-SmartUPS-3000", "--va", "3000" ); Assert.Contains("updated", output); (output, _) = await ExecuteAsync( "ups", "label", "add", "ups-rack-a-01", "--key", "rack", "--value", "a" ); Assert.Contains("added", output); (output, _) = await ExecuteAsync("ups", "get", "ups-rack-a-01"); Assert.Contains("ups-rack-a-01", output); Assert.Contains("3000", output); (output, _) = await ExecuteAsync("ups", "list"); Assert.Contains("ups-rack-a-01", output); (output, _) = await ExecuteAsync("ups", "summary"); Assert.Contains("Name", output); (output, _) = await ExecuteAsync("ups", "describe", "ups-rack-a-01"); Assert.Contains("ups-rack-a-01", output); // ============================================================ // DESKTOPS: Full workflow with components // ============================================================ (output, _) = await ExecuteAsync("desktops", "add", "dtp-workstation-01"); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "desktops", "set", "dtp-workstation-01", "--model", "Dell-Precision-7865" ); Assert.Contains("updated", output); (output, _) = await ExecuteAsync( "desktops", "cpu", "add", "dtp-workstation-01", "--model", "AMD-Ryzen-9-7950X", "--cores", "16", "--threads", "32" ); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "desktops", "drive", "add", "dtp-workstation-01", "--type", "ssd", "--size", "2048" ); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "desktops", "gpu", "add", "dtp-workstation-01", "--model", "NVIDIA-RTX-3090", "--vram", "24" ); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "desktops", "nic", "add", "dtp-workstation-01", "--type", "RJ45", "--speed", "10", "--ports", "2" ); Assert.Contains("added", output); (output, _) = await ExecuteAsync("desktops", "get", "dtp-workstation-01"); Assert.Contains("dtp-workstation-01", output); (output, _) = await ExecuteAsync("desktops", "list"); Assert.Contains("dtp-workstation-01", output); (output, _) = await ExecuteAsync("desktops", "summary"); Assert.Contains("Name", output); (output, _) = await ExecuteAsync("desktops", "describe", "dtp-workstation-01"); Assert.Contains("dtp-workstation-01", output); // ============================================================ // LAPTOPS: Full workflow with components // ============================================================ (output, _) = await ExecuteAsync("laptops", "add", "ltp-dev-01"); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "laptops", "set", "ltp-dev-01", "--model", "Lenovo-ThinkPad-X1" ); Assert.Contains("updated", output); (output, _) = await ExecuteAsync( "laptops", "cpu", "add", "ltp-dev-01", "--model", "Intel-i9-12900H", "--cores", "14", "--threads", "20" ); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "laptops", "drive", "add", "ltp-dev-01", "--type", "ssd", "--size", "1024" ); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "laptops", "gpu", "add", "ltp-dev-01", "--model", "Intel-Iris-Xe", "--vram", "2" ); Assert.Contains("added", output); (output, _) = await ExecuteAsync("laptops", "get", "ltp-dev-01"); Assert.Contains("ltp-dev-01", output); (output, _) = await ExecuteAsync("laptops", "list"); Assert.Contains("ltp-dev-01", output); (output, _) = await ExecuteAsync("laptops", "summary"); Assert.Contains("Name", output); (output, _) = await ExecuteAsync("laptops", "describe", "ltp-dev-01"); Assert.Contains("ltp-dev-01", output); // ============================================================ // SERVICES: Full workflow // ============================================================ (output, _) = await ExecuteAsync("services", "add", "svc-postgres-primary"); Assert.Contains("added", output); (output, _) = await ExecuteAsync( "services", "set", "svc-postgres-primary", "--ip", "10.0.0.100", "--port", "5432", "--protocol", "tcp", "--url", "postgresql://10.0.0.100:5432", "--runs-on", "sys-app-web-01" ); Assert.Contains("updated", output); (output, _) = await ExecuteAsync( "services", "label", "add", "svc-postgres-primary", "--key", "db-type", "--value", "postgresql" ); Assert.Contains("added", output); (output, _) = await ExecuteAsync("services", "get", "svc-postgres-primary"); Assert.Contains("svc-postgres-primary", output); (output, _) = await ExecuteAsync("services", "list"); Assert.Contains("Name", output); (output, _) = await ExecuteAsync("services", "summary"); Assert.Contains("Name", output); (output, _) = await ExecuteAsync("services", "describe", "svc-postgres-primary"); Assert.Contains("svc-postgres-primary", output); (output, _) = await ExecuteAsync("services", "subnets"); Assert.Contains("Services", output); // ============================================================ // EXPORTERS: Full workflow // ============================================================ // Ansible inventory export (output, _) = await ExecuteAsync("ansible", "inventory"); Assert.Contains("Generated Inventory", output); // SSH export (output, _) = await ExecuteAsync("ssh", "export"); Assert.Contains("Generated SSH Config", output); // Hosts export (output, _) = await ExecuteAsync("hosts", "export"); Assert.Contains("Generated Hosts File", output); // ============================================================ // CONNECTIONS: Full workflow // ============================================================ (output, _) = await ExecuteAsync( "connections", "add", "--resource-a", "sw-core-01", "--port-a", "1", "--resource-b", "fw-perimeter-01", "--port-b", "1" ); if (!output.Contains("added")) { Assert.Contains("Error", output); } else { Assert.Contains("added", output); } (output, _) = await ExecuteAsync( "connections", "remove", "--resource", "sw-core-01", "--port", "1" ); if (!output.Contains("removed")) { Assert.Contains("Error", output); } else { Assert.Contains("removed", output); } // ============================================================ // DELETE resources to verify cleanup // ============================================================ (output, _) = await ExecuteAsync("servers", "del", "srv-prod-web01"); Assert.Contains("deleted", output); (output, _) = await ExecuteAsync("switches", "del", "sw-core-01"); Assert.Contains("deleted", output); (output, _) = await ExecuteAsync("routers", "del", "rt-edge-01"); Assert.Contains("deleted", output); (output, _) = await ExecuteAsync("firewalls", "del", "fw-perimeter-01"); Assert.Contains("deleted", output); (output, _) = await ExecuteAsync("systems", "del", "sys-app-web-01"); Assert.Contains("deleted", output); (output, _) = await ExecuteAsync("accesspoints", "del", "ap-floor2-01"); Assert.Contains("deleted", output); (output, _) = await ExecuteAsync("ups", "del", "ups-rack-a-01"); Assert.Contains("deleted", output); (output, _) = await ExecuteAsync("desktops", "del", "dtp-workstation-01"); Assert.Contains("deleted", output); (output, _) = await ExecuteAsync("laptops", "del", "ltp-dev-01"); Assert.Contains("deleted", output); (output, _) = await ExecuteAsync("services", "del", "svc-postgres-primary"); Assert.Contains("deleted", output); // Verify all resources are gone (output, _) = await ExecuteAsync("summary"); } }