Skip to content

Instantly share code, notes, and snippets.

@vmandic
Created November 23, 2024 16:10
Show Gist options
  • Save vmandic/808082fb64a3ef92c2db4ffc1d705c3f to your computer and use it in GitHub Desktop.
Save vmandic/808082fb64a3ef92c2db4ffc1d705c3f to your computer and use it in GitHub Desktop.
dotnet Testcontainers setup for: MariaDb, RabbitMq, Redis and MongoDb
private async Task<TestContainerConnectionStrings> CreateAndInitDbStackAsync()
{
_network = new NetworkBuilder().Build();
var mariaDbCnfPath = Path.GetFullPath("./Setup/docker/mariadb");
if (!Directory.Exists(mariaDbCnfPath))
{
throw new FileNotFoundException("Required mariadb conf dir not found");
}
var mongoDbCnfPath = Path.GetFullPath("./Setup/docker/mongodb");
if (!Directory.Exists(mongoDbCnfPath))
{
throw new FileNotFoundException("Required mongodb conf dir not found");
}
var sqlDbMigrated = false;
var mariaDbContainerTask = Task.Run(
() =>
new MariaDbBuilder()
.WithName($"it_{CurrentTestId}_mariadb")
.WithNetworkAliases(nameof(_mariaDbContainer))
.DependsOn(_network)
.WithCleanUp(true)
.WithDatabase("it_db")
.WithUsername("root")
.WithPassword("root")
.WithBindMount(mariaDbCnfPath, "/etc/mysql/conf.d")
.Build()
);
var mongoDbContainerTask = Task.Run(
() =>
new MongoDbBuilder()
.WithName($"it_{CurrentTestId}_mongodb")
.WithNetworkAliases(nameof(_mongoDbContainer))
.DependsOn(_network)
.WithCleanUp(true)
.WithEnvironment("MONGO_INITDB_DATABASE", "dotnet_integration_tested") // to match init.js
.WithUsername("root")
.WithPassword("root")
.WithBindMount(mongoDbCnfPath, "/docker-entrypoint-initdb.d")
.Build()
);
var rabbitMqContainerTask = Task.Run(
() =>
new RabbitMqBuilder()
.WithName($"it_{CurrentTestId}_rabbitmq")
.WithNetworkAliases(nameof(_rabbitMqContainer))
.DependsOn(_network)
.WithCleanUp(true)
.WithUsername("guest")
.WithPassword("guest")
.WithEnvironment("RABBITMQ_DEFAULT_VHOST", "/it_db")
.Build()
);
_mariaDbContainer = await mariaDbContainerTask;
_mariaDbContainer.Started += (_, _) =>
{
var mariaDbConnectionString = _mariaDbContainer.GetConnectionString();
var conn = new MySqlConnection(mariaDbConnectionString);
// sanity test the connection
conn.Open();
conn.Close();
conn.Dispose();
SqlMigrator.ApplyMigrations(mariaDbConnectionString);
sqlDbMigrated = true;
Logger.LogDebug("SQL database migrated");
};
_mongoDbContainer = await mongoDbContainerTask;
_rabbitMqContainer = await rabbitMqContainerTask;
_redisContainer = new RedisBuilder()
.WithName($"it_{CurrentTestId}_redis")
.WithNetworkAliases(nameof(_redisContainer))
.DependsOn(_network)
.WithCleanUp(true)
.DependsOn(_mariaDbContainer)
.DependsOn(_mongoDbContainer)
.DependsOn(_rabbitMqContainer)
.Build();
_dockerContainers.Add(_mariaDbContainer);
_dockerContainers.Add(_mongoDbContainer);
_dockerContainers.Add(_rabbitMqContainer);
_dockerContainers.Add(_redisContainer);
// docker failsafe
var cts = new CancellationTokenSource();
cts.CancelAfter(30_000);
await _redisContainer.StartAsync(cts.Token);
var strings = new TestContainerConnectionStrings();
strings["ConnectionStrings:Sql"] = _mariaDbContainer.GetConnectionString();
strings["ConnectionStrings:Redis"] = _redisContainer.GetConnectionString();
strings["ConnectionStrings:Mongo"] = _mongoDbContainer.GetConnectionString();
strings["ConnectionStrings:RabbitMq"] = _rabbitMqContainer.GetConnectionString();
if (!await WaitUntilSuccessAsync(() => sqlDbMigrated))
{
throw new InvalidOperationException("SQL database was not migrated");
}
return strings;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment