Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/automated load test #1

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FROM grubykarol/locust:1.2.3-python3.9-alpine3.12
RUN pip install requests_toolbelt
19 changes: 9 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Locust on OpenShift

Run distributed load tests using Locust and OpenShift.
Run distributed load tests using Locust and OpenShift.

Original idea and inspiration came from: https://medium.com/locust-io-experiments/locust-io-experiments-running-in-kubernetes-95447571a550

Expand All @@ -14,7 +14,6 @@ $ ./seed.sh file_name_with_test.py https://www.url-to-test.com

__Note:__ the `seed.sh` use the `oc` command to push the changes.


### Install OC command

* Download oc Client Tools
Expand Down Expand Up @@ -50,28 +49,28 @@ $ chmod +x /usr/local/bin/oc
$ oc login https://www.cluster-address.com
```

* Create new project:
* Create new project / login to your existing project:

```
$ oc new-project locust --display-name=Locust --description="Locust.io load tests cluster";
```

* Select project namespace:

```
$ oc project locust;
```

* Deploy Locust `master` pod:
* give the setup load test file permissions to run :

```
$ oc process -f master-deployment.yaml | oc create -f -
$ chmod a+x setup_load_tests.sh
```

* Deploy Locust `slave` pod:
* change the namespace on line 2 of setup_load_tests.sh
* add host name to each load test file according to the format of locust_test_oc.py line 4
* place all you load tests in the root directory

```
$ oc process -f slave-deployment.yaml | oc create -f -
$ ./setup_load_tests.sh
```

__Note:__ the `slave-deployment.yaml` has the comment out code for setting up auto scaling the pods, but `Locust` will reset the test to distribute the load every time a new slave is added. You can manually create the `slave` pods before starting the test and destroy them when done.
NOTE : You need to run dos2unix / unix2dos for the code to work as expected
Binary file added __pycache__/locust_test.cpython-38.pyc
Binary file not shown.
1,263 changes: 1,263 additions & 0 deletions image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions locust_test_chitchat.pyc
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# import requests
# import json

# base_url = "http://15.206.63.149:8000"
# params = {
# "query": "i am happy",
# }

# r = requests.get(base_url+"/get-chitchat", data=json.dumps(params))
# response = r.json()

# print(response)

import time, json
from locust import HttpUser, task, between

# host=http://15.206.63.149:8000

class QuickstartUser(HttpUser):
wait_time = between(0, 1)

@task
def hello_world(self):
params = {
"query": "i am happy",
}

resp = self.client.get("/get-chitchat", data=json.dumps(params))
assert resp.status_code == 200
31 changes: 16 additions & 15 deletions master-deployment.yaml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
kind: Template
apiVersion: v1
labels:
template: "locust"
template: "service_name"
metadata:
name: locust-master
name: service_name
objects:
- kind: Service
apiVersion: v1
metadata:
name: locust
name: service_name
namespace: ${NAMESPACE}
spec:
selector:
app: locust-master
app: service_name
ports:
- name: "communication"
protocol: TCP
Expand All @@ -28,41 +28,42 @@ objects:
- apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: app
name: service_name
namespace: ${NAMESPACE}
spec:
port:
targetPort: web-ui
to:
kind: Service
name: locust
name: service_name
weight: 100
wildcardPolicy: None

- kind: DeploymentConfig
apiVersion: v1
metadata:
name: locust-master
name: service_name
namespace: ${NAMESPACE}
spec:
replicas: 1
template:
metadata:
labels:
app: locust-master
app: service_name
spec:
containers:
- name: locust-master
- name: service_name
image: ${LOCUST_IMAGE}
env:
- name: CONFIG_HASH
value: TO_BE_CHANGED
# - name: CONFIG_HASH
# value: TO_BE_CHANGED
- name: ATTACKED_HOST
valueFrom:
configMapKeyRef:
name: host-url
key: ATTACKED_HOST
- name: LOCUST_MODE
value: MASTER
- name: LOCUST_MODE_MASTER
value: "true"
- name: LOCUST_OPTS
value: --print-stats -P=8089
resources:
Expand Down Expand Up @@ -131,5 +132,5 @@ parameters:
- name: LOCUST_IMAGE
displayName: Locust docker image
description: Name of the image to be used.
value: grubykarol/locust:0.13.5-python3.8-alpine3.11
required: true
value: quay.io/whoacademy/chatbot-locust
required: true
39 changes: 29 additions & 10 deletions seed.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,39 @@

testFile=""
hostName=""

dcMasterName=""
dcSlaveName=""
scriptName=""
namespace=locust
# Display prompt if not arguments passed
if [[ -z "$1" && -z "$2" ]]
if [[ -z "$1" && -z "$2" && -z "$3" && -z "$4" && -z "$5" && -z "$6" ]]
then
read -p 'File to run: ' testFile
read -p 'Host to attack: ' hostName
read -p 'Name of master service: ' dcmastername
read -p 'Host to worker service: ' dcslavename
read -p 'Name of the script: ' scriptName
read -p 'Name of the host url: ' hostUrlName
read -p 'Name of the namespace: ' namespace
else
testFile=$1
hostName=$2
dcMasterName=$3
dcSlaveName=$4
scriptName=$5
hostUrlName=$6
fi

# Confirmation
echo "Confirmation: file to run is: $testFile and the host: $hostName"
echo "Confirmation: file to run is: $testFile, the host: $hostName and the script name is $scriptName in the namespace $namespace"

# Prepare Config map with new values
cat > config-map.yaml << EOF1
kind: ConfigMap
apiVersion: v1
metadata:
name: host-url
namespace: locust
name: $hostUrlName
namespace: $namespace
data:
ATTACKED_HOST: $hostName
EOF1
Expand All @@ -38,12 +50,14 @@ cat > config-map.yaml << EOF1
kind: ConfigMap
apiVersion: v1
metadata:
name: script-file
namespace: locust
name: $scriptName
namespace: $namespace
data:
locustfile.py: |
$(cat $testFile | sed 's/^/ /')
EOF1
# oldName='script-file'
# sed -i '' "s/${oldName}/${scriptName}/g" config-map.yaml

# Push it to cluster
cat config-map.yaml | oc apply -f -
Expand All @@ -52,6 +66,11 @@ cat config-map.yaml | oc apply -f -
rm ./config-map.yaml

# Update the environment variable to trigger a change
oc project locust
oc set env dc/locust-master --overwrite CONFIG_HASH=`date +%s%N`
oc set env dc/locust-slave --overwrite CONFIG_HASH=`date +%s%N`
oc project $namespace
#oc set env dc/locust-master --overwrite CONFIG_HASH=`date +%s%N`
#oc set env dc/locust-slave --overwrite CONFIG_HASH=`date +%s%N`

# confighash=`date +%s%N`

# oc set env dc/${dcMasterName} --overwrite CONFIG_HASH=$confighash
# oc set env dc/${dcSlaveName} --overwrite CONFIG_HASH=$confighash
65 changes: 65 additions & 0 deletions setup_load_tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/bin/bash
for fileName in ./*.py; do
# extract host
tempHost=$(grep '# host' $fileName)
tempHost=${tempHost/'# host='/''}
onlyName=${fileName/'.py'/''}
onlyName=${onlyName:2}
onlyName=${onlyName/'_'/'-'}
onlyName=${onlyName/'_'/'-'}
echo $onlyName

# create copies of master deployment
tempfileName='master-deployment-_.yaml'
newName=${tempfileName/'_'/$onlyName}
cp ./master-deployment.yaml $newName
# echo $onlyName
master="-master"
slave="-slave"
onlyNamemaster="$onlyName$master"
onlyNameslave="$onlyName$slave"
oldName='service_name'
sed -i '' "s/${oldName}/${onlyNamemaster}/g" $newName

oldName='script-file'
scriptName="$oldName-$onlyName"
sed -i '' "s/${oldName}/${scriptName}/g" $newName

oldName='host-url'
hostUrlName="$oldName-$onlyName"
sed -i '' "s/${oldName}/${hostUrlName}/g" $newName

# create copies of slave deployment
tempfileName='slave-deployment-_.yaml'
newNameSlave=${tempfileName/'_'/$onlyName}
cp ./slave-deployment.yaml $newNameSlave
oldName='service_name'
sed -i '' "s/${oldName}/${onlyNameslave}/g" $newNameSlave

oldName='LOCUST_SERVICE_HOST'
hostAppend="_PORT_8089_TCP_ADDR"
newHost="$onlyNamemaster$hostAppend"
newHost=${newHost/'-'/'_'}
newHost=${newHost/'-'/'_'}
newHost=${newHost/'-'/'_'}
newHost=`echo "${newHost}" | tr '[a-z]' '[A-Z]'`
sed -i '' "s/${oldName}/${newHost}/g" $newNameSlave

oldName='script-file'
scriptName="$oldName-$onlyName"
sed -i '' "s/${oldName}/${scriptName}/g" $newNameSlave

oldName='host-url'
sed -i '' "s/${oldName}/${hostUrlName}/g" $newNameSlave

# first create config variables
sh ./seed.sh $fileName $tempHost $onlyNamemaster $onlyNameslave $scriptName $hostUrlName

# create deployments which consume the configs
oc process -f $newName | oc create -f -
oc process -f $newNameSlave | oc create -f -


# cleanup
rm $newName $newNameSlave
done
Loading