Skip to content

Feature/version check #26

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 20 commits into from
Nov 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9ce25cb
Adding orai18n to the dependencies
viniciusam Oct 26, 2017
817068e
Close reporters if any unexpected errors occurred while running tests
viniciusam Oct 29, 2017
f930370
Merge pull request #24 from utPLSQL/bugfix/orai18n
viniciusam Oct 29, 2017
a1113b8
Simple approach towards checking version compability
Oct 29, 2017
c4c6e08
Merge branch 'feature/version_check' of https://github.com/utPLSQL/ut…
Nov 4, 2017
23d3dae
Merge remote-tracking branch 'upstream/develop' into feature/version_…
Nov 4, 2017
9e7fdd2
Introduced new Version-class to parse version-string information
Nov 5, 2017
4fbda90
Introduced DatabaseNotComptabileException
Nov 5, 2017
f0d6916
Changed Version-number or API to Framework-number
Nov 5, 2017
4ec2b90
Started with compatibility support
Nov 8, 2017
09eeff4
Very simple compatibility implementation
Nov 8, 2017
51ac9db
Merge pull request #25 from utPLSQL/bugfix/close_reporters_on_error
viniciusam Nov 8, 2017
b31a2e5
Merge branch 'develop' of https://github.com/utPLSQL/utPLSQL-java-api…
Nov 8, 2017
c73ccab
Merge with latest develop and bugfix
Nov 8, 2017
9c1daed
Include original error reason when Compatibility-check fails
pesse Nov 9, 2017
aed5dfe
Change travis to use 3.0.4 release of framework
pesse Nov 9, 2017
17bf456
Possible typo
pesse Nov 9, 2017
7a469d4
We of course should copy the .tar.gz and untar it before doing stuff
pesse Nov 9, 2017
6b4d2af
Included possibility to skip CompatibilityCheck
pesse Nov 9, 2017
ec81b5b
Refactoring and changing DatabaseNotCompatibleException
pesse Nov 10, 2017
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
18 changes: 9 additions & 9 deletions .travis/install_utplsql.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,26 @@ set -ev
cd $(dirname $(readlink -f $0))

# Download the specified version of utPLSQL.
# UTPLSQL_VERSION="v3.0.0-beta"
# UTPLSQL_FILE="utPLSQLv3.0.0.562-beta"
# curl -L -O "https://github.com/utPLSQL/utPLSQL/releases/download/$UTPLSQL_VERSION/$UTPLSQL_FILE.tar.gz"
UTPLSQL_VERSION="v3.0.4"
UTPLSQL_FILE="utPLSQL"
curl -L -O "https://github.com/utPLSQL/utPLSQL/releases/download/$UTPLSQL_VERSION/$UTPLSQL_FILE.tar.gz"

# Download develop branch of utPLSQL.
UTPLSQL_VERSION="develop"
UTPLSQL_FILE="utPLSQL"
git clone -b develop --single-branch https://github.com/utPLSQL/utPLSQL.git
#UTPLSQL_VERSION="develop"
#UTPLSQL_FILE="utPLSQL"
#git clone -b develop --single-branch https://github.com/utPLSQL/utPLSQL.git
# tar -czf $UTPLSQL_FILE.tar.gz $UTPLSQL_FILE && rm -rf $UTPLSQL_FILE

# Create a temporary install script.
cat > install.sh.tmp <<EOF
# tar -xzf ${UTPLSQL_FILE}.tar.gz && rm ${UTPLSQL_FILE}.tar.gz
tar -xzf ${UTPLSQL_FILE}.tar.gz && rm ${UTPLSQL_FILE}.tar.gz
cd ${UTPLSQL_FILE}/source
sqlplus -S -L sys/oracle@//127.0.0.1:1521/xe AS SYSDBA @install_headless.sql ut3 ut3 users
EOF

# Copy utPLSQL files to the container and install it.
# docker cp ./$UTPLSQL_FILE.tar.gz $ORACLE_VERSION:/$UTPLSQL_FILE.tar.gz
docker cp ./$UTPLSQL_FILE $ORACLE_VERSION:/$UTPLSQL_FILE
docker cp ./$UTPLSQL_FILE.tar.gz $ORACLE_VERSION:/$UTPLSQL_FILE.tar.gz
# docker cp ./$UTPLSQL_FILE $ORACLE_VERSION:/$UTPLSQL_FILE
docker cp ./install.sh.tmp $ORACLE_VERSION:/install.sh
docker cp ./create_api_user.sh $ORACLE_VERSION:/create_api_user.sh

