diff --git a/Directory.Packages.props b/Directory.Packages.props index d2e90f1f5..084e280f2 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -62,7 +62,7 @@ - + diff --git a/src/Testcontainers.Oracle/OracleBuilder.cs b/src/Testcontainers.Oracle/OracleBuilder.cs index c5cd3339e..7af131080 100644 --- a/src/Testcontainers.Oracle/OracleBuilder.cs +++ b/src/Testcontainers.Oracle/OracleBuilder.cs @@ -8,6 +8,7 @@ public sealed class OracleBuilder : ContainerBuilder 11 and < 23")] public const string DefaultDatabase = "XEPDB1"; public const string DefaultUsername = "oracle"; @@ -59,20 +60,63 @@ public OracleBuilder WithPassword(string password) .WithEnvironment("APP_USER_PASSWORD", password); } + /// + /// Sets the Oracle database. + /// + /// + /// The database can only be set for Oracle 18 and onwards. + /// + /// The Oracle database. + /// A configured instance of . + public OracleBuilder WithDatabase(string database) + { + if (DockerResourceConfiguration.Image.MatchVersion(v => v.Major < 18)) + throw new NotSupportedException("Setting the database is only supported on Oracle 18 and onwards."); + + return WithDatabaseUnchecked(database); + } + + private OracleBuilder WithDatabaseUnchecked(string database) + { + return Merge(DockerResourceConfiguration, new OracleConfiguration(database: database)); + } + /// public override OracleContainer Build() { Validate(); + + var defaultServiceName = GetDefaultServiceName(); + if (DockerResourceConfiguration.Database == null) + { + return new OracleContainer(WithDatabaseUnchecked(defaultServiceName).DockerResourceConfiguration); + } + + if (DockerResourceConfiguration.Database != defaultServiceName) + { + return new OracleContainer(WithEnvironment("ORACLE_DATABASE", DockerResourceConfiguration.Database).DockerResourceConfiguration); + } + return new OracleContainer(DockerResourceConfiguration); } + private string GetDefaultServiceName() + { + if (DockerResourceConfiguration.Image.MatchVersion(v => v.Major >= 23)) + return "FREEPDB1"; + + if (DockerResourceConfiguration.Image.MatchVersion(v => v.Major > 11)) + return "XEPDB1"; + + return "XE"; + } + /// protected override OracleBuilder Init() { return base.Init() .WithImage(OracleImage) .WithPortBinding(OraclePort, true) - .WithDatabase(DefaultDatabase) .WithUsername(DefaultUsername) .WithPassword(DefaultPassword) .WithWaitStrategy(Wait.ForUnixContainer().UntilMessageIsLogged("DATABASE IS READY TO USE!")); @@ -105,17 +149,4 @@ protected override OracleBuilder Merge(OracleConfiguration oldValue, OracleConfi { return new OracleBuilder(new OracleConfiguration(oldValue, newValue)); } - - /// - /// Sets the Oracle database. - /// - /// - /// The Docker image does not allow to configure the database. - /// - /// The Oracle database. - /// A configured instance of . - private OracleBuilder WithDatabase(string database) - { - return Merge(DockerResourceConfiguration, new OracleConfiguration(database: database)); - } } \ No newline at end of file diff --git a/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs b/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs index b0ee8d3ef..56b10f0ad 100644 --- a/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs +++ b/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs @@ -1,6 +1,6 @@ namespace Testcontainers.Oracle; -public class OracleContainerTest(OracleContainerTest.OracleFixture oracleFixture) : IClassFixture +public abstract class OracleContainerTest(OracleContainerTest.OracleFixture oracleFixture) { [Fact] [Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))] @@ -32,8 +32,43 @@ public async Task ExecScriptReturnsSuccessful() Assert.Empty(execResult.Stderr); } - public class OracleFixture(IMessageSink messageSink) : DbContainerFixture(messageSink) + public class OracleFixture(IMessageSink messageSink, string edition, int? version, string database = null) : DbContainerFixture(messageSink) { public override DbProviderFactory DbProviderFactory => OracleClientFactory.Instance; + + protected override OracleBuilder Configure(OracleBuilder builder) + { + if (edition == default && version == default) + { + return builder; + } + + var image = $"gvenzl/oracle-{edition}:{version}-slim-faststart"; + return database == null ? builder.WithImage(image) : builder.WithImage(image).WithDatabase(database); + } } + + [UsedImplicitly] public sealed class OracleDefault(OracleDefaultFixture fixture) : OracleContainerTest(fixture), IClassFixture; + [UsedImplicitly] public sealed class Oracle11(Oracle11Fixture fixture) : OracleContainerTest(fixture), IClassFixture; + [UsedImplicitly] public sealed class Oracle18(Oracle18Fixture fixture) : OracleContainerTest(fixture), IClassFixture; + [UsedImplicitly] public sealed class Oracle21(Oracle21Fixture fixture) : OracleContainerTest(fixture), IClassFixture; + [UsedImplicitly] public sealed class Oracle23(Oracle23Fixture fixture) : OracleContainerTest(fixture), IClassFixture; + [UsedImplicitly] public sealed class Oracle18Default(Oracle18FixtureDefault fixture) : OracleContainerTest(fixture), IClassFixture; + [UsedImplicitly] public sealed class Oracle21Default(Oracle21FixtureDefault fixture) : OracleContainerTest(fixture), IClassFixture; + [UsedImplicitly] public sealed class Oracle23Default(Oracle23FixtureDefault fixture) : OracleContainerTest(fixture), IClassFixture; + [UsedImplicitly] public sealed class Oracle18Scott(Oracle18FixtureScott fixture) : OracleContainerTest(fixture), IClassFixture; + [UsedImplicitly] public sealed class Oracle21Scott(Oracle21FixtureScott fixture) : OracleContainerTest(fixture), IClassFixture; + [UsedImplicitly] public sealed class Oracle23Scott(Oracle23FixtureScott fixture) : OracleContainerTest(fixture), IClassFixture; + + [UsedImplicitly] public class OracleDefaultFixture(IMessageSink messageSink) : OracleFixture(messageSink, default, default); + [UsedImplicitly] public class Oracle11Fixture(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 11); + [UsedImplicitly] public class Oracle18Fixture(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 18); + [UsedImplicitly] public class Oracle21Fixture(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 21); + [UsedImplicitly] public class Oracle23Fixture(IMessageSink messageSink) : OracleFixture(messageSink, "free", 23); + [UsedImplicitly] public class Oracle18FixtureDefault(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 18, "XEPDB1"); + [UsedImplicitly] public class Oracle21FixtureDefault(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 21, "XEPDB1"); + [UsedImplicitly] public class Oracle23FixtureDefault(IMessageSink messageSink) : OracleFixture(messageSink, "free", 23, "FREEPDB1"); + [UsedImplicitly] public class Oracle18FixtureScott(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 18, "SCOTT"); + [UsedImplicitly] public class Oracle21FixtureScott(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 21, "SCOTT"); + [UsedImplicitly] public class Oracle23FixtureScott(IMessageSink messageSink) : OracleFixture(messageSink, "free", 23, "SCOTT"); } \ No newline at end of file diff --git a/tests/Testcontainers.Oracle.Tests/Usings.cs b/tests/Testcontainers.Oracle.Tests/Usings.cs index 376b8566a..e1e61a204 100644 --- a/tests/Testcontainers.Oracle.Tests/Usings.cs +++ b/tests/Testcontainers.Oracle.Tests/Usings.cs @@ -2,6 +2,7 @@ global using System.Data.Common; global using System.Threading.Tasks; global using DotNet.Testcontainers.Commons; +global using JetBrains.Annotations; global using Oracle.ManagedDataAccess.Client; global using Testcontainers.Xunit; global using Xunit;