From 4d6b3d36d2a7c17c44839451aa5020953af486fc Mon Sep 17 00:00:00 2001
From: Mono <81423605+monofunc@users.noreply.github.com>
Date: Sun, 17 Aug 2025 13:09:31 +0400
Subject: [PATCH] Migrate HealthChecks.Kubernetes tests to Testcontainers
---
Directory.Packages.props | 1 +
.../Functional/KubernetesHealthCheckTests.cs | 18 +++++---
.../HealthChecks.Kubernetes.Tests.csproj | 4 ++
.../K3sContainerFixture.cs | 45 +++++++++++++++++++
4 files changed, 61 insertions(+), 7 deletions(-)
create mode 100644 test/HealthChecks.Kubernetes.Tests/K3sContainerFixture.cs
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 2c2207765a..b0ff4cea40 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -104,6 +104,7 @@
+
diff --git a/test/HealthChecks.Kubernetes.Tests/Functional/KubernetesHealthCheckTests.cs b/test/HealthChecks.Kubernetes.Tests/Functional/KubernetesHealthCheckTests.cs
index e3f3303266..9261160593 100644
--- a/test/HealthChecks.Kubernetes.Tests/Functional/KubernetesHealthCheckTests.cs
+++ b/test/HealthChecks.Kubernetes.Tests/Functional/KubernetesHealthCheckTests.cs
@@ -3,7 +3,7 @@
namespace HealthChecks.Kubernetes.Tests.Functional;
-public class kubernetes_healthcheck_should
+public class kubernetes_healthcheck_should(K3sContainerFixture k3sFixture) : IClassFixture
{
[Fact]
public async Task be_unhealthy_if_kubernetes_is_unavailable()
@@ -63,19 +63,23 @@ public async Task be_healthy_if_empty_registrations()
response.StatusCode.ShouldBe(HttpStatusCode.OK);
}
- [Fact(Skip = "TODO: Implement")]
+ [Fact]
public async Task be_healthy_if_kubernetes_is_available()
{
+ var kubeconfig = await k3sFixture.GetKubeconfigAsync();
+
var webHostBuilder = new WebHostBuilder()
.ConfigureServices(services =>
{
services
.AddHealthChecks()
- .AddKubernetes(setup => setup.WithConfiguration(new KubernetesClientConfiguration
- {
- Host = "https://localhost:443",
- SkipTlsVerify = true
- }).CheckService("DummyService", s => s.Spec.Type == "LoadBalancer"), tags: ["k8s"]);
+ .AddKubernetes(
+ setup => setup
+ .WithConfiguration(kubeconfig)
+ .CheckService(
+ "kubernetes",
+ s => s.Spec.Type == "ClusterIP"),
+ tags: ["k8s"]);
})
.Configure(app =>
{
diff --git a/test/HealthChecks.Kubernetes.Tests/HealthChecks.Kubernetes.Tests.csproj b/test/HealthChecks.Kubernetes.Tests/HealthChecks.Kubernetes.Tests.csproj
index 4ccf5c97f2..cfe74920f5 100644
--- a/test/HealthChecks.Kubernetes.Tests/HealthChecks.Kubernetes.Tests.csproj
+++ b/test/HealthChecks.Kubernetes.Tests/HealthChecks.Kubernetes.Tests.csproj
@@ -4,4 +4,8 @@
+
+
+
+
diff --git a/test/HealthChecks.Kubernetes.Tests/K3sContainerFixture.cs b/test/HealthChecks.Kubernetes.Tests/K3sContainerFixture.cs
new file mode 100644
index 0000000000..0d127cd4bc
--- /dev/null
+++ b/test/HealthChecks.Kubernetes.Tests/K3sContainerFixture.cs
@@ -0,0 +1,45 @@
+using System.Text;
+using k8s;
+using Testcontainers.K3s;
+
+namespace HealthChecks.Kubernetes.Tests;
+
+public class K3sContainerFixture : IAsyncLifetime
+{
+ private const string Registry = "docker.io";
+
+ private const string Image = "rancher/k3s";
+
+ private const string Tag = "v1.26.2-k3s1";
+
+ public K3sContainer? Container { get; private set; }
+
+ public async Task GetKubeconfigAsync()
+ {
+ if (Container is null)
+ {
+ throw new InvalidOperationException("The test container was not initialized.");
+ }
+
+ string? kubeconfig = await Container.GetKubeconfigAsync();
+
+ await using var stream = new MemoryStream(Encoding.UTF8.GetBytes(kubeconfig));
+
+ return await KubernetesClientConfiguration.BuildConfigFromConfigFileAsync(stream);
+ }
+
+ public async Task InitializeAsync() => Container = await CreateContainerAsync();
+
+ public Task DisposeAsync() => Container?.DisposeAsync().AsTask() ?? Task.CompletedTask;
+
+ private static async Task CreateContainerAsync()
+ {
+ var container = new K3sBuilder()
+ .WithImage($"{Registry}/{Image}:{Tag}")
+ .Build();
+
+ await container.StartAsync();
+
+ return container;
+ }
+}