test(core): add health checker tests

This commit is contained in:
dualfroz committed 2026-08-27 23:10:36 +02:00
1 parent 4fdbcc7417
commit 680a7198bf
2 files changed
+127

No files matched your search

@@ -0,0 +1,94 @@
using System.Net;
using System.Net.Sockets;
using Vantage.Core.Health;
using Vantage.Core.Models;
using Vantage.Core.Tests.Fakes;
using Xunit;
namespace Vantage.Core.Tests.Health;
public class HealthCheckerTests
{
private static HealthCheckConfig HttpCheck() =>
new() { Kind = HealthKind.Http, Target = "https://service.local/health", TimeoutMs = 2000 };
[Fact]
public async Task Http_ExpectedStatusIsUp()
{
var checker = new HealthChecker(new HttpClient(StubHttpMessageHandler.WithStatus(HttpStatusCode.OK)));
var result = await checker.CheckAsync(HttpCheck(), CancellationToken.None);
Assert.Equal(HealthStatus.Up, result.Status);
Assert.NotNull(result.LatencyMs);
}
[Fact]
public async Task Http_UnexpectedStatusIsDegraded()
{
var checker = new HealthChecker(new HttpClient(StubHttpMessageHandler.WithStatus(HttpStatusCode.InternalServerError)));
var result = await checker.CheckAsync(HttpCheck(), CancellationToken.None);
Assert.Equal(HealthStatus.Degraded, result.Status);
}
[Fact]
public async Task Http_ConnectionErrorIsDown()
{
var checker = new HealthChecker(new HttpClient(StubHttpMessageHandler.Throwing(new HttpRequestException("refused"))));
var result = await checker.CheckAsync(HttpCheck(), CancellationToken.None);
Assert.Equal(HealthStatus.Down, result.Status);
Assert.Contains("refused", result.Message);
}
[Fact]
public async Task Http_TimeoutIsDown()
{
var checker = new HealthChecker(new HttpClient(StubHttpMessageHandler.Delayed(TimeSpan.FromSeconds(10), HttpStatusCode.OK)));
var check = HttpCheck();
check.TimeoutMs = 100;
var result = await checker.CheckAsync(check, CancellationToken.None);
Assert.Equal(HealthStatus.Down, result.Status);
Assert.Contains("Timed out", result.Message);
}
[Fact]
public async Task Tcp_OpenPortIsUp()
{
var listener = new TcpListener(IPAddress.Loopback, 0);
listener.Start();
var port = ((IPEndPoint)listener.LocalEndpoint).Port;
try
{
var checker = new HealthChecker(new HttpClient());
var check = new HealthCheckConfig { Kind = HealthKind.Tcp, Target = $"127.0.0.1:{port}", TimeoutMs = 2000 };
var result = await checker.CheckAsync(check, CancellationToken.None);
Assert.Equal(HealthStatus.Up, result.Status);
Assert.NotNull(result.LatencyMs);
}
finally
{
listener.Stop();
}
}
[Fact]
public async Task Tcp_ClosedPortIsDown()
{
var probe = new TcpListener(IPAddress.Loopback, 0);
probe.Start();
var closedPort = ((IPEndPoint)probe.LocalEndpoint).Port;
probe.Stop();
var checker = new HealthChecker(new HttpClient());
var check = new HealthCheckConfig { Kind = HealthKind.Tcp, Target = $"127.0.0.1:{closedPort}", TimeoutMs = 2000 };
var result = await checker.CheckAsync(check, CancellationToken.None);
Assert.Equal(HealthStatus.Down, result.Status);
}
}
@@ -0,0 +1,33 @@
using Vantage.Core.Health;
using Xunit;
namespace Vantage.Core.Tests.Health;
public class TcpEndpointTests
{
[Fact]
public void Parse_HostAndPort()
{
var endpoint = TcpEndpoint.Parse("db.internal:5432");
Assert.Equal("db.internal", endpoint.Host);
Assert.Equal(5432, endpoint.Port);
}
[Fact]
public void Parse_IPv6InBrackets()
{
var endpoint = TcpEndpoint.Parse("[::1]:8080");
Assert.Equal("::1", endpoint.Host);
Assert.Equal(8080, endpoint.Port);
}
[Theory]
[InlineData("nohost")]
[InlineData("host:")]
[InlineData("host:70000")]
[InlineData("host:abc")]
public void Parse_RejectsMalformedTargets(string target)
{
Assert.Throws<FormatException>(() => TcpEndpoint.Parse(target));
}
}