diff --git a/src/NHibernate.Test/NHibernate.Test.csproj b/src/NHibernate.Test/NHibernate.Test.csproj index 847687acb9..ff728f1204 100644 --- a/src/NHibernate.Test/NHibernate.Test.csproj +++ b/src/NHibernate.Test/NHibernate.Test.csproj @@ -69,6 +69,13 @@ + + + + + + + diff --git a/src/NHibernate.Test/TestConfigurationHelper.cs b/src/NHibernate.Test/TestConfigurationHelper.cs index 89299bbd82..457c41e10a 100644 --- a/src/NHibernate.Test/TestConfigurationHelper.cs +++ b/src/NHibernate.Test/TestConfigurationHelper.cs @@ -47,6 +47,12 @@ public static Configuration GetDefaultConfiguration() Configuration result = new Configuration(); if (hibernateConfigFile != null) result.Configure(hibernateConfigFile); + + var connectionString = result.GetProperty(Cfg.Environment.ConnectionString); + if (connectionString?.StartsWith("testcontainers=") == true) + { + result.SetProperty(Cfg.Environment.ConnectionString, TestContainerSetup.GetConnectionString(connectionString)); + } return result; } @@ -71,4 +77,4 @@ private static string FindCurrentTestConfigurationFile(string filename) return null; } } -} \ No newline at end of file +} diff --git a/src/NHibernate.Test/TestContainerSetup.cs b/src/NHibernate.Test/TestContainerSetup.cs new file mode 100644 index 0000000000..0d9ac9888a --- /dev/null +++ b/src/NHibernate.Test/TestContainerSetup.cs @@ -0,0 +1,76 @@ +namespace NHibernate.Test +{ + using System; + using System.Threading.Tasks; + using DotNet.Testcontainers.Containers; + using NUnit.Framework; + using Testcontainers.Db2; + using Testcontainers.FirebirdSql; + using Testcontainers.MariaDb; + using Testcontainers.MsSql; + using Testcontainers.MySql; + using Testcontainers.Oracle; + using Testcontainers.PostgreSql; + + [SetUpFixture] + public class TestContainerSetup + { + private static volatile IDatabaseContainer _container; + private static readonly object _lock = new object(); + + internal static string GetConnectionString(string connectionString) + { + var parts = connectionString.Split('='); + if (parts.Length != 2 || parts[0] != "testcontainers") + { + throw new System.ArgumentException("Invalid testcontainers connection string format. Expected format: testcontainers=DbType"); + } + // For now, only one container is supported. In the future, we can extend this to support multiple containers. + if (_container == null) + { + lock (_lock) + { + if (_container == null) + { + var container = GetContainer(parts[1]); + Task.Run(() => container.StartAsync()).GetAwaiter().GetResult(); + _container = container; + } + } + } + return _container.GetConnectionString(); + } + + private static IDatabaseContainer GetContainer(string dbType) + { + switch (dbType.ToLower()) + { + case "db2": + return new Db2Builder().Build(); + case "firebirdsql": + return new FirebirdSqlBuilder().Build(); + case "mariadb": + return new MariaDbBuilder().Build(); + case "mssql": + return new MsSqlBuilder().Build(); + case "mysql": + return new MySqlBuilder().Build(); + case "oracle": + return new OracleBuilder().Build(); + case "postgresql": + return new PostgreSqlBuilder().Build(); + default: + throw new NotSupportedException("Database type not supported: " + dbType); + } + } + + [OneTimeTearDown] + public async Task TearDown() + { + if (_container != null) + { + await _container.DisposeAsync(); + } + } + } +}