| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 |
- using DotNet.Testcontainers.Builders;
- using DotNet.Testcontainers.Containers;
- using Xunit.Abstractions;
- namespace Tests.E2e;
- public class DockerHealthcheckTests(ITestOutputHelper output) {
- private const string _dockerImage = "rackpeek:ci";
- private static readonly TimeSpan _healthDeadline = TimeSpan.FromSeconds(60);
- [Fact]
- public async Task Container_Reports_Healthy_Status_Via_Docker_HEALTHCHECK() {
- await using IContainer container = new ContainerBuilder(_dockerImage)
- .WithPortBinding(8080, true)
- .WithWaitStrategy(
- Wait.ForUnixContainer()
- .UntilContainerIsHealthy())
- .Build();
- using var cts = new CancellationTokenSource(_healthDeadline);
- try {
- // StartAsync blocks until the wait strategy succeeds. If the image
- // has no HEALTHCHECK instruction Docker reports `health: none` forever,
- // so we bound the wait — the cancellation token forces a fast failure
- // rather than letting the test hang.
- await container.StartAsync(cts.Token);
- Assert.Equal(TestcontainersStates.Running, container.State);
- Assert.Equal(TestcontainersHealthStatus.Healthy, container.Health);
- }
- catch (Exception) {
- output.WriteLine($"Container did not reach 'Healthy' within {_healthDeadline.TotalSeconds:F0}s.");
- output.WriteLine($"Container state: {container.State}");
- output.WriteLine($"Container health: {container.Health}");
- try {
- (string Stdout, string Stderr) logs = await container.GetLogsAsync();
- output.WriteLine("==== CONTAINER STDOUT ====");
- output.WriteLine(logs.Stdout);
- output.WriteLine("==== CONTAINER STDERR ====");
- output.WriteLine(logs.Stderr);
- }
- catch (Exception logEx) {
- output.WriteLine($"Failed to capture container logs: {logEx.Message}");
- }
- throw;
- }
- }
- }
|