locust 2.18.4.dev6__py3-none-any.whl → 2.18.4.dev17__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.
Potentially problematic release.
This version of locust might be problematic. Click here for more details.
- locust/_version.py +2 -2
- locust/runners.py +4 -3
- locust/stats.py +2 -2
- locust/test/test_runners.py +61 -0
- locust/web.py +4 -1
- locust/webui/dist/assets/{index-9996beb6.js → index-8ad54eaa.js} +61 -60
- locust/webui/dist/index.html +1 -1
- {locust-2.18.4.dev6.dist-info → locust-2.18.4.dev17.dist-info}/METADATA +1 -1
- {locust-2.18.4.dev6.dist-info → locust-2.18.4.dev17.dist-info}/RECORD +13 -13
- {locust-2.18.4.dev6.dist-info → locust-2.18.4.dev17.dist-info}/LICENSE +0 -0
- {locust-2.18.4.dev6.dist-info → locust-2.18.4.dev17.dist-info}/WHEEL +0 -0
- {locust-2.18.4.dev6.dist-info → locust-2.18.4.dev17.dist-info}/entry_points.txt +0 -0
- {locust-2.18.4.dev6.dist-info → locust-2.18.4.dev17.dist-info}/top_level.txt +0 -0
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.18.4.
|
16
|
-
__version_tuple__ = version_tuple = (2, 18, 4, '
|
15
|
+
__version__ = version = '2.18.4.dev17'
|
16
|
+
__version_tuple__ = version_tuple = (2, 18, 4, 'dev17')
|
locust/runners.py
CHANGED
@@ -333,6 +333,7 @@ class Runner:
|
|
333
333
|
def shape_worker(self) -> None:
|
334
334
|
logger.info("Shape worker starting")
|
335
335
|
while self.state == STATE_INIT or self.state == STATE_SPAWNING or self.state == STATE_RUNNING:
|
336
|
+
shape_adjustment_start = time.time()
|
336
337
|
current_tick = self.environment.shape_class.tick() if self.environment.shape_class is not None else None
|
337
338
|
if current_tick is None:
|
338
339
|
logger.info("Shape test stopping")
|
@@ -343,9 +344,7 @@ class Runner:
|
|
343
344
|
self.shape_greenlet = None
|
344
345
|
self.shape_last_tick = None
|
345
346
|
return
|
346
|
-
elif self.shape_last_tick
|
347
|
-
gevent.sleep(1)
|
348
|
-
else:
|
347
|
+
elif self.shape_last_tick != current_tick:
|
349
348
|
if len(current_tick) == 2:
|
350
349
|
user_count, spawn_rate = current_tick # type: ignore
|
351
350
|
user_classes = None
|
@@ -367,6 +366,8 @@ class Runner:
|
|
367
366
|
# of each load test shape stage.
|
368
367
|
self.start(user_count=user_count, spawn_rate=spawn_rate, user_classes=user_classes)
|
369
368
|
self.shape_last_tick = current_tick
|
369
|
+
shape_adjustment_time_ms = time.time() - shape_adjustment_start
|
370
|
+
gevent.sleep(max(1 - shape_adjustment_time_ms, 0))
|
370
371
|
|
371
372
|
def stop(self) -> None:
|
372
373
|
"""
|
locust/stats.py
CHANGED
@@ -390,8 +390,8 @@ class StatsEntry:
|
|
390
390
|
|
391
391
|
if self.min_response_time is None:
|
392
392
|
self.min_response_time = response_time
|
393
|
-
|
394
|
-
|
393
|
+
else:
|
394
|
+
self.min_response_time = min(self.min_response_time, response_time)
|
395
395
|
self.max_response_time = max(self.max_response_time, response_time)
|
396
396
|
|
397
397
|
# to avoid to much data that has to be transferred to the master node when
|
locust/test/test_runners.py
CHANGED
@@ -2707,6 +2707,67 @@ class TestMasterRunner(LocustRunnerTestCase):
|
|
2707
2707
|
for i in range(USERS_COUNT):
|
2708
2708
|
self.assertEqual(indexes[i], i, "Worker index mismatch")
|
2709
2709
|
|
2710
|
+
def test_custom_shape_scale_interval(self):
|
2711
|
+
class MyUser(User):
|
2712
|
+
@task
|
2713
|
+
def my_task(self):
|
2714
|
+
pass
|
2715
|
+
|
2716
|
+
class TestShape(LoadTestShape):
|
2717
|
+
def __init__(self):
|
2718
|
+
super().__init__()
|
2719
|
+
self._users_num = [1, 1, 1, 2, 2, 3, 3, 3, 4]
|
2720
|
+
self._index = 0
|
2721
|
+
|
2722
|
+
def tick(self):
|
2723
|
+
if self._index >= len(self._users_num):
|
2724
|
+
return None
|
2725
|
+
users_num = self._users_num[self._index]
|
2726
|
+
self._index += 1
|
2727
|
+
return users_num, users_num
|
2728
|
+
|
2729
|
+
self.environment.shape_class = TestShape()
|
2730
|
+
|
2731
|
+
with mock.patch("locust.rpc.rpc.Server", mocked_rpc()) as server:
|
2732
|
+
master = self.get_runner(user_classes=[MyUser])
|
2733
|
+
for i in range(5):
|
2734
|
+
server.mocked_send(Message("client_ready", __version__, "fake_client%i" % i))
|
2735
|
+
|
2736
|
+
# Start the shape_worker
|
2737
|
+
self.environment.shape_class.reset_time()
|
2738
|
+
master.start_shape()
|
2739
|
+
|
2740
|
+
# Wait for shape_worker to update user_count
|
2741
|
+
sleep(0.5)
|
2742
|
+
num_users = sum(
|
2743
|
+
sum(msg.data["user_classes_count"].values()) for _, msg in server.outbox if msg.type != "ack"
|
2744
|
+
)
|
2745
|
+
self.assertEqual(
|
2746
|
+
1, num_users, "Total number of users in first stage of shape test is not 1: %i" % num_users
|
2747
|
+
)
|
2748
|
+
|
2749
|
+
# Wait for shape_worker to update user_count again
|
2750
|
+
sleep(1.5)
|
2751
|
+
num_users = sum(
|
2752
|
+
sum(msg.data["user_classes_count"].values()) for _, msg in server.outbox if msg.type != "ack"
|
2753
|
+
)
|
2754
|
+
self.assertEqual(
|
2755
|
+
1, num_users, "Total number of users in second stage of shape test is not 1: %i" % num_users
|
2756
|
+
)
|
2757
|
+
|
2758
|
+
# Wait for shape_worker to update user_count few times but not reach the end yet
|
2759
|
+
sleep(2.5)
|
2760
|
+
num_users = sum(
|
2761
|
+
sum(msg.data["user_classes_count"].values()) for _, msg in server.outbox if msg.type != "ack"
|
2762
|
+
)
|
2763
|
+
self.assertEqual(
|
2764
|
+
3, num_users, "Total number of users in second stage of shape test is not 3: %i" % num_users
|
2765
|
+
)
|
2766
|
+
|
2767
|
+
# Wait to ensure shape_worker has stopped the test
|
2768
|
+
sleep(3)
|
2769
|
+
self.assertEqual("stopped", master.state, "The test has not been stopped by the shape class")
|
2770
|
+
|
2710
2771
|
def test_custom_shape_scale_up(self):
|
2711
2772
|
class MyUser(User):
|
2712
2773
|
@task
|
locust/web.py
CHANGED
@@ -367,6 +367,7 @@ class WebUI:
|
|
367
367
|
"stats": stats,
|
368
368
|
"errors": errors,
|
369
369
|
"total_rps": 0.0,
|
370
|
+
"total_fail_per_sec": 0.0,
|
370
371
|
"fail_ratio": 0.0,
|
371
372
|
"current_response_time_percentile_1": None,
|
372
373
|
"current_response_time_percentile_2": None,
|
@@ -395,9 +396,11 @@ class WebUI:
|
|
395
396
|
truncated_stats += [stats[-1]]
|
396
397
|
|
397
398
|
report = {"stats": truncated_stats, "errors": errors[:500]}
|
399
|
+
total_stats = stats[-1]
|
398
400
|
|
399
401
|
if stats:
|
400
|
-
report["total_rps"] =
|
402
|
+
report["total_rps"] = total_stats["current_rps"]
|
403
|
+
report["total_fail_per_sec"] = total_stats["current_fail_per_sec"]
|
401
404
|
report["fail_ratio"] = environment.runner.stats.total.fail_ratio
|
402
405
|
report[
|
403
406
|
"current_response_time_percentile_1"
|