Performance testing with DevOps and Jmeter
Performance testing was something I always overlooked and saw it as an NFR done during application development instead of during continued support of a live application.
Context
We have a customer who would often hear from its customers around slowness on the applications when users were searching for specific information in a large database. With a fix in place, we wanted to first try and replicate what customers may be experiencing then test our fix before production release.
The application is .NET based that runs on Azure PaaS and makes use of Azure B2C for customer login. Customer would hit B2C then the WebApp, API and onto the Azure SQL Database to return required information.
Setting up a jmeter rig on DevOps is straight forward with help of the following git repo and guide https://github.com/Azure-Samples/jmeter-aci-terraform
https://docs.microsoft.com/en-us/samples/azure-samples/jmeter-aci-terraform/jmeter-aci-terraform/
It would be recommended to follow the set-up guide provided by Microsoft as this will help speed up the process instead of writing code from scratch.
The jmeter rig is using Terraform, docker and Azure container instances. There are 2 YAML pipelines, jmeter-docker-build and Jmeter-load-test. A folder within the git repo called jmeter has a file called sample.jmx, replace this file with your required jmeter script file.
How it works
A connection from DevOps to Azure Portal is required, if you follow the Microsoft guide it will provide CLI to create DevOps library of creds. This contains subscription ID, Azure ACR resource group, connection name, docker image and name.
Next, run the jmeter-docker-build pipeline which will pull latest docker image and store it in the ACR.
Run Jmeter-load-test which will use Terraform to configure the infrastructure for the JMeter. This involves workers, vNet, storage account, address space and containers. During the phase it will also move the jmeter.jmx file from the repo to a storage account where the jmeter image can obtain it. Once the infrastructure is built it will then start running the jmeter script based on the configuration you provide. At the end it will store the results in the test plan section of Azure DevOps and run terraform destroy function to clean up and help contain costs.
For our application we had a specific requirement. The application makes use of Azure B2C for logging in. We didn’t want to be creating 50 or 100 user accounts for the jmeter to hit the B2C login screen thousands of times during our performance testing in case we get a denial of service from Microsoft. Due to this we used code on the developer side and app settings on the infrastructure side to remove the B2C login screen. We did this by creating our own valid Authentication Ticket and updating the startup file for the application to use our new “Offline Authentication” method instead of using B2C to log into the application.
This was the same process used for another application called Internal Dashboard which was not public facing and used azure AD for login. We used an app setting to tell the application this is your username/password to bypass AD login.
End result
From running this, we were able to provide the customer a report on 5, 50 and 100 users hitting the application and using the filter functionality on the data table which was causing performance issues before. We were able to see slow responses and pages failing which led to the developer amending some SQL queries. A code fix was applied, and the entire JMeter rig redeployed using the pipeline which resulted in no errors on 5 or 50 users and slower responses on 100 but still showing no errors.
Using jmeter with Azure DevOps, you can easily implement automation via pipelines running on a schedule for customers to see metrics on the application performance over time or when a new code change has been implemented.