This blog walks through an example of how to create a test pipeline which incorporates unit as well as integration testing - in the Cloud. What's critical to note is the fact that the cloud service instances (for testing) are started on-demand and then stopped/terminated after test execution

  • Treat infrastructure as code and control it within our pipeline
  • Pay for what you use = cost control

 

We will be leveraging the following Oracle Cloud services

  • Oracle Developer Cloud
  • Oracle Database Cloud
  • Oracle Application Container Cloud

 

 

 

 

 

Oracle Developer Cloud: key enablers

The following capabilities play a critical role

 

The below mentioned features are available within the Build module

 

  • Integration with Oracle PaaS Service Manager (PSM): It's possible to add a PSMcli build step that invokes Oracle PaaS Service Manager command line interface (CLI) commands when the build runs. More details in the documentation
  • Integration with SQLcl: This makes it possible to invoke SQL statements on an Oracle Database when the build runs. Details here

 

Application

The sample application uses JAX-RS (Jersey impementation) to expose data over REST and JPA as the ORM solution to interact with Oracle Database Cloud service (more on Github)

 

 

Here is the test setup

 

Tests

 

Unit

There two different unit tests in the application which use Maven Surefire plugin

  • Using In-memory/embedded (Derby) database: this is invoked using mvn test
  • Using (remote) Oracle Database Cloud service instance: this test is activated by using a specific profile in the pom.xml and its executed using mvn test –Pdbcs-test

 

 

Extract from pom.xml

 

 

 

Integration

In addition to the unit test, we have an integration test layer which is handled using the Maven Failsafe plugin

 

 

Its invoked by mvn integration-test or mvn verify

 

 

Packaging

It's handled using Maven Shade plugin (fat JAR) and Maven assembly plugin (to create a zip file with the ACCS manifest.json)

 

Developer Cloud service configuration

 

Setup

Before we dive into the details, let’s get a high level overview of how you can set this up

 

Project & code repository creation

Please refer to the Project & code repository creation section in the Tracking JUnit test results in Developer Cloud service blog or check the product documentation for more details

 

Configure source code in Git repository

Push the project from your local system to your Developer Cloud Git repo you just created. We will do this via command line and all you need is Git client installed on your local machine. You can use Git or any other tool of your choice

 

cd <project_folder> //where you unzipped the source code  
git init  
git remote add origin <developer_cloud_git_repo>  
//e.g. https://john.doe@developer.us.oraclecloud.com/developer007-foodomain/s/developer007-foodomain-project_2009/scm/sample.git//john.doe@developer.us.oraclecloud.com/developer007-foodomain/s/developer007-foodomain-project_2009/scm/sample.git   
git add .  
git commit -m "first commit"  
git push -u origin master  //Please enter the password for your Oracle Developer Cloud account when prompted

 

Once this is done, we can now start configuring our Build

 

  • The pipeline is divided into multiple phases each of which corresponds to a Build
  • These individual phases/builds are then stitched together to create an end-to-end test flow. Let’s explore each phase and its corresponding build configuration

 

Phases

 

Unit test: part I

The JPA logic is tested using the embedded Derby database. It links to the Git repo where we pushed the code and also connects to the Oracle Maven repository

 

 

 

 

The build step invokes Maven

 

 

The post-build step

  • Invokes the next job in the pipeline
  • Archives the test results and enables JUnit test reports availability

 

 

 

 

 

Bootstrap Oracle Database Cloud service

 

  • This phase leverages the PSMcli to first start the Oracle Database Cloud  service and then,
  • SQLcl to create the table and load it up with test data. It is invoked by the previous job

 

 

Please note that the PSM command is asynchronous in nature and returns a Job ID which you can further use (within a shell script) in order to poll the status of the job

 

Here is an example of a such a script

 

VALUE=`psm dbcs stop --service-name test`

echo $VALUE

#Split on ':' which contains the Job ID on the right side of :
OIFS=$IFS
IFS=':'
JSONDATA=${VALUE}

#trying to skip over the left side of : to get the JobID
COUNTER=0
for X in $JSONDATA
do
  if [ "$COUNTER" -eq 1 ]
  then
  #clean string, removing leading white space and tab
  X=$(echo $X |sed -e 's/^[ \t]*//')
  JOBID=$X
  else
  COUNTER=$(($COUNTER+1))
  fi
done

echo "Job ID is "$JOBID

#Repeat check until SUCCEED is in the status
PSMSTATUS=-1
while [ $PSMSTATUS -ne 0 ]; do 

CHECKSTATUS=`psm dbcs operation-status --job-id $JOBID`


  if [[ $CHECKSTATUS == *"SUCCEED"* ]]
  then
  PSMSTATUS=0
    echo "PSM operation Succeeded!"
  else 
  echo "Waiting for PSM operation to complete"
  fi
  sleep 60
done

 

 

Here is the SQLcl configuration which populates the Oracle Database Cloud service table

 

 

 

 

 

Unit test: part II

  • Runs test against the Oracle Database Cloud service instance which we just bootstrapped
  • Triggers application deployment (to Oracle Application Container Cloud)
  • and, like the previous job, this too links to the Git repo and connects to the Oracle Maven repository

 

Certain values for the test code are passed in as parameters

 

 

 

The build step involves invocation of a specific (Maven) profile defined in the pom.xml

 

 

 

The post build section does a bunch of things

  • Invokes the next job in the pipeline
  • Archives the deployment artifact (in this case, a ZIP file for ACCS)
  • Archives the test results and enables test reports availability
  • Invocation of the Deployment step to Application Container Cloud

 

 

 

 

Integration test

Now that we have executed the unit tests and our application is deployed, its now time to execute the integration test against the live application. In this case we test the REST API exposed by our application

 

 

 

Build step invokes Maven goal

 

 

We use the HTTPS proxy in order to access external URL (the ACC application in this case) from within the Oracle Developer Cloud build machines

 

Post build section invokes two subsequent jobs (both of them can run in parallel) as well the test result archive

 

 

 

 

Tear Down

 

  • PSMcli is used to stop the ACCS application and runs in parallel with another job which uses SQLcl to clean up the data in Oracle Database Cloud (drop the table)
  • After that, the final tear down job is invoke, which shuts down the Oracle Database Cloud service instance (again, using PSMcli)

 

 

 

 

 

 

 

Finally, shut down the Oracle Database Cloud service instance

 

 

 

Total recall...

 

  • Split pipeline into phases and implement them using a Build job - the choice of granularity is up to you e.g. you can invoke PSMcli and SQLcl steps in the same job
  • Treat infrastructure (cloud services) as code and manage them from within your pipeline - Developer Cloud makes it easy to across the entire Oracle PaaS platform by PSMcli integration

 

**The views expressed in this post are my own and do not necessarily reflect the views of Oracle