locust 2.46.8.dev8__tar.gz → 2.46.8.dev24__tar.gz

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.
Files changed (69) hide show
  1. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/PKG-INFO +1 -1
  2. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/_version.py +2 -2
  3. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/contrib/csv_request_logger.py +2 -2
  4. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/contrib/fasthttp.py +3 -3
  5. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/opentelemetry.py +6 -2
  6. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/web.py +11 -1
  7. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/.gitignore +0 -0
  8. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/LICENSE +0 -0
  9. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/README.md +0 -0
  10. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/hatch_build.py +0 -0
  11. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/__init__.py +0 -0
  12. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/__main__.py +0 -0
  13. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/argument_parser.py +0 -0
  14. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/clients.py +0 -0
  15. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/contrib/__init__.py +0 -0
  16. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/contrib/dns.py +0 -0
  17. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/contrib/milvus.py +0 -0
  18. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/contrib/mongodb.py +0 -0
  19. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/contrib/mqtt.py +0 -0
  20. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/contrib/oai.py +0 -0
  21. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/contrib/postgres.py +0 -0
  22. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/contrib/qdrant.py +0 -0
  23. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/contrib/socketio.py +0 -0
  24. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/debug.py +0 -0
  25. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/dispatch.py +0 -0
  26. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/env.py +0 -0
  27. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/event.py +0 -0
  28. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/exception.py +0 -0
  29. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/html.py +0 -0
  30. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/input_events.py +0 -0
  31. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/log.py +0 -0
  32. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/main.py +0 -0
  33. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/py.typed +0 -0
  34. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/rpc/__init__.py +0 -0
  35. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/rpc/protocol.py +0 -0
  36. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/rpc/zmqrpc.py +0 -0
  37. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/runners.py +0 -0
  38. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/shape.py +0 -0
  39. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/stats.py +0 -0
  40. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/user/__init__.py +0 -0
  41. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/user/inspectuser.py +0 -0
  42. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/user/markov_taskset.py +0 -0
  43. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/user/sequential_taskset.py +0 -0
  44. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/user/task.py +0 -0
  45. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/user/users.py +0 -0
  46. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/user/wait_time.py +0 -0
  47. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/util/__init__.py +0 -0
  48. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/util/cache.py +0 -0
  49. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/util/date.py +0 -0
  50. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/util/deprecation.py +0 -0
  51. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/util/directory.py +0 -0
  52. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/util/exception_handler.py +0 -0
  53. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/util/load_locustfile.py +0 -0
  54. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/util/rounding.py +0 -0
  55. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/util/timespan.py +0 -0
  56. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/util/url.py +0 -0
  57. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/webui/dist/assets/favicon-dark.png +0 -0
  58. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/webui/dist/assets/favicon-light.png +0 -0
  59. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/webui/dist/assets/graphs-dark.png +0 -0
  60. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/webui/dist/assets/graphs-light.png +0 -0
  61. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/webui/dist/assets/src-pSlzKFX1.js +0 -0
  62. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/webui/dist/assets/terminal.gif +0 -0
  63. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/webui/dist/assets/testruns-dark.png +0 -0
  64. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/webui/dist/assets/testruns-light.png +0 -0
  65. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/webui/dist/auth.html +0 -0
  66. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/webui/dist/index.html +0 -0
  67. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/locust/webui/dist/report.html +0 -0
  68. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/pyproject.toml +0 -0
  69. {locust-2.46.8.dev8 → locust-2.46.8.dev24}/pytest_locust/plugin.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: locust
3
- Version: 2.46.8.dev8
3
+ Version: 2.46.8.dev24
4
4
  Summary: Developer-friendly load testing framework
5
5
  Project-URL: Homepage, https://locust.cloud/
6
6
  Project-URL: Repository, https://github.com/locustio/locust
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '2.46.8.dev8'
22
- __version_tuple__ = version_tuple = (2, 46, 8, 'dev8')
21
+ __version__ = version = '2.46.8.dev24'
22
+ __version_tuple__ = version_tuple = (2, 46, 8, 'dev24')
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -149,7 +149,7 @@ class CsvRequestLogger:
149
149
  *,
150
150
  request_type: str,
151
151
  name: str,
152
- response_time: float,
152
+ response_time: float | None,
153
153
  response_length: int,
154
154
  exception: Any = None,
155
155
  response: Any = None,
@@ -170,7 +170,7 @@ class CsvRequestLogger:
170
170
  round(ts, 6),
171
171
  request_type,
172
172
  name,
