Skip to content

Commit b171b05

Browse files
authored
[fix][test] Fix flaky PulsarDebeziumOracleSourceTest (apache#25314)
1 parent 6c357f6 commit b171b05

1 file changed

Lines changed: 41 additions & 10 deletions

File tree

tests/integration/src/test/java/org/apache/pulsar/tests/integration/io/sources/debezium/DebeziumOracleDbSourceTester.java

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -146,18 +146,15 @@ public void prepareSource() {
146146
// configure logminer
147147
runSqlCmd("shutdown immediate");
148148

149-
// good first approximation but still not enough:
150149
waitForOracleStatus("ORACLE not available");
151150
Thread.sleep(SLEEP_AFTER_COMMAND_MS);
152151

153-
runSqlCmd("startup mount");
154-
// good first approximation but still not enough:
155-
waitForOracleStatus("MOUNTED");
152+
// startup mount may need retries if Oracle is still shutting down
153+
retryCommand("startup mount", "MOUNTED");
156154
Thread.sleep(SLEEP_AFTER_COMMAND_MS);
157155

158156
runSqlCmd("alter database archivelog;");
159157
runSqlCmd("alter database open;");
160-
// good first approximation but still not enough:
161158
waitForOracleStatus("OPEN");
162159
Thread.sleep(SLEEP_AFTER_COMMAND_MS);
163160

@@ -175,15 +172,49 @@ public void prepareSource() {
175172
}
176173

177174
private void waitForOracleStatus(String status) throws Exception {
175+
log.info("Waiting for Oracle status '{}'", status);
176+
String lastStdout = "";
177+
String lastStderr = "";
178178
for (int i = 0; i < 1000; i++) {
179-
ContainerExecResult response = runSqlCmd("SELECT INSTANCE_NAME, STATUS, DATABASE_STATUS FROM V$INSTANCE;");
180-
if ((response.getStderr() != null && response.getStderr().contains(status))
181-
|| (response.getStdout() != null && response.getStdout().contains(status))) {
182-
return;
179+
try {
180+
ContainerExecResult response =
181+
runSqlCmd("SELECT INSTANCE_NAME, STATUS, DATABASE_STATUS FROM V$INSTANCE;");
182+
lastStdout = response.getStdout() != null ? response.getStdout() : "";
183+
lastStderr = response.getStderr() != null ? response.getStderr() : "";
184+
if (lastStderr.contains(status) || lastStdout.contains(status)) {
185+
log.info("Oracle reached status '{}' after {} attempts", status, i + 1);
186+
return;
187+
}
188+
} catch (Exception e) {
189+
lastStderr = e.getMessage();
190+
log.debug("Error polling Oracle status (attempt {}): {}", i + 1, e.getMessage());
191+
}
192+
if (i % 30 == 29) {
193+
log.info("Still waiting for Oracle status '{}' after {} attempts. "
194+
+ "Last stdout: {}, Last stderr: {}", status, i + 1, lastStdout, lastStderr);
183195
}
184196
Thread.sleep(1000);
185197
}
186-
throw new IllegalStateException("Oracle did not initialize properly");
198+
throw new IllegalStateException(
199+
String.format("Oracle did not reach status '%s'. Last stdout: %s, Last stderr: %s",
200+
status, lastStdout, lastStderr));
201+
}
202+
203+
private void retryCommand(String cmd, String expectedStatus) throws Exception {
204+
for (int attempt = 1; attempt <= 3; attempt++) {
205+
runSqlCmd(cmd);
206+
try {
207+
waitForOracleStatus(expectedStatus);
208+
return;
209+
} catch (IllegalStateException e) {
210+
if (attempt == 3) {
211+
throw e;
212+
}
213+
log.warn("Command '{}' did not lead to status '{}' (attempt {}), retrying...",
214+
cmd, expectedStatus, attempt);
215+
Thread.sleep(SLEEP_AFTER_COMMAND_MS);
216+
}
217+
}
187218
}
188219

189220
private ContainerExecResult runSqlCmd(String cmd) throws Exception {

0 commit comments

Comments
 (0)