Skip to content

Commit 41b6d31

Browse files
authored
Merge pull request #77 from utPLSQL/bugfix/watchdog_createStatement_stuck_issue20
Bugfix/watchdog create statement stuck issue20
2 parents c4539ea + e703c33 commit 41b6d31

File tree

2 files changed

+62
-8
lines changed

2 files changed

+62
-8
lines changed

src/main/java/org/utplsql/api/TestRunner.java

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.utplsql.api.compatibility.CompatibilityProxy;
66
import org.utplsql.api.db.DatabaseInformation;
77
import org.utplsql.api.db.DefaultDatabaseInformation;
8+
import org.utplsql.api.exception.OracleCreateStatmenetStuckException;
89
import org.utplsql.api.exception.SomeTestsFailedException;
910
import org.utplsql.api.exception.UtPLSQLNotInstalledException;
1011
import org.utplsql.api.reporter.DocumentationReporter;
@@ -16,6 +17,7 @@
1617
import java.sql.SQLException;
1718
import java.util.ArrayList;
1819
import java.util.List;
20+
import java.util.concurrent.*;
1921

2022
/**
2123
* Created by Vinicius Avellar on 12/04/2017.
@@ -124,6 +126,26 @@ private void delayedAddReporters() {
124126
}
125127
}
126128

129+
private void handleException(Throwable e) throws SQLException {
130+
// Just pass exceptions already categorized
131+
if ( e instanceof UtPLSQLNotInstalledException ) throw (UtPLSQLNotInstalledException)e;
132+
else if ( e instanceof SomeTestsFailedException ) throw (SomeTestsFailedException)e;
133+
else if ( e instanceof OracleCreateStatmenetStuckException ) throw (OracleCreateStatmenetStuckException)e;
134+
// Categorize exceptions
135+
else if (e instanceof SQLException) {
136+
SQLException sqlException = (SQLException) e;
137+
if (sqlException.getErrorCode() == SomeTestsFailedException.ERROR_CODE) {
138+
throw new SomeTestsFailedException(sqlException.getMessage(), e);
139+
} else if (((SQLException) e).getErrorCode() == UtPLSQLNotInstalledException.ERROR_CODE) {
140+
throw new UtPLSQLNotInstalledException(sqlException);
141+
} else {
142+
throw sqlException;
143+
}
144+
} else {
145+
throw new SQLException("Unknown exception, wrapping: " + e.getMessage(), e);
146+
}
147+
}
148+
127149
public void run(Connection conn) throws SQLException {
128150

129151
logger.info("TestRunner initialized");
@@ -156,19 +178,42 @@ public void run(Connection conn) throws SQLException {
156178
options.reporterList.add(new DocumentationReporter().init(conn));
157179
}
158180

159-
try (TestRunnerStatement testRunnerStatement = compatibilityProxy.getTestRunnerStatement(options, conn)) {
181+
TestRunnerStatement testRunnerStatement = null;
182+
try {
183+
testRunnerStatement = initStatementWithTimeout(conn);
160184
logger.info("Running tests");
161185
testRunnerStatement.execute();
162186
logger.info("Running tests finished.");
187+
testRunnerStatement.close();
188+
} catch (OracleCreateStatmenetStuckException e) {
189+
// Don't close statement in this case for it will be stuck, too
190+
throw e;
163191
} catch (SQLException e) {
164-
if (e.getErrorCode() == SomeTestsFailedException.ERROR_CODE) {
165-
throw new SomeTestsFailedException(e.getMessage(), e);
166-
} else if (e.getErrorCode() == UtPLSQLNotInstalledException.ERROR_CODE) {
167-
throw new UtPLSQLNotInstalledException(e);
168-
} else {
169-
throw e;
170-
}
192+
if (testRunnerStatement != null) testRunnerStatement.close();
193+
handleException(e);
194+
}
195+
}
196+
197+
private TestRunnerStatement initStatementWithTimeout( Connection conn ) throws OracleCreateStatmenetStuckException, SQLException {
198+
ExecutorService executor = Executors.newSingleThreadExecutor();
199+
Callable<TestRunnerStatement> callable = () -> compatibilityProxy.getTestRunnerStatement(options, conn);
200+
Future<TestRunnerStatement> future = executor.submit(callable);
201+
202+
// We want to leave the statement open in case of stuck scenario
203+
TestRunnerStatement testRunnerStatement = null;
204+
try {
205+
testRunnerStatement = future.get(2, TimeUnit.SECONDS);
206+
} catch (TimeoutException e) {
207+
logger.error("Detected Oracle driver stuck during Statement initialization");
208+
executor.shutdownNow();
209+
throw new OracleCreateStatmenetStuckException(e);
210+
} catch (InterruptedException e) {
211+
handleException(e);
212+
} catch (ExecutionException e) {
213+
handleException(e.getCause());
171214
}
215+
216+
return testRunnerStatement;
172217
}
173218

174219
/**
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.utplsql.api.exception;
2+
3+
import java.sql.SQLException;
4+
5+
public class OracleCreateStatmenetStuckException extends SQLException {
6+
public OracleCreateStatmenetStuckException(Throwable cause) {
7+
super("Oracle driver stuck during creating the TestRunner statement. Retry.", cause);
8+
}
9+
}

0 commit comments

Comments
 (0)