A Simple Load Testing Pipeline on Openshift 4 and Jenkins
Theres one thing needed to be done before deploying your app to production environment, and that is ensuring that your app able to perform well under a high load of transaction. One way to achieve that is by doing a load testing and stress testing internally before deploying to production, but there are times when load testing are being done at the end of development phase with not many time left for developer to do performance tuning. Therefore the better approach is by “shifting left” both load and stress testing phase to an earlier phase, and that is since development phase.
The concept on this blog is doing a load testing on a temporary deployed application, with a maximum one percent acceptable fail. Why i need to deploy the application first before doing a load testing? Because im trying to simulate the exact same condition with production, where each application is a standalone pod, with a specific memory and cpu allocation.
Everything is automated, monitored and managed thru jenkins pipeline with a specific load testing scenario created separatedly in a regular JMeter desktop ui, saved and mapped to a specific application. The detail can be see on on below image where scenario 1 is a scenario created for application 1.
The hard part is creating a JMeter application that is able to consume different scenario, with a parameterized thread and testing endpoint. Thats why im leveraging jmeter-maven-plugin for this, because it’s so lightweight and have a dynamic configuration.
It consist only a one pom file with multiple parameterized fields,
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.edw</groupId> <artifactId>JMeterLoadTesting</artifactId> <version>1.0-SNAPSHOT</version> <name>JMeterLoadTesting</name> <description>A Load Testing tool</description> <properties> <java.version>11</java.version> </properties> <dependencies> </dependencies> <build> <plugins> <plugin> <groupId>com.lazerycode.jmeter</groupId> <artifactId>jmeter-maven-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <id>configuration</id> <goals> <goal>configure</goal> </goals> </execution> <execution> <id>jmeter-tests</id> <phase>integration-test</phase> <goals> <goal>jmeter</goal> </goals> </execution> <execution> <id>jmeter-check-results</id> <goals> <goal>results</goal> </goals> </execution> </executions> <configuration> <testFilesIncluded> <jMeterTestFile>${testfile}</jMeterTestFile> </testFilesIncluded> <propertiesJMeter> <threads>${threads}</threads> <rampup>${rampup}</rampup> <loops>${loops}</loops> <url>${url}</url> <port>${port}</port> </propertiesJMeter> <errorRateThresholdInPercent>1</errorRateThresholdInPercent> </configuration> </plugin> </plugins> </build> </project>
Next is we need to create a JMeter test scenario, a simple http GET to root url. And save it to test01.jmx, and put it on /test/jmeter folder so that jmeter-maven-plugin can detect this scenario.
We can test our JMeter script with below command, below example we are running test01.jmx which is doing a 25 hit testing within a 5 seconds timeframe.
mvn clean verify -Dthreads=5 -Dloops=5 -Drampup=5 \ -Durl=localhost -Dport=8080 -Dtestfile=test01.jmx
The next complicated task is to create a simple Jenkins pipeline script to run this. It needs to have the ability to build and deploy an apps on a temporary pod, do load testing, and clean all resources once load testing is done.
node('maven2') { def appname = "app-loadtest-${env.BUILD_NUMBER}" try { stage ('pull code') { sh "git clone https://github.com/edwin/app-loadtest.git source" } stage ('deploy to ocp') { dir("source") { sh "oc new-build jenkins2/openjdk-11-rhel7 --name=${appname} --binary " sh "oc start-build ${appname} --from-dir=. --follow --wait" sh "oc new-app --docker-image=image-registry.openshift-image-registry.svc:5000/jenkins2/${appname}:latest --name=${appname} || true" sh "oc set resources dc ${appname} --limits=cpu=500m,memory=1024Mi --requests=cpu=200m,memory=256Mi" } } stage ('do load test') { sh "git clone https://github.com/edwin/jmeter-loadtesting.git load" dir("load") { // 5 threads x 5 loops in 5 seconds sh "mvn clean verify -Dthreads=5 -Dloops=5 -Drampup=5 -Durl=${appname} -Dport=8080 -Dtestfile=test01.jmx" } } } catch (error) { throw error } finally { stage('housekeeping') { sh "oc delete svc ${appname}" sh "oc delete bc ${appname}" sh "oc delete is ${appname}" sh "oc delete dc ${appname}" } } }
If we run the pipeline, we can see that it will spawn an appication pod. We can check whether application runs perfectly or not, by running terminal directly inside it.
The result on Jenkins Dashboard will be like this,
As for the loadtest result, we can see those on our Jenkins logs
All codes are available on github,
https://github.com/edwin/app-loadtest https://github.com/edwin/jmeter-loadtesting
So, have fun with Jenkins and JMeter 🙂