Locust is one of the load generators implemented in Kangal. It uses the official docker image locustio/locust.
Kangal requires a .py testfile describing the test.
For more information, check the Locust official site.
You can create Locust load tests using Kangal Proxy.
Let's create a simple test file named locustfile.py with this content:
from locust import HttpUser, task, between
class ExampleLoadTest(HttpUser):
wait_time = between(5, 15)
@task
def example_page(self):
self.client.get('/example-page')Now, send this to Kangal using this command:
$ curl -X POST http://${KANGAL_PROXY_ADDRESS}/load-test \
-H 'Content-Type: multipart/form-data' \
-F distributedPods=1 \
-F testFile=@locustfile.py \
-F type=Locust \
-F duration=10m \
-F targetURL=http://my-app.example.comLet's break the parameters down:
distributedPodsis the number of Locust workers desiredtestFileis the locustfile containing your testtypeis the backend you want to use,Locustin this casedurationconfigures how long the load test will run fortargetURLis the host to be prefixed on all relative URLs in the locustfile
Note: If you don't specify
duration, your tests will run infinitely.
Note: If you don't specify
targetURL, be sure to use absolute URLs on your locustfile or your tests will fail.
Here's another example:
from locust import HttpUser, task, between
class ExampleLoadTest(HttpUser):
wait_time = between(5, 15)
@task
def example_page(self):
self.client.get('http://my-app.example.com/example-page')And again, upload it to Kangal:
$ curl -X POST http://${KANGAL_PROXY_ADDRESS}/load-test \
-H 'Content-Type: multipart/form-data' \
-F distributedPods=1 \
-F testFile=@locustfile.py \
-F type=LocustIn this last example, the test will run infinitely and no targetURL is specified in the request, since it's set in the test code.
By default, Kangal does not specify resource requirements for loadtests run with Locust as a backend.
You can specify resource limits and requests for Locust master and worker containers to ensure that when the load generator runs, it has sufficient resources and will not fail before the service does.
The following environment variables can be specified to configure this parameter:
LOCUST_MASTER_CPU_LIMITS
LOCUST_MASTER_CPU_REQUESTS
LOCUST_MASTER_MEMORY_LIMITS
LOCUST_MASTER_MEMORY_REQUESTS
LOCUST_WORKER_CPU_LIMITS
LOCUST_WORKER_CPU_REQUESTS
LOCUST_WORKER_MEMORY_LIMITS
LOCUST_WORKER_MEMORY_REQUESTSYou have to specify these variables on the Kangal Controller, read more at charts/kangal/README.md.
More information regarding resource limits and requests can be found in the following page(s):
- https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
- https://cloud.google.com/blog/products/gcp/kubernetes-best-practices-resource-requests-and-limits
It's recommended to read the official Locust documentation.
Using test data in load tests with Locust and Kangal is currently not supported.
Locust can write test statistics in CSV format, to persist those files, put the code below into your locustfile.
Note: Kangal Locust implementation automatically exports reports to the
/tmp/folder.
import glob
import os
import tarfile
import requests
from locust import HttpUser, events
from locust.runners import MasterRunner
@events.quitting.add_listener
def hook_quit(environment):
presigned_url = os.environ.get("REPORT_PRESIGNED_URL")
if presigned_url is None:
return
if not isinstance(environment.runner, MasterRunner):
return
report = "/home/locust/report.tar.gz"
tar = tarfile.open(report, "w:gz")
for item in glob.glob("/tmp/*.csv"):
print("Adding %s..." % item)
tar.add(item, arcname=os.path.basename(item))
tar.close()
request_headers = {"content-type": "application/gzip"}
requests.put(presigned_url, data=open(report, "rb"), headers=request_headers)