117 lines
3.5 KiB
C#
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);
|
|
}
|
|
} |