|
1 | 1 | # |
2 | | -# Targets for DEVELOPMENT for performance test web-api |
| 2 | +# Targets for DEVELOPMENT of tests/public-api |
3 | 3 | # |
4 | 4 | include ../../scripts/common.Makefile |
5 | | - |
6 | | -LOCUST_VERSION=2.29.1 |
7 | | -export LOCUST_VERSION |
8 | | - |
9 | | -ENV_FILE=$(shell pwd)/.env |
10 | | -export ENV_FILE |
11 | | - |
12 | | -KERNEL_NAME=$(shell uname -s) |
13 | | - |
14 | | -NETWORK_NAME=dashboards_timenet |
15 | | - |
16 | | -TEST_IMAGE_NAME := itisfoundation/performance-tests |
17 | | -TEST_IMAGE_TAG := v0 |
18 | | - |
19 | | -# UTILS |
20 | | -# NOTE: keep short arguments for `cut` so it works in both BusyBox (alpine) AND Ubuntu |
21 | | -get_my_ip := $(shell (hostname --all-ip-addresses || hostname -i) 2>/dev/null | cut -d " " -f 1) |
22 | | - |
23 | | -# Check that given variables are set and all have non-empty values, |
24 | | -# die with an error otherwise. |
25 | | -# |
26 | | -# Params: |
27 | | -# 1. Variable name(s) to test. |
28 | | -# 2. (optional) Error message to print. |
29 | | -check_defined = \ |
30 | | - $(strip $(foreach 1,$1, \ |
31 | | - $(call __check_defined,$1,$(strip $(value 2))))) |
32 | | -__check_defined = \ |
33 | | - $(if $(value $1),, \ |
34 | | - $(error Undefined $1$(if $2, ($2)))) |
35 | | - |
36 | | - |
37 | | - |
38 | | -.PHONY: build |
39 | | -build: ## builds distributed osparc locust docker image |
40 | | - docker \ |
41 | | - buildx build \ |
42 | | - --load \ |
43 | | - --build-arg LOCUST_VERSION=$(LOCUST_VERSION) \ |
44 | | - --tag itisfoundation/locust:$(LOCUST_VERSION) \ |
45 | | - --tag local/locust:latest \ |
46 | | - . |
47 | | - |
48 | | -.PHONY: push |
49 | | -push: |
50 | | - docker push itisfoundation/locust:$(LOCUST_VERSION) |
51 | | - |
52 | | -.PHONY: test-up test-down |
53 | | -test-up: ## runs osparc locust. Locust and test configuration are specified in ENV_FILE |
54 | | - @if [ ! -f $${ENV_FILE} ]; then echo "You must generate a .env file before running tests!!! See the README..." && exit 1; fi; |
55 | | - @if ! docker network ls | grep -q $(NETWORK_NAME); then \ |
56 | | - docker network create $(NETWORK_NAME); \ |
57 | | - echo "Created docker network $(NETWORK_NAME)"; \ |
| 5 | +include ../../scripts/common-package.Makefile |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +.PHONY: install-dev install-prod install-ci |
| 10 | +install-dev install-prod install-ci: _check_venv_active ## install app in development/production or CI mode |
| 11 | + # installing in $(subst install-,,$@) mode |
| 12 | + @uv pip sync requirements/$(subst install-,,$@).txt |
| 13 | + |
| 14 | + |
| 15 | +# Configuration files and default values |
| 16 | +LOCUST_CONFIG_FILE := .locust.conf |
| 17 | +AUTH_CREDS_FILE := .auth-credentials.env |
| 18 | + |
| 19 | +# Default Database settings |
| 20 | +PG_HOST := 127.0.0.1 |
| 21 | +PG_PORT := 5432 |
| 22 | +PG_USER := postgres |
| 23 | +PG_PASSWORD := password |
| 24 | + |
| 25 | +# Default Grafana settings |
| 26 | +GRAFANA_URL := http://127.0.0.1:3000/ |
| 27 | + |
| 28 | +# Default Locust test settings |
| 29 | +DEFAULT_PROCESSES := 4 |
| 30 | +DEFAULT_USERS := 10 |
| 31 | +DEFAULT_SPAWN_RATE := 1 |
| 32 | +DEFAULT_RUN_TIME := 1m |
| 33 | +DEFAULT_HOST := http://127.0.0.1:9081 |
| 34 | + |
| 35 | + |
| 36 | + |
| 37 | +define create_locust_config |
| 38 | + @if [ ! -f $(LOCUST_CONFIG_FILE) ]; then \ |
| 39 | + printf "$(YELLOW)First time setup: Creating Locust configuration file$(NC)\n"; \ |
| 40 | + printf "Available locust files in locustfiles/:\n"; \ |
| 41 | + find locustfiles -maxdepth 1 -type f -name '*.py' ! -name '__init__.py' -printf ' %p\n'; \ |
| 42 | + find locustfiles -mindepth 2 -type f -name 'workflow.py' -printf ' %p\n'; \ |
| 43 | + read -p "Locust file to use [./locustfiles/deployment_max_rps_single_endpoint.py]: " locustfile; \ |
| 44 | + locustfile=$${locustfile:-./locustfiles/deployment_max_rps_single_endpoint.py}; \ |
| 45 | + read -p "Number of processes [$(DEFAULT_PROCESSES)]: " processes; \ |
| 46 | + processes=$${processes:-$(DEFAULT_PROCESSES)}; \ |
| 47 | + read -p "Number of users [$(DEFAULT_USERS)]: " users; \ |
| 48 | + users=$${users:-$(DEFAULT_USERS)}; \ |
| 49 | + read -p "Spawn rate [$(DEFAULT_SPAWN_RATE)]: " spawn_rate; \ |
| 50 | + spawn_rate=$${spawn_rate:-$(DEFAULT_SPAWN_RATE)}; \ |
| 51 | + read -p "Run time [$(DEFAULT_RUN_TIME)]: " run_time; \ |
| 52 | + run_time=$${run_time:-$(DEFAULT_RUN_TIME)}; \ |
| 53 | + read -p "Host to load test [$(DEFAULT_HOST)]: " host; \ |
| 54 | + host=$${host:-$(DEFAULT_HOST)}; \ |
| 55 | + echo; \ |
| 56 | + echo "# Locust configuration file - Autogenerated" > $(LOCUST_CONFIG_FILE); \ |
| 57 | + echo "[locust]" >> $(LOCUST_CONFIG_FILE); \ |
| 58 | + echo "locustfile = $$locustfile" >> $(LOCUST_CONFIG_FILE); \ |
| 59 | + echo "host = $$host" >> $(LOCUST_CONFIG_FILE); \ |
| 60 | + echo "users = $$users" >> $(LOCUST_CONFIG_FILE); \ |
| 61 | + echo "spawn-rate = $$spawn_rate" >> $(LOCUST_CONFIG_FILE); \ |
| 62 | + echo "run-time = $$run_time" >> $(LOCUST_CONFIG_FILE); \ |
| 63 | + echo "processes = $$processes" >> $(LOCUST_CONFIG_FILE); \ |
| 64 | + echo "loglevel = INFO" >> $(LOCUST_CONFIG_FILE); \ |
| 65 | + echo "" >> $(LOCUST_CONFIG_FILE); \ |
| 66 | + printf "$(GREEN)Locust configuration file created. It won't be asked again.$(NC)\n"; \ |
| 67 | + else \ |
| 68 | + printf "$(GREEN)Using existing Locust configuration file $(LOCUST_CONFIG_FILE)$(NC)\n"; \ |
58 | 69 | fi |
59 | | - docker compose --file docker-compose.yml up --scale worker=4 --exit-code-from=master |
60 | | - |
61 | | -test-down: ## stops and removes osparc locust containers |
62 | | - @docker compose --file docker-compose.yml down |
63 | | - |
64 | | -.PHONY: dashboards-up dashboards-down |
65 | | - |
66 | | -dashboards-up: ## Create Grafana dashboard for inspecting locust results. See dashboard on localhost:3000 |
67 | | - @echo "View your dashboard on localhost:3000" |
68 | | - @if docker network ls | grep -q $(NETWORK_NAME); then \ |
69 | | - docker network rm $(NETWORK_NAME); \ |
70 | | - echo "Removed docker network $(NETWORK_NAME)"; \ |
| 70 | +endef |
| 71 | + |
| 72 | +# Function to prompt for credentials if they don't exist |
| 73 | +define prompt_for_credentials |
| 74 | + @if [ ! -f $(AUTH_CREDS_FILE) ]; then \ |
| 75 | + printf "$(YELLOW)First time setup: Please enter the deployment credentials$(NC)\n"; \ |
| 76 | + read -p "Username: " username; \ |
| 77 | + read -sp "Password: " password; \ |
| 78 | + echo; \ |
| 79 | + echo "SC_USER_NAME=$$username" > $(AUTH_CREDS_FILE); \ |
| 80 | + echo "SC_PASSWORD=$$password" >> $(AUTH_CREDS_FILE); \ |
| 81 | + read -p "osparc Username (required if login in osparc is necessary, press enter to skip): " osparc_username; \ |
| 82 | + if [ ! -z "$$osparc_username" ]; then \ |
| 83 | + read -sp "osparc Password: " osparc_password; \ |
| 84 | + echo; \ |
| 85 | + echo "OSPARC_USER_NAME=$$osparc_username" >> $(AUTH_CREDS_FILE); \ |
| 86 | + echo "OSPARC_PASSWORD=$$osparc_password" >> $(AUTH_CREDS_FILE); \ |
| 87 | + fi; \ |
| 88 | + printf "$(GREEN)Credentials saved. They won't be asked again.$(NC)\n"; \ |
| 89 | + else \ |
| 90 | + printf "$(GREEN)Using cached credentials from $(AUTH_CREDS_FILE)$(NC)\n"; \ |
71 | 91 | fi |
72 | | - @if [[ "$(KERNEL_NAME)" == "Linux" ]]; then \ |
73 | | - ( sleep 3 && xdg-open http://localhost:3000 ) & \ |
| 92 | +endef |
| 93 | + |
| 94 | + |
| 95 | +test-deployment: _check_venv_active ## runs deployment test on deploy |
| 96 | + @$(call prompt_for_credentials) |
| 97 | + @$(call create_locust_config) |
| 98 | + @printf "$(YELLOW)Starting Locust...$(NC)\n" |
| 99 | + @xdg-open http://localhost:8089/ & |
| 100 | + @export $$(cat $(AUTH_CREDS_FILE) | xargs) && \ |
| 101 | + locust --config $(LOCUST_CONFIG_FILE) |
| 102 | + |
| 103 | +test-deployment-ci: _check_venv_active $(AUTH_CREDS_FILE) $(LOCUST_CONFIG_FILE) ## runs deployment test on CI, expects all config and credentials files to be present, does not prompt |
| 104 | + @printf "$(YELLOW)Starting Locust headless...$(NC)\n" |
| 105 | + @export $$(cat $(AUTH_CREDS_FILE) | xargs) && \ |
| 106 | + locust --config $(LOCUST_CONFIG_FILE) \ |
| 107 | + --headless \ |
| 108 | + --html test_report_{u}users_{r}userspawnrate_{t}s.html |
| 109 | + |
| 110 | +test-deployment-with-grafana: _check_venv_active grafana-dashboards-up ## runs deployment test with Grafana integration |
| 111 | + @$(call prompt_for_credentials) |
| 112 | + @$(call create_locust_config) |
| 113 | + @printf "$(YELLOW)Starting Locust with Grafana integration...$(NC)\n" |
| 114 | + @xdg-open $(GRAFANA_URL) |
| 115 | + @export $$(cat $(AUTH_CREDS_FILE) | xargs) && \ |
| 116 | + locust --config $(LOCUST_CONFIG_FILE) \ |
| 117 | + --grafana-url $(GRAFANA_URL) \ |
| 118 | + --pghost $(PG_HOST) \ |
| 119 | + --pgport $(PG_PORT) \ |
| 120 | + --pguser $(PG_USER) \ |
| 121 | + --pgpassword=$(PG_PASSWORD) \ |
| 122 | + --headless \ |
| 123 | + --timescale |
| 124 | + |
| 125 | + |
| 126 | + |
| 127 | + |
| 128 | +clear-credentials: ## Clear the cached authentication credentials |
| 129 | + @if [ -f $(AUTH_CREDS_FILE) ]; then \ |
| 130 | + rm $(AUTH_CREDS_FILE); \ |
| 131 | + printf "$(GREEN)Credentials cleared.$(NC)\n"; \ |
| 132 | + else \ |
| 133 | + printf "$(YELLOW)No credentials file found.$(NC)\n"; \ |
74 | 134 | fi |
75 | | - @locust-compose up |
76 | | - |
77 | | - |
78 | | -dashboards-down: ## stops and removes Grafana dashboard and Timescale postgress containers |
79 | | - @locust-compose down |
80 | | - |
81 | | -.PHONY: install-ci install-dev |
82 | 135 |
|
83 | | -install-dev: |
84 | | - @uv pip install -r requirements/requirements-dev.txt |
85 | 136 |
|
86 | | -install-ci: |
87 | | - @uv pip install -r requirements/requirements-ci.txt |
| 137 | +clear: down clear-credentials clear-locust-config ## Clear all cached data including credentials and Locust configuration files |
88 | 138 |
|
| 139 | +clear-locust-config: ## Clear all Locust configuration files |
| 140 | + @for config_file in $(LOCUST_CONFIG_FILE) $(LOCUST_CONFIG_FILE)_light $(LOCUST_CONFIG_FILE)_heavy; do \ |
| 141 | + if [ -f $$config_file ]; then \ |
| 142 | + rm $$config_file; \ |
| 143 | + printf "$(GREEN)$$config_file cleared.$(NC)\n"; \ |
| 144 | + fi; \ |
| 145 | + done |
| 146 | + @if [ ! -f $(LOCUST_CONFIG_FILE) ] && [ ! -f $(LOCUST_CONFIG_FILE)_light ] && [ ! -f $(LOCUST_CONFIG_FILE)_heavy ]; then \ |
| 147 | + printf "$(YELLOW)No Locust configuration files found.$(NC)\n"; \ |
| 148 | + fi |
89 | 149 |
|
90 | | -.PHONY: config |
91 | | -config: ## Create config for your locust tests |
92 | | - @$(call check_defined, input, please define inputs when calling $@ - e.g. ```make $@ input="--help"```) |
93 | | - @uv run locust_settings.py $(input) | tee "${ENV_FILE}" |
94 | | - |
95 | | - |
96 | | -.PHONY: build-test-image push-test-image |
97 | | -build-test-image: _check_venv_active ## Build test image |
98 | | - docker build --build-arg PYTHON_VERSION="$(shell python --version | cut -d' ' -f2)" --build-arg UV_VERSION="$(shell uv --version | cut -d' ' -f2)" -t ${TEST_IMAGE_NAME}:${TEST_IMAGE_TAG} ./docker |
99 | | - |
100 | | -push-test-image: ## Push test image to dockerhub |
101 | | - docker push ${TEST_IMAGE_NAME}:${TEST_IMAGE_TAG} |
| 150 | +grafana-dashboards-up: ## start grafana dashboards for locust |
| 151 | + @locust-compose up -d |
| 152 | +down grafana-dashboards-down: ## stop grafana dashboards for locust |
| 153 | + @locust-compose down |
0 commit comments