too much for one commit
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
using EntKube.Clusters.Domain;
|
||||
using EntKube.Clusters.Features.DiscoverPrometheus;
|
||||
using EntKube.Clusters.Infrastructure;
|
||||
using EntKube.SharedKernel.Domain;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace EntKube.Clusters.Tests.Features;
|
||||
|
||||
public class DiscoverPrometheusHandlerTests
|
||||
{
|
||||
private readonly InMemoryClusterRepository repository;
|
||||
|
||||
public DiscoverPrometheusHandlerTests()
|
||||
{
|
||||
repository = new InMemoryClusterRepository();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HandleAsync_WithDiscoveredEndpoints_StoresThemOnCluster()
|
||||
{
|
||||
// Arrange — A registered cluster and a scanner that finds two Prometheus instances.
|
||||
|
||||
KubernetesCluster cluster = KubernetesCluster.Register(
|
||||
"production",
|
||||
"https://k8s.example.com:6443",
|
||||
"kubeconfig-data",
|
||||
Guid.NewGuid(),
|
||||
"prod-ctx", Guid.NewGuid());
|
||||
|
||||
await repository.AddAsync(cluster);
|
||||
|
||||
List<PrometheusEndpoint> fakeEndpoints = new()
|
||||
{
|
||||
new PrometheusEndpoint("http://prometheus.monitoring:9090", "monitoring", "prometheus-server"),
|
||||
new PrometheusEndpoint("http://prometheus.observability:9090", "observability", "prom-stack")
|
||||
};
|
||||
|
||||
FakePrometheusScanner scanner = new(fakeEndpoints);
|
||||
DiscoverPrometheusHandler handler = new(repository, scanner);
|
||||
|
||||
// Act — Run discovery on the cluster.
|
||||
|
||||
Result<List<PrometheusEndpoint>> result = await handler.HandleAsync(cluster.Id);
|
||||
|
||||
// Assert — Both endpoints should be stored and returned.
|
||||
|
||||
result.IsSuccess.Should().BeTrue();
|
||||
result.Value.Should().HaveCount(2);
|
||||
result.Value![0].Namespace.Should().Be("monitoring");
|
||||
result.Value[1].Namespace.Should().Be("observability");
|
||||
|
||||
KubernetesCluster? updated = await repository.GetByIdAsync(cluster.Id);
|
||||
updated!.PrometheusEndpoints.Should().HaveCount(2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HandleAsync_WithNoPrometheus_ReturnsEmptyList()
|
||||
{
|
||||
// Arrange — A cluster with no Prometheus running.
|
||||
|
||||
KubernetesCluster cluster = KubernetesCluster.Register(
|
||||
"staging",
|
||||
"https://staging.example.com:6443",
|
||||
"kubeconfig-data",
|
||||
Guid.NewGuid(),
|
||||
"staging-ctx", Guid.NewGuid());
|
||||
|
||||
await repository.AddAsync(cluster);
|
||||
|
||||
FakePrometheusScanner scanner = new(new List<PrometheusEndpoint>());
|
||||
DiscoverPrometheusHandler handler = new(repository, scanner);
|
||||
|
||||
// Act
|
||||
|
||||
Result<List<PrometheusEndpoint>> result = await handler.HandleAsync(cluster.Id);
|
||||
|
||||
// Assert — Success but empty list. No Prometheus found is not an error.
|
||||
|
||||
result.IsSuccess.Should().BeTrue();
|
||||
result.Value.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HandleAsync_WithNonExistentCluster_ReturnsFailure()
|
||||
{
|
||||
// Arrange
|
||||
|
||||
FakePrometheusScanner scanner = new(new List<PrometheusEndpoint>());
|
||||
DiscoverPrometheusHandler handler = new(repository, scanner);
|
||||
|
||||
// Act
|
||||
|
||||
Result<List<PrometheusEndpoint>> result = await handler.HandleAsync(Guid.NewGuid());
|
||||
|
||||
// Assert
|
||||
|
||||
result.IsFailure.Should().BeTrue();
|
||||
result.Error.Should().Contain("not found");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HandleAsync_ReplacesExistingEndpoints_OnRediscovery()
|
||||
{
|
||||
// Arrange — A cluster that already had endpoints from a previous scan.
|
||||
|
||||
KubernetesCluster cluster = KubernetesCluster.Register(
|
||||
"production",
|
||||
"https://k8s.example.com:6443",
|
||||
"kubeconfig-data",
|
||||
Guid.NewGuid(),
|
||||
"prod-ctx", Guid.NewGuid());
|
||||
|
||||
cluster.SetPrometheusEndpoints(new List<PrometheusEndpoint>
|
||||
{
|
||||
new("http://old-prometheus:9090", "legacy", "old-prom")
|
||||
});
|
||||
|
||||
await repository.AddAsync(cluster);
|
||||
|
||||
// A new scan finds a different Prometheus.
|
||||
|
||||
List<PrometheusEndpoint> newEndpoints = new()
|
||||
{
|
||||
new PrometheusEndpoint("http://prometheus.monitoring:9090", "monitoring", "prometheus-server")
|
||||
};
|
||||
|
||||
FakePrometheusScanner scanner = new(newEndpoints);
|
||||
DiscoverPrometheusHandler handler = new(repository, scanner);
|
||||
|
||||
// Act
|
||||
|
||||
Result<List<PrometheusEndpoint>> result = await handler.HandleAsync(cluster.Id);
|
||||
|
||||
// Assert — The old endpoint is replaced by the new one.
|
||||
|
||||
result.IsSuccess.Should().BeTrue();
|
||||
result.Value.Should().HaveCount(1);
|
||||
result.Value![0].ServiceName.Should().Be("prometheus-server");
|
||||
|
||||
KubernetesCluster? updated = await repository.GetByIdAsync(cluster.Id);
|
||||
updated!.PrometheusEndpoints.Should().HaveCount(1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test double that returns pre-configured Prometheus endpoints
|
||||
/// without actually connecting to a Kubernetes cluster.
|
||||
/// </summary>
|
||||
public class FakePrometheusScanner : IPrometheusScanner
|
||||
{
|
||||
private readonly List<PrometheusEndpoint> endpoints;
|
||||
|
||||
public FakePrometheusScanner(List<PrometheusEndpoint> endpoints)
|
||||
{
|
||||
this.endpoints = endpoints;
|
||||
}
|
||||
|
||||
public Task<List<PrometheusEndpoint>> ScanAsync(KubernetesCluster cluster, CancellationToken ct = default)
|
||||
{
|
||||
return Task.FromResult(endpoints);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user