fix: address review feedback for health check endpoints
PR Checks / test-and-build (pull_request) Successful in 8m34s
PR Checks / test-and-build (pull_request) Successful in 8m34s
- Install wget in Web Dockerfile for compose healthcheck - Ensure HttpListener response is always closed in BotHealthCheckHostedService - Use ephemeral port in Bot health check test to avoid port conflicts - Rename NpgsqlHealthCheck test to reflect actual behavior Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -72,10 +72,10 @@ public sealed class BotHealthCheckHostedService : IHostedService
|
|||||||
|
|
||||||
private async Task HandleRequestAsync(HttpListenerContext context)
|
private async Task HandleRequestAsync(HttpListenerContext context)
|
||||||
{
|
{
|
||||||
|
var response = context.Response;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var request = context.Request;
|
var request = context.Request;
|
||||||
var response = context.Response;
|
|
||||||
|
|
||||||
if (request.Url?.AbsolutePath == "/health")
|
if (request.Url?.AbsolutePath == "/health")
|
||||||
{
|
{
|
||||||
@@ -88,12 +88,14 @@ public sealed class BotHealthCheckHostedService : IHostedService
|
|||||||
{
|
{
|
||||||
response.StatusCode = (int)HttpStatusCode.NotFound;
|
response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
response.Close();
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Error handling health check request");
|
_logger.LogError(ex, "Error handling health check request");
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
response.Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ RUN dotnet publish "GmRelay.Web.csproj" -c Release -o /app/publish /p:UseAppHost
|
|||||||
# Stage 2: Runtime
|
# Stage 2: Runtime
|
||||||
FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble AS final
|
FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble AS final
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends libgssapi-krb5-2 && rm -rf /var/lib/apt/lists/*
|
RUN apt-get update && apt-get install -y --no-install-recommends libgssapi-krb5-2 wget && rm -rf /var/lib/apt/lists/*
|
||||||
COPY --from=build /app/publish .
|
COPY --from=build /app/publish .
|
||||||
RUN mkdir -p /app/dataprotection-keys && chown -R $APP_UID:$APP_UID /app/dataprotection-keys
|
RUN mkdir -p /app/dataprotection-keys && chown -R $APP_UID:$APP_UID /app/dataprotection-keys
|
||||||
ENV ASPNETCORE_URLS=http://+:8080
|
ENV ASPNETCORE_URLS=http://+:8080
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
using GmRelay.Bot.Infrastructure.Health;
|
using GmRelay.Bot.Infrastructure.Health;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
@@ -8,13 +9,15 @@ namespace GmRelay.Bot.Tests.Infrastructure.Health;
|
|||||||
public sealed class BotHealthCheckHostedServiceTests : IDisposable
|
public sealed class BotHealthCheckHostedServiceTests : IDisposable
|
||||||
{
|
{
|
||||||
private readonly BotHealthCheckHostedService _service;
|
private readonly BotHealthCheckHostedService _service;
|
||||||
|
private readonly int _port;
|
||||||
|
|
||||||
public BotHealthCheckHostedServiceTests()
|
public BotHealthCheckHostedServiceTests()
|
||||||
{
|
{
|
||||||
|
_port = GetAvailablePort();
|
||||||
var config = new ConfigurationBuilder()
|
var config = new ConfigurationBuilder()
|
||||||
.AddInMemoryCollection(new Dictionary<string, string?>
|
.AddInMemoryCollection(new Dictionary<string, string?>
|
||||||
{
|
{
|
||||||
["HealthCheck:Prefix"] = "http://localhost:8081/"
|
["HealthCheck:Prefix"] = $"http://localhost:{_port}/"
|
||||||
})
|
})
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
@@ -35,8 +38,17 @@ public sealed class BotHealthCheckHostedServiceTests : IDisposable
|
|||||||
|
|
||||||
using var client = new HttpClient();
|
using var client = new HttpClient();
|
||||||
client.Timeout = TimeSpan.FromSeconds(5);
|
client.Timeout = TimeSpan.FromSeconds(5);
|
||||||
var response = await client.GetAsync("http://localhost:8081/health");
|
var response = await client.GetAsync($"http://localhost:{_port}/health");
|
||||||
|
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int GetAvailablePort()
|
||||||
|
{
|
||||||
|
var listener = new TcpListener(IPAddress.Loopback, 0);
|
||||||
|
listener.Start();
|
||||||
|
var port = ((IPEndPoint)listener.LocalEndpoint).Port;
|
||||||
|
listener.Stop();
|
||||||
|
return port;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public sealed class WebHealthEndpointTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task NpgsqlHealthCheck_ShouldReturnHealthy_WhenDatabaseIsAccessible()
|
public async Task NpgsqlHealthCheck_ShouldReturnUnhealthy_WhenDatabaseIsInaccessible()
|
||||||
{
|
{
|
||||||
var dataSource = NpgsqlDataSource.Create("Host=localhost;Port=5432;Database=gmrelay_db;Username=gmrelay;Password=fake");
|
var dataSource = NpgsqlDataSource.Create("Host=localhost;Port=5432;Database=gmrelay_db;Username=gmrelay;Password=fake");
|
||||||
var healthCheck = new NpgsqlHealthCheck(dataSource);
|
var healthCheck = new NpgsqlHealthCheck(dataSource);
|
||||||
|
|||||||
Reference in New Issue
Block a user