locust 2.29.2.dev10__tar.gz → 2.29.2.dev15__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 (328) hide show
  1. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/PKG-INFO +1 -1
  2. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/test_data_management.py +36 -11
  3. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/_version.py +2 -2
  4. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/event.py +32 -0
  5. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/runners.py +13 -22
  6. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_runners.py +145 -11
  7. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust.egg-info/PKG-INFO +1 -1
  8. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.coveragerc +0 -0
  9. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.dockerignore +0 -0
  10. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.git-blame-ignore-revs +0 -0
  11. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.gitattributes +0 -0
  12. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.github/CONTRIBUTING.md +0 -0
  13. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
  14. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  15. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  16. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.github/workflows/stale.yml +0 -0
  17. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.github/workflows/tests.yml +0 -0
  18. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.gitignore +0 -0
  19. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.pre-commit-config.yaml +0 -0
  20. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.readthedocs.yaml +0 -0
  21. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.vscode/extensions.json +0 -0
  22. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.vscode/launch.json +0 -0
  23. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.vscode/launch_locust.json +0 -0
  24. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/.vscode/settings.json +0 -0
  25. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/CHANGELOG.md +0 -0
  26. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/Dockerfile +0 -0
  27. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/LICENSE +0 -0
  28. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/MANIFEST.in +0 -0
  29. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/Makefile +0 -0
  30. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/README.md +0 -0
  31. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/SECURITY.md +0 -0
  32. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/Vagrantfile +0 -0
  33. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/benchmarks/dispatch.py +0 -0
  34. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/_static/theme-overrides.css +0 -0
  35. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/api.rst +0 -0
  36. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/changelog.rst +0 -0
  37. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/conf.py +0 -0
  38. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/configuration.rst +0 -0
  39. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/custom-load-shape.rst +0 -0
  40. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/developing-locust.rst +0 -0
  41. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/extending-locust.rst +0 -0
  42. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/extensions.rst +0 -0
  43. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/faq.rst +0 -0
  44. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/further-reading.rst +0 -0
  45. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/history.rst +0 -0
  46. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/images/extend_modern_web_ui_cache_stats.png +0 -0
  47. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/images/locust_workers.png +0 -0
  48. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/images/number_of_users.png +0 -0
  49. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/images/response_times.png +0 -0
  50. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/images/total_requests_per_second.png +0 -0
  51. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/images/userclass_picker_example.png +0 -0
  52. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/images/webui-running-statistics.png +0 -0
  53. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/images/webui-splash-screenshot.png +0 -0
  54. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/increase-performance.rst +0 -0
  55. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/increasing-request-rate.rst +0 -0
  56. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/index.rst +0 -0
  57. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/installation.rst +0 -0
  58. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/logging.rst +0 -0
  59. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/quickstart.rst +0 -0
  60. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/requirements.txt +0 -0
  61. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/retrieving-stats.rst +0 -0
  62. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/running-distributed.rst +0 -0
  63. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/running-in-debugger.rst +0 -0
  64. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/running-in-docker.rst +0 -0
  65. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/running-without-web-ui.rst +0 -0
  66. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/tasksets.rst +0 -0
  67. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/testing-other-systems.rst +0 -0
  68. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/use-as-lib.rst +0 -0
  69. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/what-is-locust.rst +0 -0
  70. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/docs/writing-a-locustfile.rst +0 -0
  71. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/add_command_line_argument.py +0 -0
  72. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/basic.py +0 -0
  73. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/browse_docs_sequence_test.py +0 -0
  74. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/browse_docs_test.py +0 -0
  75. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/custom_messages.py +0 -0
  76. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/custom_shape/double_wave.py +0 -0
  77. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/custom_shape/stages.py +0 -0
  78. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/custom_shape/staging_user_classes.py +0 -0
  79. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/custom_shape/step_load.py +0 -0
  80. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/custom_shape/wait_user_count.py +0 -0
  81. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/custom_wait_function.py +0 -0
  82. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/custom_xmlrpc_client/server.py +0 -0
  83. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/custom_xmlrpc_client/xmlrpc_locustfile.py +0 -0
  84. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/debugging.py +0 -0
  85. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/debugging_advanced.py +0 -0
  86. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/dispatch_test_scripts/locustfile.py +0 -0
  87. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/dispatch_test_scripts/run-disributed-headless.sh +0 -0
  88. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/dispatch_test_scripts/run-disributed-web.sh +0 -0
  89. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/dispatch_test_scripts/run-local-headless.sh +0 -0
  90. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/dispatch_test_scripts/run-local-web.sh +0 -0
  91. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/docker-compose/docker-compose.yml +0 -0
  92. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/dynamic_user_credentials.py +0 -0
  93. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/events.py +0 -0
  94. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/extend_web_ui.py +0 -0
  95. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/fast_http_locust.py +0 -0
  96. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/grpc/grpc_user.py +0 -0
  97. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/grpc/hello.proto +0 -0
  98. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/grpc/hello_pb2.py +0 -0
  99. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/grpc/hello_pb2_grpc.py +0 -0
  100. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/grpc/hello_server.py +0 -0
  101. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/grpc/locustfile.py +0 -0
  102. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/locustfile.py +0 -0
  103. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/manual_stats_reporting.py +0 -0
  104. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/multiple_hosts.py +0 -0
  105. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/nested_inline_tasksets.py +0 -0
  106. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/rest.py +0 -0
  107. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/sdk_session_patching/session_patch_locustfile.py +0 -0
  108. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/semaphore_wait.py +0 -0
  109. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/stop_on_threshold.py +0 -0
  110. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/terraform/aws/README.md +0 -0
  111. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/terraform/aws/data_subnet.tf +0 -0
  112. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/terraform/aws/main.tf +0 -0
  113. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/terraform/aws/output.tf +0 -0
  114. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/terraform/aws/plan/basic.py +0 -0
  115. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/terraform/aws/provisioner.tf +0 -0
  116. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/terraform/aws/variables.tf +0 -0
  117. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/use_as_lib.py +0 -0
  118. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/vagrant/README.md +0 -0
  119. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/vagrant/supervisord.conf +0 -0
  120. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/web_ui_auth.py +0 -0
  121. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/web_ui_cache_stats.py +0 -0
  122. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/examples/worker_index.py +0 -0
  123. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/generate_changelog.py +0 -0
  124. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/__init__.py +0 -0
  125. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/__main__.py +0 -0
  126. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/argument_parser.py +0 -0
  127. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/clients.py +0 -0
  128. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/contrib/__init__.py +0 -0
  129. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/contrib/fasthttp.py +0 -0
  130. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/debug.py +0 -0
  131. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/dispatch.py +0 -0
  132. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/env.py +0 -0
  133. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/exception.py +0 -0
  134. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/html.py +0 -0
  135. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/input_events.py +0 -0
  136. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/log.py +0 -0
  137. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/main.py +0 -0
  138. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/py.typed +0 -0
  139. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/rpc/__init__.py +0 -0
  140. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/rpc/protocol.py +0 -0
  141. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/rpc/zmqrpc.py +0 -0
  142. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/shape.py +0 -0
  143. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/stats.py +0 -0
  144. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/__init__.py +0 -0
  145. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/fake_module1_for_env_test.py +0 -0
  146. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/fake_module2_for_env_test.py +0 -0
  147. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/mock_locustfile.py +0 -0
  148. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/mock_logging.py +0 -0
  149. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_debugging.py +0 -0
  150. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_dispatch.py +0 -0
  151. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_env.py +0 -0
  152. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_fasthttp.py +0 -0
  153. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_http.py +0 -0
  154. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_interruptable_task.py +0 -0
  155. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_load_locustfile.py +0 -0
  156. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_locust_class.py +0 -0
  157. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_log.py +0 -0
  158. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_main.py +0 -0
  159. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_old_wait_api.py +0 -0
  160. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_parser.py +0 -0
  161. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_sequential_taskset.py +0 -0
  162. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_stats.py +0 -0
  163. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_tags.py +0 -0
  164. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_taskratio.py +0 -0
  165. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_users.py +0 -0
  166. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_util.py +0 -0
  167. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_wait_time.py +0 -0
  168. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_web.py +0 -0
  169. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/test_zmqrpc.py +0 -0
  170. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/testcases.py +0 -0
  171. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/test/util.py +0 -0
  172. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/user/__init__.py +0 -0
  173. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/user/inspectuser.py +0 -0
  174. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/user/sequential_taskset.py +0 -0
  175. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/user/task.py +0 -0
  176. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/user/users.py +0 -0
  177. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/user/wait_time.py +0 -0
  178. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/util/__init__.py +0 -0
  179. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/util/cache.py +0 -0
  180. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/util/date.py +0 -0
  181. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/util/deprecation.py +0 -0
  182. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/util/exception_handler.py +0 -0
  183. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/util/load_locustfile.py +0 -0
  184. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/util/rounding.py +0 -0
  185. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/util/timespan.py +0 -0
  186. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/web.py +0 -0
  187. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/.eslintrc +0 -0
  188. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/.gitignore +0 -0
  189. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/.prettierrc +0 -0
  190. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/auth.html +0 -0
  191. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/dev.html +0 -0
  192. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/dist/assets/favicon.ico +0 -0
  193. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/dist/assets/logo.png +0 -0
  194. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/dist/auth.html +0 -0
  195. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/dist/index.html +0 -0
  196. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/dist/report.html +0 -0
  197. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/index.html +0 -0
  198. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/package.json +0 -0
  199. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/public/assets/favicon.ico +0 -0
  200. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/public/assets/logo.png +0 -0
  201. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/public/report.html +0 -0
  202. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/App.test.tsx +0 -0
  203. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/App.tsx +0 -0
  204. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/DataTable/DataTable.test.tsx +0 -0
  205. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/DataTable/DataTable.tsx +0 -0
  206. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/ExceptionsTable/ExceptionsTable.tsx +0 -0
  207. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/FailuresTable/FailuresTable.tsx +0 -0
  208. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/FallbackRender/FallbackRender.test.tsx +0 -0
  209. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/FallbackRender/FallbackRender.tsx +0 -0
  210. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Form/Form.tsx +0 -0
  211. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Form/Select.tsx +0 -0
  212. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Form/tests/Form.test.tsx +0 -0
  213. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Form/tests/Select.test.tsx +0 -0
  214. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Layout/Footer/About.tsx +0 -0
  215. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Layout/Footer/Footer.tsx +0 -0
  216. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Layout/Layout.tsx +0 -0
  217. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Layout/Navbar/DarkLightToggle.tsx +0 -0
  218. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Layout/Navbar/Navbar.tsx +0 -0
  219. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Layout/Navbar/SwarmMonitor.test.tsx +0 -0
  220. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Layout/Navbar/SwarmMonitor.tsx +0 -0
  221. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/LineChart/LineChart.test.tsx +0 -0
  222. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/LineChart/LineChart.tsx +0 -0
  223. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/LogViewer/LogViewer.tsx +0 -0
  224. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/LogViewer/logUtils.tsx +0 -0
  225. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/LogViewer/tests/LogViewer.test.tsx +0 -0
  226. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/LogViewer/tests/useLogViewer.test.tsx +0 -0
  227. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/LogViewer/useLogViewer.ts +0 -0
  228. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Modal/Modal.tsx +0 -0
  229. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Reports/Reports.test.tsx +0 -0
  230. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Reports/Reports.tsx +0 -0
  231. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/ResponseTimeTable/ResponseTimeTable.test.tsx +0 -0
  232. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/ResponseTimeTable/ResponseTimeTable.tsx +0 -0
  233. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/StateButtons/EditButton.tsx +0 -0
  234. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/StateButtons/NewTestButton.tsx +0 -0
  235. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/StateButtons/ResetButton.tsx +0 -0
  236. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/StateButtons/StateButtons.tsx +0 -0
  237. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/StateButtons/StopButton.tsx +0 -0
  238. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/StateButtons/tests/ResetButton.test.tsx +0 -0
  239. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/StateButtons/tests/StateButtons.test.tsx +0 -0
  240. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/StateButtons/tests/StopButton.test.tsx +0 -0
  241. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/StatsTable/StatsTable.tsx +0 -0
  242. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/SwarmCharts/SwarmCharts.tsx +0 -0
  243. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/SwarmForm/SwarmCustomParameters.tsx +0 -0
  244. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/SwarmForm/SwarmEditForm.tsx +0 -0
  245. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/SwarmForm/SwarmForm.tsx +0 -0
  246. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/SwarmForm/SwarmUserClassPicker.tsx +0 -0
  247. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/SwarmForm/tests/SwarmCustomParameters.test.tsx +0 -0
  248. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/SwarmForm/tests/SwarmEditForm.test.tsx +0 -0
  249. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/SwarmForm/tests/SwarmForm.test.tsx +0 -0
  250. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/SwarmForm/tests/SwarmUserClassPicker.test.tsx +0 -0
  251. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/SwarmRatios/SwarmRatios.test.tsx +0 -0
  252. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/SwarmRatios/SwarmRatios.tsx +0 -0
  253. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Table/Table.test.tsx +0 -0
  254. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Table/Table.tsx +0 -0
  255. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Tabs/Tabs.constants.tsx +0 -0
  256. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Tabs/Tabs.test.tsx +0 -0
  257. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/Tabs/Tabs.tsx +0 -0
  258. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/ViewColumnSelector/ViewColumnSelector.test.tsx +0 -0
  259. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/ViewColumnSelector/ViewColumnSelector.tsx +0 -0
  260. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/components/WorkersTable/WorkersTable.tsx +0 -0
  261. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/constants/auth.ts +0 -0
  262. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/constants/logs.ts +0 -0
  263. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/constants/swarm.ts +0 -0
  264. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/constants/theme.ts +0 -0
  265. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/global.d.ts +0 -0
  266. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/hooks/tests/useNotifications.test.tsx +0 -0
  267. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/hooks/tests/useSelecteViewColumns.test.tsx +0 -0
  268. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/hooks/tests/useSortByField.test.tsx +0 -0
  269. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/hooks/tests/useSwarmUi.test.tsx +0 -0
  270. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/hooks/useInterval.ts +0 -0
  271. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/hooks/useNotifications.ts +0 -0
  272. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/hooks/useSelectViewColumns.ts +0 -0
  273. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/hooks/useSortByField.ts +0 -0
  274. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/hooks/useSwarmUi.ts +0 -0
  275. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/index.tsx +0 -0
  276. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/pages/Auth.tsx +0 -0
  277. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/pages/Dashboard.tsx +0 -0
  278. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/pages/HtmlReport.tsx +0 -0
  279. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/pages/tests/Auth.test.tsx +0 -0
  280. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/pages/tests/Dashboard.test.tsx +0 -0
  281. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/pages/tests/HtmlReport.test.tsx +0 -0
  282. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/redux/api/swarm.ts +0 -0
  283. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/redux/hooks.ts +0 -0
  284. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/redux/slice/logViewer.slice.ts +0 -0
  285. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/redux/slice/notification.slice.ts +0 -0
  286. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/redux/slice/root.slice.ts +0 -0
  287. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/redux/slice/swarm.slice.ts +0 -0
  288. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/redux/slice/tests/ui.slice.test.ts +0 -0
  289. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/redux/slice/theme.slice.ts +0 -0
  290. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/redux/slice/ui.slice.ts +0 -0
  291. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/redux/slice/url.slice.ts +0 -0
  292. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/redux/store.ts +0 -0
  293. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/redux/utils.ts +0 -0
  294. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/styles/theme.ts +0 -0
  295. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/test/constants.ts +0 -0
  296. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/test/mocks/statsRequest.mock.ts +0 -0
  297. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/test/mocks/swarmState.mock.ts +0 -0
  298. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/test/setup.ts +0 -0
  299. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/test/testUtils.tsx +0 -0
  300. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/types/auth.types.ts +0 -0
  301. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/types/swarm.types.ts +0 -0
  302. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/types/tab.types.ts +0 -0
  303. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/types/table.types.ts +0 -0
  304. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/types/ui.types.ts +0 -0
  305. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/utils/array.ts +0 -0
  306. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/utils/date.ts +0 -0
  307. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/utils/number.ts +0 -0
  308. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/utils/object.ts +0 -0
  309. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/utils/string.ts +0 -0
  310. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/utils/tests/number.test.ts +0 -0
  311. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/utils/tests/object.test.ts +0 -0
  312. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/utils/tests/string.test.ts +0 -0
  313. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/utils/tests/url.test.ts +0 -0
  314. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/src/utils/url.ts +0 -0
  315. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/tsconfig.json +0 -0
  316. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/vite.config.ts +0 -0
  317. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/vitest.config.ts +0 -0
  318. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust/webui/yarn.lock +0 -0
  319. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust.egg-info/SOURCES.txt +0 -0
  320. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust.egg-info/dependency_links.txt +0 -0
  321. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust.egg-info/entry_points.txt +0 -0
  322. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust.egg-info/not-zip-safe +0 -0
  323. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust.egg-info/requires.txt +0 -0
  324. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/locust.egg-info/top_level.txt +0 -0
  325. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/package.json +0 -0
  326. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/pyproject.toml +0 -0
  327. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/setup.cfg +0 -0
  328. {locust-2.29.2.dev10 → locust-2.29.2.dev15}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: locust
