From 3bc56e30152bfd66b09bd5055c098bbe98471f32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Luthi?= Date: Fri, 20 Dec 2024 17:44:27 +0100 Subject: [PATCH 1/6] Use Testcontainers.Xunit in Oracle tests --- .../OracleContainerTest.cs | 24 +++++++------------ .../Testcontainers.Oracle.Tests.csproj | 1 + tests/Testcontainers.Oracle.Tests/Usings.cs | 5 +++- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs b/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs index 5b6984dd0..a929cc265 100644 --- a/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs +++ b/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs @@ -1,25 +1,13 @@ namespace Testcontainers.Oracle; -public sealed class OracleContainerTest : IAsyncLifetime +public sealed class OracleContainerTest(OracleContainerTest.OracleFixture oracleFixture) : IClassFixture { - private readonly OracleContainer _oracleContainer = new OracleBuilder().Build(); - - public Task InitializeAsync() - { - return _oracleContainer.StartAsync(); - } - - public Task DisposeAsync() - { - return _oracleContainer.DisposeAsync().AsTask(); - } - [Fact] [Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))] public void ConnectionStateReturnsOpen() { // Given - using DbConnection connection = new OracleConnection(_oracleContainer.GetConnectionString()); + using DbConnection connection = oracleFixture.CreateConnection(); // When connection.Open(); @@ -36,11 +24,17 @@ public async Task ExecScriptReturnsSuccessful() const string scriptContent = "SELECT 1 FROM DUAL;"; // When - var execResult = await _oracleContainer.ExecScriptAsync(scriptContent) + var execResult = await oracleFixture.Container.ExecScriptAsync(scriptContent) .ConfigureAwait(true); // Then Assert.True(0L.Equals(execResult.ExitCode), execResult.Stderr); Assert.Empty(execResult.Stderr); } + + [UsedImplicitly] + public class OracleFixture(IMessageSink messageSink) : DbContainerFixture(messageSink) + { + public override DbProviderFactory DbProviderFactory => OracleClientFactory.Instance; + } } \ No newline at end of file diff --git a/tests/Testcontainers.Oracle.Tests/Testcontainers.Oracle.Tests.csproj b/tests/Testcontainers.Oracle.Tests/Testcontainers.Oracle.Tests.csproj index 4d619cd84..264c5af93 100644 --- a/tests/Testcontainers.Oracle.Tests/Testcontainers.Oracle.Tests.csproj +++ b/tests/Testcontainers.Oracle.Tests/Testcontainers.Oracle.Tests.csproj @@ -13,6 +13,7 @@ + \ No newline at end of file diff --git a/tests/Testcontainers.Oracle.Tests/Usings.cs b/tests/Testcontainers.Oracle.Tests/Usings.cs index eb37bd7e3..e1e61a204 100644 --- a/tests/Testcontainers.Oracle.Tests/Usings.cs +++ b/tests/Testcontainers.Oracle.Tests/Usings.cs @@ -2,5 +2,8 @@ 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 Xunit; \ No newline at end of file +global using Testcontainers.Xunit; +global using Xunit; +global using Xunit.Abstractions; \ No newline at end of file From 3485e6d1e35a000eeaeffec05a707766e1edceaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Luthi?= Date: Fri, 20 Dec 2024 17:50:09 +0100 Subject: [PATCH 2/6] Improve Oracle support Use the correct database default name depending on the Docker image version and enable setting a custom database name for Oracle 18 and onwards. Fixes #1233 --- Directory.Packages.props | 2 +- src/Testcontainers.Oracle/OracleBuilder.cs | 54 ++++++++++++++----- .../OracleContainerTest.cs | 40 ++++++++++++-- 3 files changed, 78 insertions(+), 18 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index cc102df63..3f4c27a11 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -64,7 +64,7 @@ - + diff --git a/src/Testcontainers.Oracle/OracleBuilder.cs b/src/Testcontainers.Oracle/OracleBuilder.cs index c5cd3339e..c259f103e 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,55 @@ 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) + { + return Merge(DockerResourceConfiguration, new OracleConfiguration(database: database)); + } + /// public override OracleContainer Build() { Validate(); + + var defaultServiceName = GetDefaultServiceName(); + if (DockerResourceConfiguration.Database == null) + { + return new OracleContainer(WithDatabase(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!")); @@ -86,6 +122,9 @@ protected override void Validate() _ = Guard.Argument(DockerResourceConfiguration.Password, nameof(DockerResourceConfiguration.Password)) .NotNull() .NotEmpty(); + + if (DockerResourceConfiguration.Database != null && DockerResourceConfiguration.Image.MatchVersion(v => v.Major < 18)) + throw new NotSupportedException($"Setting the database is not supported with {DockerResourceConfiguration.Image.FullName}. It is only supported on Oracle 18 and onwards."); } /// @@ -105,17 +144,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 a929cc265..21c82f48b 100644 --- a/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs +++ b/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs @@ -1,6 +1,6 @@ namespace Testcontainers.Oracle; -public sealed class OracleContainerTest(OracleContainerTest.OracleFixture oracleFixture) : IClassFixture +public abstract class OracleContainerTest(OracleContainerTest.OracleFixture oracleFixture) { [Fact] [Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))] @@ -32,9 +32,43 @@ public async Task ExecScriptReturnsSuccessful() Assert.Empty(execResult.Stderr); } - [UsedImplicitly] - public class OracleFixture(IMessageSink messageSink) : DbContainerFixture(messageSink) + public abstract 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 == null && version == null) + { + 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, null, null); + [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 From 588f89bc9a0be1b2d298b14df00f6e62554a655b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Luthi?= Date: Fri, 14 Feb 2025 17:04:27 +0100 Subject: [PATCH 3/6] Split Oracle test projects In order to avoid "No space left on device" error on GitHub actions --- .github/workflows/cicd.yml | 4 ++ Testcontainers.sln | 28 +++++++++++++ .../OracleContainerTest.cs | 42 +++++++++++++------ .../Testcontainers.Oracle.Tests.csproj | 1 + .../Testcontainers.Oracle11.Tests.csproj | 23 ++++++++++ .../.editorconfig | 1 + .../Testcontainers.Oracle18.Tests.csproj | 23 ++++++++++ .../.editorconfig | 1 + .../Testcontainers.Oracle21.Tests.csproj | 23 ++++++++++ .../.editorconfig | 1 + .../Testcontainers.Oracle23.Tests.csproj | 23 ++++++++++ 11 files changed, 158 insertions(+), 12 deletions(-) create mode 100644 tests/Testcontainers.Oracle11.Tests/Testcontainers.Oracle11.Tests.csproj create mode 100644 tests/Testcontainers.Oracle18.Tests/.editorconfig create mode 100644 tests/Testcontainers.Oracle18.Tests/Testcontainers.Oracle18.Tests.csproj create mode 100644 tests/Testcontainers.Oracle21.Tests/.editorconfig create mode 100644 tests/Testcontainers.Oracle21.Tests/Testcontainers.Oracle21.Tests.csproj create mode 100644 tests/Testcontainers.Oracle23.Tests/.editorconfig create mode 100644 tests/Testcontainers.Oracle23.Tests/Testcontainers.Oracle23.Tests.csproj diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 80f7cbee3..cdbf3a9b5 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -70,6 +70,10 @@ jobs: { name: "Testcontainers.Nats", runs-on: "ubuntu-22.04" }, { name: "Testcontainers.Neo4j", runs-on: "ubuntu-22.04" }, { name: "Testcontainers.Oracle", runs-on: "ubuntu-22.04" }, + { name: "Testcontainers.Oracle11", runs-on: "ubuntu-22.04" }, + { name: "Testcontainers.Oracle18", runs-on: "ubuntu-22.04" }, + { name: "Testcontainers.Oracle21", runs-on: "ubuntu-22.04" }, + { name: "Testcontainers.Oracle23", runs-on: "ubuntu-22.04" }, { name: "Testcontainers.Papercut", runs-on: "ubuntu-22.04" }, { name: "Testcontainers.PostgreSql", runs-on: "ubuntu-22.04" }, { name: "Testcontainers.PubSub", runs-on: "ubuntu-22.04" }, diff --git a/Testcontainers.sln b/Testcontainers.sln index 4afa799e9..0bdf6fc5b 100644 --- a/Testcontainers.sln +++ b/Testcontainers.sln @@ -179,6 +179,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Neo4j.Tests" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Oracle.Tests", "tests\Testcontainers.Oracle.Tests\Testcontainers.Oracle.Tests.csproj", "{4AC1088B-9965-4497-AC8E-570F1AD5631F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Oracle11.Tests", "tests\Testcontainers.Oracle11.Tests\Testcontainers.Oracle11.Tests.csproj", "{0A0AC20D-226B-46F9-B267-0D00964A7601}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Oracle18.Tests", "tests\Testcontainers.Oracle18.Tests\Testcontainers.Oracle18.Tests.csproj", "{E4C887A9-A44A-4641-BB9B-0664CC4C362F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Oracle21.Tests", "tests\Testcontainers.Oracle21.Tests\Testcontainers.Oracle21.Tests.csproj", "{1F6415BD-646E-436A-9F57-9AE30A0AA694}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Oracle23.Tests", "tests\Testcontainers.Oracle23.Tests\Testcontainers.Oracle23.Tests.csproj", "{FC417A93-4521-4FDB-943E-23886F3243C8}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Papercut.Tests", "tests\Testcontainers.Papercut.Tests\Testcontainers.Papercut.Tests.csproj", "{F03FA970-BE2B-4AE2-96FE-7E1F805CEA20}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Platform.Linux.Tests", "tests\Testcontainers.Platform.Linux.Tests\Testcontainers.Platform.Linux.Tests.csproj", "{DA1D7ADE-452C-4369-83CC-56289176EACD}" @@ -554,6 +562,22 @@ Global {4AC1088B-9965-4497-AC8E-570F1AD5631F}.Debug|Any CPU.Build.0 = Debug|Any CPU {4AC1088B-9965-4497-AC8E-570F1AD5631F}.Release|Any CPU.ActiveCfg = Release|Any CPU {4AC1088B-9965-4497-AC8E-570F1AD5631F}.Release|Any CPU.Build.0 = Release|Any CPU + {0A0AC20D-226B-46F9-B267-0D00964A7601}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0A0AC20D-226B-46F9-B267-0D00964A7601}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0A0AC20D-226B-46F9-B267-0D00964A7601}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0A0AC20D-226B-46F9-B267-0D00964A7601}.Release|Any CPU.Build.0 = Release|Any CPU + {E4C887A9-A44A-4641-BB9B-0664CC4C362F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E4C887A9-A44A-4641-BB9B-0664CC4C362F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E4C887A9-A44A-4641-BB9B-0664CC4C362F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E4C887A9-A44A-4641-BB9B-0664CC4C362F}.Release|Any CPU.Build.0 = Release|Any CPU + {1F6415BD-646E-436A-9F57-9AE30A0AA694}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1F6415BD-646E-436A-9F57-9AE30A0AA694}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1F6415BD-646E-436A-9F57-9AE30A0AA694}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1F6415BD-646E-436A-9F57-9AE30A0AA694}.Release|Any CPU.Build.0 = Release|Any CPU + {FC417A93-4521-4FDB-943E-23886F3243C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FC417A93-4521-4FDB-943E-23886F3243C8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FC417A93-4521-4FDB-943E-23886F3243C8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FC417A93-4521-4FDB-943E-23886F3243C8}.Release|Any CPU.Build.0 = Release|Any CPU {F03FA970-BE2B-4AE2-96FE-7E1F805CEA20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F03FA970-BE2B-4AE2-96FE-7E1F805CEA20}.Debug|Any CPU.Build.0 = Debug|Any CPU {F03FA970-BE2B-4AE2-96FE-7E1F805CEA20}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -707,6 +731,10 @@ Global {87A3F137-6DC3-4CE5-91E6-01797D076086} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF} {D3F63405-C0FA-4F83-8B79-E30BFF5FF5BF} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF} {4AC1088B-9965-4497-AC8E-570F1AD5631F} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF} + {0A0AC20D-226B-46F9-B267-0D00964A7601} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF} + {E4C887A9-A44A-4641-BB9B-0664CC4C362F} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF} + {1F6415BD-646E-436A-9F57-9AE30A0AA694} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF} + {FC417A93-4521-4FDB-943E-23886F3243C8} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF} {F03FA970-BE2B-4AE2-96FE-7E1F805CEA20} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF} {DA1D7ADE-452C-4369-83CC-56289176EACD} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF} {3E55CBE8-AFE8-426D-9470-49D63CD1051C} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF} diff --git a/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs b/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs index 21c82f48b..89fe7362e 100644 --- a/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs +++ b/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs @@ -48,27 +48,45 @@ protected override OracleBuilder Configure(OracleBuilder builder) } } +#if ORACLE_DEFAULT [UsedImplicitly] public sealed class OracleDefault(OracleDefaultFixture fixture) : OracleContainerTest(fixture), IClassFixture; + + [UsedImplicitly] public class OracleDefaultFixture(IMessageSink messageSink) : OracleFixture(messageSink, null, null); +#endif + +#if ORACLE_11 [UsedImplicitly] public sealed class Oracle11(Oracle11Fixture fixture) : OracleContainerTest(fixture), IClassFixture; + + [UsedImplicitly] public class Oracle11Fixture(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 11); +#endif + +#if ORACLE_18 [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, null, null); - [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"); +#endif + +#if ORACLE_21 + [UsedImplicitly] public sealed class Oracle21(Oracle21Fixture fixture) : OracleContainerTest(fixture), IClassFixture; + [UsedImplicitly] public sealed class Oracle21Default(Oracle21FixtureDefault fixture) : OracleContainerTest(fixture), IClassFixture; + [UsedImplicitly] public sealed class Oracle21Scott(Oracle21FixtureScott fixture) : OracleContainerTest(fixture), IClassFixture; + + [UsedImplicitly] public class Oracle21Fixture(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 21); + [UsedImplicitly] public class Oracle21FixtureDefault(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 21, "XEPDB1"); [UsedImplicitly] public class Oracle21FixtureScott(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 21, "SCOTT"); +#endif + +#if ORACLE_23 + [UsedImplicitly] public sealed class Oracle23(Oracle23Fixture fixture) : OracleContainerTest(fixture), IClassFixture; + [UsedImplicitly] public sealed class Oracle23Default(Oracle23FixtureDefault fixture) : OracleContainerTest(fixture), IClassFixture; + [UsedImplicitly] public sealed class Oracle23Scott(Oracle23FixtureScott fixture) : OracleContainerTest(fixture), IClassFixture; + + [UsedImplicitly] public class Oracle23Fixture(IMessageSink messageSink) : OracleFixture(messageSink, "free", 23); + [UsedImplicitly] public class Oracle23FixtureDefault(IMessageSink messageSink) : OracleFixture(messageSink, "free", 23, "FREEPDB1"); [UsedImplicitly] public class Oracle23FixtureScott(IMessageSink messageSink) : OracleFixture(messageSink, "free", 23, "SCOTT"); +#endif } \ No newline at end of file diff --git a/tests/Testcontainers.Oracle.Tests/Testcontainers.Oracle.Tests.csproj b/tests/Testcontainers.Oracle.Tests/Testcontainers.Oracle.Tests.csproj index 264c5af93..307836309 100644 --- a/tests/Testcontainers.Oracle.Tests/Testcontainers.Oracle.Tests.csproj +++ b/tests/Testcontainers.Oracle.Tests/Testcontainers.Oracle.Tests.csproj @@ -3,6 +3,7 @@ net9.0 false false + $(DefineConstants);ORACLE_DEFAULT diff --git a/tests/Testcontainers.Oracle11.Tests/Testcontainers.Oracle11.Tests.csproj b/tests/Testcontainers.Oracle11.Tests/Testcontainers.Oracle11.Tests.csproj new file mode 100644 index 000000000..e743dd72a --- /dev/null +++ b/tests/Testcontainers.Oracle11.Tests/Testcontainers.Oracle11.Tests.csproj @@ -0,0 +1,23 @@ + + + net9.0 + false + false + $(DefineConstants);ORACLE_11 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Testcontainers.Oracle18.Tests/.editorconfig b/tests/Testcontainers.Oracle18.Tests/.editorconfig new file mode 100644 index 000000000..6f066619d --- /dev/null +++ b/tests/Testcontainers.Oracle18.Tests/.editorconfig @@ -0,0 +1 @@ +root = true \ No newline at end of file diff --git a/tests/Testcontainers.Oracle18.Tests/Testcontainers.Oracle18.Tests.csproj b/tests/Testcontainers.Oracle18.Tests/Testcontainers.Oracle18.Tests.csproj new file mode 100644 index 000000000..c57c010ee --- /dev/null +++ b/tests/Testcontainers.Oracle18.Tests/Testcontainers.Oracle18.Tests.csproj @@ -0,0 +1,23 @@ + + + net9.0 + false + false + $(DefineConstants);ORACLE_18 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Testcontainers.Oracle21.Tests/.editorconfig b/tests/Testcontainers.Oracle21.Tests/.editorconfig new file mode 100644 index 000000000..6f066619d --- /dev/null +++ b/tests/Testcontainers.Oracle21.Tests/.editorconfig @@ -0,0 +1 @@ +root = true \ No newline at end of file diff --git a/tests/Testcontainers.Oracle21.Tests/Testcontainers.Oracle21.Tests.csproj b/tests/Testcontainers.Oracle21.Tests/Testcontainers.Oracle21.Tests.csproj new file mode 100644 index 000000000..a811742b4 --- /dev/null +++ b/tests/Testcontainers.Oracle21.Tests/Testcontainers.Oracle21.Tests.csproj @@ -0,0 +1,23 @@ + + + net9.0 + false + false + $(DefineConstants);ORACLE_21 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/Testcontainers.Oracle23.Tests/.editorconfig b/tests/Testcontainers.Oracle23.Tests/.editorconfig new file mode 100644 index 000000000..6f066619d --- /dev/null +++ b/tests/Testcontainers.Oracle23.Tests/.editorconfig @@ -0,0 +1 @@ +root = true \ No newline at end of file diff --git a/tests/Testcontainers.Oracle23.Tests/Testcontainers.Oracle23.Tests.csproj b/tests/Testcontainers.Oracle23.Tests/Testcontainers.Oracle23.Tests.csproj new file mode 100644 index 000000000..cd1f8448b --- /dev/null +++ b/tests/Testcontainers.Oracle23.Tests/Testcontainers.Oracle23.Tests.csproj @@ -0,0 +1,23 @@ + + + net9.0 + false + false + $(DefineConstants);ORACLE_23 + + + + + + + + + + + + + + + + + \ No newline at end of file From a311829e34c28af86325bbb11a13aedf6864ed2a Mon Sep 17 00:00:00 2001 From: Andre Hofmeister <9199345+HofmeisterAn@users.noreply.github.com> Date: Sat, 15 Feb 2025 12:26:27 +0100 Subject: [PATCH 4/6] chore: Apply minor repo standards --- src/Testcontainers.Oracle/OracleBuilder.cs | 69 +++++++++++-------- .../OracleContainerTest.cs | 27 +++----- .../Testcontainers.Oracle.Tests.csproj | 2 +- .../.editorconfig | 1 + .../Testcontainers.Oracle11.Tests.csproj | 4 +- .../Testcontainers.Oracle18.Tests.csproj | 4 +- .../Testcontainers.Oracle21.Tests.csproj | 4 +- .../Testcontainers.Oracle23.Tests.csproj | 4 +- 8 files changed, 62 insertions(+), 53 deletions(-) create mode 100644 tests/Testcontainers.Oracle11.Tests/.editorconfig diff --git a/src/Testcontainers.Oracle/OracleBuilder.cs b/src/Testcontainers.Oracle/OracleBuilder.cs index c259f103e..e6c5710b5 100644 --- a/src/Testcontainers.Oracle/OracleBuilder.cs +++ b/src/Testcontainers.Oracle/OracleBuilder.cs @@ -8,7 +8,7 @@ public sealed class OracleBuilder : ContainerBuilder 11 and < 23")] + [Obsolete("This constant is obsolete and should not be used. It is only applicable for Oracle images between versions 11 and 22.")] public const string DefaultDatabase = "XEPDB1"; public const string DefaultUsername = "oracle"; @@ -37,6 +37,19 @@ private OracleBuilder(OracleConfiguration resourceConfiguration) /// protected override OracleConfiguration DockerResourceConfiguration { get; } + /// + /// 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) + { + return Merge(DockerResourceConfiguration, new OracleConfiguration(database: database)); + } + /// /// Sets the Oracle username. /// @@ -60,19 +73,6 @@ 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) - { - return Merge(DockerResourceConfiguration, new OracleConfiguration(database: database)); - } - /// public override OracleContainer Build() { @@ -92,17 +92,6 @@ public override OracleContainer Build() 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() { @@ -119,12 +108,21 @@ protected override void Validate() { base.Validate(); - _ = Guard.Argument(DockerResourceConfiguration.Password, nameof(DockerResourceConfiguration.Password)) + const string message = "The image '{0}' does not support configuring the database. It is only supported on Oracle 18 and onwards."; + + Predicate databaseConfigurationNotSupported = value => + value.Database != null && value.Image.MatchVersion(v => v.Major < 18); + + _ = Guard.Argument(DockerResourceConfiguration, nameof(DockerResourceConfiguration.Database)) + .ThrowIf(argument => databaseConfigurationNotSupported(argument.Value), _ => throw new NotSupportedException(string.Format(message, DockerResourceConfiguration.Image.FullName))); + + _ = Guard.Argument(DockerResourceConfiguration.Username, nameof(DockerResourceConfiguration.Username)) .NotNull() .NotEmpty(); - if (DockerResourceConfiguration.Database != null && DockerResourceConfiguration.Image.MatchVersion(v => v.Major < 18)) - throw new NotSupportedException($"Setting the database is not supported with {DockerResourceConfiguration.Image.FullName}. It is only supported on Oracle 18 and onwards."); + _ = Guard.Argument(DockerResourceConfiguration.Password, nameof(DockerResourceConfiguration.Password)) + .NotNull() + .NotEmpty(); } /// @@ -144,4 +142,19 @@ protected override OracleBuilder Merge(OracleConfiguration oldValue, OracleConfi { return new OracleBuilder(new OracleConfiguration(oldValue, newValue)); } + + 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"; + } } \ No newline at end of file diff --git a/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs b/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs index 89fe7362e..e0bf81335 100644 --- a/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs +++ b/tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs @@ -50,43 +50,38 @@ protected override OracleBuilder Configure(OracleBuilder builder) #if ORACLE_DEFAULT [UsedImplicitly] public sealed class OracleDefault(OracleDefaultFixture fixture) : OracleContainerTest(fixture), IClassFixture; - - [UsedImplicitly] public class OracleDefaultFixture(IMessageSink messageSink) : OracleFixture(messageSink, null, null); + [UsedImplicitly] public sealed class OracleDefaultFixture(IMessageSink messageSink) : OracleFixture(messageSink, null, null); #endif #if ORACLE_11 [UsedImplicitly] public sealed class Oracle11(Oracle11Fixture fixture) : OracleContainerTest(fixture), IClassFixture; - - [UsedImplicitly] public class Oracle11Fixture(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 11); + [UsedImplicitly] public sealed class Oracle11Fixture(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 11); #endif #if ORACLE_18 [UsedImplicitly] public sealed class Oracle18(Oracle18Fixture fixture) : OracleContainerTest(fixture), IClassFixture; [UsedImplicitly] public sealed class Oracle18Default(Oracle18FixtureDefault fixture) : OracleContainerTest(fixture), IClassFixture; [UsedImplicitly] public sealed class Oracle18Scott(Oracle18FixtureScott fixture) : OracleContainerTest(fixture), IClassFixture; - - [UsedImplicitly] public class Oracle18Fixture(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 18); - [UsedImplicitly] public class Oracle18FixtureDefault(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 18, "XEPDB1"); - [UsedImplicitly] public class Oracle18FixtureScott(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 18, "SCOTT"); + [UsedImplicitly] public sealed class Oracle18Fixture(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 18); + [UsedImplicitly] public sealed class Oracle18FixtureDefault(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 18, "XEPDB1"); + [UsedImplicitly] public sealed class Oracle18FixtureScott(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 18, "SCOTT"); #endif #if ORACLE_21 [UsedImplicitly] public sealed class Oracle21(Oracle21Fixture fixture) : OracleContainerTest(fixture), IClassFixture; [UsedImplicitly] public sealed class Oracle21Default(Oracle21FixtureDefault fixture) : OracleContainerTest(fixture), IClassFixture; [UsedImplicitly] public sealed class Oracle21Scott(Oracle21FixtureScott fixture) : OracleContainerTest(fixture), IClassFixture; - - [UsedImplicitly] public class Oracle21Fixture(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 21); - [UsedImplicitly] public class Oracle21FixtureDefault(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 21, "XEPDB1"); - [UsedImplicitly] public class Oracle21FixtureScott(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 21, "SCOTT"); + [UsedImplicitly] public sealed class Oracle21Fixture(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 21); + [UsedImplicitly] public sealed class Oracle21FixtureDefault(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 21, "XEPDB1"); + [UsedImplicitly] public sealed class Oracle21FixtureScott(IMessageSink messageSink) : OracleFixture(messageSink, "xe", 21, "SCOTT"); #endif #if ORACLE_23 [UsedImplicitly] public sealed class Oracle23(Oracle23Fixture fixture) : OracleContainerTest(fixture), IClassFixture; [UsedImplicitly] public sealed class Oracle23Default(Oracle23FixtureDefault fixture) : OracleContainerTest(fixture), IClassFixture; [UsedImplicitly] public sealed class Oracle23Scott(Oracle23FixtureScott fixture) : OracleContainerTest(fixture), IClassFixture; - - [UsedImplicitly] public class Oracle23Fixture(IMessageSink messageSink) : OracleFixture(messageSink, "free", 23); - [UsedImplicitly] public class Oracle23FixtureDefault(IMessageSink messageSink) : OracleFixture(messageSink, "free", 23, "FREEPDB1"); - [UsedImplicitly] public class Oracle23FixtureScott(IMessageSink messageSink) : OracleFixture(messageSink, "free", 23, "SCOTT"); + [UsedImplicitly] public sealed class Oracle23Fixture(IMessageSink messageSink) : OracleFixture(messageSink, "free", 23); + [UsedImplicitly] public sealed class Oracle23FixtureDefault(IMessageSink messageSink) : OracleFixture(messageSink, "free", 23, "FREEPDB1"); + [UsedImplicitly] public sealed class Oracle23FixtureScott(IMessageSink messageSink) : OracleFixture(messageSink, "free", 23, "SCOTT"); #endif } \ No newline at end of file diff --git a/tests/Testcontainers.Oracle.Tests/Testcontainers.Oracle.Tests.csproj b/tests/Testcontainers.Oracle.Tests/Testcontainers.Oracle.Tests.csproj index 307836309..914e234f4 100644 --- a/tests/Testcontainers.Oracle.Tests/Testcontainers.Oracle.Tests.csproj +++ b/tests/Testcontainers.Oracle.Tests/Testcontainers.Oracle.Tests.csproj @@ -14,7 +14,7 @@ - + \ No newline at end of file diff --git a/tests/Testcontainers.Oracle11.Tests/.editorconfig b/tests/Testcontainers.Oracle11.Tests/.editorconfig new file mode 100644 index 000000000..6f066619d --- /dev/null +++ b/tests/Testcontainers.Oracle11.Tests/.editorconfig @@ -0,0 +1 @@ +root = true \ No newline at end of file diff --git a/tests/Testcontainers.Oracle11.Tests/Testcontainers.Oracle11.Tests.csproj b/tests/Testcontainers.Oracle11.Tests/Testcontainers.Oracle11.Tests.csproj index e743dd72a..3b6fae47e 100644 --- a/tests/Testcontainers.Oracle11.Tests/Testcontainers.Oracle11.Tests.csproj +++ b/tests/Testcontainers.Oracle11.Tests/Testcontainers.Oracle11.Tests.csproj @@ -14,10 +14,10 @@ - + - + \ No newline at end of file diff --git a/tests/Testcontainers.Oracle18.Tests/Testcontainers.Oracle18.Tests.csproj b/tests/Testcontainers.Oracle18.Tests/Testcontainers.Oracle18.Tests.csproj index c57c010ee..cdd26379a 100644 --- a/tests/Testcontainers.Oracle18.Tests/Testcontainers.Oracle18.Tests.csproj +++ b/tests/Testcontainers.Oracle18.Tests/Testcontainers.Oracle18.Tests.csproj @@ -14,10 +14,10 @@ - + - + \ No newline at end of file diff --git a/tests/Testcontainers.Oracle21.Tests/Testcontainers.Oracle21.Tests.csproj b/tests/Testcontainers.Oracle21.Tests/Testcontainers.Oracle21.Tests.csproj index a811742b4..a75f705bc 100644 --- a/tests/Testcontainers.Oracle21.Tests/Testcontainers.Oracle21.Tests.csproj +++ b/tests/Testcontainers.Oracle21.Tests/Testcontainers.Oracle21.Tests.csproj @@ -14,10 +14,10 @@ - + - + \ No newline at end of file diff --git a/tests/Testcontainers.Oracle23.Tests/Testcontainers.Oracle23.Tests.csproj b/tests/Testcontainers.Oracle23.Tests/Testcontainers.Oracle23.Tests.csproj index cd1f8448b..60f0cfc65 100644 --- a/tests/Testcontainers.Oracle23.Tests/Testcontainers.Oracle23.Tests.csproj +++ b/tests/Testcontainers.Oracle23.Tests/Testcontainers.Oracle23.Tests.csproj @@ -14,10 +14,10 @@ - + - + \ No newline at end of file From e17bd73ce6a9969e64aef44223e5426222a06546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Luthi?= Date: Sun, 16 Feb 2025 10:13:21 +0100 Subject: [PATCH 5/6] Always set the ORACLE_DATABASE environment variable Older images that don't support a custom database will simply ignore it. --- src/Testcontainers.Oracle/OracleBuilder.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Testcontainers.Oracle/OracleBuilder.cs b/src/Testcontainers.Oracle/OracleBuilder.cs index e6c5710b5..1382622e7 100644 --- a/src/Testcontainers.Oracle/OracleBuilder.cs +++ b/src/Testcontainers.Oracle/OracleBuilder.cs @@ -47,7 +47,8 @@ private OracleBuilder(OracleConfiguration resourceConfiguration) /// A configured instance of . public OracleBuilder WithDatabase(string database) { - return Merge(DockerResourceConfiguration, new OracleConfiguration(database: database)); + return Merge(DockerResourceConfiguration, new OracleConfiguration(database: database)) + .WithEnvironment("ORACLE_DATABASE", database); } /// @@ -84,11 +85,6 @@ public override OracleContainer Build() return new OracleContainer(WithDatabase(defaultServiceName).DockerResourceConfiguration); } - if (DockerResourceConfiguration.Database != defaultServiceName) - { - return new OracleContainer(WithEnvironment("ORACLE_DATABASE", DockerResourceConfiguration.Database).DockerResourceConfiguration); - } - return new OracleContainer(DockerResourceConfiguration); } From 9af66e27732650c6a8f5f7f5991f2b16f1c9d071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Luthi?= Date: Sun, 16 Feb 2025 17:11:53 +0100 Subject: [PATCH 6/6] Revert "Always set the ORACLE_DATABASE environment variable" This reverts commit e17bd73ce6a9969e64aef44223e5426222a06546. Container would fail to start with this error. > ORA-65012: Pluggable database FREEPDB1 already exists. --- src/Testcontainers.Oracle/OracleBuilder.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Testcontainers.Oracle/OracleBuilder.cs b/src/Testcontainers.Oracle/OracleBuilder.cs index 1382622e7..e6c5710b5 100644 --- a/src/Testcontainers.Oracle/OracleBuilder.cs +++ b/src/Testcontainers.Oracle/OracleBuilder.cs @@ -47,8 +47,7 @@ private OracleBuilder(OracleConfiguration resourceConfiguration) /// A configured instance of . public OracleBuilder WithDatabase(string database) { - return Merge(DockerResourceConfiguration, new OracleConfiguration(database: database)) - .WithEnvironment("ORACLE_DATABASE", database); + return Merge(DockerResourceConfiguration, new OracleConfiguration(database: database)); } /// @@ -85,6 +84,11 @@ public override OracleContainer Build() return new OracleContainer(WithDatabase(defaultServiceName).DockerResourceConfiguration); } + if (DockerResourceConfiguration.Database != defaultServiceName) + { + return new OracleContainer(WithEnvironment("ORACLE_DATABASE", DockerResourceConfiguration.Database).DockerResourceConfiguration); + } + return new OracleContainer(DockerResourceConfiguration); }