diff --git a/modules/oracle-free/src/main/java/org/testcontainers/oracle/OracleContainer.java b/modules/oracle-free/src/main/java/org/testcontainers/oracle/OracleContainer.java index 2080c24283b..471cb735b61 100644 --- a/modules/oracle-free/src/main/java/org/testcontainers/oracle/OracleContainer.java +++ b/modules/oracle-free/src/main/java/org/testcontainers/oracle/OracleContainer.java @@ -15,7 +15,7 @@ /** * Testcontainers implementation for Oracle Database Free. *

- * Supported image: {@code gvenzl/oracle-free} + * Supported images: {@code gvenzl/oracle-free}, {@code gvenzl/oracle-xe} *

* Exposed ports: 1521 */ @@ -25,6 +25,8 @@ public class OracleContainer extends JdbcDatabaseContainer { private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName.parse("gvenzl/oracle-free"); + private static final DockerImageName ORACLE_XE_IMAGE_NAME = DockerImageName.parse("gvenzl/oracle-xe"); + static final String DEFAULT_TAG = "slim"; static final String IMAGE = DEFAULT_IMAGE_NAME.getUnversionedPart(); @@ -40,6 +42,10 @@ public class OracleContainer extends JdbcDatabaseContainer { static final String DEFAULT_SID = "free"; + private static final String ORACLE_XE_DEFAULT_DATABASE_NAME = "xepdb1"; + + private static final String ORACLE_XE_DEFAULT_SID = "xe"; + static final String DEFAULT_SYSTEM_USER = "system"; static final String DEFAULT_SYS_USER = "sys"; @@ -52,6 +58,10 @@ public class OracleContainer extends JdbcDatabaseContainer { // Restricted user and database names private static final List ORACLE_SYSTEM_USERS = Arrays.asList(DEFAULT_SYSTEM_USER, DEFAULT_SYS_USER); + private String defaultDatabaseName = DEFAULT_DATABASE_NAME; + + private String defaultSid = DEFAULT_SID; + private String databaseName = DEFAULT_DATABASE_NAME; private String username = APP_USER; @@ -66,7 +76,12 @@ public OracleContainer(String dockerImageName) { public OracleContainer(final DockerImageName dockerImageName) { super(dockerImageName); - dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME); + dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME, ORACLE_XE_IMAGE_NAME); + if (dockerImageName.isCompatibleWith(ORACLE_XE_IMAGE_NAME)) { + defaultDatabaseName = ORACLE_XE_DEFAULT_DATABASE_NAME; + defaultSid = ORACLE_XE_DEFAULT_SID; + databaseName = defaultDatabaseName; + } waitingFor( Wait .forLogMessage(".*DATABASE IS READY TO USE!.*\\s", 1) @@ -151,8 +166,8 @@ public OracleContainer withDatabaseName(String databaseName) { throw new IllegalArgumentException("Database name cannot be null or empty"); } - if (DEFAULT_DATABASE_NAME.equals(databaseName.toLowerCase())) { - throw new IllegalArgumentException("Database name cannot be set to " + DEFAULT_DATABASE_NAME); + if (defaultDatabaseName.equals(databaseName.toLowerCase())) { + throw new IllegalArgumentException("Database name cannot be set to " + defaultDatabaseName); } this.databaseName = databaseName; @@ -169,9 +184,8 @@ public OracleContainer withUrlParam(String paramName, String paramValue) { throw new UnsupportedOperationException("The Oracle Database driver does not support this"); } - @SuppressWarnings("SameReturnValue") public String getSid() { - return DEFAULT_SID; + return defaultSid; } public Integer getOraclePort() { @@ -187,8 +201,8 @@ public String getTestQueryString() { protected void configure() { withEnv("ORACLE_PASSWORD", password); - // Only set ORACLE_DATABASE if different than the default. - if (databaseName != DEFAULT_DATABASE_NAME) { + // Only set ORACLE_DATABASE if different than the image default. + if (!defaultDatabaseName.equals(databaseName)) { withEnv("ORACLE_DATABASE", databaseName); } diff --git a/modules/oracle-free/src/test/java/org/testcontainers/oracle/OracleContainerTest.java b/modules/oracle-free/src/test/java/org/testcontainers/oracle/OracleContainerTest.java new file mode 100644 index 00000000000..ced14ba9a78 --- /dev/null +++ b/modules/oracle-free/src/test/java/org/testcontainers/oracle/OracleContainerTest.java @@ -0,0 +1,66 @@ +package org.testcontainers.oracle; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class OracleContainerTest { + + @Test + void acceptsOracleXeImage() { + assertThatCode(() -> new OracleContainer("gvenzl/oracle-xe:21-slim-faststart")).doesNotThrowAnyException(); + } + + @Test + void usesOracleXeConnectionDefaults() { + final OracleContainer container = new FixedAddressOracleContainer("gvenzl/oracle-xe:21-slim-faststart"); + + assertThat(container.getDatabaseName()).isEqualTo("xepdb1"); + assertThat(container.getSid()).isEqualTo("xe"); + assertThat(container.getJdbcUrl()).isEqualTo("jdbc:oracle:thin:@localhost:15210/xepdb1"); + assertThat(container.usingSid().getJdbcUrl()).isEqualTo("jdbc:oracle:thin:@localhost:15210:xe"); + } + + @Test + void keepsOracleFreeConnectionDefaults() { + final OracleContainer container = new FixedAddressOracleContainer("gvenzl/oracle-free:slim"); + + assertThat(container.getDatabaseName()).isEqualTo("freepdb1"); + assertThat(container.getSid()).isEqualTo("free"); + assertThat(container.getJdbcUrl()).isEqualTo("jdbc:oracle:thin:@localhost:15210/freepdb1"); + assertThat(container.usingSid().getJdbcUrl()).isEqualTo("jdbc:oracle:thin:@localhost:15210:free"); + } + + @Test + void preservesExplicitDatabaseNameForOracleXe() { + final OracleContainer container = new FixedAddressOracleContainer("gvenzl/oracle-xe:21-slim-faststart") + .withDatabaseName("custompdb"); + + assertThat(container.getDatabaseName()).isEqualTo("custompdb"); + assertThat(container.getJdbcUrl()).isEqualTo("jdbc:oracle:thin:@localhost:15210/custompdb"); + } + + @Test + void rejectsUnrelatedImage() { + assertThatThrownBy(() -> new OracleContainer("postgres:17")).isInstanceOf(IllegalStateException.class); + } + + private static final class FixedAddressOracleContainer extends OracleContainer { + + private FixedAddressOracleContainer(String dockerImageName) { + super(dockerImageName); + } + + @Override + public String getHost() { + return "localhost"; + } + + @Override + public Integer getMappedPort(int originalPort) { + return 15210; + } + } +}