3
- Version: 2.29.2.dev10
3
+ Version: 2.29.2.dev15
4
4
  Summary: Developer-friendly load testing framework
5
5
  License: MIT
6
6
  Project-URL: Homepage, https://github.com/locustio/locust
@@ -6,6 +6,10 @@
6
6
  # 3. Test start
7
7
  # 4. User start
8
8
  # 5. Inside a task
9
+ # M1. CPU & memory usage
10
+ # M2. master sent heartbeat to worker 1-N
11
+ # M3. worker 1-N received heartbeat from master
12
+ # (M* are repeated as long as locust is running)
9
13
  # ...
10
14
  # 6. Test run stopping
11
15
  # 7. User stop
@@ -15,17 +19,21 @@
15
19
  # 10. Locust quit
16
20
  #
17
21
  # try it out by running:
18
- # locust -f test_data_management.py --headless -u 2 -t 5
22
+ # locust -f test_data_management.py --headless -u 2 -t 5 --processes 2
23
+ from __future__ import annotations
24
+
19
25
  from locust import HttpUser, events, task
26
+ from locust.env import Environment
20
27
  from locust.runners import MasterRunner
21
28
  from locust.user.wait_time import constant
22
29
 
23
30
  import datetime
31
+ from typing import Any
24
32
 
