using EntKube.Clusters.Domain; using EntKube.Clusters.Features.AdoptCluster; using EntKube.Clusters.Features.InstallPrometheus; using EntKube.Clusters.Infrastructure; using EntKube.SharedKernel.Domain; using FluentAssertions; namespace EntKube.Clusters.Tests.Features; public class InstallPrometheusHandlerTests { private readonly InMemoryClusterRepository repository; public InstallPrometheusHandlerTests() { repository = new InMemoryClusterRepository(); } [Fact] public async Task HandleAsync_WithValidCluster_InstallsAndReturnsSuccess() { // Arrange — A cluster with no Prometheus. The user wants to install // kube-prometheus-stack via Helm with a production configuration. KubernetesCluster cluster = KubernetesCluster.Register( "fresh-cluster", "https://k8s.example.com:6443", "kubeconfig-data", Guid.NewGuid(), "prod-ctx", Guid.NewGuid()); await repository.AddAsync(cluster); FakeMonitoringInstaller installer = new(success: true); InstallPrometheusHandler handler = new(repository, new List { installer }); // Act — Install Prometheus on the cluster. Result result = await handler.HandleAsync( new InstallPrometheusRequest(cluster.Id, "monitoring")); // Assert — The install should succeed and the cluster should have // the Prometheus endpoint stored. result.IsSuccess.Should().BeTrue(); result.Value!.Namespace.Should().Be("monitoring"); result.Value.ReleaseName.Should().Be("kube-prometheus-stack"); KubernetesCluster? updated = await repository.GetByIdAsync(cluster.Id); updated!.PrometheusEndpoints.Should().HaveCount(1); updated.PrometheusEndpoints[0].Namespace.Should().Be("monitoring"); } [Fact] public async Task HandleAsync_WithNonExistentCluster_ReturnsFailure() { // Arrange FakeMonitoringInstaller installer = new(success: true); InstallPrometheusHandler handler = new(repository, new List { installer }); // Act Result result = await handler.HandleAsync( new InstallPrometheusRequest(Guid.NewGuid(), "monitoring")); // Assert result.IsFailure.Should().BeTrue(); result.Error.Should().Contain("not found"); } [Fact] public async Task HandleAsync_WhenHelmFails_ReturnsFailure() { // Arrange — Helm install fails (e.g., no connectivity, insufficient permissions). KubernetesCluster cluster = KubernetesCluster.Register( "broken-cluster", "https://broken.example.com:6443", "kubeconfig-data", Guid.NewGuid(), "ctx", Guid.NewGuid()); await repository.AddAsync(cluster); FakeMonitoringInstaller installer = new(success: false, errorMessage: "Tiller not available"); InstallPrometheusHandler handler = new(repository, new List { installer }); // Act Result result = await handler.HandleAsync( new InstallPrometheusRequest(cluster.Id, "monitoring")); // Assert result.IsFailure.Should().BeTrue(); result.Error.Should().Contain("Tiller not available"); } [Fact] public async Task HandleAsync_DefaultsToMonitoringNamespace() { // Arrange — The request doesn't specify a namespace, so it should // default to "monitoring". KubernetesCluster cluster = KubernetesCluster.Register( "default-ns-cluster", "https://k8s.example.com:6443", "kubeconfig-data", Guid.NewGuid(), "ctx", Guid.NewGuid()); await repository.AddAsync(cluster); FakeMonitoringInstaller installer = new(success: true); InstallPrometheusHandler handler = new(repository, new List { installer }); // Act Result result = await handler.HandleAsync( new InstallPrometheusRequest(cluster.Id, null)); // Assert — Should install to "monitoring" namespace. result.IsSuccess.Should().BeTrue(); result.Value!.Namespace.Should().Be("monitoring"); } } /// /// Test double for the monitoring component installer. Returns pre-configured results /// without actually running helm commands. /// public class FakeMonitoringInstaller : IComponentInstaller { private readonly bool success; private readonly string? errorMessage; public string ComponentName => "monitoring"; public FakeMonitoringInstaller(bool success, string? errorMessage = null) { this.success = success; this.errorMessage = errorMessage; } public Task InstallAsync(KubernetesCluster cluster, ComponentInstallOptions options, CancellationToken ct = default) { if (success) { return Task.FromResult(new InstallResult( true, ComponentName, "kube-prometheus-stack installed", new List { "Helm install succeeded" })); } return Task.FromResult(new InstallResult( false, ComponentName, errorMessage ?? "Install failed", new List { $"Error: {errorMessage}" })); } public Task ConfigureAsync(KubernetesCluster cluster, ComponentConfiguration configuration, CancellationToken ct = default) { return Task.FromResult(new InstallResult( true, ComponentName, "Monitoring reconfigured", new List { "Configuration applied" })); } }