locust 2.27.1.dev31__py3-none-any.whl → 2.27.1.dev40__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/_version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '2.27.1.dev31'
16
- __version_tuple__ = version_tuple = (2, 27, 1, 'dev31')
15
+ __version__ = version = '2.27.1.dev40'
16
+ __version_tuple__ = version_tuple = (2, 27, 1, 'dev40')
locust/runners.py CHANGED
@@ -223,6 +223,9 @@ class Runner:
223
223
  new_users: list[User] = []
224
224
  while n < spawn_count:
225
225
  new_user = self.user_classes_by_name[user_class](self.environment)
226
+ assert hasattr(
227
+ new_user, "environment"
228
+ ), f"Attribute 'environment' is missing on user {user_class}. Perhaps you defined your own __init__ and forgot to call the base constructor? (super().__init__(*args, **kwargs))"
226
229
  new_user.start(self.user_greenlets)
227
230
  new_users.append(new_user)
228
231
  n += 1
locust/stats.py CHANGED
@@ -708,7 +708,10 @@ class StatsError:
708
708
 
709
709
  @classmethod
710
710
  def parse_error(cls, error: Exception | str | None) -> str:
711
- string_error = repr(error)
711
+ if isinstance(error, str):
712
+ string_error = error
713
+ else:
714
+ string_error = repr(error)
712
715
  target = "object at 0x"
713
716
  target_index = string_error.find(target)
714
717
  if target_index < 0:
@@ -730,16 +733,19 @@ class StatsError:
730
733
 
731
734
  def to_name(self) -> str:
732
735
  error = self.error
733
- if isinstance(error, CatchResponseError):
734
- # standalone
735
- unwrapped_error = error.args[0]
736
- if isinstance(error, str) and error.startswith("CatchResponseError("):
737
- # distributed
738
- length = len("CatchResponseError(")
739
- unwrapped_error = error[length:-1]
740
- else:
741
- # standalone, unwrapped exception
742
- unwrapped_error = repr(error)
736
+ if isinstance(error, str): # in distributed mode, all errors have been converted to strings
737
+ if error.startswith("CatchResponseError("):
738
+ # unwrap CatchResponseErrors
739
+ length = len("CatchResponseError(")
740
+ unwrapped_error = error[length:-1]
741
+ else:
742
+ unwrapped_error = error
743
+ else: # in standalone mode, errors are still objects
744
+ if isinstance(error, CatchResponseError):
745
+ # unwrap CatchResponseErrors
746
+ unwrapped_error = error.args[0]
747
+ else:
748
+ unwrapped_error = repr(error)
743
749
 
744
750
  return f"{self.method} {self.name}: {unwrapped_error}"
745
751
 
locust/test/test_main.py CHANGED
@@ -2129,6 +2129,8 @@ class AnyUser(HttpUser):
2129
2129
  self.assertIn("(index 3) reported as ready", stderr)
2130
2130
  self.assertIn("The last worker quit, stopping test", stderr)
2131
2131
  self.assertIn("Shutting down (exit code 0)", stderr)
2132
+ # ensure no weird escaping in error report. Not really related to ctrl-c...
2133
+ self.assertIn(", 'Connection refused') ", stderr)
2132
2134
 
2133
2135
  @unittest.skipIf(os.name == "nt", reason="--processes doesnt work on windows")
2134
2136
  def test_workers_shut_down_if_master_is_gone(self):
@@ -144,6 +144,24 @@ class LocustRunnerTestCase(LocustTestCase):
144
144
 
145
145
 
146
146
  class TestLocustRunner(LocustRunnerTestCase):
147
+ def test_missing_constructor_call_in_user(self):
148
+ class BadUser(User):
149
+ def __init__(self, *args, **kwargs):
150
+ pass # not calling base class constructor!!!
151
+
152
+ @task
153
+ def t(self):
154
+ pass
155
+
156
+ environment = Environment(user_classes=[BadUser])
157
+ runner = LocalRunner(environment)
158
+ with self.assertRaises(AssertionError) as assert_raises_context:
159
+ runner.spawn_users({BadUser.__name__: 1})
160
+ self.assertIn(
161
+ "Attribute 'environment' is missing on user BadUser. Perhaps you defined your own __init__ and forgot to call the base constructor",
162
+ str(assert_raises_context.exception),
163
+ )
164
+
147
165
  def test_cpu_warning(self):