25
33
  import requests
26
34
 
27
35
 
28
- def timestring():
36
+ def timestring() -> str:
29
37
  now = datetime.datetime.now()
30
38
  return datetime.datetime.strftime(now, "%m:%S.%f")[:-5]
31
39
 
@@ -42,17 +50,17 @@ test_run_specific_data = None
42
50
 
43
51
 
44
52
  @events.init.add_listener
45
- def init(environment, **_kwargs):
53
+ def init(environment: Environment, **_kwargs: Any) -> None:
46
54
  print("2. Initializing locust, happens after parsing the locustfile but before test start")
47
55
 
48
56
 
49
57
  @events.quitting.add_listener
50
- def quitting(environment, **_kwargs):
58
+ def quitting(environment: Environment, **_kwargs: Any) -> None:
51
59
  print("9. locust is about to shut down")
52
60
 
53
61
 
54
62
  @events.test_start.add_listener
55
- def test_start(environment, **_kwargs):
63
+ def test_start(environment: Environment, **_kwargs) -> None:
56
64
  # happens only once in headless runs, but can happen multiple times in web ui-runs
57
65
  global test_run_specific_data
58
66
  print("3. Starting test run")
@@ -64,18 +72,35 @@ def test_start(environment, **_kwargs):
64
72
  ).json()["data"]