Expand Down
8 changes: 7 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>org.utplsql</groupId>
<artifactId>java-api</artifactId>
<version>1.0-SNAPSHOT</version>
<version>3.0.4-SNAPSHOT</version>
<packaging>jar</packaging>

<name>utPLSQL-java-api</name>
Expand All @@ -23,6 +23,12 @@
<version>12.2.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.oracle.jdbc</groupId>
<artifactId>orai18n</artifactId>
<version>12.2.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Expand Down
54 changes: 48 additions & 6 deletions src/main/java/org/utplsql/api/DBHelper.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package org.utplsql.api;

import oracle.jdbc.OracleTypes;
import org.utplsql.api.exception.DatabaseNotCompatibleException;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Types;
import java.sql.*;

/**
* Database utility functions.
*/
public final class DBHelper {

public static final String UTPLSQL_COMPATIBILITY_VERSION = "3.0.3";
public static final String UTPLSQL_COMPATIBILITY_VERSION = "3";

private DBHelper() {}

Expand Down Expand Up @@ -96,6 +94,51 @@ public static boolean versionCompatibilityCheck(Connection conn)
return versionCompatibilityCheck(conn, UTPLSQL_COMPATIBILITY_VERSION);
}


/** Checks if actual API-version is compatible with utPLSQL database version and throws a DatabaseNotCompatibleException if not
* Throws a DatabaseNotCompatibleException if version compatibility can not be checked.
*
* @param conn Active db connection
*/
public static void failOnVersionCompatibilityCheckFailed( Connection conn ) throws DatabaseNotCompatibleException
{
try {
if (!versionCompatibilityCheck(conn))
{
// Try to find out Framework Version
Version v = DBHelper.getDatabaseFrameworkVersion(conn);

throw new DatabaseNotCompatibleException( v );
}
}
catch ( SQLException e )
{
throw new DatabaseNotCompatibleException("Compatibility-check failed with error. Aborting. Reason: " + e.getMessage(), new Version(UTPLSQL_COMPATIBILITY_VERSION), new Version("Unknown"), e);
}
}

/** Returns the Frameworks version string of the given connection
*
* @param conn Active db connection
* @return
* @throws SQLException
*/
public static Version getDatabaseFrameworkVersion( Connection conn )
throws SQLException {
Version result = new Version("");
try (PreparedStatement stmt = conn.prepareStatement("select ut_runner.version() from dual"))
{
ResultSet rs = stmt.executeQuery();

if ( rs.next() )
result = new Version(rs.getString(1));

rs.close();
}

return result;
}

