page_type | languages | products | name | description | urlFragment | ||||
---|---|---|---|---|---|---|---|---|---|
sample |
|
|
Azure Search Performance Tests |
Performance testing tool for Azure Cognitive Search |
azure-search-perf |
This pipeline helps to load test Azure Cognitive Search, it leverages Apache JMeter as an open source load and performance testing tool and Terraform to dynamically provision and destroy the required infrastructure on Azure. The JMeter workers and controller are hosted in Azure Container Instances (ACI) to allow VNET injection and Private Endpoint scenarios too.
Note: This is a fork from this original repo customized for Azure Cognitive Search (ACS) REST API and syntax.
The flow is triggered and controlled by an Azure Pipeline on Azure DevOps. The pipeline contains a set of tasks that are organized logically in SETUP
, TEST
, RESULTS
and TEARDOWN
groups.
Task group | Tasks |
---|---|
SETUP | |
TEST | |
RESULTS | |
TEARDOWN |
On the SETUP
phase, JMeter agents are provisioned as Azure Container Instance (ACI) using a custom Docker image on Terraform. Through a Remote Testing approach, JMeter controller is responsible to configure all workers, consolidating all results and generating the resulting artifacts (dashboard, logs, etc).
The infrastructure provisioned by Terraform includes:
- Resource Group
- Virtual Network (VNet)
- Storage Account File Share
- 1 JMeter controller on ACI
- N JMeter workers on ACI
On the RESULTS
phase, a JMeter Report Dashboard and Tests Results are published in the end of each load testing execution.
You should have the following Azure resources:
- Azure DevOps Organization
- Azure Container Registry (ACR) with admin user enabled
- An Azure Cognitive Search Service
Go to Azure DevOps, create a new project, and import this repo.
Click into the Repos tab. You will get a warning saying that the repo is empty. Click on Import a repository, then for the Clone URL copy and paste this url: https://github.com/Azure-Samples/azure-search-performance-testing
Next, create a service connection in Azure Devops as described in the DevOps documentation. This service connection will create a service principal allowing the Azure Pipelines to access the resource group.
Note: Make sure to add the service connection at the subscription level (don't specify a resource group) so the service connection has access to install resource providers.
Make a note of the Service Connection name as it will be used in next step.
Create a variable group named JMETER_TERRAFORM_SETTINGS
as described in the DevOps documentation.
Add the following variables to the variable group:
- TF_VAR_JMETER_ACR_NAME = <your_azurecr_name>
- TF_VAR_RESOURCE_GROUP_NAME = <your_rg_name>
- TF_VAR_JMETER_DOCKER_IMAGE = <your_azurecr_name>.azurecr.io/jmeter
- TF_VAR_LOCATION = <your_preferred_azure_region> (i.e. eastus, westeurope, etc.)
- AZURE_SERVICE_CONNECTION_NAME = <your_service_connection_name>
- AZURE_SUBSCRIPTION_ID = <your_subscription_id>
When you're finished, the variable group should look similar to the image below:
Create a pipeline with New Pipeline (blue button, right side), chose Azure Repos Git (YAML), click on your existing repo (cloned in step #1), configure the pipeline with Existing Azure Pipelines YAML file, the path of the existing file is /pipelines/azure-pipelines.docker.yml.
Rename the new pipeline to jmeter-docker-build
so you won't confuse it with the pipeline created in the next step (in the Pipelines tab, find the three dots inside your pipeline row and there you can rename it).
Run this pipeline before proceeding to the next step.
Replicate the steps as in step #4 but with yaml file pipelines/azure-pipelines.load-test.yml and rename it to jmeter-load-test.
For this pipeline you will need some additional variables:
- API_KEY = <search_service_api_key> (and keep it secret in devops)
- SEARCH_SERVICE_NAME = <your_search_service_name>
- SEARCH_INDEX_NAME = <your_search_index_name>
- TF_VAR_JMETER_JMX_FILE = sample.jmx
- TF_VAR_JMETER_WORKERS_COUNT = 1 (or as many as you want for scalability of the JMeter workers)
Save the pipeline but don't run it yet. You may want to update sample.jmx
as described in the next step.
By default the test uses sample.jmx
. This JMX file contains a test definition for performing HTTP requests on <your-search-service-name>.search.windows.net
endpoint through the 443
port.
You can update the JMX file with the test definition of your preference. You can find more details on updating the test definition in jmeter/README.md.
Now you're ready to run the pipeline:
Note: The variables you created in step #5 might not show up on this view, but rest assured they haven't been deleted.
If you're using the default test configuration this should take about 10-15 minutes to complete.
JMeter test results are created in a JTL file (results.jtl
) with CSV formatting. A Python script was created to convert JTL to JUnit format and used during the pipeline to have full integration with Azure DevOps test visualization.
Error messages generated by JMeter for failed HTTP requests can also be seen on Azure DevOps. In this case, Sevice Unavailable
usually means the request was throttled by the search service.
Some artifacts are published after the test ends. Some of them are a static JMeter Dashboard, logs and others.
You can also download these build artifacts using
az pipelines runs artifact download
.
After downloading the dashboard and unzipping it, open dashboard/index.html
on your browser.
The sample.jmx includes some modules to configure the HTTP request, headers and body that Azure Cognitive Search is expecting. It also includes subsections to configure the query distribution (ie 10 concurrent users per second during 1 minute), a section to define which search terms will be sent (to avoid distortion in latencies thanks to cache) that read an input CSV. For more details and examples: JMeter official doc.
If you struggle adding new modules to the .jmx (the syntax can be quite tricky) I would suggest to use JMeter's UI and save the config to a temporary jmx file, analyze the new module and embed it in your jmx config file.
All Terraform parameters can be configured using the Variable Group JMETER_TERRAFORM_SETTINGS
. Please read JMeter Pipeline Settings to know more details about it.
-
Load Test duration Please note that for Microsoft hosted agents, you can have pipelines that runs up to 1 hour (private project) or 6 hours (public project). You can have your own agents to bypass this limitation.
-
ACI on VNET regions Please note that not all regions currently support ACI and VNET integration. If you need private JMeter agents, you can deploy it in a different region and use VNET peering between them. Also note that vCPUs and memory limits change based on regions.
- Implementation Notes
- Adding plugins to JMeter Docker image
- JMeter pipeline settings
- Estimating costs
- Integrating with Application Insights
- User Manual: Remote Testing
- User Manual: Apache JMeter Distributed Testing Step-by-step
- Azure DevOps CLI reference
- Create your Azure Cognitive Search instance and populate an index with clinical trials docs
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.