65
73
 
66
74
 
75
+ @events.heartbeat_sent.add_listener
76
+ def heartbeat_sent(client_id: str, timestamp: float) -> None:
77
+ print(f"M2. master sent heartbeat to worker {client_id} at {datetime.datetime.fromtimestamp(timestamp)}")
78
+
79
+
80
+ @events.heartbeat_received.add_listener
81
+ def heartbeat_received(client_id: str, timestamp: float) -> None:
82
+ print(f"M3. worker {client_id} received heartbeat from master at {datetime.datetime.fromtimestamp(timestamp)}")
83
+
84
+
85
+ @events.usage_monitor.add_listener
86
+ def usage_monitor(environment: Environment, cpu_usage: float, memory_usage: int) -> None:
87
+ # convert from bytes to Mebibytes
88
+ memory_usage = memory_usage / 1024 / 1024
89
+ print(f"M1. {environment.runner.__class__.__name__}: cpu={cpu_usage}%, memory={memory_usage}M")
90
+
91
+
67
92
  @events.quit.add_listener
68
- def quit(exit_code, **kwargs):
93
+ def quit(exit_code: int, **kwargs: Any) -> None:
69
94
  print(f"10. Locust has shut down with code {exit_code}")
70
95
 
71
96
 
72
97
  @events.test_stopping.add_listener
