From 7eae4dadaf0d905fdb763d38a647ab7260441fff Mon Sep 17 00:00:00 2001 From: Lars Holmberg Date: Thu, 18 Apr 2024 21:56:57 +0200 Subject: [PATCH 1/4] Lint various tests. --- locust/test/mock_logging.py | 3 +-- locust/test/test_dispatch.py | 40 ++++++-------------------------- locust/test/test_env.py | 6 ++--- locust/test/test_fasthttp.py | 18 +++++++------- locust/test/test_http.py | 14 +++++------ locust/test/test_locust_class.py | 8 +++---- locust/test/test_main.py | 4 ++-- locust/test/test_parser.py | 17 +++++++------- locust/test/test_runners.py | 1 - locust/test/test_web.py | 8 ++----- pyproject.toml | 1 - 11 files changed, 44 insertions(+), 76 deletions(-) diff --git a/locust/test/mock_logging.py b/locust/test/mock_logging.py index 1a57d3393c..63f35dcfc9 100644 --- a/locust/test/mock_logging.py +++ b/locust/test/mock_logging.py @@ -1,9 +1,8 @@ from __future__ import annotations import logging - -from typing import List, Union, Dict from types import TracebackType +from typing import Union LogMessage = list[Union[str, dict[str, TracebackType]]] diff --git a/locust/test/test_dispatch.py b/locust/test/test_dispatch.py index 35d3481375..0bd4979321 100644 --- a/locust/test/test_dispatch.py +++ b/locust/test/test_dispatch.py @@ -2167,9 +2167,7 @@ def test_ramp_up_from_0_to_100_000_users_with_50_user_classes_and_1000_workers_a dispatch_iteration_duration <= tol for dispatch_iteration_duration in users_dispatcher.dispatch_iteration_durations ), - "One or more dispatch took more than {:.0f}s to compute (max = {}ms)".format( - tol * 1000, 1000 * max(users_dispatcher.dispatch_iteration_durations) - ), + f"One or more dispatch took more than {tol * 1000:.0f}s to compute (max = {1000 * max(users_dispatcher.dispatch_iteration_durations)}ms)", ) self.assertEqual(_user_count(all_dispatched_users[-1]), target_user_count) @@ -2181,9 +2179,7 @@ def test_ramp_up_from_0_to_100_000_users_with_50_user_classes_and_1000_workers_a self.assertLessEqual( max(user_count_on_workers) - min(user_count_on_workers), 1, - "One or more workers have too much users compared to the other workers when user count is {}".format( - _user_count(dispatch_users) - ), + f"One or more workers have too much users compared to the other workers when user count is {_user_count(dispatch_users)}", ) for i, dispatch_users in enumerate(all_dispatched_users): @@ -2202,9 +2198,7 @@ def test_ramp_up_from_0_to_100_000_users_with_50_user_classes_and_1000_workers_a self.assertLessEqual( error_percent, tol, - "Distribution for user class {} is off by more than {}% when user count is {}".format( - user_class, tol, _user_count(dispatch_users) - ), + f"Distribution for user class {user_class} is off by more than {tol}% when user count is {_user_count(dispatch_users)}", ) def test_ramp_down_from_100_000_to_0_users_with_50_user_classes_and_1000_workers_and_5000_spawn_rate(self): @@ -2236,9 +2230,7 @@ def test_ramp_down_from_100_000_to_0_users_with_50_user_classes_and_1000_workers dispatch_iteration_duration <= tol for dispatch_iteration_duration in users_dispatcher.dispatch_iteration_durations ), - "One or more dispatch took more than {:.0f}ms to compute (max = {}ms)".format( - tol * 1000, 1000 * max(users_dispatcher.dispatch_iteration_durations) - ), + f"One or more dispatch took more than {tol * 1000:.0f}ms to compute (max = {1000 * max(users_dispatcher.dispatch_iteration_durations)}ms)", ) self.assertEqual(_user_count(all_dispatched_users[-1]), 0) @@ -2250,9 +2242,7 @@ def test_ramp_down_from_100_000_to_0_users_with_50_user_classes_and_1000_workers self.assertLessEqual( max(user_count_on_workers) - min(user_count_on_workers), 1, - "One or more workers have too much users compared to the other workers when user count is {}".format( - _user_count(dispatch_users) - ), + f"One or more workers have too much users compared to the other workers when user count is {_user_count(dispatch_users)}", ) for dispatch_users in all_dispatched_users[:-1]: @@ -2267,9 +2257,7 @@ def test_ramp_down_from_100_000_to_0_users_with_50_user_classes_and_1000_workers self.assertLessEqual( error_percent, tol, - "Distribution for user class {} is off by more than {}% when user count is {}".format( - user_class, tol, _user_count(dispatch_users) - ), + f"Distribution for user class {user_class} is off by more than {tol}% when user count is {_user_count(dispatch_users)}", ) @@ -3448,9 +3436,7 @@ def __init__(self, fixed_counts: tuple[int], weights: tuple[int], target_user_co self.target_user_count = target_user_count def __str__(self): - return "".format( - self.fixed_counts, self.weights, self.target_user_count - ) + return f"" def case_handler(self, cases: list[RampUpCase], expected: list[dict[str, int]], user_classes: list[type[User]]): self.assertEqual(len(cases), len(expected)) @@ -3734,8 +3720,6 @@ class User3(User): worker_node1 = WorkerNode("1") - sleep_time = 0.2 - user_dispatcher = UsersDispatcher(worker_nodes=[worker_node1], user_classes=[User1, User2, User3]) user_dispatcher.new_dispatch(target_user_count=3, spawn_rate=3) @@ -3761,8 +3745,6 @@ class User3(User): worker_node1 = WorkerNode("1") - sleep_time = 0.2 - user_dispatcher = UsersDispatcher(worker_nodes=[worker_node1], user_classes=[User1, User2, User3]) user_dispatcher.new_dispatch(target_user_count=10, spawn_rate=10, user_classes=[User2]) @@ -3780,8 +3762,6 @@ class User3(User): worker_node1 = WorkerNode("1") - sleep_time = 0.2 - user_dispatcher = UsersDispatcher(worker_nodes=[worker_node1], user_classes=[User1, User2, User3]) user_dispatcher.new_dispatch(target_user_count=10, spawn_rate=10, user_classes=[User2]) @@ -3802,8 +3782,6 @@ class User3(User): worker_node1 = WorkerNode("1") - sleep_time = 0.2 - user_dispatcher = UsersDispatcher(worker_nodes=[worker_node1], user_classes=[User1, User2, User3]) user_dispatcher.new_dispatch(target_user_count=10, spawn_rate=10, user_classes=[User2]) @@ -3826,8 +3804,6 @@ class User3(User): worker_node2 = WorkerNode("2") worker_node3 = WorkerNode("3") - sleep_time = 0.2 - user_dispatcher = UsersDispatcher( worker_nodes=[worker_node1, worker_node2, worker_node3], user_classes=[User1, User2, User3] ) @@ -3886,8 +3862,6 @@ class User3(User): worker_node2 = WorkerNode("2") worker_node3 = WorkerNode("3") - sleep_time = 0.2 - user_dispatcher = UsersDispatcher( worker_nodes=[worker_node1, worker_node2, worker_node3], user_classes=[User1, User2, User3] ) diff --git a/locust/test/test_env.py b/locust/test/test_env.py index 43d713854f..a903ab3ca6 100644 --- a/locust/test/test_env.py +++ b/locust/test/test_env.py @@ -36,7 +36,7 @@ def my_task(self): def test_user_classes_with_same_name_is_error(self): with self.assertRaises(ValueError) as e: - environment = Environment(user_classes=[MyUserWithSameName1, MyUserWithSameName2]) + Environment(user_classes=[MyUserWithSameName1, MyUserWithSameName2]) self.assertEqual( e.exception.args[0], @@ -186,7 +186,7 @@ def my_task(self): pass with self.assertRaises(ValueError) as e: - environment = Environment(user_classes=[MyUser1, MyUser2]) + Environment(user_classes=[MyUser1, MyUser2]) self.assertEqual( e.exception.args[0], @@ -269,7 +269,7 @@ def my_task(self): available_user_classes={"User1": MyUser1, "User2": MyUser2}, available_user_tasks={"User1": MyUser1.tasks, "User2": MyUser2.tasks}, ) - worker = worker_env.create_worker_runner("127.0.0.1", master.server.port) + worker_env.create_worker_runner("127.0.0.1", master.server.port) master_env.update_user_class({"user_class_name": "User1", "host": "http://localhost", "tasks": ["my_task_2"]}) diff --git a/locust/test/test_fasthttp.py b/locust/test/test_fasthttp.py index b27cc2cf9a..f71ae73435 100644 --- a/locust/test/test_fasthttp.py +++ b/locust/test/test_fasthttp.py @@ -96,7 +96,7 @@ def test_streaming_response_catch_response(self): def test_slow_redirect(self): s = self.get_client() url = "/redirect?url=/redirect&delay=0.5" - r = s.get(url) + s.get(url) stats = self.runner.stats.get(url, method="GET") self.assertEqual(1, stats.num_requests) self.assertGreater(stats.avg_response_time, 500) @@ -187,7 +187,7 @@ class OtherException(Exception): with s.get("/fail", catch_response=True) as r: r.success() raise OtherException("wtf") - except OtherException as e: + except OtherException: pass else: self.fail("OtherException should have been raised") @@ -197,14 +197,14 @@ class OtherException(Exception): def test_catch_response_default_success(self): s = self.get_client() - with s.get("/ultra_fast", catch_response=True) as r: + with s.get("/ultra_fast", catch_response=True): pass self.assertEqual(1, self.environment.stats.get("/ultra_fast", "GET").num_requests) self.assertEqual(0, self.environment.stats.get("/ultra_fast", "GET").num_failures) def test_catch_response_default_fail(self): s = self.get_client() - with s.get("/fail", catch_response=True) as r: + with s.get("/fail", catch_response=True): pass self.assertEqual(1, self.environment.stats.total.num_requests) self.assertEqual(1, self.environment.stats.total.num_failures) @@ -301,7 +301,7 @@ class MyUser(FastHttpUser): l = MyUser(self.environment) path = "/no_content_length" - r = l.client.get(path) + l.client.get(path) self.assertEqual( self.runner.stats.get(path, "GET").avg_content_length, len("This response does not have content-length in the header"), @@ -313,7 +313,7 @@ class MyUser(FastHttpUser): l = MyUser(self.environment) path = "/no_content_length" - r = l.client.get(path, stream=True) + l.client.get(path, stream=True) self.assertEqual(0, self.runner.stats.get(path, "GET").avg_content_length) def test_request_stats_named_endpoint(self): @@ -526,7 +526,7 @@ class MyLocust(FastHttpUser): def test_slow_redirect(self): s = FastHttpSession(self.environment, "http://127.0.0.1:%i" % self.port, user=None) url = "/redirect?url=/redirect&delay=0.5" - r = s.get(url) + s.get(url) stats = self.runner.stats.get(url, method="GET") self.assertEqual(1, stats.num_requests) self.assertGreater(stats.avg_response_time, 500) @@ -650,7 +650,7 @@ def test_catch_response(self): self.assertEqual(1, self.num_success) def test_catch_response_http_fail(self): - with self.user.client.get("/fail", catch_response=True) as response: + with self.user.client.get("/fail", catch_response=True): pass self.assertEqual(1, self.num_failures) self.assertEqual(0, self.num_success) @@ -683,7 +683,7 @@ def test_interrupt_taskset_with_catch_response(self): class MyTaskSet(TaskSet): @task def interrupted_task(self): - with self.client.get("/ultra_fast", catch_response=True) as r: + with self.client.get("/ultra_fast", catch_response=True): raise InterruptTaskSet() class MyUser(FastHttpUser): diff --git a/locust/test/test_http.py b/locust/test/test_http.py index f866fb4672..6644650c87 100644 --- a/locust/test/test_http.py +++ b/locust/test/test_http.py @@ -65,7 +65,7 @@ def test_streaming_response(self): def test_slow_redirect(self): s = self.get_client() url = "/redirect?url=/redirect&delay=0.5" - r = s.get(url) + s.get(url) stats = self.runner.stats.get(url, method="GET") self.assertEqual(1, stats.num_requests) self.assertGreater(stats.avg_response_time, 500) @@ -217,7 +217,7 @@ class OtherException(Exception): with s.get("/fail", catch_response=True) as r: r.success() raise OtherException("wtf") - except OtherException as e: + except OtherException: pass else: self.fail("OtherException should have been raised") @@ -228,9 +228,9 @@ class OtherException(Exception): def test_catch_response_response_error(self): s = self.get_client() try: - with s.get("/fail", catch_response=True) as r: + with s.get("/fail", catch_response=True): raise ResponseError("response error") - except ResponseError as e: + except ResponseError: self.fail("ResponseError should not have been raised") self.assertEqual(1, self.environment.stats.total.num_requests) @@ -238,14 +238,14 @@ def test_catch_response_response_error(self): def test_catch_response_default_success(self): s = self.get_client() - with s.get("/ultra_fast", catch_response=True) as r: + with s.get("/ultra_fast", catch_response=True): pass self.assertEqual(1, self.environment.stats.get("/ultra_fast", "GET").num_requests) self.assertEqual(0, self.environment.stats.get("/ultra_fast", "GET").num_failures) def test_catch_response_default_fail(self): s = self.get_client() - with s.get("/fail", catch_response=True) as r: + with s.get("/fail", catch_response=True): pass self.assertEqual(1, self.environment.stats.total.num_requests) self.assertEqual(1, self.environment.stats.total.num_failures) @@ -260,7 +260,7 @@ def on_request(**kw): self.environment.events.request.add_listener(on_request) - with s.get("/wrong_url/01", name="replaced_url_name") as r: + with s.get("/wrong_url/01", name="replaced_url_name"): pass self.assertIn("for url: replaced_url_name", str(kwargs["exception"])) diff --git a/locust/test/test_locust_class.py b/locust/test/test_locust_class.py index f6f1dc9616..6fc0c0b829 100644 --- a/locust/test/test_locust_class.py +++ b/locust/test/test_locust_class.py @@ -748,19 +748,19 @@ def test_catch_response(self): self.assertEqual(1, self.num_failures) self.assertEqual(0, self.num_success) - with self.locust.client.get("/ultra_fast", catch_response=True) as response: + with self.locust.client.get("/ultra_fast", catch_response=True): pass self.assertEqual(1, self.num_failures) self.assertEqual(1, self.num_success) - with self.locust.client.get("/ultra_fast", catch_response=True) as response: + with self.locust.client.get("/ultra_fast", catch_response=True): raise ResponseError("Not working") self.assertEqual(2, self.num_failures) self.assertEqual(1, self.num_success) def test_catch_response_http_fail(self): - with self.locust.client.get("/fail", catch_response=True) as response: + with self.locust.client.get("/fail", catch_response=True): pass self.assertEqual(1, self.num_failures) self.assertEqual(0, self.num_success) @@ -793,7 +793,7 @@ def test_interrupt_taskset_with_catch_response(self): class MyTaskSet(TaskSet): @task def interrupted_task(self): - with self.client.get("/ultra_fast", catch_response=True) as r: + with self.client.get("/ultra_fast", catch_response=True): raise InterruptTaskSet() class MyUser(HttpUser): diff --git a/locust/test/test_main.py b/locust/test/test_main.py index ecedfaec41..583260b02a 100644 --- a/locust/test/test_main.py +++ b/locust/test/test_main.py @@ -811,7 +811,7 @@ def my_task(self): try: response = requests.get(f"http://localhost:{port}/") except ConnectionError: - succcess = False + success = False try: _, stderr = proc.communicate(timeout=5) except subprocess.TimeoutExpired: @@ -1084,7 +1084,7 @@ def test_html_report_option(self): with mock_locustfile() as mocked: with temporary_file("", suffix=".html") as html_report_file_path: try: - output = subprocess.check_output( + subprocess.check_output( [ "locust", "-f", diff --git a/locust/test/test_parser.py b/locust/test/test_parser.py index 34d2b946a5..d7f69cd5c4 100644 --- a/locust/test/test_parser.py +++ b/locust/test/test_parser.py @@ -69,6 +69,8 @@ def test_parse_options_from_toml_file(self): web-port = 45787 headless = true tags = ["Critical", "Normal"] + [tool.something_else] + this = "should be ignored by locust" """ file.write(config_data) @@ -248,7 +250,7 @@ def test_parse_locustfile_with_directory_ignores_invalid_filenames(self): def test_parse_locustfile_empty_directory_error(self): with mock.patch("sys.stderr", new=StringIO()): with self.assertRaises(SystemExit): - locustfiles = parse_locustfile_option( + parse_locustfile_option( args=[ "-f", self.parent_dir.name, @@ -258,7 +260,7 @@ def test_parse_locustfile_empty_directory_error(self): def test_parse_locustfile_invalid_directory_error(self): with mock.patch("sys.stderr", new=StringIO()): with self.assertRaises(SystemExit): - locustfiles = parse_locustfile_option( + parse_locustfile_option( args=[ "-f", "non_existent_dir", @@ -401,13 +403,12 @@ def test_find_locustfiles_ignores_invalid_files_in_directory(self): def test_find_locustfiles_with_multiple_locustfiles(self): with mock_locustfile() as mocked1: with mock_locustfile() as mocked2: - with mock_locustfile() as mocked3: - locustfiles = find_locustfiles([mocked1.file_path, mocked2.file_path], False) + locustfiles = find_locustfiles([mocked1.file_path, mocked2.file_path], False) - self.assertIn(mocked1.file_path, locustfiles) - self.assertIn(mocked2.file_path, locustfiles) + self.assertIn(mocked1.file_path, locustfiles) + self.assertIn(mocked2.file_path, locustfiles) - assert 2 == len(locustfiles) + assert 2 == len(locustfiles) def test_find_locustfiles_error_for_invalid_file_extension(self): with mock.patch("sys.stderr", new=StringIO()): @@ -450,7 +451,7 @@ def test_locustfile_is_directory_single_locustfile(self): def test_locustfile_is_directory_single_locustfile_without_file_extension(self): prefix_name = "foobar" - with NamedTemporaryFile(prefix=prefix_name, suffix=".py") as mocked: + with NamedTemporaryFile(prefix=prefix_name, suffix=".py"): is_dir = locustfile_is_directory([prefix_name]) assert not is_dir diff --git a/locust/test/test_runners.py b/locust/test/test_runners.py index eb060f3197..3d630d5a39 100644 --- a/locust/test/test_runners.py +++ b/locust/test/test_runners.py @@ -3547,7 +3547,6 @@ def my_task(self): pass with mock.patch("locust.rpc.rpc.Client", mocked_rpc(raise_on_close=False)) as client: - client_id = id(client) worker = self.get_runner(environment=Environment(), user_classes=[MyUser], client=client) client.mocked_send( Message( diff --git a/locust/test/test_web.py b/locust/test/test_web.py index ae816f3518..689d12786a 100644 --- a/locust/test/test_web.py +++ b/locust/test/test_web.py @@ -1110,11 +1110,7 @@ class MyUser2(User): self.environment.available_user_classes = {"User1": MyUser, "User2": MyUser2} self.environment.available_user_tasks = {"User1": MyUser.tasks, "User2": MyUser2.tasks} - users = {"User1": MyUser.json(), "User2": MyUser2.json()} - available_user_tasks = {"User1": ["my_task", "my_task_2"], "User2": []} - - # environment.update_user_class({"user_class_name": "User1", "host": "http://localhost", "tasks": ["my_task_2"]}) - response = requests.post( + requests.post( "http://127.0.0.1:%i/user" % self.web_port, json={"user_class_name": "User1", "host": "http://localhost", "tasks": ["my_task_2"]}, ) @@ -1290,7 +1286,7 @@ class TestModernWebUI(LocustTestCase, _HeaderCheckMixin): def setUp(self): super().setUp() - parser = get_parser(default_config_files=[]) + get_parser(default_config_files=[]) self.stats = self.environment.stats self.web_ui = self.environment.create_web_ui("127.0.0.1", 0, modern_ui=True) diff --git a/pyproject.toml b/pyproject.toml index d2700b13d4..1fc7a3a0b9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,7 +72,6 @@ lint.select = ["E", "F", "W", "UP", "FA102", "I001"] [tool.ruff.lint.per-file-ignores] "examples/*" = ["F841"] -"locust/test/*" = ["F841"] [tool.ruff.lint.isort] section-order = ["future", "locust", "standard-library", "third-party", "first-party", "local-folder"] From 3c0c5c27216e544cbd944b71f17d409ff50d92d1 Mon Sep 17 00:00:00 2001 From: Lars Holmberg Date: Thu, 18 Apr 2024 21:57:53 +0200 Subject: [PATCH 2/4] clarify --tags argument description --- locust/argument_parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locust/argument_parser.py b/locust/argument_parser.py index b52573eebb..5f5c34984b 100644 --- a/locust/argument_parser.py +++ b/locust/argument_parser.py @@ -666,7 +666,7 @@ def setup_parser_arguments(parser): nargs="*", metavar="", env_var="LOCUST_TAGS", - help="List of tags to include in the test, so only tasks with any matching tags will be executed", + help="List of tags to include in the test, so only tasks with at least one matching tag will be executed", ) tag_group.add_argument( "-E", From bd710b56a1217fe9ae6110269817f338729adf1b Mon Sep 17 00:00:00 2001 From: Lars Holmberg Date: Thu, 18 Apr 2024 22:05:11 +0200 Subject: [PATCH 3/4] update python version in doc logs --- docs/developing-locust.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/developing-locust.rst b/docs/developing-locust.rst index 4dc60e67b6..9a640e2c68 100644 --- a/docs/developing-locust.rst +++ b/docs/developing-locust.rst @@ -34,10 +34,10 @@ We use `tox `_ to automate tests across m $ pip3 install tox $ tox ... - py38: install_deps> python -I -m pip install cryptography mock pyquery retry - py38: commands[0]> python3 -m pip install . + py39: install_deps> python -I -m pip install cryptography mock pyquery retry + py39: commands[0]> python3 -m pip install . ... - py38: commands[1]> python3 -m unittest discover + py39: commands[1]> python3 -m unittest discover ... To only run a specific suite or specific test you can call `pytest `_ directly: From af16d2c6e9a2a8ceb2d1b36c3c758ebc3ceab5d5 Mon Sep 17 00:00:00 2001 From: Lars Holmberg Date: Thu, 18 Apr 2024 22:12:16 +0200 Subject: [PATCH 4/4] Pin geventhttpclient version. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1fc7a3a0b9..0347c8bd04 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,7 @@ dependencies = [ "requests >=2.26.0", "msgpack >=1.0.0", "pyzmq >=25.0.0", - "geventhttpclient >=2.2.1", + "geventhttpclient ==2.2.1", "ConfigArgParse >=1.5.5", "tomli >=1.1.0; python_version<'3.11'", "psutil >=5.9.1",