too much for one commit
This commit is contained in:
194
tests/EntKube.Clusters.Tests/Features/IngressCheckTests.cs
Normal file
194
tests/EntKube.Clusters.Tests/Features/IngressCheckTests.cs
Normal file
@@ -0,0 +1,194 @@
|
||||
using EntKube.Clusters.Domain;
|
||||
using EntKube.Clusters.Features.AdoptCluster;
|
||||
using EntKube.Clusters.Features.AdoptCluster.Components.Ingress;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace EntKube.Clusters.Tests.Features;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for IngressCheck.DetectProvider — the static method that determines
|
||||
/// which ingress provider is installed on a cluster by examining its component
|
||||
/// list. This drives the auto-detection behavior so users never have to
|
||||
/// manually select "istio" or "traefik" when configuring ingress.
|
||||
/// </summary>
|
||||
public class IngressCheckTests
|
||||
{
|
||||
[Fact]
|
||||
public void DetectProvider_IstioInstalled_ReturnsIstio()
|
||||
{
|
||||
// When the cluster has an Istio component marked as Installed,
|
||||
// the detector should pick Istio as the provider.
|
||||
|
||||
KubernetesCluster cluster = CreateClusterWithComponent("istio", ComponentStatus.Installed);
|
||||
|
||||
string? provider = IngressCheck.DetectProvider(cluster);
|
||||
|
||||
provider.Should().Be("istio");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DetectProvider_TraefikInstalled_ReturnsTraefik()
|
||||
{
|
||||
// When the cluster has a Traefik component marked as Installed,
|
||||
// the detector should pick Traefik as the provider.
|
||||
|
||||
KubernetesCluster cluster = CreateClusterWithComponent("traefik", ComponentStatus.Installed);
|
||||
|
||||
string? provider = IngressCheck.DetectProvider(cluster);
|
||||
|
||||
provider.Should().Be("traefik");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DetectProvider_IstioDegraded_StillReturnsIstio()
|
||||
{
|
||||
// Even if Istio is degraded (partially working), we should still
|
||||
// detect it as the provider — the gateway infra can still be deployed.
|
||||
|
||||
KubernetesCluster cluster = CreateClusterWithComponent("istio", ComponentStatus.Degraded);
|
||||
|
||||
string? provider = IngressCheck.DetectProvider(cluster);
|
||||
|
||||
provider.Should().Be("istio");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DetectProvider_NeitherInstalled_ReturnsNull()
|
||||
{
|
||||
// When no ingress controller is installed, the detector returns null
|
||||
// so the installer can report "install Istio or Traefik first."
|
||||
|
||||
KubernetesCluster cluster = CreateClusterWithComponent("kyverno", ComponentStatus.Installed);
|
||||
|
||||
string? provider = IngressCheck.DetectProvider(cluster);
|
||||
|
||||
provider.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DetectProvider_BothInstalled_PrefersIstio()
|
||||
{
|
||||
// If both Istio and Traefik are installed (unusual but possible),
|
||||
// Istio takes priority because it requires dedicated gateway infrastructure.
|
||||
|
||||
KubernetesCluster cluster = CreateClusterWithComponents(
|
||||
("istio", ComponentStatus.Installed),
|
||||
("traefik", ComponentStatus.Installed));
|
||||
|
||||
string? provider = IngressCheck.DetectProvider(cluster);
|
||||
|
||||
provider.Should().Be("istio");
|
||||
}
|
||||
|
||||
// ─── Gateway resolution from ingress component ───────────────────────
|
||||
|
||||
[Fact]
|
||||
public void IngressComponent_WithIstioGateways_ExposesGatewayInfo()
|
||||
{
|
||||
// When the ingress component is installed with Istio and has discovered
|
||||
// internal and external gateways, the component's configuration should
|
||||
// contain the gateway details that services can use to auto-resolve.
|
||||
|
||||
KubernetesCluster cluster = CreateClusterWithIngressConfig(
|
||||
provider: "istio",
|
||||
hasInternalGateway: true,
|
||||
hasExternalGateway: true);
|
||||
|
||||
ClusterComponent? ingress = cluster.Components.FirstOrDefault(
|
||||
c => c.ComponentName == "ingress");
|
||||
|
||||
ingress.Should().NotBeNull();
|
||||
ingress!.Configuration["provider"].Should().Be("istio");
|
||||
ingress.Configuration["hasInternalGateway"].Should().Be("True");
|
||||
ingress.Configuration["hasExternalGateway"].Should().Be("True");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IngressComponent_WithTraefik_NoGatewayRefs()
|
||||
{
|
||||
// Traefik manages its own ingress — no Gateway API gateway refs needed.
|
||||
// The component config should show traefik as provider.
|
||||
|
||||
KubernetesCluster cluster = CreateClusterWithIngressConfig(
|
||||
provider: "traefik",
|
||||
hasInternalGateway: false,
|
||||
hasExternalGateway: false);
|
||||
|
||||
ClusterComponent? ingress = cluster.Components.FirstOrDefault(
|
||||
c => c.ComponentName == "ingress");
|
||||
|
||||
ingress.Should().NotBeNull();
|
||||
ingress!.Configuration["provider"].Should().Be("traefik");
|
||||
ingress.Configuration.ContainsKey("hasInternalGateway").Should().BeFalse();
|
||||
}
|
||||
|
||||
// ─── Helpers ─────────────────────────────────────────────────────────
|
||||
|
||||
private static KubernetesCluster CreateClusterWithComponent(string componentName, ComponentStatus status)
|
||||
{
|
||||
return CreateClusterWithComponents((componentName, status));
|
||||
}
|
||||
|
||||
private static KubernetesCluster CreateClusterWithComponents(params (string Name, ComponentStatus Status)[] componentDefs)
|
||||
{
|
||||
KubernetesCluster cluster = KubernetesCluster.Register(
|
||||
"test-cluster", "https://k8s.example.com", "fake-kubeconfig",
|
||||
Guid.NewGuid(), "test-context", Guid.NewGuid());
|
||||
|
||||
List<ComponentCheckResult> results = componentDefs
|
||||
.Select(c => new ComponentCheckResult(
|
||||
c.Name, c.Status,
|
||||
Details: new List<string>(),
|
||||
MissingItems: new List<string>()))
|
||||
.ToList();
|
||||
|
||||
cluster.UpdateComponents(results);
|
||||
|
||||
return cluster;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a cluster with an ingress component that has discovered
|
||||
/// configuration values — provider, gateway presence flags. This mimics
|
||||
/// what the real IngressCheck discovers during an adoption scan.
|
||||
/// </summary>
|
||||
private static KubernetesCluster CreateClusterWithIngressConfig(
|
||||
string provider, bool hasInternalGateway, bool hasExternalGateway)
|
||||
{
|
||||
KubernetesCluster cluster = KubernetesCluster.Register(
|
||||
"test-cluster", "https://k8s.example.com", "fake-kubeconfig",
|
||||
Guid.NewGuid(), "test-context", Guid.NewGuid());
|
||||
|
||||
Dictionary<string, string> configValues = new()
|
||||
{
|
||||
["provider"] = provider
|
||||
};
|
||||
|
||||
if (hasInternalGateway)
|
||||
{
|
||||
configValues["hasInternalGateway"] = "True";
|
||||
}
|
||||
|
||||
if (hasExternalGateway)
|
||||
{
|
||||
configValues["hasExternalGateway"] = "True";
|
||||
}
|
||||
|
||||
List<ComponentCheckResult> results = new()
|
||||
{
|
||||
new ComponentCheckResult(
|
||||
"ingress", ComponentStatus.Installed,
|
||||
Details: new List<string>(),
|
||||
MissingItems: new List<string>(),
|
||||
Configuration: new DiscoveredConfiguration(
|
||||
Version: null,
|
||||
Namespace: "internal-ingress",
|
||||
HelmReleaseName: null,
|
||||
Values: configValues))
|
||||
};
|
||||
|
||||
cluster.UpdateComponents(results);
|
||||
|
||||
return cluster;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user