73
- def test_stopping(environment, **_kwargs):
98
+ def test_stopping(environment: Environment, **_kwargs: Any) -> None:
74
99
  print("6. stopping test run")
75
100
 
76
101
 
77
102
  @events.test_stop.add_listener
78
- def test_stop(environment, **_kwargs):
103
+ def test_stop(environment: Environment, **_kwargs: Any) -> None:
79
104
  print("8. test run stopped")
80
105
 
81
106
 
@@ -84,7 +109,7 @@ class MyUser(HttpUser):
84
109
  wait_time = constant(180) # be nice to postman-echo
85
110
  first_start = True
86
111
 
87
- def on_start(self):
112
+ def on_start(self) -> None:
88
113
  if MyUser.first_start:
89
114
  MyUser.first_start = False
90
115
  # This is useful for similar things as to test_start, but happens in the context of a User
@@ -101,7 +126,7 @@ class MyUser(HttpUser):
101
126
  ).json()["data"]
102
127
 
103
128
  @task
104
- def t(self):
129
+ def t(self) -> None:
105
130
  self.client.get(f"/get?{global_test_data}")
106
131
  self.client.get(f"/get?{test_run_specific_data}")
107
132
  self.client.get(f"/get?{self.user_specific_testdata}")
@@ -114,6 +139,6 @@ class MyUser(HttpUser):
114
139
  ).json()["data"]
115
140
  self.client.get(f"/get?{task_run_specific_testdata}")
116
141
 
117
- def on_stop(self):
142
+ def on_stop(self) -> None:
118
143
  # this is a good place to clean up/release any user-specific test data
