locust-cloud 1.5.8__py3-none-any.whl → 1.5.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- locust_cloud/__init__.py +1 -1
- locust_cloud/cloud.py +33 -21
- locust_cloud/timescale/exporter.py +11 -2
- locust_cloud/timescale/queries.py +5 -2
- locust_cloud/timescale/query.py +1 -1
- locust_cloud/webui/dist/assets/{index-EqSfuHMz.js → index-DRoU0Oli.js} +70 -70
- locust_cloud/webui/dist/index.html +1 -1
- locust_cloud/webui/tsconfig.tsbuildinfo +1 -1
- {locust_cloud-1.5.8.dist-info → locust_cloud-1.5.10.dist-info}/METADATA +1 -1
- locust_cloud-1.5.10.dist-info/RECORD +23 -0
- locust_cloud-1.5.8.dist-info/RECORD +0 -23
- {locust_cloud-1.5.8.dist-info → locust_cloud-1.5.10.dist-info}/WHEEL +0 -0
- {locust_cloud-1.5.8.dist-info → locust_cloud-1.5.10.dist-info}/entry_points.txt +0 -0
locust_cloud/__init__.py
CHANGED
locust_cloud/cloud.py
CHANGED
@@ -64,22 +64,28 @@ parser = configargparse.ArgumentParser(
|
|
64
64
|
configargparse.DefaultConfigFileParser,
|
65
65
|
]
|
66
66
|
),
|
67
|
-
description="""Launches distributed Locust runs on locust.cloud infrastructure.
|
67
|
+
description="""Launches a distributed Locust runs on locust.cloud infrastructure.
|
68
68
|
|
69
|
-
Example: locust-cloud -f my_locustfile.py --
|
69
|
+
Example: locust-cloud -f my_locustfile.py --users 1000 ...""",
|
70
70
|
epilog="""Any parameters not listed here are forwarded to locust master unmodified, so go ahead and use things like --users, --host, --run-time, ...
|
71
71
|
Locust config can also be set using config file (~/.locust.conf, locust.conf, pyproject.toml, ~/.cloud.conf or cloud.conf).
|
72
72
|
Parameters specified on command line override env vars, which in turn override config files.""",
|
73
73
|
add_config_file_help=False,
|
74
74
|
add_env_var_help=False,
|
75
|
+
add_help=False,
|
76
|
+
)
|
77
|
+
parser.add_argument(
|
78
|
+
"-h",
|
79
|
+
"--help",
|
80
|
+
action="help",
|
81
|
+
help=configargparse.SUPPRESS,
|
75
82
|
)
|
76
|
-
|
77
83
|
parser.add_argument(
|
78
84
|
"-f",
|
79
85
|
"--locustfile",
|
80
86
|
metavar="<filename>",
|
81
87
|
default="locustfile.py",
|
82
|
-
help="The Python file
|
88
|
+
help="The Python file that contains your test. Defaults to 'locustfile.py'.",
|
83
89
|
env_var="LOCUST_LOCUSTFILE",
|
84
90
|
)
|
85
91
|
parser.add_argument(
|
@@ -90,29 +96,37 @@ parser.add_argument(
|
|
90
96
|
help="Number of users to launch. This is the same as the regular Locust argument, but also affects how many workers to launch.",
|
91
97
|
env_var="LOCUST_USERS",
|
92
98
|
)
|
93
|
-
parser.
|
99
|
+
advanced = parser.add_argument_group("advanced")
|
100
|
+
advanced.add_argument(
|
101
|
+
"--loglevel",
|
102
|
+
"-L",
|
103
|
+
type=str,
|
104
|
+
help="Set --loglevel DEBUG for extra info.",
|
105
|
+
default="INFO",
|
106
|
+
)
|
107
|
+
advanced.add_argument(
|
94
108
|
"--requirements",
|
95
109
|
type=str,
|
96
110
|
help="Optional requirements.txt file that contains your external libraries.",
|
97
111
|
)
|
98
|
-
|
112
|
+
advanced.add_argument(
|
99
113
|
"--region",
|
100
114
|
type=str,
|
101
115
|
default=os.environ.get("AWS_DEFAULT_REGION", DEFAULT_REGION_NAME),
|
102
116
|
help="Sets the AWS region to use for the deployed cluster, e.g. us-east-1. It defaults to use AWS_DEFAULT_REGION env var, like AWS tools.",
|
103
117
|
)
|
104
|
-
|
118
|
+
advanced.add_argument(
|
105
119
|
"--kube-cluster-name",
|
106
120
|
type=str,
|
107
121
|
default=DEFAULT_CLUSTER_NAME,
|
108
|
-
help=
|
122
|
+
help=configargparse.SUPPRESS,
|
109
123
|
env_var="KUBE_CLUSTER_NAME",
|
110
124
|
)
|
111
|
-
|
125
|
+
advanced.add_argument(
|
112
126
|
"--kube-namespace",
|
113
127
|
type=str,
|
114
128
|
default=DEFAULT_NAMESPACE,
|
115
|
-
help=
|
129
|
+
help=configargparse.SUPPRESS,
|
116
130
|
env_var="KUBE_NAMESPACE",
|
117
131
|
)
|
118
132
|
parser.add_argument(
|
@@ -138,26 +152,19 @@ parser.add_argument(
|
|
138
152
|
parser.add_argument(
|
139
153
|
"--username",
|
140
154
|
type=str,
|
141
|
-
help=
|
155
|
+
help=configargparse.SUPPRESS,
|
142
156
|
default=os.getenv("LOCUST_CLOUD_USERNAME", None), # backwards compatitibility for dmdb
|
143
157
|
)
|
144
158
|
parser.add_argument(
|
145
159
|
"--password",
|
146
160
|
type=str,
|
147
|
-
help=
|
161
|
+
help=configargparse.SUPPRESS,
|
148
162
|
default=os.getenv("LOCUST_CLOUD_PASSWORD", None), # backwards compatitibility for dmdb
|
149
163
|
)
|
150
|
-
parser.add_argument(
|
151
|
-
"--loglevel",
|
152
|
-
"-L",
|
153
|
-
type=str,
|
154
|
-
help="Log level",
|
155
|
-
default="INFO",
|
156
|
-
)
|
157
164
|
parser.add_argument(
|
158
165
|
"--workers",
|
159
166
|
type=int,
|
160
|
-
help=f"Number of workers to use for the deployment. Defaults to number of users divided by {USERS_PER_WORKER}",
|
167
|
+
help=f"Number of workers to use for the deployment. Defaults to number of users divided by {USERS_PER_WORKER}.",
|
161
168
|
default=None,
|
162
169
|
)
|
163
170
|
parser.add_argument(
|
@@ -230,6 +237,7 @@ def main() -> None:
|
|
230
237
|
return
|
231
238
|
|
232
239
|
logger.info(f"Uploading {options.locustfile}")
|
240
|
+
logger.debug(f"... to {s3_bucket}")
|
233
241
|
s3 = credential_manager.session.client("s3")
|
234
242
|
try:
|
235
243
|
s3.upload_file(options.locustfile, s3_bucket, os.path.basename(options.locustfile))
|
@@ -318,6 +326,9 @@ def main() -> None:
|
|
318
326
|
except CredentialError as ce:
|
319
327
|
logger.error(f"Credential error: {ce}")
|
320
328
|
sys.exit(1)
|
329
|
+
except KeyboardInterrupt:
|
330
|
+
logger.debug("Interrupted by user")
|
331
|
+
sys.exit(0)
|
321
332
|
|
322
333
|
log_group_name = f"/eks/{options.kube_cluster_name}-{options.kube_namespace}"
|
323
334
|
master_pod_name = next((pod for pod in deployed_pods if "master" in pod), None)
|
@@ -410,9 +421,10 @@ def delete(s3_bucket, credential_manager):
|
|
410
421
|
)
|
411
422
|
|
412
423
|
if response.status_code != 200:
|
413
|
-
logger.
|
424
|
+
logger.info(
|
414
425
|
f"Could not automatically tear down Locust Cloud: HTTP {response.status_code}/{response.reason} - Response: {response.text} - URL: {response.request.url}"
|
415
426
|
)
|
427
|
+
logger.debug(response.json()["message"])
|
416
428
|
except Exception as e:
|
417
429
|
logger.error(f"Could not automatically tear down Locust Cloud: {e.__class__.__name__}:{e}")
|
418
430
|
|
@@ -12,6 +12,7 @@ import locust.env
|
|
12
12
|
import psycopg
|
13
13
|
import psycopg.types.json
|
14
14
|
from locust.exception import CatchResponseError
|
15
|
+
from locust.runners import MasterRunner
|
15
16
|
|
16
17
|
|
17
18
|
def safe_serialize(obj):
|
@@ -185,11 +186,19 @@ class Exporter:
|
|
185
186
|
cmd = sys.argv[1:]
|
186
187
|
with self.pool.connection() as conn:
|
187
188
|
conn.execute(
|
188
|
-
"INSERT INTO testruns (id, num_users, description, arguments) VALUES (%s,%s,%s,%s)",
|
189
|
+
"INSERT INTO testruns (id, num_users, worker_count, username, locustfile, description, arguments) VALUES (%s,%s,%s,%s,%s,%s,%s)",
|
189
190
|
(
|
190
191
|
self._run_id,
|
191
192
|
self.env.runner.target_user_count if self.env.runner else 1,
|
192
|
-
|
193
|
+
len(self.env.runner.clients)
|
194
|
+
if isinstance(
|
195
|
+
self.env.runner,
|
196
|
+
MasterRunner,
|
197
|
+
)
|
198
|
+
else 0,
|
199
|
+
self.env.web_ui.template_args.get("username", "") if self.env.web_ui else "",
|
200
|
+
self.env.parsed_locustfiles[0].split("/")[-1],
|
201
|
+
self.env.parsed_options.description,
|
193
202
|
" ".join(cmd),
|
194
203
|
),
|
195
204
|
)
|
@@ -198,7 +198,10 @@ SELECT
|
|
198
198
|
requests,
|
199
199
|
date_trunc('second', end_time - id) AS "runTime",
|
200
200
|
description,
|
201
|
-
exit_code as "exitCode"
|
201
|
+
exit_code as "exitCode",
|
202
|
+
username,
|
203
|
+
worker_count as "workerCount",
|
204
|
+
locustfile
|
202
205
|
FROM testruns
|
203
206
|
ORDER BY id DESC
|
204
207
|
"""
|
@@ -261,7 +264,7 @@ total_runtime = """
|
|
261
264
|
SELECT
|
262
265
|
SUM((end_time - id) * num_users) AS "totalVuh"
|
263
266
|
FROM testruns
|
264
|
-
WHERE id >= date_trunc('month', NOW())
|
267
|
+
WHERE id >= date_trunc('month', NOW()) AND NOT refund
|
265
268
|
"""
|
266
269
|
|
267
270
|
queries: dict["str", LiteralString] = {
|
locust_cloud/timescale/query.py
CHANGED
@@ -59,5 +59,5 @@ def register_query(environment, pool):
|
|
59
59
|
logger.warning(f"Received invalid query key: '{query}'")
|
60
60
|
return make_response("Invalid query key", 401)
|
61
61
|
except Exception as e:
|
62
|
-
logger.
|
62
|
+
logger.info(f"Error executing UI query '{query}': {e}", exc_info=True)
|
63
63
|
return make_response("Error executing query", 401)
|