173
- round(response_time, 2),
173
+ round(response_time, 2) if response_time is not None else "",
174
174
  response_length,
175
175
  status_code,
176
176
  exc_str,
@@ -633,9 +633,9 @@ class LocustUserAgent(UserAgent):
633
633
  def _urlopen(self, request):
634
634
  """Override _urlopen() in order to make it use the response_type attribute"""
635
635
  client = self.clientpool.get_client(request.url_split)
636
- resp = client.request(
637
- request.method, request.url_split.request_uri, body=request.payload, headers=request.headers
638
- )
636
+ # quoted_uri (percent-encoded, as geventhttpclient's own UserAgent sends it) was added in geventhttpclient 2.3.4
637
+ request_uri = getattr(request.url_split, "quoted_uri", request.url_split.request_uri)
638
+ resp = client.request(request.method, request_uri, body=request.payload, headers=request.headers)
639
639
  return self.response_type(resp, request=request, sent_request=resp._sent_request)
640
640
 
641
641
  def _verify_status(self, status_code, url=None):
@@ -53,7 +53,9 @@ def setup_opentelemetry(locustfile: str, profile: str | None) -> bool:
53
53
 
54
54
  @events.request.add_listener
55
55
  def on_request(name, response_time, exception, **kwargs):
56
- if len(request_names) < MAX_REQUEST_NAMES:
56
+ if name in request_names:
57
+ attributes = {"name": name}
58
+ elif len(request_names) < MAX_REQUEST_NAMES:
57
59
  request_names.add(name)
58
60
  attributes = {"name": name}
59
61
  else:
@@ -62,7 +64,9 @@ def setup_opentelemetry(locustfile: str, profile: str | None) -> bool:
62
64
  if exception:
63
65
  attributes["error.type"] = exception.__class__.__name__
64
66
 
65
- ttlb_histogram.record(response_time / 1000.0, attributes=attributes)
67
+ # response_time is None for requests that have no duration (typically async requests)
68
+ if response_time is not None:
69
+ ttlb_histogram.record(response_time / 1000.0, attributes=attributes)
66
70
 
67
71
  @events.init.add_listener
68
72
  def on_locust_init(runner, **kwargs):
@@ -162,6 +162,7 @@ class WebUI:
162
162
  app.debug = True
163
163
  self.greenlet: gevent.Greenlet | None = None
164
164
  self._swarm_greenlet: gevent.Greenlet | None = None
165
+ self._run_time_greenlet: gevent.Greenlet | None = None
165
166
  self.template_args = {}
166
167
  self.auth_args = {}
167
168
  self.app.template_folder = build_path or DEFAULT_BUILD_PATH
@@ -336,6 +337,7 @@ class WebUI:
336
337
  if self._swarm_greenlet is not None:
337
338
  self._swarm_greenlet.kill(block=True)
338
339
  self._swarm_greenlet = None
340
+ self._cancel_run_time_timer()
339
341
 
340
342
  if environment.runner is not None:
341
343
  if user_count is None or user_count < 0 or spawn_rate is None or spawn_rate <= 0:
@@ -350,7 +352,8 @@ class WebUI:
350
352
  "host": environment.host,
351
353
  }
352
354
  if run_time:
353
- gevent.spawn_later(run_time, self._stop_runners).link_exception(greenlet_exception_handler)
355
+ self._run_time_greenlet = gevent.spawn_later(run_time, self._stop_runners)
356
+ self._run_time_greenlet.link_exception(greenlet_exception_handler)
354
357
  response_data["run_time"] = run_time
355
358
 
356
359
  if self.userclass_picker_is_active:
@@ -366,6 +369,7 @@ class WebUI:
366
369
  if self._swarm_greenlet is not None:
367
370
  self._swarm_greenlet.kill(block=True)
368
371
  self._swarm_greenlet = None
372
+ self._cancel_run_time_timer()
369
373
  if environment.runner is not None:
370
374
  environment.runner.stop()
371
375
  return jsonify({"success": True, "message": "Test stopped"})
@@ -797,5 +801,11 @@ class WebUI:
797
801
  self.environment._remove_user_classes_with_weight_zero()
798
802
  self.environment._validate_user_class_name_uniqueness()
799
803
 
804
+ def _cancel_run_time_timer(self):
805
+ if self._run_time_greenlet is not None:
806
+ self._run_time_greenlet.kill(block=False)
807
+ self._run_time_greenlet = None
808
+
800
809
  def _stop_runners(self):
810
+ self._run_time_greenlet = None
801
811
  self.environment.runner.stop()
File without changes
File without changes
File without changes