Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using DotNet.Testcontainers.Containers;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.Configuration;
Expand All @@ -19,6 +20,8 @@ public sealed class TestWebApplicationFactory : WebApplicationFactory<Program>,
private const string DockerGroupLabel = "com.docker.compose.project";
private const string DockerGroupName = "StrongTypes";

private static readonly TimeSpan ContainerStartTimeout = TimeSpan.FromSeconds(45);

private readonly MsSqlContainer _sqlContainer = new MsSqlBuilder()
.WithLabel(DockerGroupLabel, DockerGroupName)
.Build();
Expand All @@ -31,7 +34,9 @@ async ValueTask IAsyncLifetime.InitializeAsync()
{
// Start both containers in parallel; containers must be up before the
// host is built so that ConfigureAppConfiguration can read their connection strings.
await Task.WhenAll(_sqlContainer.StartAsync(), _pgContainer.StartAsync());
await Task.WhenAll(
StartContainerAsync(_sqlContainer, "SQL Server"),
StartContainerAsync(_pgContainer, "PostgreSQL"));

// Accessing Services triggers the lazy host build.
using var scope = Services.CreateScope();
Expand All @@ -40,6 +45,22 @@ async ValueTask IAsyncLifetime.InitializeAsync()
await sp.GetRequiredService<PostgreSqlDbContext>().Database.EnsureCreatedAsync();
}

private static async Task StartContainerAsync(IContainer container, string name)
{
using var cts = new CancellationTokenSource(ContainerStartTimeout);
try
{
await container.StartAsync(cts.Token);
}
catch (OperationCanceledException) when (cts.IsCancellationRequested)
{
throw new TimeoutException(
$"The {name} test container did not start within {ContainerStartTimeout.TotalSeconds:0}s. " +
"It either failed to start or never began accepting connections — check the container logs. " +
"On ARM64 hosts this can also happen when the image has no native ARM build, as the emulated process may crash on startup.");
}
}

protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureAppConfiguration((_, config) =>
Expand Down
Loading