148
166
  _monitor_interval = runners.CPU_MONITOR_INTERVAL
149
167
  runners.CPU_MONITOR_INTERVAL = 2.0
locust/web.py CHANGED
@@ -147,7 +147,10 @@ class WebUI:
147
147
  def handle_exception(error):
148
148
  error_message = str(error)
149
149
  error_code = getattr(error, "code", 500)
150
- logger.log(logging.INFO if error_code <= 404 else logging.ERROR, error_message)
150
+ logger.log(
151
+ logging.INFO if error_code <= 404 else logging.ERROR,
152
+ f"UI got request for {request.path}, but it resulted in a {error.code}: {error.name}",
153
+ )
151
154
  return make_response(error_message, error_code)
152
155
 
153
156
  @app.route("/assets/<path:path>")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: locust
3
- Version: 2.27.1.dev31
3
+ Version: 2.27.1.dev40
4
4
  Summary: Developer-friendly load testing framework
5
5
  License: MIT
6
6
  Project-URL: Homepage, https://github.com/locustio/locust
@@ -1,6 +1,6 @@
1
1
  locust/__init__.py,sha256=g6oA-Ba_hs3gLWVf5MKJ1mvfltI8MFnDWG8qslqm8yg,1402
2
2
  locust/__main__.py,sha256=vBQ82334kX06ImDbFlPFgiBRiLIinwNk3z8Khs6hd74,31
3
- locust/_version.py,sha256=HNXUelTsGm6bsluVLMgm9poEZdP4iGkdzm3eDBkNMKQ,428
3
+ locust/_version.py,sha256=3uMMGoO04UD8xBt4WrGeqL6Lo4R5EgC72VHpkOTnU-8,428
4
4
  locust/argument_parser.py,sha256=w4-Ue1XAFPwG3sLyXrpdV9ejKjTUOpcSsPBbCKwRbiQ,28740
5
5
  locust/clients.py,sha256=YKuAyMAbxs8_-w7XJw0hc67KFBNNLxibsw6FwiS01Q8,14781
6
6
  locust/debug.py,sha256=We6Z9W0btkKSc7PxWmrZx-xMynvOOsKhG6jmDgQin0g,5134
@@ -13,10 +13,10 @@ locust/input_events.py,sha256=ZIyePyAMuA_YFYWg18g_pE4kwuQV3RbEB250MzXRwjY,3314
13
13
  locust/log.py,sha256=cqLt7nnxnQuM4vWFB5EpJpNUTxGBVEkUJuaJPI1S7_Y,3186
14
14
  locust/main.py,sha256=NGjL5QqakU5aeyUzwu2Fh00xVZfC3eoBE3DtfOmRtcM,27854
15
15
  locust/py.typed,sha256=gkWLl8yD4mIZnNYYAIRM8g9VarLvWmTAFeUfEbxJLBw,65
16
- locust/runners.py,sha256=Go8b8fpOAfFy6JuNcot7KyguHuExA6eoPHVmcgx3RoI,67813
16
+ locust/runners.py,sha256=kbEJtHVbDyQnd4IFo0GogasiZKWGXqFgiOiKt3aMjxw,68083
17
17
  locust/shape.py,sha256=t-lwBS8LOjWcKXNL7j2U3zroIXJ1b0fazUwpRYQOKXw,1973
18
- locust/stats.py,sha256=-kI5fTGgs6w5FSaFYGhBAE2PnnCQWuBqmhYPTGPctTA,45558
19
- locust/web.py,sha256=4XKB_5OJzugXC-YguBg19hhAk1vfOmuOg9UQc7Djkv8,26857
18
+ locust/stats.py,sha256=IXhOtYJ_B863kyrHysNQmuFHv2Vd57vE3Rnerwp3bzs,45859
19
+ locust/web.py,sha256=5Zj8nTa3Kr0aLhC1bXjZ5bissSOddYFQnIw8NOFUdPI,26976
20
20
  locust/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  locust/contrib/fasthttp.py,sha256=vByPepw35DF84qZ2xK89yHgjOA_8btV0wig_rSR6p4g,26757
22
22
  locust/rpc/__init__.py,sha256=nVGoHWFQxZjnhCDWjbgXIbmFbN9sizAjkhvSs9_642c,58
@@ -36,10 +36,10 @@ locust/test/test_interruptable_task.py,sha256=LZKSV-aJNnwfvAxguz6SckBEuGEnfGimoI
36
36
  locust/test/test_load_locustfile.py,sha256=v-muHoM-CYu8t7DXm4AQtFP2q8RYfnTTUBqj7uVqhig,8494
