Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ public class OracleContainer extends JdbcDatabaseContainer<OracleContainer> {

private String password = APP_USER_PASSWORD;

/**
* Password for Oracle system user (e.g. SYSTEM/SYS). Defaults to {@link #APP_USER_PASSWORD}
* for backwards compatibility, but can be customized independently via {@link #withOraclePassword(String)}.
*/
private String systemPassword = APP_USER_PASSWORD;

/**
* Tracks whether {@link #withOraclePassword(String)} was called to avoid overriding
* the system password when {@link #withPassword(String)} is used for the application user only.
*/
private boolean systemPasswordExplicitlySet = false;

private boolean usingSid = false;

public OracleContainer(String dockerImageName) {
Expand Down Expand Up @@ -112,7 +124,8 @@ public String getUsername() {

@Override
public String getPassword() {
return password;
// When connecting via SID we authenticate as SYSTEM. Use the dedicated system password.
return isUsingSid() ? systemPassword : password;
}

@Override
Expand Down Expand Up @@ -142,6 +155,27 @@ public OracleContainer withPassword(String password) {
throw new IllegalArgumentException("Password cannot be null or empty");
}
this.password = password;
// Maintain backwards compatibility: if system password wasn't set explicitly,
// align it with the application user's password.
if (!systemPasswordExplicitlySet) {
this.systemPassword = password;
}
return self();
}

/**
* Sets the password for the Oracle system user (SYSTEM/SYS). This is independent from the
* application user password set via {@link #withPassword(String)}.
*
* @param systemPassword password for SYSTEM/SYS users inside the container
* @return this container instance
*/
public OracleContainer withOraclePassword(String systemPassword) {
if (StringUtils.isEmpty(systemPassword)) {
throw new IllegalArgumentException("Oracle password cannot be null or empty");
}
this.systemPassword = systemPassword;
this.systemPasswordExplicitlySet = true;
return self();
}

Expand Down Expand Up @@ -185,7 +219,8 @@ public String getTestQueryString() {

@Override
protected void configure() {
withEnv("ORACLE_PASSWORD", password);
// Configure system user password independently from application user's password
withEnv("ORACLE_PASSWORD", systemPassword);

// Only set ORACLE_DATABASE if different than the default.
if (databaseName != DEFAULT_DATABASE_NAME) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,24 @@ private void runTest(OracleContainer container, String databaseName, String user
assertThat(resultSetInt).as("A basic SELECT query succeeds").isEqualTo(1);
}

private void runTestSystemUser(OracleContainer container, String databaseName, String username, String password)
throws SQLException {
//Test config was honored
assertThat(container.getDatabaseName()).isEqualTo(databaseName);
assertThat(container.getUsername()).isEqualTo(username);
assertThat(container.getPassword()).isEqualTo(password);

//Test we can get a connection and verify current user
container.start();

// Verify we are connected as the system user
ResultSet resultSet = performQuery(container, "SELECT USER FROM DUAL");
String currentUser = resultSet.getString(1);
assertThat(currentUser)
.as("Connected session should run as the system user")
.isEqualToIgnoringCase(username);
}

@Test
void testDefaultSettings() throws SQLException {
try ( // container {
Expand Down Expand Up @@ -78,7 +96,7 @@ void testCustomUser() throws SQLException {
@Test
void testSID() throws SQLException {
try (OracleContainer oracle = new OracleContainer(ORACLE_DOCKER_IMAGE_NAME).usingSid()) {
runTest(oracle, "freepdb1", "system", "test");
runTestSystemUser(oracle, "freepdb1", "system", "test");

// Match against the last ':'
String urlSuffix = oracle.getJdbcUrl().split("(\\:)(?!.*\\:)", 2)[1];
Expand All @@ -93,7 +111,30 @@ void testSIDAndCustomPassword() throws SQLException {
.usingSid()
.withPassword("testPassword")
) {
runTest(oracle, "freepdb1", "system", "testPassword");
runTestSystemUser(oracle, "freepdb1", "system", "testPassword");
}
}

@Test
public void testWithSystemPassword() throws SQLException {
try (
OracleContainer oracle = new OracleContainer(ORACLE_DOCKER_IMAGE_NAME)
.usingSid()
.withOraclePassword("SysP@ss1!")
.withPassword("AppP@ss1!")
) {
runTestSystemUser(oracle, "freepdb1", "system", "SysP@ss1!");
}
}

@Test
public void testWithPassword() throws SQLException {
try (
OracleContainer oracle = new OracleContainer(ORACLE_DOCKER_IMAGE_NAME)
.withOraclePassword("SysP@ss2!")
.withPassword("AppP@ss2!")
) {
runTest(oracle, "freepdb1", "test", "AppP@ss2!");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ public class OracleContainer extends JdbcDatabaseContainer<OracleContainer> {

private String password = APP_USER_PASSWORD;

/**
* Password for Oracle system user (e.g. SYSTEM/SYS). Defaults to {@link #APP_USER_PASSWORD}
* for backwards compatibility, but can be customized independently via {@link #withOraclePassword(String)}.
*/
private String systemPassword = APP_USER_PASSWORD;

/**
* Tracks whether {@link #withOraclePassword(String)} was called to avoid overriding
* the system password when {@link #withPassword(String)} is used for the application user only.
*/
private boolean systemPasswordExplicitlySet = false;

private boolean usingSid = false;

/**
Expand Down Expand Up @@ -133,7 +145,8 @@ public String getUsername() {

@Override
public String getPassword() {
return password;
// When connecting via SID we authenticate as SYSTEM. Use the dedicated system password.
return isUsingSid() ? systemPassword : password;
}

@Override
Expand Down Expand Up @@ -163,6 +176,27 @@ public OracleContainer withPassword(String password) {
throw new IllegalArgumentException("Password cannot be null or empty");
}
this.password = password;
// Maintain backwards compatibility: if system password wasn't set explicitly,
// align it with the application user's password.
if (!systemPasswordExplicitlySet) {
this.systemPassword = password;
}
return self();
}

/**
* Sets the password for the Oracle system user (SYSTEM/SYS). This is independent from the
* application user password set via {@link #withPassword(String)}.
*
* @param systemPassword password for SYSTEM/SYS users inside the container
* @return this container instance
*/
public OracleContainer withOraclePassword(String systemPassword) {
if (StringUtils.isEmpty(systemPassword)) {
throw new IllegalArgumentException("Oracle password cannot be null or empty");
}
this.systemPassword = systemPassword;
this.systemPasswordExplicitlySet = true;
return self();
}

Expand Down Expand Up @@ -211,7 +245,8 @@ public String getTestQueryString() {

@Override
protected void configure() {
withEnv("ORACLE_PASSWORD", password);
// Configure system user password independently from application user's password
withEnv("ORACLE_PASSWORD", systemPassword);

// Only set ORACLE_DATABASE if different than the default.
if (databaseName != DEFAULT_DATABASE_NAME) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ private void runTest(OracleContainer container, String databaseName, String user
assertThat(resultSetInt).as("A basic SELECT query succeeds").isEqualTo(1);
}

private void runTestSystemUser(OracleContainer container, String databaseName, String username, String password)
throws SQLException {
assertThat(container.getDatabaseName()).isEqualTo(databaseName);
assertThat(container.getUsername()).isEqualTo(username);
assertThat(container.getPassword()).isEqualTo(password);

container.start();

// Verify we are connected as the system user
ResultSet resultSet = performQuery(container, "SELECT USER FROM DUAL");
String currentUser = resultSet.getString(1);
assertThat(currentUser)
.as("Connected session should run as the system user")
.isEqualToIgnoringCase(username);
}

@Test
void testDefaultSettings() throws SQLException {
try ( // container {
Expand Down Expand Up @@ -78,7 +94,7 @@ void testCustomUser() throws SQLException {
@Test
void testSID() throws SQLException {
try (OracleContainer oracle = new OracleContainer(ORACLE_DOCKER_IMAGE_NAME).usingSid();) {
runTest(oracle, "xepdb1", "system", "test");
runTestSystemUser(oracle, "xepdb1", "system", "test");

// Match against the last ':'
String urlSuffix = oracle.getJdbcUrl().split("(\\:)(?!.*\\:)", 2)[1];
Expand All @@ -93,7 +109,28 @@ void testSIDAndCustomPassword() throws SQLException {
.usingSid()
.withPassword("testPassword");
) {
runTest(oracle, "xepdb1", "system", "testPassword");
runTestSystemUser(oracle, "xepdb1", "system", "testPassword");
}
}

@Test
public void testSeparateSystemAndAppPasswords() throws SQLException {
try (
OracleContainer oracleSid = new OracleContainer(ORACLE_DOCKER_IMAGE_NAME)
.usingSid()
.withOraclePassword("SysP@ss1!")
.withPassword("AppP@ss1!")
) {
runTestSystemUser(oracleSid, "xepdb1", "system", "SysP@ss1!");
}

// Non-SID mode should use application user's password
try (
OracleContainer oraclePdb = new OracleContainer(ORACLE_DOCKER_IMAGE_NAME)
.withOraclePassword("SysP@ss2!")
.withPassword("AppP@ss2!")
) {
runTest(oraclePdb, "xepdb1", "test", "AppP@ss2!");
}
}

Expand Down