119
144
  print("7. a user was stopped")
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '2.29.2.dev10'
16
- __version_tuple__ = version_tuple = (2, 29, 2, 'dev10')
15
+ __version__ = version = '2.29.2.dev15'
16
+ __version_tuple__ = version_tuple = (2, 29, 2, 'dev15')
@@ -235,6 +235,38 @@ class Events:
235
235
  Fired when the CPU usage exceeds runners.CPU_WARNING_THRESHOLD (90% by default)
236
236
  """
237
237
 
238
+ heartbeat_sent: EventHook
239
+ """
240
+ Fired when a heartbeat is sent by master to a worker.
241
+
242
+ Event arguments:
243
+
244
+ :param client_id: worker client id
245
+ :param timestamp: time in seconds since the epoch (float) when the event occured
246
+ """
247
+
248
+ heartbeat_received: EventHook
249
+ """
250
+ Fired when a heartbeat is received by a worker from master.
251
+
252
+ Event arguments:
253
+
254
+ :param client_id: worker client id
255
+ :param timestamp: time in seconds since the epoch (float) when the event occured
256
+ """
257
+
258
+ usage_monitor: EventHook
259
+ """
260
+ Fired every runners.CPU_MONITOR_INTERVAL (5.0 seconds by default) with information about
261
+ current CPU and memory usage.
262
+
263
+ Event arguments:
264
+
265
+ :param environment: locust environment
266
+ :param cpu_usage: current CPU usage in percent
267
+ :param memory_usage: current memory usage (RSS) in bytes
268
+ """
269
+
238
270
  def __init__(self):
239
271
  # For backward compatibility use also values of class attributes
240
272
  for name, value in vars(type(self)).items():
@@ -15,19 +15,9 @@ import traceback
15
15
  from abc import abstractmethod
16
16
  from collections import defaultdict
17
17
  from collections.abc import Iterator, MutableMapping, ValuesView
18
- from operator import (
19
- itemgetter,
20
- methodcaller,
21
- )
18
+ from operator import itemgetter, methodcaller
22
19
  from types import TracebackType
23
- from typing import (
24
- TYPE_CHECKING,
25
- Any,
26
- Callable,
27
- NoReturn,
28
- TypedDict,
29
- cast,
30
- )
20
+ from typing import TYPE_CHECKING, Any, Callable, NoReturn, TypedDict, cast
31
21
  from uuid import uuid4
32
22
 
33
23
  import gevent
@@ -40,15 +30,8 @@ from . import argument_parser
40
30
  from .dispatch import UsersDispatcher
41
31
  from .exception import RPCError, RPCReceiveError, RPCSendError
42
32
  from .log import get_logs, greenlet_exception_logger
43
- from .rpc import (
44
- Message,
45
- rpc,
46
- )
47
- from .stats import (
48
- RequestStats,
49
- StatsError,
50
- setup_distributed_stats_event_listeners,
51
- )
33
+ from .rpc import Message, rpc
34
+ from .stats import RequestStats, StatsError, setup_distributed_stats_event_listeners
52
35
 
53
36
  if TYPE_CHECKING:
54
37
  from . import User
@@ -106,7 +89,7 @@ class Runner:
106
89
  self.spawning_greenlet: gevent.Greenlet | None = None
107
90
  self.shape_greenlet: gevent.Greenlet | None = None
108
91
  self.shape_last_tick: tuple[int, float] | tuple[int, float, list[type[User]] | None] | None = None
109
- self.current_cpu_usage: int = 0
92
+ self.current_cpu_usage: float = 0.0
110
93
  self.cpu_warning_emitted: bool = False
111
94
  self.worker_cpu_warning_emitted: bool = False
112
95
  self.current_memory_usage: int = 0
@@ -308,6 +291,10 @@ class Runner:
308
291
  f"CPU usage above {CPU_WARNING_THRESHOLD}%! This may constrain your throughput and may even give inconsistent response time measurements! See https://docs.locust.io/en/stable/running-distributed.html for how to distribute the load over multiple CPU cores or machines"
309
292
  )
310
293
  self.cpu_warning_emitted = True
294
+
295
+ self.environment.events.usage_monitor.fire(
296
+ environment=self.environment, cpu_usage=self.current_cpu_usage, memory_usage=self.current_memory_usage
297
+ )
311
298
  gevent.sleep(CPU_MONITOR_INTERVAL)
312
299
 
313
300
  @abstractmethod
@@ -1102,6 +1089,7 @@ class MasterRunner(DistributedRunner):
1102
1089
  )
1103
1090
  if "current_memory_usage" in msg.data:
1104
1091
  c.memory_usage = msg.data["current_memory_usage"]
1092
+ self.environment.events.heartbeat_sent.fire(client_id=msg.node_id, timestamp=time.time())
1105
1093
  self.server.send_to_client(Message("heartbeat", None, msg.node_id))
1106
1094
  else:
1107
1095
  logging.debug(f"Got heartbeat message from unknown worker {msg.node_id}")
@@ -1399,6 +1387,9 @@ class WorkerRunner(DistributedRunner):
1399
1387
  self.reset_connection()
1400
1388
  elif msg.type == "heartbeat":
1401
1389
  self.last_heartbeat_timestamp = time.time()
1390
+ self.environment.events.heartbeat_received.fire(
1391
+ client_id=msg.node_id, timestamp=self.last_heartbeat_timestamp
1392
+ )
1402
1393
  elif msg.type == "update_user_class":
1403
1394
  self.environment.update_user_class(msg.data)
1404
1395
  elif msg.type == "spawning_complete":
@@ -1,12 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import locust
4
- from locust import (
5
- LoadTestShape,
6
- __version__,
7
- constant,
8
- runners,
9
- )
4
+ from locust import LoadTestShape, __version__, constant, runners
10
5
  from locust.argument_parser import parse_options
11
6
  from locust.dispatch import UsersDispatcher
12
7
  from locust.env import Environment
@@ -26,11 +21,7 @@ from locust.runners import (
26
21
  WorkerRunner,
27
22
  )
28
23
  from locust.stats import RequestStats
29
- from locust.user import (
30
- TaskSet,
31
- User,
32
- task,
33
- )
24
+ from locust.user import TaskSet, User, task
34
25
 
35
26
  import json
36
27
  import logging
@@ -2136,6 +2127,149 @@ class TestMasterWorkerRunners(LocustTestCase):
2136
2127
 
2137
2128
  self.assertEqual(test_start_exec_count, 1)
2138
2129
 
2130
+ def test_heartbeat_event(self) -> None:
2131
+ """
2132
+ Tests that heartbeat event is fired during a test
2133
+ """
2134
+
2135
+ class TestUser(User):
2136
+ wait_time = constant(0.1)
2137
+
2138
+ @task
2139
+ def noop(self) -> None:
2140
+ pass
2141
+
2142
+ with mock.patch("locust.runners.HEARTBEAT_INTERVAL", new=1):
2143
+ # start a Master runner
2144
+ master_env = Environment(user_classes=[TestUser])
2145
+ worker_connect_events = []
2146
+ timestamp_start: list[float] = [time.time() + 3600.0]
2147
+
2148
+ def on_connect(client_id: str) -> None:
2149
+ worker_connect_events.append(client_id)
2150
+ timestamp_start[0] = time.time()
2151
+
2152
+ master_env.events.worker_connect.add_listener(on_connect)
2153
+ master = master_env.create_master_runner("*", 0)
2154
+ sleep(0)
2155
+ worker_env = Environment(user_classes=[TestUser])
2156
+ worker: WorkerRunner = worker_env.create_worker_runner("127.0.0.1", master.server.port)
2157
+
2158
+ with (
2159
+ mock.patch.object(
2160
+ worker.environment.events.heartbeat_received,
2161
+ "fire",
2162
+ wraps=worker.environment.events.heartbeat_received.fire,
2163
+ ) as worker_heartbeat_received_mock,
2164
+ mock.patch.object(
2165
+ master.environment.events.heartbeat_sent,
2166
+ "fire",
2167
+ wraps=master.environment.events.heartbeat_sent.fire,
2168
+ ) as master_heartbeat_sent_mock,
2169
+ ):
2170
+ # give workers time to connect
2171
+ sleep(0.1)
2172
+ # issue start command that should trigger TestUsers to be spawned in the Workers
2173
+ master.start(2, spawn_rate=2)
2174
+ sleep(0.1)
2175
+ # check that worker nodes have started locusts
2176
+ self.assertEqual(2, worker.user_count)
2177
+
2178
+ # give time for nodes to send and receive 5 heartbeats, HEARTBEAT_INTERVAL mocked to 1 second, so
2179
+ # sleep 5 seconds - 1 second that represents the overhead from connecting
2180
+ sleep(5 - 1)
2181
+ master.quit()
2182
+
2183
+ # make sure users are killed
2184
+ self.assertEqual(0, worker.user_count)
2185
+ # make sure events happened correctly
2186
+ self.assertIn(worker.client_id, worker_connect_events)
2187
+
2188
+ timestamp_stop = time.time()
2189
+
2190
+ self.assertEqual(worker_heartbeat_received_mock.call_count, 5)
2191
+ self.assertEqual(master_heartbeat_sent_mock.call_count, 5)
2192
+
2193
+ for call_args, call_kwargs in [
2194
+ *worker_heartbeat_received_mock.call_args_list,
2195
+ *master_heartbeat_sent_mock.call_args_list,
2196
+ ]:
2197
+ self.assertEqual(call_args, ()) # args
2198
+ self.assertEqual(call_kwargs, {"client_id": worker.client_id, "timestamp": mock.ANY}) # kwargs
2199
+ self.assertGreaterEqual(call_kwargs["timestamp"], timestamp_start[0])
2200
+ self.assertLessEqual(call_kwargs["timestamp"], timestamp_stop)
2201
+
2202
+ def test_usage_monitor_event(self) -> None:
2203
+ """
2204
+ Tests that usage_monitor event is fired during a test
2205
+ """
2206
+
2207
+ class TestUser(User):
2208
+ wait_time = constant(0.1)
2209
+
2210
+ @task
2211
+ def noop(self) -> None:
2212
+ pass
2213
+
2214
+ with mock.patch("locust.runners.CPU_MONITOR_INTERVAL", new=1):
2215
+ # start a Master runner
2216
+ master_env = Environment(user_classes=[TestUser])
2217
+ worker_connect_events = []
2218
+
2219
+ def on_connect(client_id: str) -> None:
2220
+ worker_connect_events.append(client_id)
2221
+
2222
+ master_env.events.worker_connect.add_listener(on_connect)
2223
+ master = master_env.create_master_runner("*", 0)
2224
+ sleep(0)
2225
+ worker_env = Environment(user_classes=[TestUser])
2226
+ worker: WorkerRunner = worker_env.create_worker_runner("127.0.0.1", master.server.port)
2227
+
2228
+ with (
2229
+ mock.patch.object(
2230
+ worker.environment.events.usage_monitor, "fire", wraps=worker.environment.events.usage_monitor.fire
2231
+ ) as worker_usage_monitor_mock,
2232
+ mock.patch.object(
2233
+ master.environment.events.usage_monitor, "fire", wraps=master.environment.events.usage_monitor.fire
2234
+ ) as master_usage_monitor_mock,
2235
+ ):
2236
+ # give workers time to connect
2237
+ sleep(0.1)
2238
+ # issue start command that should trigger TestUsers to be spawned in the Workers
2239
+ master.start(2, spawn_rate=2)
2240
+ sleep(0.1)
2241
+ # check that worker nodes have started locusts
2242
+ self.assertEqual(2, worker.user_count)
2243
+
2244
+ # give time for nodes to send 5 usage_monitor events, CPU_MONITOR_INTERVAL mocked to 1 second, so
2245
+ # sleep 5 seconds
2246
+ sleep(5)
2247
+ master.quit()
2248
+
2249
+ # make sure users are killed
2250
+ self.assertEqual(0, worker.user_count)
2251
+ # make sure events happened correctly
2252
+ self.assertIn(worker.client_id, worker_connect_events)
2253
+
2254
+ self.assertEqual(worker_usage_monitor_mock.call_count, 5)
2255
+ self.assertEqual(master_usage_monitor_mock.call_count, 5)
2256
+
2257
+ for call_args, call_kwargs in master_usage_monitor_mock:
2258
+ self.assertEqual(call_args, ()) # args
2259
+ self.assertEqual(
2260
+ call_kwargs, {"environment": master_env, "cpu_usage": mock.ANY, "memory_usage": mock.ANY}
2261
+ ) # kwargs
2262
+ self.assertTrue(isinstance(call_kwargs["cpu_usage"], float))
2263
+ self.assertTrue(isinstance(call_kwargs["memory_usage"], int))
2264
+
2265
+ for call_args, call_kwargs in worker_usage_monitor_mock:
2266
+ self.assertEqual(call_args, ()) # args
2267
+ self.assertEqual(
2268
+ call_kwargs, {"environment": worker_env, "cpu_usage": mock.ANY, "memory_usage": mock.ANY}
2269
+ ) # kwargs
2270
+ self.assertTrue(isinstance(call_kwargs["cpu_usage"], float))
2271
+ self.assertTrue(isinstance(call_kwargs["memory_usage"], int))
2272
+
2139
2273
 
2140
2274
  class TestMasterRunner(LocustRunnerTestCase):
2141
2275
  def setUp(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: locust
3
- Version: 2.29.2.dev10
3
+ Version: 2.29.2.dev15
4
4
  Summary: Developer-friendly load testing framework
5
5
  License: MIT
6
6
  Project-URL: Homepage, https://github.com/locustio/locust
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes