Skip to content

Bugfix/watchdog create statement stuck issue20 #77

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 53 additions & 8 deletions src/main/java/org/utplsql/api/TestRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.utplsql.api.compatibility.CompatibilityProxy;
import org.utplsql.api.db.DatabaseInformation;
import org.utplsql.api.db.DefaultDatabaseInformation;
import org.utplsql.api.exception.OracleCreateStatmenetStuckException;
import org.utplsql.api.exception.SomeTestsFailedException;
import org.utplsql.api.exception.UtPLSQLNotInstalledException;
import org.utplsql.api.reporter.DocumentationReporter;
Expand All @@ -16,6 +17,7 @@
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
* Created by Vinicius Avellar on 12/04/2017.
Expand Down Expand Up @@ -124,6 +126,26 @@ private void delayedAddReporters() {
}
}

private void handleException(Throwable e) throws SQLException {
// Just pass exceptions already categorized
if ( e instanceof UtPLSQLNotInstalledException ) throw (UtPLSQLNotInstalledException)e;
else if ( e instanceof SomeTestsFailedException ) throw (SomeTestsFailedException)e;
else if ( e instanceof OracleCreateStatmenetStuckException ) throw (OracleCreateStatmenetStuckException)e;
// Categorize exceptions
else if (e instanceof SQLException) {
SQLException sqlException = (SQLException) e;
if (sqlException.getErrorCode() == SomeTestsFailedException.ERROR_CODE) {
throw new SomeTestsFailedException(sqlException.getMessage(), e);
} else if (((SQLException) e).getErrorCode() == UtPLSQLNotInstalledException.ERROR_CODE) {
throw new UtPLSQLNotInstalledException(sqlException);
} else {
throw sqlException;
}
} else {
throw new SQLException("Unknown exception, wrapping: " + e.getMessage(), e);
}
}

public void run(Connection conn) throws SQLException {

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

try (TestRunnerStatement testRunnerStatement = compatibilityProxy.getTestRunnerStatement(options, conn)) {
TestRunnerStatement testRunnerStatement = null;
try {
testRunnerStatement = initStatementWithTimeout(conn);
logger.info("Running tests");
testRunnerStatement.execute();
logger.info("Running tests finished.");
testRunnerStatement.close();
} catch (OracleCreateStatmenetStuckException e) {
// Don't close statement in this case for it will be stuck, too
throw e;
} catch (SQLException e) {
if (e.getErrorCode() == SomeTestsFailedException.ERROR_CODE) {
throw new SomeTestsFailedException(e.getMessage(), e);
} else if (e.getErrorCode() == UtPLSQLNotInstalledException.ERROR_CODE) {
throw new UtPLSQLNotInstalledException(e);
} else {
throw e;
}
if (testRunnerStatement != null) testRunnerStatement.close();
handleException(e);
}
}

private TestRunnerStatement initStatementWithTimeout( Connection conn ) throws OracleCreateStatmenetStuckException, SQLException {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<TestRunnerStatement> callable = () -> compatibilityProxy.getTestRunnerStatement(options, conn);
Future<TestRunnerStatement> future = executor.submit(callable);

// We want to leave the statement open in case of stuck scenario
TestRunnerStatement testRunnerStatement = null;
try {
testRunnerStatement = future.get(2, TimeUnit.SECONDS);
} catch (TimeoutException e) {
logger.error("Detected Oracle driver stuck during Statement initialization");
executor.shutdownNow();
throw new OracleCreateStatmenetStuckException(e);
} catch (InterruptedException e) {
handleException(e);
} catch (ExecutionException e) {
handleException(e.getCause());
}

return testRunnerStatement;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.utplsql.api.exception;

import java.sql.SQLException;

public class OracleCreateStatmenetStuckException extends SQLException {
public OracleCreateStatmenetStuckException(Throwable cause) {
super("Oracle driver stuck during creating the TestRunner statement. Retry.", cause);
}
}