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.com
Let's break the parameters down:
distributedPods
is the number of Locust workers desiredtestFile
is the locustfile containing your testtype
is the backend you want to use,Locust
in this caseduration
configures how long the load test will run fortargetURL
is 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=Locust
In 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_REQUESTS
You 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)