Skip to content
Open
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion backend/Infrastructure/Infrastructure.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.10"/>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0"/>
<PackageReference Include="Scrutor" Version="5.0.1"/>
<PackageReference Include="Testcontainers" Version="4.1.0"/>
<PackageReference Include="Testcontainers" Version="4.4.0" />
<PackageReference Include="Testcontainers.SqlEdge" Version="3.10.0"/>
</ItemGroup>

Expand Down
58 changes: 47 additions & 11 deletions backend/Infrastructure/TestContainers/TestContainersFactory.cs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fungerer fint hos meg! 🥳

Men hva med kjøring av Vibes-APIet med test containers? Altså, med "TestContainersConfig": { "Enabled": true, ... } i appsettings.Local.json. Burde vi like gjerne erstatte konfigen for det også, med det nye du har fått inn? Da tenker jeg på f.eks. å erstatte DefaultConnectionString, som nå brukes i TestContainersHostBuilder.

Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using DotNet.Testcontainers.Builders;
using DotNet.Testcontainers.Containers;
using Infrastructure.DatabaseContext;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Testcontainers.SqlEdge;

namespace Infrastructure.TestContainers;

Expand All @@ -11,13 +12,16 @@ public class TestContainersFactory(TestContainersConfig config, ILogger<TestCont
private const string DbContainerName = "testcontainers-api-db";
private const string DbPassword = "test123!";
private const int DbHostPort = 14333;
private const int DbContainerPort = 1433;
private const string SqlServerImage = "mcr.microsoft.com/azure-sql-edge:latest";

public static readonly string DefaultConnectionString =
$"Server=127.0.0.1,{DbHostPort};Database=master;User Id=sa;Password={DbPassword};TrustServerCertificate=True";

private SqlEdgeContainer? _sqlEdgeContainer;
private string? _currentConnectionString;
private IContainer? _dbContainer;

public string? CurrentConnectionString => _sqlEdgeContainer?.GetConnectionString();
public string? CurrentConnectionString => _currentConnectionString;

public async Task Start(CancellationToken cancellationToken = default, Overrides? overrides = null)
{
Expand All @@ -28,20 +32,34 @@ public async Task Start(CancellationToken cancellationToken = default, Overrides
var dbHostPort = overrides?.DbHostPortOverride ?? DbHostPort;
var dbContainerName = overrides?.DbContainerNameOverride ?? DbContainerName;

logger.LogInformation("Starting TestContainers");
logger.LogInformation("Starting TestContainers using generic container");

_sqlEdgeContainer = new SqlEdgeBuilder()
var containerBuilder = new ContainerBuilder()
.WithImage(SqlServerImage)
.WithName(dbContainerName)
.WithReuse(true)
.WithPassword(DbPassword)
.WithPortBinding(dbHostPort, 1433)
.Build();
.WithEnvironment("ACCEPT_EULA", "Y")
.WithEnvironment("SA_PASSWORD", DbPassword)
.WithPortBinding(dbHostPort, DbContainerPort)
.WithCreateParameterModifier(p => { p.Platform = "linux/amd64"; })
.WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(DbContainerPort)
);

_dbContainer = containerBuilder.Build();

await _dbContainer.StartAsync(cancellationToken);

var mappedHostPort = _dbContainer.GetMappedPublicPort(DbContainerPort);
_currentConnectionString =
$"Server=127.0.0.1,{mappedHostPort};Database=master;User Id=sa;Password={DbPassword};TrustServerCertificate=True";

logger.LogInformation("Test container started. Actual Connection String: {ConnectionString}",
_currentConnectionString);

await _sqlEdgeContainer.StartAsync(cancellationToken);

var options = Options.Create(new InfrastructureConfig
{
ConnectionString = _sqlEdgeContainer.GetConnectionString(),
ConnectionString = _currentConnectionString,
EnableSensitiveDataLogging = true
});

Expand All @@ -56,12 +74,29 @@ public async Task Start(CancellationToken cancellationToken = default, Overrides
catch (Exception e)
{
logger.LogError(e, "Error while starting TestContainers");
if (_dbContainer != null)
{
try
{
await _dbContainer.StopAsync(CancellationToken.None);
await _dbContainer.DisposeAsync();
}
catch (Exception cleanupEx)
{
logger.LogError(cleanupEx, "Error during container cleanup after failed start.");
}

_dbContainer = null;
}

_currentConnectionString = null;
throw;
}
}

public Task Stop(CancellationToken cancellationToken = default)
{
var stopTask = _sqlEdgeContainer?.StopAsync(cancellationToken) ?? Task.CompletedTask;
var stopTask = _dbContainer?.StopAsync(cancellationToken) ?? Task.CompletedTask;
return stopTask;
}

Expand All @@ -79,5 +114,6 @@ private async Task MigrateDatabase(DbContext context, CancellationToken cancella

logger.LogInformation("Running database migrations");
await context.Database.MigrateAsync(cancellationToken);
logger.LogInformation("Database migrations completed.");
}
}
Loading