37
37
  locust/test/test_locust_class.py,sha256=oGhhOX848jHRQnIfFlhLlW-kHGYLyYsfDX8hM07Ro7g,25506
38
38
  locust/test/test_log.py,sha256=YPY6vgTAy1KaNU2qoVvQrTH5x_mzRrljEHrkSBy3yxs,7553
39
- locust/test/test_main.py,sha256=R2akeBreg6aXC2Dhs-HxvFq_0EE64hzEaIZmAVALW4w,84866
39
+ locust/test/test_main.py,sha256=7OuH2-7noD_rbeoKJD9hIZsylSugu7ze3XFIrU1u0HI,85016
40
40
  locust/test/test_old_wait_api.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
41
  locust/test/test_parser.py,sha256=-2VO5Dopg-VoWvIgXrmr7GN40cqrnjUoctBHmVlyewg,17826
42
- locust/test/test_runners.py,sha256=xfBdRPOH1CiNk4Rwqmbx6S1e2BDuWdtqDw9omDJ50Ec,159395
42
+ locust/test/test_runners.py,sha256=UWHmQW59QV1ZQzHRZjFIZiSW8ROUIVCuUgU-VAwOpH8,160110
43
43
  locust/test/test_sequential_taskset.py,sha256=QjVMWWfGHn9hU5AvPxRDU7Vo5DcVW1VkMVfDA0k9OPE,3398
44
44
  locust/test/test_stats.py,sha256=F51VkL3k3y4OhYBlRyV6vWzisenSAOmSWKy2IPVrnWM,33929
45
45
  locust/test/test_tags.py,sha256=mzhGLPMizSnSItTHLHizYvloxDfuIDAOgelwInyrf28,13138
@@ -70,9 +70,9 @@ locust/webui/dist/report.html,sha256=sOdZZVgZbqgu86BBCSQf3uQUYXgmgSnXF32JpnyAII8
70
70
  locust/webui/dist/assets/favicon.ico,sha256=IUl-rYqfpHdV38e-s0bkmFIeLS-n3Ug0DQxk-h202hI,8348
71
71
  locust/webui/dist/assets/index-941b6e82.js,sha256=G3n5R81Svt0HzbWaV3AV20jLWGLr4X50UZ-Adu2KcxU,1645614
72
72
  locust/webui/dist/assets/logo.png,sha256=EIVPqr6wE_yqguHaqFHIsH0ZACLSrvNWyYO7PbyIj4w,19299
73
- locust-2.27.1.dev31.dist-info/LICENSE,sha256=78XGpIn3fHVBfaxlPNUfjVufSN7QsdhpJMRJHv2AFpo,1095
74
- locust-2.27.1.dev31.dist-info/METADATA,sha256=YpVC6vJUygCNZ3NsEaEHhuP9pxMl2M-IZW1NpGdvLtw,7264
75
- locust-2.27.1.dev31.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
76
- locust-2.27.1.dev31.dist-info/entry_points.txt,sha256=RAdt8Ku-56m7bFjmdj-MBhbF6h4NX7tVODR9QNnOg0E,44
77
- locust-2.27.1.dev31.dist-info/top_level.txt,sha256=XSsjgPA8Ggf9TqKVbkwSqZFuPlZ085X13M9orDycE20,7
78
- locust-2.27.1.dev31.dist-info/RECORD,,
73
+ locust-2.27.1.dev40.dist-info/LICENSE,sha256=78XGpIn3fHVBfaxlPNUfjVufSN7QsdhpJMRJHv2AFpo,1095
74
+ locust-2.27.1.dev40.dist-info/METADATA,sha256=H6rAgduxpQhRMeW1XsN2UgZNOJIp_JBC_XeWhAa0Hew,7264
75
+ locust-2.27.1.dev40.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
76
+ locust-2.27.1.dev40.dist-info/entry_points.txt,sha256=RAdt8Ku-56m7bFjmdj-MBhbF6h4NX7tVODR9QNnOg0E,44
77
+ locust-2.27.1.dev40.dist-info/top_level.txt,sha256=XSsjgPA8Ggf9TqKVbkwSqZFuPlZ085X13M9orDycE20,7
78
+ locust-2.27.1.dev40.dist-info/RECORD,,