too much for one commit
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
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<IComponentInstaller> { installer });
|
||||
|
||||
// Act — Install Prometheus on the cluster.
|
||||
|
||||
Result<PrometheusInstallResult> 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<IComponentInstaller> { installer });
|
||||
|
||||
// Act
|
||||
|
||||
Result<PrometheusInstallResult> 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<IComponentInstaller> { installer });
|
||||
|
||||
// Act
|
||||
|
||||
Result<PrometheusInstallResult> 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<IComponentInstaller> { installer });
|
||||
|
||||
// Act
|
||||
|
||||
Result<PrometheusInstallResult> 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");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test double for the monitoring component installer. Returns pre-configured results
|
||||
/// without actually running helm commands.
|
||||
/// </summary>
|
||||
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<InstallResult> InstallAsync(KubernetesCluster cluster, ComponentInstallOptions options, CancellationToken ct = default)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
return Task.FromResult(new InstallResult(
|
||||
true,
|
||||
ComponentName,
|
||||
"kube-prometheus-stack installed",
|
||||
new List<string> { "Helm install succeeded" }));
|
||||
}
|
||||
|
||||
return Task.FromResult(new InstallResult(
|
||||
false,
|
||||
ComponentName,
|
||||
errorMessage ?? "Install failed",
|
||||
new List<string> { $"Error: {errorMessage}" }));
|
||||
}
|
||||
|
||||
public Task<InstallResult> ConfigureAsync(KubernetesCluster cluster, ComponentConfiguration configuration, CancellationToken ct = default)
|
||||
{
|
||||
return Task.FromResult(new InstallResult(
|
||||
true,
|
||||
ComponentName,
|
||||
"Monitoring reconfigured",
|
||||
new List<string> { "Configuration applied" }));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user