Skip to content

Commit 39de6e4

Browse files
committed
refactor: remove stop-timeout from Locust config and improve logging in webserver services
1 parent 64635ff commit 39de6e4

File tree

4 files changed

+56
-13
lines changed

4 files changed

+56
-13
lines changed

tests/performance/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ define create_locust_config
6161
echo "spawn-rate = $$spawn_rate" >> $(LOCUST_CONFIG_FILE); \
6262
echo "run-time = $$run_time" >> $(LOCUST_CONFIG_FILE); \
6363
echo "processes = $$processes" >> $(LOCUST_CONFIG_FILE); \
64-
echo "stop-timeout = 10s" >> $(LOCUST_CONFIG_FILE); \
6564
echo "loglevel = INFO" >> $(LOCUST_CONFIG_FILE); \
6665
echo "" >> $(LOCUST_CONFIG_FILE); \
6766
printf "$(GREEN)Locust configuration file created. It won't be asked again.$(NC)\n"; \

tests/performance/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ users = 10
7777
spawn-rate = 1
7878
run-time = 5m
7979
processes = 4
80-
stop-timeout = 10s
8180
loglevel = INFO
8281
EOF
8382

tests/performance/common/base_user.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import locust_plugins
66
from locust import FastHttpUser, events
7+
from locust.argument_parser import LocustArgumentParser
78
from locust.env import Environment
89

910
from .auth_settings import DeploymentAuth, OsparcAuth
@@ -59,7 +60,7 @@ def authenticated_patch(self, url, **kwargs):
5960

6061

6162
@events.init_command_line_parser.add_listener
62-
def _(parser) -> None:
63+
def _(parser: LocustArgumentParser) -> None:
6364
parser.add_argument(
6465
"--requires-login",
6566
action="store_true",
@@ -83,12 +84,20 @@ class OsparcWebUserBase(OsparcUserBase):
8384
"""
8485

8586
abstract = True # This class is abstract and won't be instantiated by Locust
87+
requires_login = False # Default value, can be overridden by subclasses
8688

8789
def __init__(self, *args, **kwargs):
8890
super().__init__(*args, **kwargs)
89-
if self.environment.parsed_options.requires_login:
91+
# Determine if login is required once during initialization
92+
self._login_required = (
93+
getattr(self.__class__, "requires_login", False)
94+
or self.environment.parsed_options.requires_login
95+
)
96+
97+
# Initialize auth if login is required
98+
if self._login_required:
9099
self.osparc_auth = OsparcAuth()
91-
_logger.debug(
100+
_logger.info(
92101
"Using OsparcAuth for login with username: %s",
93102
self.osparc_auth.OSPARC_USER_NAME,
94103
)
@@ -98,15 +107,15 @@ def on_start(self) -> None:
98107
Called when a web user starts. Can be overridden by subclasses
99108
to implement custom startup behavior, such as logging in.
100109
"""
101-
if self.environment.parsed_options.requires_login:
110+
if self._login_required:
102111
self._login()
103112

104113
def on_stop(self) -> None:
105114
"""
106115
Called when a web user stops. Can be overridden by subclasses
107116
to implement custom shutdown behavior, such as logging out.
108117
"""
109-
if self.environment.parsed_options.requires_login:
118+
if self._login_required:
110119
self._logout()
111120

112121
def _login(self) -> None:
@@ -119,13 +128,13 @@ def _login(self) -> None:
119128
},
120129
)
121130
response.raise_for_status()
122-
logging.debug(
131+
_logger.debug(
123132
"Logged in user with email: %s", self.osparc_auth.OSPARC_USER_NAME
124133
)
125134

126135
def _logout(self) -> None:
127136
# Implement logout logic here
128137
self.authenticated_post("/v0/auth/logout")
129-
logging.debug(
138+
_logger.debug(
130139
"Logged out user with email: %s", self.osparc_auth.OSPARC_USER_NAME
131140
)

tests/performance/locustfiles/webserver_services.py

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,70 @@
22
# SEE https://docs.locust.io/en/stable/quickstart.html
33
#
44

5+
import json
56
import logging
67
import urllib
78
import urllib.parse
9+
from typing import Any
810

911
import locust
1012
from common.base_user import OsparcWebUserBase
13+
from locust import events
14+
from locust.env import Environment
1115

1216
_logger = logging.getLogger(__name__)
1317

1418

19+
@events.init.add_listener
20+
def _(environment: Environment, **_kwargs: Any) -> None:
21+
"""
22+
Log the testing environment options when Locust initializes.
23+
24+
Args:
25+
environment: The Locust environment
26+
_kwargs: Additional keyword arguments
27+
"""
28+
# Log that this test requires login
29+
_logger.info(
30+
"This test requires login (requires_login=True class attribute is set)."
31+
)
32+
33+
# Only log the parsed options, as the full environment is not JSON serializable
34+
assert (
35+
environment.parsed_options is not None
36+
), "Environment parsed options must not be None"
37+
options_dict: dict[str, Any] = vars(environment.parsed_options)
38+
_logger.info("Testing environment options: %s", json.dumps(options_dict, indent=2))
39+
40+
1541
class WebApiUser(OsparcWebUserBase):
42+
"""Web API user that always requires login regardless of command line flags."""
43+
44+
# This overrides the class attribute in OsparcWebUserBase
45+
requires_login = True
46+
1647
@locust.task
1748
def list_latest_services(self):
1849
base_url = "/v0/catalog/services/-/latest"
19-
params = {"offset": 20, "limit": 20}
20-
50+
params = {"offset": 0, "limit": 20}
51+
page_num = 0
2152
while True:
22-
response = self.authenticated_get(base_url, params=params)
53+
response = self.authenticated_get(
54+
base_url, params=params, name=f"{base_url}/{page_num}"
55+
)
2356
response.raise_for_status()
2457

2558
page = response.json()
2659

2760
# Process the current page data here
28-
next_link = page["_links"].get("next")
61+
next_link = page["data"]["_links"].get("next")
2962
if not next_link:
3063
break
3164

3265
# Update base_url and params for the next request
66+
page_num += 1
3367
parsed_next = urllib.parse.urlparse(next_link)
3468
base_url = parsed_next.path
3569
params = dict(urllib.parse.parse_qsl(parsed_next.query))
70+
71+
_logger.info(params)

0 commit comments

Comments
 (0)