Files
jsmr/JSMR.Tests/Fixtures/MariaDbFixture.cs
Brian Bicknell abd5a81e3e
Some checks failed
ci / build-test (push) Failing after 8m39s
Improved performance of integration tests.
2025-11-02 13:56:34 -05:00

117 lines
3.5 KiB
C#

using JSMR.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;
using MySqlConnector;
using Testcontainers.MariaDb;
namespace JSMR.Tests.Fixtures;
public class MariaDbFixture : IAsyncLifetime
{
const int MajorVersion = 10;
const int MinorVersion = 11;
const int Build = 6;
public MariaDbContainer? MariaDbContainer { get; private set; }
public string ConnectionString { get; private set; } = default!;
public async ValueTask InitializeAsync()
{
MariaDbContainer = new MariaDbBuilder()
.WithImage($"mariadb:{MajorVersion}.{MinorVersion}.{Build}")
.Build();
await MariaDbContainer.StartAsync();
ConnectionString = MariaDbContainer.GetConnectionString();
await using AppDbContext context = CreateDbContext();
await context.Database.EnsureCreatedAsync();
//await context.Database.MigrateAsync(); // Testing
await OnInitializedAsync(context);
}
protected virtual Task OnInitializedAsync(AppDbContext context)
{
return Task.FromResult(Task.CompletedTask);
}
public async ValueTask DisposeAsync()
{
if (MariaDbContainer is not null)
{
await MariaDbContainer.StopAsync();
await MariaDbContainer.DisposeAsync();
}
GC.SuppressFinalize(this);
}
public AppDbContext CreateDbContext()
{
MySqlServerVersion serverVersion = new(new Version(MajorVersion, MinorVersion, Build));
DbContextOptions<AppDbContext> options = new DbContextOptionsBuilder<AppDbContext>()
.UseMySql(ConnectionString, serverVersion,
o => o.EnableRetryOnFailure())
.EnableSensitiveDataLogging()
.Options;
return new AppDbContext(options);
}
public async Task ResetAsync()
{
await using AppDbContext context = CreateDbContext();
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();
}
}
public static class MariaTestDb
{
public static async Task<AppDbContext> CreateIsolatedAsync(string rootConnectionString, Func<AppDbContext, Task>? seed = null)
{
string databaseName = $"t_{DateTime.UtcNow:yyyyMMddHHmmss}_{Guid.NewGuid():N}";
await CreateDatabaseAsync(rootConnectionString, databaseName);
MySqlConnectionStringBuilder connectionStringBuilder = new(rootConnectionString)
{
Database = databaseName
};
AppDbContext dbContext = CreateDbContext(connectionStringBuilder.ConnectionString);
await dbContext.Database.EnsureCreatedAsync();
if (seed != null)
await seed(dbContext);
return dbContext;
}
private static async Task CreateDatabaseAsync(string rootConnectionString, string databaseName)
{
await using MySqlConnection connection = new(rootConnectionString);
await connection.OpenAsync();
await using MySqlCommand command = connection.CreateCommand();
command.CommandText = $"CREATE DATABASE `{databaseName}` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;";
await command.ExecuteNonQueryAsync();
}
private static AppDbContext CreateDbContext(string connectionString)
{
DbContextOptions<AppDbContext> options = new DbContextOptionsBuilder<AppDbContext>()
.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString),
o => o.EnableRetryOnFailure())
.EnableSensitiveDataLogging()
.Options;
return new AppDbContext(options);
}
}