/**
* Enable the dbms_output buffer with unlimited size.
* @param conn the connection
Expand All @@ -119,5 +162,4 @@ public static void disableDBMSOutput(Connection conn) {
System.out.println("Failed to disable dbms_output.");
}
}

}
149 changes: 50 additions & 99 deletions src/main/java/org/utplsql/api/TestRunner.java
Original file line number Diff line number Diff line change
@@ -1,181 +1,132 @@
package org.utplsql.api;

import oracle.jdbc.OracleConnection;
import org.utplsql.api.compatibility.CompatibilityProvider;
import org.utplsql.api.exception.DatabaseNotCompatibleException;
import org.utplsql.api.exception.SomeTestsFailedException;
import org.utplsql.api.reporter.DocumentationReporter;
import org.utplsql.api.reporter.Reporter;
import oracle.jdbc.OracleConnection;
import org.utplsql.api.testRunner.TestRunnerStatement;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

/**
* Created by Vinicius Avellar on 12/04/2017.
*
* @author Vinicius Avellar
* @author pesse
*/
public class TestRunner {

private List<String> pathList = new ArrayList<>();
private List<Reporter> reporterList = new ArrayList<>();
private boolean colorConsole = false;
private List<String> coverageSchemes = new ArrayList<>();
private List<String> sourceFiles = new ArrayList<>();
private List<String> testFiles = new ArrayList<>();
private List<String> includeObjects = new ArrayList<>();
private List<String> excludeObjects = new ArrayList<>();
private FileMapperOptions sourceMappingOptions;
private FileMapperOptions testMappingOptions;
private boolean failOnErrors = false;
private TestRunnerOptions options = new TestRunnerOptions();

public TestRunner addPath(String path) {
this.pathList.add(path);
options.pathList.add(path);
return this;
}

public TestRunner addPathList(List<String> paths) {
if (pathList != null) this.pathList.addAll(paths);
if (options.pathList != null) options.pathList.addAll(paths);
return this;
}

public TestRunner addReporter(Reporter reporter) {
this.reporterList.add(reporter);
options.reporterList.add(reporter);
return this;
}

public TestRunner colorConsole(boolean colorConsole) {
this.colorConsole = colorConsole;
options.colorConsole = colorConsole;
return this;
}

public TestRunner addReporterList(List<Reporter> reporterList) {
if (reporterList != null) this.reporterList.addAll(reporterList);
if (options.reporterList != null) options.reporterList.addAll(reporterList);
return this;
}

public TestRunner addCoverageScheme(String coverageScheme) {
this.coverageSchemes.add(coverageScheme);
options.coverageSchemes.add(coverageScheme);
return this;
}

public TestRunner includeObject(String obj) {
this.includeObjects.add(obj);
options.includeObjects.add(obj);
return this;
}

public TestRunner excludeObject(String obj) {
this.excludeObjects.add(obj);
options.excludeObjects.add(obj);
return this;
}

public TestRunner sourceMappingOptions(FileMapperOptions mapperOptions) {
this.sourceMappingOptions = mapperOptions;
options.sourceMappingOptions = mapperOptions;
return this;
}

public TestRunner testMappingOptions(FileMapperOptions mapperOptions) {
this.testMappingOptions = mapperOptions;
options.testMappingOptions = mapperOptions;
return this;
}

public TestRunner failOnErrors(boolean failOnErrors) {
this.failOnErrors = failOnErrors;
options.failOnErrors = failOnErrors;
return this;
}

public void run(Connection conn) throws SomeTestsFailedException, SQLException {
for (Reporter r : this.reporterList)
public TestRunner skipCompatibilityCheck( boolean skipCompatibilityCheck )
{
options.skipCompatibilityCheck = skipCompatibilityCheck;
return this;
}

public void run(Connection conn) throws SomeTestsFailedException, SQLException, DatabaseNotCompatibleException {

// First of all check version compatibility
if ( !options.skipCompatibilityCheck )
DBHelper.failOnVersionCompatibilityCheckFailed(conn);

for (Reporter r : options.reporterList)
validateReporter(conn, r);

if (this.pathList.isEmpty()) {
this.pathList.add(DBHelper.getCurrentSchema(conn));
if (options.pathList.isEmpty()) {
options.pathList.add(DBHelper.getCurrentSchema(conn));
}

if (this.reporterList.isEmpty()) {
this.reporterList.add(new DocumentationReporter().init(conn));
if (options.reporterList.isEmpty()) {
options.reporterList.add(new DocumentationReporter().init(conn));
}

// Workaround because Oracle JDBC doesn't support passing boolean to stored procedures.
String colorConsoleStr = Boolean.toString(this.colorConsole);
String failOnErrors = Boolean.toString(this.failOnErrors);
TestRunnerStatement testRunnerStatement = null;

OracleConnection oraConn = conn.unwrap(OracleConnection.class);
CallableStatement callableStatement = null;
try {
DBHelper.enableDBMSOutput(conn);

callableStatement = conn.prepareCall(
"BEGIN " +
"ut_runner.run(" +
"a_paths => ?, " +
"a_reporters => ?, " +
"a_color_console => " + colorConsoleStr + ", " +
"a_coverage_schemes => ?, " +
"a_source_file_mappings => ?, " +
"a_test_file_mappings => ?, " +
"a_include_objects => ?, " +
"a_exclude_objects => ?, " +
"a_fail_on_errors => " + failOnErrors + "); " +
"END;");

int paramIdx = 0;

callableStatement.setArray(
++paramIdx, oraConn.createOracleArray(CustomTypes.UT_VARCHAR2_LIST, this.pathList.toArray()));

callableStatement.setArray(
++paramIdx, oraConn.createOracleArray(CustomTypes.UT_REPORTERS, this.reporterList.toArray()));

if (this.coverageSchemes.isEmpty()) {
callableStatement.setNull(++paramIdx, Types.ARRAY, CustomTypes.UT_VARCHAR2_LIST);
} else {
callableStatement.setArray(
++paramIdx, oraConn.createOracleArray(CustomTypes.UT_VARCHAR2_LIST, this.coverageSchemes.toArray()));
}

if (this.sourceMappingOptions == null) {
callableStatement.setNull(++paramIdx, Types.ARRAY, CustomTypes.UT_FILE_MAPPINGS);
} else {
List<FileMapping> sourceMappings = FileMapper.buildFileMappingList(conn, this.sourceMappingOptions);

callableStatement.setArray(
++paramIdx, oraConn.createOracleArray(CustomTypes.UT_FILE_MAPPINGS, sourceMappings.toArray()));
}
testRunnerStatement = CompatibilityProvider.getTestRunnerStatement(options, conn);

if (this.testMappingOptions == null) {
callableStatement.setNull(++paramIdx, Types.ARRAY, CustomTypes.UT_FILE_MAPPINGS);
} else {
List<FileMapping> sourceMappings = FileMapper.buildFileMappingList(conn, this.testMappingOptions);

callableStatement.setArray(
++paramIdx, oraConn.createOracleArray(CustomTypes.UT_FILE_MAPPINGS, sourceMappings.toArray()));
}

if (this.includeObjects.isEmpty()) {
callableStatement.setNull(++paramIdx, Types.ARRAY, CustomTypes.UT_VARCHAR2_LIST);
} else {
callableStatement.setArray(
++paramIdx, oraConn.createOracleArray(CustomTypes.UT_VARCHAR2_LIST, this.includeObjects.toArray()));
}

if (this.excludeObjects.isEmpty()) {
callableStatement.setNull(++paramIdx, Types.ARRAY, CustomTypes.UT_VARCHAR2_LIST);
} else {
callableStatement.setArray(
++paramIdx, oraConn.createOracleArray(CustomTypes.UT_VARCHAR2_LIST, this.excludeObjects.toArray()));
}

callableStatement.execute();
testRunnerStatement.execute();
} catch (SQLException e) {
if (e.getErrorCode() == SomeTestsFailedException.ERROR_CODE) {
throw new SomeTestsFailedException(e.getMessage(), e);
} else {
// If the execution failed by unexpected reasons finishes all reporters,
// this way the users don't need to care about reporters' sessions hanging.
OracleConnection oraConn = conn.unwrap(OracleConnection.class);

try (CallableStatement closeBufferStmt = conn.prepareCall("BEGIN ut_output_buffer.close(?); END;")) {
closeBufferStmt.setArray(1, oraConn.createOracleArray(CustomTypes.UT_REPORTERS, options.reporterList.toArray()));
closeBufferStmt.execute();
} catch (SQLException ignored) {}

throw e;
}
} finally {
if (callableStatement != null) {
callableStatement.close();
if (testRunnerStatement != null) {
testRunnerStatement.close();
}

DBHelper.disableDBMSOutput(conn);
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/org/utplsql/api/TestRunnerOptions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.utplsql.api;

import org.utplsql.api.reporter.Reporter;

import java.util.ArrayList;
import java.util.List;

/** Holds the various possible options of TestRunner
*
* @author pesse
*/
public class TestRunnerOptions {
public List<String> pathList = new ArrayList<>();
public List<Reporter> reporterList = new ArrayList<>();
public boolean colorConsole = false;
public List<String> coverageSchemes = new ArrayList<>();
public List<String> sourceFiles = new ArrayList<>();
public List<String> testFiles = new ArrayList<>();
public List<String> includeObjects = new ArrayList<>();
public List<String> excludeObjects = new ArrayList<>();
public FileMapperOptions sourceMappingOptions;
public FileMapperOptions testMappingOptions;
public boolean failOnErrors = false;
public boolean skipCompatibilityCheck = false;
}
Loading