From f9adde1ea4a7addfabf0cfd4386cb83b2ca40dd2 Mon Sep 17 00:00:00 2001 From: Maxence Boutet Date: Fri, 9 Jul 2021 17:54:17 -0400 Subject: [PATCH] Some scripts I use to manually test locust locally --- scripts/locustfile.py | 81 ++++++++++++++++++++++++++++++ scripts/run-disributed-headless.sh | 58 +++++++++++++++++++++ scripts/run-disributed-web.sh | 57 +++++++++++++++++++++ scripts/run-local-headless.sh | 20 ++++++++ scripts/run-local-web.sh | 19 +++++++ 5 files changed, 235 insertions(+) create mode 100644 scripts/locustfile.py create mode 100755 scripts/run-disributed-headless.sh create mode 100755 scripts/run-disributed-web.sh create mode 100755 scripts/run-local-headless.sh create mode 100755 scripts/run-local-web.sh diff --git a/scripts/locustfile.py b/scripts/locustfile.py new file mode 100644 index 0000000000..7702543f84 --- /dev/null +++ b/scripts/locustfile.py @@ -0,0 +1,81 @@ +import math + +from locust import HttpUser, task, constant +from locust import LoadTestShape + + +class UserA(HttpUser): + wait_time = constant(600) + + # host = "https://example.com" + + @task + def get_root(self): + self.client.get("/", name="UserA") + + +class UserB(HttpUser): + wait_time = constant(600) + + # host = "https://example.com" + + @task + def get_root(self): + self.client.get("/", name="UserB") + + +class UserC(HttpUser): + wait_time = constant(600) + + # host = "https://example.com" + + @task + def get_root(self): + self.client.get("/", name="UserC") + + +# class StepLoadShape(LoadTestShape): +# step_time = 30 +# step_load = 10 +# spawn_rate = 1 +# time_limit = 300 +# +# def tick(self): +# run_time = self.get_run_time() +# +# if run_time > self.time_limit: +# return None +# +# current_step = math.floor(run_time / self.step_time) + 1 +# return current_step * self.step_load, self.spawn_rate + + +class RampUpThenDownLoadShape(LoadTestShape): + stages = [ + {"duration": 5, "users": 1, "spawn_rate": 1}, + {"duration": 35, "users": 30, "spawn_rate": 1}, + {"duration": 35, "users": 1, "spawn_rate": 1}, + {"duration": 35, "users": 73, "spawn_rate": 6}, + {"duration": 35, "users": 1, "spawn_rate": 6}, + {"duration": 35, "users": 153, "spawn_rate": 17}, + {"duration": 10, "users": 145, "spawn_rate": 1}, + {"duration": 60, "users": 130, "spawn_rate": 0.25}, + {"duration": 15, "users": 50, "spawn_rate": 25}, + {"duration": 20, "users": 1, "spawn_rate": 5}, + ] + + for previous_stage, stage in zip(stages[:-1], stages[1:]): + stage["duration"] += previous_stage["duration"] + + for previous_stage, stage in zip(stages[:-1], stages[1:]): + assert stage["duration"] > previous_stage["duration"] + + def tick(self): + run_time = self.get_run_time() + + for stage in self.stages: + if run_time < stage["duration"]: + tick_data = (stage["users"], stage["spawn_rate"]) + return tick_data + + return None diff --git a/scripts/run-disributed-headless.sh b/scripts/run-disributed-headless.sh new file mode 100755 index 0000000000..e9f938f629 --- /dev/null +++ b/scripts/run-disributed-headless.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +set -o errexit +set -o pipefail +set -o nounset + +script_dir="$(realpath "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )")" +root_dir="$(realpath "${script_dir}/..")" + +pushd "${root_dir}" +"${VIRTUAL_ENV}/bin/pip" install --editable . +popd + +pushd "${script_dir}" + +pids=() + +function cleanup(){ + for pid in ${pids} + do + echo "Killing worker with pid ${pid}" + kill -9 "${pid}" || echo "Failed killing worker with pid ${pid}" + done +} + +trap cleanup EXIT + +export LOCUST_WORKER_ADDITIONAL_WAIT_BEFORE_READY_AFTER_STOP=5 + +n_workers=4 + +for n in $(seq 1 ${n_workers}) +do + tmp_file="$(mktemp /tmp/locust-worker-${n}.log.XXXXXX)" + echo "Starting worker ${n} (logs in ${tmp_file})" + "${VIRTUAL_ENV}/bin/python" -m locust \ + --locustfile "${script_dir}/locustfile.py" \ + --host "https://example.com" \ + --worker \ + --master-host "0.0.0.0" \ + --master-port "5557" \ + --logfile "${tmp_file}" \ + --loglevel "DEBUG" & + pids+=($!) +done + +echo "Starting master" +"${VIRTUAL_ENV}/bin/python" -m locust \ + --locustfile "${script_dir}/locustfile.py" \ + --host "https://example.com" \ + --headless \ + --master \ + --master-bind-host "0.0.0.0" \ + --master-bind-port "5557" \ + --expect-workers ${n_workers} \ + --loglevel "DEBUG" + +popd diff --git a/scripts/run-disributed-web.sh b/scripts/run-disributed-web.sh new file mode 100755 index 0000000000..6bf17706a2 --- /dev/null +++ b/scripts/run-disributed-web.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +set -o errexit +set -o pipefail +set -o nounset + +script_dir="$(realpath "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )")" +root_dir="$(realpath "${script_dir}/..")" + +pushd "${root_dir}" +"${VIRTUAL_ENV}/bin/pip" install --editable . +popd + +pushd "${script_dir}" + +pids=() + +function cleanup(){ + for pid in ${pids} + do + echo "Killing worker with pid ${pid}" + kill -9 "${pid}" || echo "Failed killing worker with pid ${pid}" + done +} + +trap cleanup EXIT + +export LOCUST_WORKER_ADDITIONAL_WAIT_BEFORE_READY_AFTER_STOP=5 + +n_workers=13 + +for n in $(seq 1 ${n_workers}) +do + tmp_file="$(mktemp /tmp/locust-worker-${n}.log.XXXXXX)" + echo "Starting worker ${n} (logs in ${tmp_file})" + "${VIRTUAL_ENV}/bin/python" -m locust \ + --locustfile "${script_dir}/locustfile.py" \ + --host "https://example.com" \ + --worker \ + --master-host "0.0.0.0" \ + --master-port "5557" \ + --logfile "${tmp_file}" \ + --loglevel "DEBUG" & + pids+=($!) +done + +echo "Starting master" +"${VIRTUAL_ENV}/bin/python" -m locust \ + --locustfile "${script_dir}/locustfile.py" \ + --host "https://example.com" \ + --master \ + --master-bind-host "0.0.0.0" \ + --master-bind-port "5557" \ + --expect-workers ${n_workers} \ + --loglevel "DEBUG" + +popd diff --git a/scripts/run-local-headless.sh b/scripts/run-local-headless.sh new file mode 100755 index 0000000000..5ed3f5cf01 --- /dev/null +++ b/scripts/run-local-headless.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +set -o errexit +set -o pipefail +set -o nounset + +script_dir="$(realpath "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )")" +root_dir="$(realpath "${script_dir}/..")" + +pushd "${root_dir}" +"${VIRTUAL_ENV}/bin/pip" install --editable . +popd + +pushd "${script_dir}" +"${VIRTUAL_ENV}/bin/python" -m locust \ + --locustfile "${script_dir}/locustfile.py" \ + --headless \ + --host "https://example.com" \ + --loglevel "INFO" +popd diff --git a/scripts/run-local-web.sh b/scripts/run-local-web.sh new file mode 100755 index 0000000000..da48572253 --- /dev/null +++ b/scripts/run-local-web.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -o errexit +set -o pipefail +set -o nounset + +script_dir="$(realpath "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )")" +root_dir="$(realpath "${script_dir}/..")" + +pushd "${root_dir}" +"${VIRTUAL_ENV}/bin/pip" install --editable . +popd + +pushd "${script_dir}" +"${VIRTUAL_ENV}/bin/python" -m locust \ + --locustfile "${script_dir}/locustfile.py" \ + --host "https://example.com" \ + --loglevel "DEBUG" +popd