diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index e2ad056..5a55f46 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -51,11 +51,19 @@ jobs: java-version: 11 - name: Build with Maven run: mvn -B package --file pom.xml -DskipTests=true - # Tests the Oracle R2DBC Driver with an Oracle Database - test: + # Tests the Oracle R2DBC Driver with an 18.4 XE Oracle Database + test-18-4-xe: needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Test with Oracle Database - run: cd $GITHUB_WORKSPACE/.github/workflows && bash test.sh + - name: Test with Oracle Database 18.4.0 XE + run: cd $GITHUB_WORKSPACE/.github/workflows && bash test.sh 18.4.0 + # Tests the Oracle R2DBC Driver with a 21.3 XE Oracle Database + test-21-3-xe: + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Test with Oracle Database 21.3.0 XE + run: cd $GITHUB_WORKSPACE/.github/workflows && bash test.sh 21.3.0 diff --git a/.github/workflows/test.sh b/.github/workflows/test.sh index d978e97..24a92e8 100755 --- a/.github/workflows/test.sh +++ b/.github/workflows/test.sh @@ -23,64 +23,75 @@ # execute the Oracle R2DBC test suite with a configuration that has it connect # to that database. # -# This script makes no attempt to clean up. The docker container is left -# running, and the database retains the test user and any other modifications -# that the test suite may have performed. -# It is assumed that the Github Runner will clean up any state this script -# leaves behind. +# The database version is configured by the first parameter. The version is +# expressed is as .. version number, for example: "18.4.0" +# +# The database port number is configured by the second parameter. If multiple +# databases are created by running this script in parallel, then a unique port +# number should be provided for each database. # The startup directory is mounted as a volume inside the docker container. # The container's entry point script will execute any .sh and .sql scripts # it finds under /opt/oracle/scripts/startup. The startup scripts are run -# after the database instance is active.A numeric prefix on the script name -# determines the order in which scripts are run. The final script, prefixed -# with "99_" will create a file named "done" in the mounted volumn. When the -# "done" file exists, this signals that the database is active and that all -# startup scripts have completed. -startUpScripts=$PWD/startup -startUpMount=/opt/oracle/scripts/startup -echo "touch $startUpMount/done" > $startUpScripts/99_done.sh +# after the database instance is active. +startUp=$PWD/$1/startup +mkdir -p $startUp +cp $PWD/startup/* $startUp +# Create a 99_ready.sh script. The numeric prefix of the file name determines +# the order in which scripts are run. The final script, prefixed with "99_" +# will create a file named "oracle-r2dbc-ready" in the $HOME directory within +# the container. The existence of this file is waited for before any tests are +# run. +readyFile='$HOME/oracle-r2dbc-ready' +echo "touch -f $readyFile" > $startUp/99_ready.sh # The oracle/docker-images repo is cloned. This repo provides Dockerfiles along # with a handy script to build images of Oracle Database. For now, this script -# is just going to build an 18.4.0 XE image, because this can be done in an -# automated fashion, without having to accept license agreements required by -# newer versions like 19 and 21. -# TODO: Also test with newer database versions +# is just going to build an Express Edition (XE) image, because this can be +# done in an automated fashion. Other editions would require a script to accept +# a license agreement. +# Parallel executions of this script clone the repo into isolated directories. +cd $PWD/$1 git clone https://github.com/oracle/docker-images.git cd docker-images/OracleDatabase/SingleInstance/dockerfiles/ -./buildContainerImage.sh -v 18.4.0 -x +./buildContainerImage.sh -v $1 -x # Run the image in a detached container # The startup directory is mounted. It contains a createUser.sql script that # creates a test user. The docker container will run this script once the # database has started. -# The database port number, 1521, is mapped to the host system. The Oracle -# R2DBC test suite is configured to connect with this port. -docker run --name test_db --detach --rm -p 1521:1521 -v $startUpScripts:$startUpMount oracle/database:18.4.0-xe +containerName=test_db_$1 +dbPort=$(echo "5$1" | tr -d '.') +echo "Starting container: $containerName" +echo "Host port: $dbPort" +docker run --name $containerName --detach --rm -p $dbPort:1521 -v $startUp:/opt/oracle/scripts/startup -e ORACLE_PDB=xepdb1 oracle/database:$1-xe # Wait for the database instance to start. The final startup script will create -# a file named "done" in the startup directory. When that file exists, it means -# the database is ready for testing. +# a file named "ready" in the startup scripts directory. When that file exists, +# it means the database is ready for testing. echo "Waiting for database to start..." -until [ -f $startUpScripts/done ] +until docker exec $containerName sh -c "test -f $readyFile" do - docker logs --since 3s test_db - sleep 3 + docker logs --since 1s $containerName + sleep 1 done # Create a configuration file and run the tests. The service name, "xepdb1", -# is always created for the 18.4.0 XE database, but it would probably change -# for other database versions (TODO). The test user is created by the -# startup/01_createUser.sql script +# is always created for the XE database. It would probably change for other +# database editions. The test user is created by the startup/01_createUser.sql +# script cd $GITHUB_WORKSPACE -echo "DATABASE=xepdb1" > src/test/resources/config.properties -echo "HOST=localhost" >> src/test/resources/config.properties -echo "PORT=1521" >> src/test/resources/config.properties -echo "USER=test" >> src/test/resources/config.properties -echo "PASSWORD=test" >> src/test/resources/config.properties -echo "CONNECT_TIMEOUT=60" >> src/test/resources/config.properties -echo "SQL_TIMEOUT=60" >> src/test/resources/config.properties -mvn clean compile test +echo "# Configuration for testing with Oracle Database $1" > src/test/resources/$1.properties +echo "DATABASE=xepdb1" >> src/test/resources/$1.properties +echo "HOST=localhost" >> src/test/resources/$1.properties +echo "PORT=$dbPort" >> src/test/resources/$1.properties +echo "USER=test" >> src/test/resources/$1.properties +echo "PASSWORD=test" >> src/test/resources/$1.properties +echo "CONNECT_TIMEOUT=120" >> src/test/resources/$1.properties +echo "SQL_TIMEOUT=120" >> src/test/resources/$1.properties +mvn -Doracle.r2dbc.config=$1.properties clean compile test + +# Stop the database container to free up resources +docker stop $containerName diff --git a/.gitignore b/.gitignore index f63f671..604ed5f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,19 @@ +# Exclude properties files, as they may contain user/password credentials and +# names of internal systems. Include only example-config.properties files +/src/test/resources/*.properties +/sample/*.properties +!/src/test/resources/example-config.properties +!/sample/example-config.properties + +# Excluded complier output /target/ -.DS_Store -*.iml -/src/test/resources/config.properties /sample/target/ -/sample/config.properties + +# Exclude the scripts and files generated by the test workflow .github/workflows/startup/99_done.sh .github/workflows/startup/done + +# Exclude files generated by the OS and other programs +.DS_Store +*.iml +*.swp diff --git a/README.md b/README.md index f886a06..ba8dd67 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,11 @@ +![](https://github.com/oracle/oracle-r2dbc/actions/workflows/build-and-test.yml/badge.svg) + # About Oracle R2DBC The Oracle R2DBC Driver is a Java library that supports reactive programming with Oracle Database. Oracle R2DBC implements the R2DBC Service Provider Interface (SPI) as specified by the Reactive Relational Database Connectivity (R2DBC) project. The R2DBC SPI exposes Reactive Streams as an abstraction for remote database operations. Reactive Streams is a well defined standard for asynchronous, non-blocking, and back-pressured communication. This standard allows an R2DBC driver to interoperate with other reactive libraries and frameworks, such as Spring, Project Reactor, RxJava, and Akka Streams. - ### Learn More About R2DBC: [R2DBC Project Home Page](https://r2dbc.io) diff --git a/sample/example-config.properties b/sample/example-config.properties index e3c5c0c..817297a 100644 --- a/sample/example-config.properties +++ b/sample/example-config.properties @@ -1,5 +1,10 @@ -# Values in this properties file configure how sample code connects to a # database. # This file contains example values. Create a copy named config.properties in -# /sample and change the example values to actual values for your test database. +# Values in this properties file configure how sample code connects to a +# database. +# This file contains example values. Create a copy named config.properties in +# /sample, and then change the example values to actual values +# for your test database. +# The example-config.properties file is versioned controlled. DO NOT TYPE +# SENSITIVE VALUES INTO THE EXAMPLE FILE. # Host name of a test database HOST=db.host.example.com diff --git a/src/main/java/oracle/r2dbc/impl/OracleStatementImpl.java b/src/main/java/oracle/r2dbc/impl/OracleStatementImpl.java index 5839cd6..6cafa7f 100755 --- a/src/main/java/oracle/r2dbc/impl/OracleStatementImpl.java +++ b/src/main/java/oracle/r2dbc/impl/OracleStatementImpl.java @@ -1590,4 +1590,4 @@ protected Publisher executeJdbc() { } } -} \ No newline at end of file +} diff --git a/src/test/java/oracle/r2dbc/test/DatabaseConfig.java b/src/test/java/oracle/r2dbc/test/DatabaseConfig.java index e7e4729..ebbd5cb 100644 --- a/src/test/java/oracle/r2dbc/test/DatabaseConfig.java +++ b/src/test/java/oracle/r2dbc/test/DatabaseConfig.java @@ -213,7 +213,13 @@ public static void showErrors(Connection connection) { private static final ConnectionFactory CONNECTION_FACTORY; private static final ConnectionFactory SHARED_CONNECTION_FACTORY; - private static final String CONFIG_FILE_NAME = "config.properties"; + /** + * Name of configuration file. It is "config.properties" by default, but can + * be set to a none default with: -Doracle.r2dbc.config=something-else + */ + private static final String CONFIG_FILE_NAME = + System.getProperty("oracle.r2dbc.config", "config.properties"); + static { try (InputStream inputStream = DatabaseConfig.class.getClassLoader() diff --git a/src/test/resources/example-config.properties b/src/test/resources/example-config.properties index 670bd64..286a199 100755 --- a/src/test/resources/example-config.properties +++ b/src/test/resources/example-config.properties @@ -1,8 +1,12 @@ # Values in this properties file configure how test cases connect to a database. - # This file contains example values. Create a copy named config.properties in -# /src/test/resources/ and change the example values to actual values for your -# test database. +# /src/test/resources/, and then change the example values to actual values +# for your test database. +# The example-config.properties file is versioned controlled. DO NOT TYPE +# SENSITIVE VALUES INTO THE EXAMPLE FILE. +# Running the Oracle R2DBC test suite with -Doracle.r2dbc.config= +# has it read configuration from the named file under src/test/resources, +# rather than from the default "config.properties" file. # Host name of a test database HOST=db.host.example.com