diff --git a/Makefile b/Makefile index b6b5f45611c..696e93bb9a2 100644 --- a/Makefile +++ b/Makefile @@ -102,7 +102,7 @@ SWARM_HOSTS = $(shell docker node ls --format="{{.Hostname}}" 2>$(if $(IS_WIN),N define _docker_compose_build export BUILD_TARGET=$(if $(findstring -devel,$@),development,$(if $(findstring -cache,$@),cache,production));\ $(if $(findstring -x,$@),\ - pushd services; docker buildx bake --file docker-compose-build.yml; popd;,\ + pushd services; docker buildx bake --file docker-compose-build.yml $(if $(target),$(target),); popd;,\ docker-compose --file services/docker-compose-build.yml build $(if $(findstring -nc,$@),--no-cache,) $(if $(target),,--parallel)\ ) endef @@ -126,7 +126,7 @@ ifeq ($(findstring webserver,$(target)),webserver) endif # Building service $(target) $(if $(findstring -kit,$@),export DOCKER_BUILDKIT=1;export COMPOSE_DOCKER_CLI_BUILD=1;,) \ - $(_docker_compose_build) $(target) + $(_docker_compose_build) endif diff --git a/tests/performance/Dockerfile b/tests/performance/Dockerfile new file mode 100644 index 00000000000..eee75266b21 --- /dev/null +++ b/tests/performance/Dockerfile @@ -0,0 +1,6 @@ +FROM locustio/locust:1.4.4 + +RUN pip3 --version && \ + pip3 install \ + faker \ + python-dotenv diff --git a/tests/performance/Makefile b/tests/performance/Makefile index a0ae96d5158..3ad7ed13fe9 100644 --- a/tests/performance/Makefile +++ b/tests/performance/Makefile @@ -3,6 +3,19 @@ # include ../../scripts/common.Makefile +# Check that given variables are set and all have non-empty values, +# die with an error otherwise. +# +# Params: +# 1. Variable name(s) to test. +# 2. (optional) Error message to print. +check_defined = \ + $(strip $(foreach 1,$1, \ + $(call __check_defined,$1,$(strip $(value 2))))) +__check_defined = \ + $(if $(value $1),, \ + $(error Undefined $1$(if $2, ($2)))) + .PHONY: requirements requirements: ## compiles pip requirements (.in -> .txt) @$(MAKE_C) requirements reqs @@ -13,17 +26,30 @@ requirements: ## compiles pip requirements (.in -> .txt) @echo "WARNING ##### $< is newer than $@ ####"; diff -uN $@ $<; false;,\ @echo "WARNING ##### $@ does not exist, cloning $< as $@ ############"; cp $< $@) +.PHONY: build +build: + docker buildx build --tag local/locust:latest . + +.PHONY: up +up: + @$(call check_defined, target, please define target file when calling $@ - e.g. ```make $@ target=MY_LOCUST_FILE.py```) + @export TARGET=$(target); \ + docker-compose --file docker-compose.yml up + +down: + docker-compose --file docker-compose.yml down .PHONY: install install-dev: _check_venv_active ## installs dependencies # installing requirements pip-sync requirements/dev.txt +locusfile=$(if $(target),$(target),locusfile.py) .PHONY: start start: _check_venv_active .env ## starts locust, a scriptable and scalable performance testing tool # Open http://localhost:8089/ - locust --locustfile locustfile.py --host http://127.0.0.1:9081 --users 3 --spawn-rate 1 + locust --locustfile $(locusfile) --host http://127.0.0.1:9081 --users 3 --spawn-rate 1 .PHONY: list diff --git a/tests/performance/catalog_services.py b/tests/performance/catalog_services.py new file mode 100644 index 00000000000..0a44dc63748 --- /dev/null +++ b/tests/performance/catalog_services.py @@ -0,0 +1,52 @@ +# +# SEE https://docs.locust.io/en/stable/quickstart.html +# + +import logging +import os + +import faker +from dotenv import load_dotenv +from locust import task +from locust.contrib.fasthttp import FastHttpUser + +logging.basicConfig(level=logging.INFO) + +fake = faker.Faker() + +load_dotenv() # take environment variables from .env + + +class WebApiUser(FastHttpUser): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.email = fake.email() + + # @task + # def health_check(self): + # self.client.get("/v0/health") + + @task(weight=5) + def get_services(self): + self.client.get( + f"/v0/catalog/services", + ) + + def on_start(self): + print("Created User ", self.email) + self.client.post( + "/v0/auth/register", + json={ + "email": self.email, + "password": "my secret", + "confirm": "my secret", + }, + ) + self.client.post( + "/v0/auth/login", json={"email": self.email, "password": "my secret"} + ) + + def on_stop(self): + self.client.post("/v0/auth/logout") + print("Stopping", self.email) diff --git a/tests/performance/director_services.py b/tests/performance/director_services.py new file mode 100644 index 00000000000..765f017ce99 --- /dev/null +++ b/tests/performance/director_services.py @@ -0,0 +1,31 @@ +# +# SEE https://docs.locust.io/en/stable/quickstart.html +# + +import logging + +from dotenv import load_dotenv +from locust import task +from locust.contrib.fasthttp import FastHttpUser + +logging.basicConfig(level=logging.INFO) + + +load_dotenv() # take environment variables from .env + + +class WebApiUser(FastHttpUser): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + @task() + def get_services(self): + self.client.get( + f"/v0/services", + ) + + def on_start(self): + print("Created User ") + + def on_stop(self): + print("Stopping") diff --git a/tests/performance/docker-compose.yml b/tests/performance/docker-compose.yml new file mode 100644 index 00000000000..565eb6159a0 --- /dev/null +++ b/tests/performance/docker-compose.yml @@ -0,0 +1,16 @@ +version: '3.8' + +services: + master: + image: local/locust:latest + ports: + - "8089:8089" + volumes: + - ./:/mnt/locust + command: -f /mnt/locust/${TARGET} --master -H http://master:8089 + + worker: + image: local/locust:latest + volumes: + - ./:/mnt/locust + command: -f /mnt/locust/${TARGET} --worker --master-host master