locust 2.24.1.dev23__tar.gz → 2.24.2.dev8__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 (349) hide show
  1. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/CHANGELOG.md +25 -0
  2. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/PKG-INFO +1 -1
  3. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/changelog.rst +5 -0
  4. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/running-distributed.rst +14 -1
  5. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/custom_messages.py +12 -0
  6. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/_version.py +2 -2
  7. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/runners.py +14 -6
  8. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_runners.py +25 -0
  9. locust-2.24.1.dev23/locust/webui/dist/assets/index-fd3e763b.js → locust-2.24.2.dev8/locust/webui/dist/assets/index-941b6e82.js +1 -1
  10. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/dist/auth.html +1 -1
  11. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/dist/index.html +1 -1
  12. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/ExceptionsTable/ExceptionsTable.tsx +2 -2
  13. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust.egg-info/PKG-INFO +1 -1
  14. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust.egg-info/SOURCES.txt +1 -1
  15. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/.coveragerc +0 -0
  16. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/.dockerignore +0 -0
  17. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/.git-blame-ignore-revs +0 -0
  18. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/.gitattributes +0 -0
  19. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/.github/CONTRIBUTING.md +0 -0
  20. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
  21. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  22. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  23. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/.github/workflows/stale.yml +0 -0
  24. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/.github/workflows/tests.yml +0 -0
  25. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/.gitignore +0 -0
  26. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/.readthedocs.yaml +0 -0
  27. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/.vscode/extensions.json +0 -0
  28. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/.vscode/launch.json +0 -0
  29. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/.vscode/launch_locust.json +0 -0
  30. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/.vscode/settings.json +0 -0
  31. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/Dockerfile +0 -0
  32. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/LICENSE +0 -0
  33. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/MANIFEST.in +0 -0
  34. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/Makefile +0 -0
  35. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/README +0 -0
  36. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/README.md +0 -0
  37. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/SECURITY.md +0 -0
  38. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/Vagrantfile +0 -0
  39. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/benchmarks/dispatch.py +0 -0
  40. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/_static/theme-overrides.css +0 -0
  41. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/api.rst +0 -0
  42. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/conf.py +0 -0
  43. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/configuration.rst +0 -0
  44. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/custom-load-shape.rst +0 -0
  45. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/developing-locust.rst +0 -0
  46. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/extending-locust.rst +0 -0
  47. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/further-reading.rst +0 -0
  48. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/history.rst +0 -0
  49. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/images/locust_workers.png +0 -0
  50. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/images/number_of_users.png +0 -0
  51. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/images/response_times.png +0 -0
  52. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/images/total_requests_per_second.png +0 -0
  53. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/images/userclass_picker_example.png +0 -0
  54. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/images/webui-running-statistics.png +0 -0
  55. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/images/webui-splash-screenshot.png +0 -0
  56. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/increase-performance.rst +0 -0
  57. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/index.rst +0 -0
  58. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/installation.rst +0 -0
  59. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/logging.rst +0 -0
  60. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/quickstart.rst +0 -0
  61. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/requirements.txt +0 -0
  62. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/retrieving-stats.rst +0 -0
  63. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/running-cloud-integration.rst +0 -0
  64. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/running-in-debugger.rst +0 -0
  65. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/running-in-docker.rst +0 -0
  66. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/running-without-web-ui.rst +0 -0
  67. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/tasksets.rst +0 -0
  68. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/testing-other-systems.rst +0 -0
  69. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/use-as-lib.rst +0 -0
  70. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/what-is-locust.rst +0 -0
  71. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/docs/writing-a-locustfile.rst +0 -0
  72. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/add_command_line_argument.py +0 -0
  73. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/basic.py +0 -0
  74. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/browse_docs_sequence_test.py +0 -0
  75. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/browse_docs_test.py +0 -0
  76. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/custom_shape/double_wave.py +0 -0
  77. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/custom_shape/stages.py +0 -0
  78. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/custom_shape/staging_user_classes.py +0 -0
  79. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/custom_shape/step_load.py +0 -0
  80. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/custom_shape/wait_user_count.py +0 -0
  81. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/custom_wait_function.py +0 -0
  82. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/custom_xmlrpc_client/server.py +0 -0
  83. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/custom_xmlrpc_client/xmlrpc_locustfile.py +0 -0
  84. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/debugging.py +0 -0
  85. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/debugging_advanced.py +0 -0
  86. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/docker-compose/docker-compose.yml +0 -0
  87. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/dynamic_user_credentials.py +0 -0
  88. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/events.py +0 -0
  89. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/extend_modern_web_ui.py +0 -0
  90. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/extend_web_ui/extend.py +0 -0
  91. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/extend_web_ui/static/custom-stats-table.css +0 -0
  92. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/extend_web_ui/static/extend.js +0 -0
  93. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/extend_web_ui/templates/extend.html +0 -0
  94. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/fast_http_locust.py +0 -0
  95. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/grpc/grpc_user.py +0 -0
  96. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/grpc/hello.proto +0 -0
  97. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/grpc/hello_pb2.py +0 -0
  98. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/grpc/hello_pb2_grpc.py +0 -0
  99. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/grpc/hello_server.py +0 -0
  100. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/grpc/locustfile.py +0 -0
  101. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/locustfile.py +0 -0
  102. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/manual_stats_reporting.py +0 -0
  103. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/multiple_hosts.py +0 -0
  104. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/nested_inline_tasksets.py +0 -0
  105. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/rest.py +0 -0
  106. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/sdk_session_patching/session_patch_locustfile.py +0 -0
  107. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/semaphore_wait.py +0 -0
  108. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/stop_on_threshold.py +0 -0
  109. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/terraform/aws/README.md +0 -0
  110. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/terraform/aws/data_subnet.tf +0 -0
  111. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/terraform/aws/main.tf +0 -0
  112. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/terraform/aws/output.tf +0 -0
  113. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/terraform/aws/plan/basic.py +0 -0
  114. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/terraform/aws/provisioner.tf +0 -0
  115. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/terraform/aws/variables.tf +0 -0
  116. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/test_data_management.py +0 -0
  117. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/use_as_lib.py +0 -0
  118. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/vagrant/README.md +0 -0
  119. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/vagrant/supervisord.conf +0 -0
  120. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/web_ui_auth.py +0 -0
  121. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/examples/worker_index.py +0 -0
  122. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/generate_changelog.py +0 -0
  123. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/__init__.py +0 -0
  124. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/__main__.py +0 -0
  125. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/argument_parser.py +0 -0
  126. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/clients.py +0 -0
  127. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/contrib/__init__.py +0 -0
  128. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/contrib/fasthttp.py +0 -0
  129. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/debug.py +0 -0
  130. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/dispatch.py +0 -0
  131. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/env.py +0 -0
  132. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/event.py +0 -0
  133. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/exception.py +0 -0
  134. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/html.py +0 -0
  135. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/input_events.py +0 -0
  136. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/log.py +0 -0
  137. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/main.py +0 -0
  138. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/py.typed +0 -0
  139. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/rpc/__init__.py +0 -0
  140. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/rpc/protocol.py +0 -0
  141. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/rpc/zmqrpc.py +0 -0
  142. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/shape.py +0 -0
  143. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/chart.js +0 -0
  144. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/css/application.css +0 -0
  145. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/css/application.css.map +0 -0
  146. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/css/tables.css +0 -0
  147. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/css/tables.css.map +0 -0
  148. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/echarts.common.min.js +0 -0
  149. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/img/favicon.ico +0 -0
  150. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/img/logo.png +0 -0
  151. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/img/ui-screenshot-charts.png +0 -0
  152. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/img/ui-screenshot-start-test.png +0 -0
  153. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/img/ui-screenshot-stats.png +0 -0
  154. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/img/ui-screenshot-workers.png +0 -0
  155. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/jquery-1.11.3.min.js +0 -0
  156. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/jquery.jqote2.min.js +0 -0
  157. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/jquery.tools.min.js +0 -0
  158. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/locust.js +0 -0
  159. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/sass/_base.sass +0 -0
  160. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/sass/_mixins.sass +0 -0
  161. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/sass/application.sass +0 -0
  162. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/sass/tables.sass +0 -0
  163. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/tasks.js +0 -0
  164. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/static/vintage.js +0 -0
  165. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/stats.py +0 -0
  166. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/templates/index.html +0 -0
  167. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/templates/report.html +0 -0
  168. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/templates/stats_data.html +0 -0
  169. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/__init__.py +0 -0
  170. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/fake_module1_for_env_test.py +0 -0
  171. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/fake_module2_for_env_test.py +0 -0
  172. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/mock_locustfile.py +0 -0
  173. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/mock_logging.py +0 -0
  174. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_debugging.py +0 -0
  175. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_dispatch.py +0 -0
  176. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_env.py +0 -0
  177. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_fasthttp.py +0 -0
  178. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_http.py +0 -0
  179. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_interruptable_task.py +0 -0
  180. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_load_locustfile.py +0 -0
  181. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_locust_class.py +0 -0
  182. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_log.py +0 -0
  183. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_main.py +0 -0
  184. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_old_wait_api.py +0 -0
  185. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_parser.py +0 -0
  186. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_sequential_taskset.py +0 -0
  187. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_stats.py +0 -0
  188. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_tags.py +0 -0
  189. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_taskratio.py +0 -0
  190. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_users.py +0 -0
  191. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_util.py +0 -0
  192. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_wait_time.py +0 -0
  193. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_web.py +0 -0
  194. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/test_zmqrpc.py +0 -0
  195. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/testcases.py +0 -0
  196. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/test/util.py +0 -0
  197. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/user/__init__.py +0 -0
  198. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/user/inspectuser.py +0 -0
  199. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/user/sequential_taskset.py +0 -0
  200. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/user/task.py +0 -0
  201. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/user/users.py +0 -0
  202. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/user/wait_time.py +0 -0
  203. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/util/__init__.py +0 -0
  204. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/util/cache.py +0 -0
  205. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/util/deprecation.py +0 -0
  206. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/util/exception_handler.py +0 -0
  207. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/util/load_locustfile.py +0 -0
  208. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/util/rounding.py +0 -0
  209. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/util/timespan.py +0 -0
  210. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/web.py +0 -0
  211. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/.eslintrc +0 -0
  212. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/.gitignore +0 -0
  213. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/.prettierrc +0 -0
  214. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/auth.html +0 -0
  215. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/dev.html +0 -0
  216. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/dist/assets/favicon.ico +0 -0
  217. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/dist/assets/logo.png +0 -0
  218. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/dist/report.html +0 -0
  219. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/index.html +0 -0
  220. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/package.json +0 -0
  221. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/public/assets/favicon.ico +0 -0
  222. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/public/assets/logo.png +0 -0
  223. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/public/report.html +0 -0
  224. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/App.test.tsx +0 -0
  225. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/App.tsx +0 -0
  226. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/DataTable/DataTable.test.tsx +0 -0
  227. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/DataTable/DataTable.tsx +0 -0
  228. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/FailuresTable/FailuresTable.tsx +0 -0
  229. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/FallbackRender/FallbackRender.test.tsx +0 -0
  230. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/FallbackRender/FallbackRender.tsx +0 -0
  231. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Form/Form.tsx +0 -0
  232. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Form/Select.tsx +0 -0
  233. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Form/tests/Form.test.tsx +0 -0
  234. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Form/tests/Select.test.tsx +0 -0
  235. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Layout/Footer/About.tsx +0 -0
  236. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Layout/Footer/Footer.tsx +0 -0
  237. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Layout/Layout.tsx +0 -0
  238. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Layout/Navbar/DarkLightToggle.tsx +0 -0
  239. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Layout/Navbar/Navbar.tsx +0 -0
  240. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Layout/Navbar/SwarmMonitor.test.tsx +0 -0
  241. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Layout/Navbar/SwarmMonitor.tsx +0 -0
  242. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/LineChart/LineChart.test.tsx +0 -0
  243. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/LineChart/LineChart.tsx +0 -0
  244. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/LogViewer/LogViewer.tsx +0 -0
  245. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/LogViewer/tests/LogViewer.test.tsx +0 -0
  246. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/LogViewer/tests/useLogViewer.test.tsx +0 -0
  247. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/LogViewer/useLogViewer.ts +0 -0
  248. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Modal/Modal.tsx +0 -0
  249. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Reports/Reports.test.tsx +0 -0
  250. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Reports/Reports.tsx +0 -0
  251. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/ResponseTimeTable/ResponseTimeTable.test.tsx +0 -0
  252. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/ResponseTimeTable/ResponseTimeTable.tsx +0 -0
  253. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/StateButtons/EditButton.tsx +0 -0
  254. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/StateButtons/NewTestButton.tsx +0 -0
  255. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/StateButtons/ResetButton.tsx +0 -0
  256. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/StateButtons/StateButtons.tsx +0 -0
  257. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/StateButtons/StopButton.tsx +0 -0
  258. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/StateButtons/tests/ResetButton.test.tsx +0 -0
  259. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/StateButtons/tests/StateButtons.test.tsx +0 -0
  260. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/StateButtons/tests/StopButton.test.tsx +0 -0
  261. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/StatsTable/StatsTable.tsx +0 -0
  262. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/SwarmCharts/SwarmCharts.tsx +0 -0
  263. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/SwarmForm/SwarmCustomParameters.tsx +0 -0
  264. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/SwarmForm/SwarmEditForm.tsx +0 -0
  265. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/SwarmForm/SwarmForm.tsx +0 -0
  266. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/SwarmForm/SwarmUserClassPicker.tsx +0 -0
  267. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/SwarmForm/tests/SwarmCustomParameters.test.tsx +0 -0
  268. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/SwarmForm/tests/SwarmEditForm.test.tsx +0 -0
  269. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/SwarmForm/tests/SwarmForm.test.tsx +0 -0
  270. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/SwarmForm/tests/SwarmUserClassPicker.test.tsx +0 -0
  271. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/SwarmRatios/SwarmRatios.test.tsx +0 -0
  272. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/SwarmRatios/SwarmRatios.tsx +0 -0
  273. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Table/Table.test.tsx +0 -0
  274. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Table/Table.tsx +0 -0
  275. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Tabs/Tabs.constants.tsx +0 -0
  276. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Tabs/Tabs.test.tsx +0 -0
  277. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/Tabs/Tabs.tsx +0 -0
  278. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/ViewColumnSelector/ViewColumnSelector.test.tsx +0 -0
  279. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/ViewColumnSelector/ViewColumnSelector.tsx +0 -0
  280. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/components/WorkersTable/WorkersTable.tsx +0 -0
  281. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/constants/auth.ts +0 -0
  282. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/constants/swarm.ts +0 -0
  283. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/constants/theme.ts +0 -0
  284. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/global.d.ts +0 -0
  285. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/hooks/tests/useNotifications.test.tsx +0 -0
  286. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/hooks/tests/useSelecteViewColumns.test.tsx +0 -0
  287. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/hooks/tests/useSortByField.test.tsx +0 -0
  288. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/hooks/tests/useSwarmUi.test.tsx +0 -0
  289. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/hooks/useInterval.ts +0 -0
  290. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/hooks/useNotifications.ts +0 -0
  291. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/hooks/useSelectViewColumns.ts +0 -0
  292. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/hooks/useSortByField.ts +0 -0
  293. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/hooks/useSwarmUi.ts +0 -0
  294. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/index.tsx +0 -0
  295. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/pages/Auth.tsx +0 -0
  296. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/pages/Dashboard.tsx +0 -0
  297. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/pages/HtmlReport.tsx +0 -0
  298. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/pages/tests/Auth.test.tsx +0 -0
  299. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/pages/tests/Dashboard.test.tsx +0 -0
  300. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/pages/tests/HtmlReport.test.tsx +0 -0
  301. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/redux/api/swarm.ts +0 -0
  302. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/redux/hooks.ts +0 -0
  303. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/redux/slice/logViewer.slice.ts +0 -0
  304. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/redux/slice/notification.slice.ts +0 -0
  305. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/redux/slice/root.slice.ts +0 -0
  306. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/redux/slice/swarm.slice.ts +0 -0
  307. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/redux/slice/tests/ui.slice.test.ts +0 -0
  308. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/redux/slice/theme.slice.ts +0 -0
  309. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/redux/slice/ui.slice.ts +0 -0
  310. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/redux/slice/url.slice.ts +0 -0
  311. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/redux/store.ts +0 -0
  312. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/redux/utils.ts +0 -0
  313. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/styles/theme.ts +0 -0
  314. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/test/constants.ts +0 -0
  315. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/test/mocks/statsRequest.mock.ts +0 -0
  316. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/test/mocks/swarmState.mock.ts +0 -0
  317. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/test/setup.ts +0 -0
  318. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/test/testUtils.tsx +0 -0
  319. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/types/auth.types.ts +0 -0
  320. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/types/swarm.types.ts +0 -0
  321. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/types/tab.types.ts +0 -0
  322. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/types/table.types.ts +0 -0
  323. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/types/ui.types.ts +0 -0
  324. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/utils/number.ts +0 -0
  325. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/utils/object.ts +0 -0
  326. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/utils/string.ts +0 -0
  327. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/utils/tests/number.test.ts +0 -0
  328. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/utils/tests/object.test.ts +0 -0
  329. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/utils/tests/string.test.ts +0 -0
  330. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/utils/tests/url.test.ts +0 -0
  331. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/src/utils/url.ts +0 -0
  332. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/tsconfig.json +0 -0
  333. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/vite.config.ts +0 -0
  334. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/vitest.config.ts +0 -0
  335. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust/webui/yarn.lock +0 -0
  336. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust.egg-info/dependency_links.txt +0 -0
  337. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust.egg-info/entry_points.txt +0 -0
  338. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust.egg-info/not-zip-safe +0 -0
  339. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust.egg-info/requires.txt +0 -0
  340. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/locust.egg-info/top_level.txt +0 -0
  341. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/package.json +0 -0
  342. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/pyproject.toml +0 -0
  343. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/scripts/locustfile.py +0 -0
  344. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/scripts/run-disributed-headless.sh +0 -0
  345. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/scripts/run-disributed-web.sh +0 -0
  346. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/scripts/run-local-headless.sh +0 -0
  347. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/scripts/run-local-web.sh +0 -0
  348. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/setup.cfg +0 -0
  349. {locust-2.24.1.dev23 → locust-2.24.2.dev8}/tox.ini +0 -0
@@ -1,6 +1,31 @@
1
1
  # Detailed changelog
2
2
  The most important changes can also be found in [the documentation](https://docs.locust.io/en/latest/changelog.html).
3
3
 
4
+ ## [2.24.1](https://github.com/locustio/locust/tree/2.24.1) (2024-03-20)
5
+
6
+ [Full Changelog](https://github.com/locustio/locust/compare/2.24.0...2.24.1)
7
+
8
+ **Fixed bugs:**
9
+
10
+ - `'NoneType' object has no attribute 'get'` when `stream=True` in `FastHttpSession.request` [\#2640](https://github.com/locustio/locust/issues/2640)
11
+ - Locust --processes argument generating multiple html reports [\#2639](https://github.com/locustio/locust/issues/2639)
12
+ - cannot open dashboard and console error shows 'the server responded with a MIME type of "text/plain".' [\#2632](https://github.com/locustio/locust/issues/2632)
13
+ - extend web ui not working since 2.22.0 [\#2629](https://github.com/locustio/locust/issues/2629)
14
+ - Custom parameters incomplete display [\#2628](https://github.com/locustio/locust/issues/2628)
15
+
16
+ **Closed issues:**
17
+
18
+ - pyproject.toml support for locust configuration [\#2298](https://github.com/locustio/locust/issues/2298)
19
+
20
+ **Merged pull requests:**
21
+
22
+ - Do not call blocking `content` property and lazily load response [\#2643](https://github.com/locustio/locust/pull/2643) ([neiser](https://github.com/neiser))
23
+ - Dont throw an exception in FastHttpUser if a request is made with stream=True and the connection fails [\#2642](https://github.com/locustio/locust/pull/2642) ([cyberw](https://github.com/cyberw))
24
+ - \[Modern UI\] Modal Can Extend Beyond Screen Limits [\#2631](https://github.com/locustio/locust/pull/2631) ([andrewbaldwin44](https://github.com/andrewbaldwin44))
25
+ - chore: remove repetitive words [\#2625](https://github.com/locustio/locust/pull/2625) ([tgolang](https://github.com/tgolang))
26
+ - Add documentation about manually closing TCP/HTTP connections [\#2623](https://github.com/locustio/locust/pull/2623) ([DennisKrone](https://github.com/DennisKrone))
27
+ - Update ruff to 0.3.0 [\#2619](https://github.com/locustio/locust/pull/2619) ([cyberw](https://github.com/cyberw))
28
+
4
29
  ## [2.24.0](https://github.com/locustio/locust/tree/2.24.0) (2024-02-29)
5
30
 
6
31
  [Full Changelog](https://github.com/locustio/locust/compare/2.23.1...2.24.0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: locust
3
- Version: 2.24.1.dev23
3
+ Version: 2.24.2.dev8
4
4
  Summary: Developer friendly load testing framework
5
5
  License: MIT
6
6
  Project-URL: Homepage, https://github.com/locustio/locust
@@ -4,6 +4,11 @@ Changelog Highlights
4
4
 
5
5
  For full details of the Locust changelog, please see https://github.com/locustio/locust/blob/master/CHANGELOG.md
6
6
 
7
+ 2.24.1
8
+ ======
9
+ * Some documentation updates & minor fixes to UI
10
+ * Fixes to FastHttpUser content streaming (https://github.com/locustio/locust/pull/2642, https://github.com/locustio/locust/pull/2643)
11
+
7
12
  2.24.0
8
13
  ======
9
14
  * Pluggable dispatcher logic https://github.com/locustio/locust/pull/2606
@@ -131,7 +131,20 @@ order to coordinate the test. This can be easily accomplished with custom messag
131
131
  environment.runner.send_message('test_users', users)
132
132
 
133
133
  Note that when running locally (i.e. non-distributed), this functionality will be preserved;
134
- the messages will simply be handled by the runner that sends them.
134
+ the messages will simply be handled by the runner that sends them.
135
+
136
+ .. note::
137
+ Using the default options while registering a message handler will run the listener function
138
+ in a **blocking** way, resulting in the heartbeat and other messages being delayed for the amount
139
+ of the execution.
140
+ If it is known that the listener function will handle time-intensive tasks, it is possible to register the
141
+ function as **concurrent** (as a separate greenlet).
142
+
143
+ .. code-block::
144
+ environment.runner.register_message('test_users', setup_test_users, concurrent=True)
145
+
146
+ Please use this feature with care, as otherwise it could result in greenlets running and influencing
147
+ the running loadtest.
135
148
 
136
149
  For more details, see the `complete example <https://github.com/locustio/locust/tree/master/examples/custom_messages.py>`_.
137
150
 
@@ -1,12 +1,18 @@
1
1
  from locust import HttpUser, between, events, task
2
2
  from locust.runners import MasterRunner, WorkerRunner
3
3
 
4
+ import gevent
5
+
4
6
  usernames = []
5
7
 
6
8
 
7
9
  def setup_test_users(environment, msg, **kwargs):
8
10
  # Fired when the worker receives a message of type 'test_users'
9
11
  usernames.extend(map(lambda u: u["name"], msg.data))
12
+ # Even though "acknowledge_concurrent_users" was sent first, "acknowledge_users"
13
+ # will print its statement first, as "acknowledge_concurrent_users" was registered
14
+ # running concurrently, and therefore not blocking other messages.
15
+ environment.runner.send_message("concurrent_message", "This is a non blocking message")
10
16
  environment.runner.send_message("acknowledge_users", f"Thanks for the {len(msg.data)} users!")
11
17
 
12
18
 
@@ -15,12 +21,18 @@ def on_acknowledge(msg, **kwargs):
15
21
  print(msg.data)
16
22
 
17
23
 
24
+ def on_concurrent_message(msg, **kwargs):
25
+ gevent.sleep(10)
26
+ print(msg.data)
27
+
28
+
18
29
  @events.init.add_listener
19
30
  def on_locust_init(environment, **_kwargs):
20
31
  if not isinstance(environment.runner, MasterRunner):
21
32
  environment.runner.register_message("test_users", setup_test_users)
22
33
  if not isinstance(environment.runner, WorkerRunner):
23
34
  environment.runner.register_message("acknowledge_users", on_acknowledge)
35
+ environment.runner.register_message("concurrent_message", on_concurrent_message, concurrent=True)
24
36
 
25
37
 
26
38
  @events.test_start.add_listener
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '2.24.1.dev23'
16
- __version_tuple__ = version_tuple = (2, 24, 1, 'dev23')
15
+ __version__ = version = '2.24.2.dev8'
16
+ __version_tuple__ = version_tuple = (2, 24, 2, 'dev8')
@@ -119,7 +119,7 @@ class Runner:
119
119
  self.target_user_classes_count: dict[str, int] = {}
120
120
  # target_user_count is set before the ramp-up/ramp-down occurs.
121
121
  self.target_user_count: int = 0
122
- self.custom_messages: dict[str, Callable] = {}
122
+ self.custom_messages: dict[str, tuple[Callable, bool]] = {}
123
123
 
124
124
  self._users_dispatcher: UsersDispatcher | None = None
125
125
 
@@ -420,7 +420,7 @@ class Runner:
420
420
  row["nodes"].add(node_id)
421
421
  self.exceptions[key] = row
422
422
 
423
- def register_message(self, msg_type: str, listener: Callable) -> None:
423
+ def register_message(self, msg_type: str, listener: Callable, concurrent=False) -> None:
424
424
  """
425
425
  Register a listener for a custom message from another node
426
426
 
@@ -429,7 +429,7 @@ class Runner:
429
429
  """
430
430
  if msg_type in self.custom_messages:
431
431
  raise Exception(f"Tried to register listener method for {msg_type}, but it already had a listener!")
432
- self.custom_messages[msg_type] = listener
432
+ self.custom_messages[msg_type] = (listener, concurrent)
433
433
 
434
434
 
435
435
  class LocalRunner(Runner):
@@ -568,7 +568,7 @@ class LocalRunner(Runner):
568
568
  """
569
569
  logger.debug("Running locally: sending %s message to self" % msg_type)
570
570
  if msg_type in self.custom_messages:
571
- listener = self.custom_messages[msg_type]
571
+ listener, concurrent = self.custom_messages[msg_type]
572
572
  msg = Message(msg_type, data, "local")
573
573
  listener(environment=self.environment, msg=msg)
574
574
  else:
@@ -1139,7 +1139,11 @@ class MasterRunner(DistributedRunner):
1139
1139
  f"Received {msg.type} message from worker {msg.node_id} (index {self.get_worker_index(msg.node_id)})"
1140
1140
  )
1141
1141
  try:
1142
- self.custom_messages[msg.type](environment=self.environment, msg=msg)
1142
+ listener, concurrent = self.custom_messages[msg.type]
1143
+ if not concurrent:
1144
+ listener(environment=self.environment, msg=msg)
1145
+ else:
1146
+ gevent.spawn(listener, self.environment, msg)
1143
1147
  except Exception:
1144
1148
  logging.error(f"Uncaught exception in handler for {msg.type}\n{traceback.format_exc()}")
1145
1149
 
@@ -1393,7 +1397,11 @@ class WorkerRunner(DistributedRunner):
1393
1397
  self.last_heartbeat_timestamp = time.time()
1394
1398
  elif msg.type in self.custom_messages:
1395
1399
  logger.debug("Received %s message from master" % msg.type)
1396
- self.custom_messages[msg.type](environment=self.environment, msg=msg)
1400
+ listener, concurrent = self.custom_messages[msg.type]
1401
+ if not concurrent:
1402
+ listener(environment=self.environment, msg=msg)
1403
+ else:
1404
+ gevent.spawn(listener, self.environment, msg)
1397
1405
  else:
1398
1406
  logger.warning(f"Unknown message type received: {msg.type}")
1399
1407
 
@@ -606,6 +606,31 @@ class TestLocustRunner(LocustRunnerTestCase):
606
606
  self.assertTrue(test_custom_msg[0])
607
607
  self.assertEqual(123, test_custom_msg_data[0]["test_data"])
608
608
 
609
+ def test_concurrent_custom_message(self):
610
+ class MyUser(User):
611
+ wait_time = constant(1)
612
+
613
+ @task
614
+ def my_task(self):
615
+ pass
616
+
617
+ test_custom_msg = [False]
618
+ test_custom_msg_data = [{}]
619
+
620
+ def on_custom_msg(msg, **kw):
621
+ test_custom_msg[0] = True
622
+ test_custom_msg_data[0] = msg.data
623
+
624
+ environment = Environment(user_classes=[MyUser])
625
+ runner = LocalRunner(environment)
626
+
627
+ runner.register_message("test_custom_msg", on_custom_msg, concurrent=True)
628
+ runner.send_message("test_custom_msg", {"test_data": 123})
629
+
630
+ gevent.sleep(0.5)
631
+ self.assertTrue(test_custom_msg[0])
632
+ self.assertEqual(123, test_custom_msg_data[0]["test_data"])
633
+
609
634
  def test_undefined_custom_message(self):
610
635
  class MyUser(User):
611
636
  wait_time = constant(1)
@@ -168,7 +168,7 @@ ${W.current.stack}
168
168
  `});++n<e.length;)n&&r.push({type:"text",value:`
169
169
  `}),r.push(e[n]);return t&&e.length>0&&r.push({type:"text",value:`
170
170
  `}),r}function tE(e){let t=0,r=e.charCodeAt(t);for(;r===9||r===32;)t++,r=e.charCodeAt(t);return e.slice(t)}function rE(e,t){const r=ive(e,t),n=r.one(e,void 0),i=qpe(r),a=Array.isArray(n)?{type:"root",children:n}:n||{type:"root",children:[]};return i&&a.children.push({type:"text",value:`
171
- `},i),a}function uve(e,t){return e&&"run"in e?async function(r,n){const i=rE(r,t);await e.run(i,n)}:function(r){return rE(r,t||e)}}function nE(e){if(e)throw e}var Ym=Object.prototype.hasOwnProperty,F6=Object.prototype.toString,iE=Object.defineProperty,aE=Object.getOwnPropertyDescriptor,oE=function(t){return typeof Array.isArray=="function"?Array.isArray(t):F6.call(t)==="[object Array]"},sE=function(t){if(!t||F6.call(t)!=="[object Object]")return!1;var r=Ym.call(t,"constructor"),n=t.constructor&&t.constructor.prototype&&Ym.call(t.constructor.prototype,"isPrototypeOf");if(t.constructor&&!r&&!n)return!1;var i;for(i in t);return typeof i>"u"||Ym.call(t,i)},lE=function(t,r){iE&&r.name==="__proto__"?iE(t,r.name,{enumerable:!0,configurable:!0,value:r.newValue,writable:!0}):t[r.name]=r.newValue},uE=function(t,r){if(r==="__proto__")if(Ym.call(t,r)){if(aE)return aE(t,r).value}else return;return t[r]},cve=function e(){var t,r,n,i,a,o,s=arguments[0],l=1,u=arguments.length,c=!1;for(typeof s=="boolean"&&(c=s,s=arguments[1]||{},l=2),(s==null||typeof s!="object"&&typeof s!="function")&&(s={});l<u;++l)if(t=arguments[l],t!=null)for(r in t)n=uE(s,r),i=uE(t,r),s!==i&&(c&&i&&(sE(i)||(a=oE(i)))?(a?(a=!1,o=n&&oE(n)?n:[]):o=n&&sE(n)?n:{},lE(s,{name:r,newValue:e(c,o,i)})):typeof i<"u"&&lE(s,{name:r,newValue:i}));return s};const lb=dv(cve);function oT(e){if(typeof e!="object"||e===null)return!1;const t=Object.getPrototypeOf(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Symbol.toStringTag in e)&&!(Symbol.iterator in e)}function fve(){const e=[],t={run:r,use:n};return t;function r(...i){let a=-1;const o=i.pop();if(typeof o!="function")throw new TypeError("Expected function as last argument, not "+o);s(null,...i);function s(l,...u){const c=e[++a];let f=-1;if(l){o(l);return}for(;++f<i.length;)(u[f]===null||u[f]===void 0)&&(u[f]=i[f]);i=u,c?dve(c,s)(...u):o(null,...u)}}function n(i){if(typeof i!="function")throw new TypeError("Expected `middelware` to be a function, not "+i);return e.push(i),t}}function dve(e,t){let r;return n;function n(...o){const s=e.length>o.length;let l;s&&o.push(i);try{l=e.apply(this,o)}catch(u){const c=u;if(s&&r)throw c;return i(c)}s||(l instanceof Promise?l.then(a,i):l instanceof Error?i(l):a(l))}function i(o,...s){r||(r=!0,t(o,...s))}function a(o){i(null,o)}}const da={basename:hve,dirname:pve,extname:vve,join:gve,sep:"/"};function hve(e,t){if(t!==void 0&&typeof t!="string")throw new TypeError('"ext" argument must be a string');Mv(e);let r=0,n=-1,i=e.length,a;if(t===void 0||t.length===0||t.length>e.length){for(;i--;)if(e.codePointAt(i)===47){if(a){r=i+1;break}}else n<0&&(a=!0,n=i+1);return n<0?"":e.slice(r,n)}if(t===e)return"";let o=-1,s=t.length-1;for(;i--;)if(e.codePointAt(i)===47){if(a){r=i+1;break}}else o<0&&(a=!0,o=i+1),s>-1&&(e.codePointAt(i)===t.codePointAt(s--)?s<0&&(n=i):(s=-1,n=o));return r===n?n=o:n<0&&(n=e.length),e.slice(r,n)}function pve(e){if(Mv(e),e.length===0)return".";let t=-1,r=e.length,n;for(;--r;)if(e.codePointAt(r)===47){if(n){t=r;break}}else n||(n=!0);return t<0?e.codePointAt(0)===47?"/":".":t===1&&e.codePointAt(0)===47?"//":e.slice(0,t)}function vve(e){Mv(e);let t=e.length,r=-1,n=0,i=-1,a=0,o;for(;t--;){const s=e.codePointAt(t);if(s===47){if(o){n=t+1;break}continue}r<0&&(o=!0,r=t+1),s===46?i<0?i=t:a!==1&&(a=1):i>-1&&(a=-1)}return i<0||r<0||a===0||a===1&&i===r-1&&i===n+1?"":e.slice(i,r)}function gve(...e){let t=-1,r;for(;++t<e.length;)Mv(e[t]),e[t]&&(r=r===void 0?e[t]:r+"/"+e[t]);return r===void 0?".":mve(r)}function mve(e){Mv(e);const t=e.codePointAt(0)===47;let r=yve(e,!t);return r.length===0&&!t&&(r="."),r.length>0&&e.codePointAt(e.length-1)===47&&(r+="/"),t?"/"+r:r}function yve(e,t){let r="",n=0,i=-1,a=0,o=-1,s,l;for(;++o<=e.length;){if(o<e.length)s=e.codePointAt(o);else{if(s===47)break;s=47}if(s===47){if(!(i===o-1||a===1))if(i!==o-1&&a===2){if(r.length<2||n!==2||r.codePointAt(r.length-1)!==46||r.codePointAt(r.length-2)!==46){if(r.length>2){if(l=r.lastIndexOf("/"),l!==r.length-1){l<0?(r="",n=0):(r=r.slice(0,l),n=r.length-1-r.lastIndexOf("/")),i=o,a=0;continue}}else if(r.length>0){r="",n=0,i=o,a=0;continue}}t&&(r=r.length>0?r+"/..":"..",n=2)}else r.length>0?r+="/"+e.slice(i+1,o):r=e.slice(i+1,o),n=o-i-1;i=o,a=0}else s===46&&a>-1?a++:a=-1}return r}function Mv(e){if(typeof e!="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}const xve={cwd:Sve};function Sve(){return"/"}function sT(e){return!!(e!==null&&typeof e=="object"&&"href"in e&&e.href&&"protocol"in e&&e.protocol&&e.auth===void 0)}function bve(e){if(typeof e=="string")e=new URL(e);else if(!sT(e)){const t=new TypeError('The "path" argument must be of type string or an instance of URL. Received `'+e+"`");throw t.code="ERR_INVALID_ARG_TYPE",t}if(e.protocol!=="file:"){const t=new TypeError("The URL must be of scheme file");throw t.code="ERR_INVALID_URL_SCHEME",t}return _ve(e)}function _ve(e){if(e.hostname!==""){const n=new TypeError('File URL host must be "localhost" or empty on darwin');throw n.code="ERR_INVALID_FILE_URL_HOST",n}const t=e.pathname;let r=-1;for(;++r<t.length;)if(t.codePointAt(r)===37&&t.codePointAt(r+1)===50){const n=t.codePointAt(r+2);if(n===70||n===102){const i=new TypeError("File URL path must not include encoded / characters");throw i.code="ERR_INVALID_FILE_URL_PATH",i}}return decodeURIComponent(t)}const ub=["history","path","basename","stem","extname","dirname"];class V6{constructor(t){let r;t?sT(t)?r={path:t}:typeof t=="string"||wve(t)?r={value:t}:r=t:r={},this.cwd=xve.cwd(),this.data={},this.history=[],this.messages=[],this.value,this.map,this.result,this.stored;let n=-1;for(;++n<ub.length;){const a=ub[n];a in r&&r[a]!==void 0&&r[a]!==null&&(this[a]=a==="history"?[...r[a]]:r[a])}let i;for(i in r)ub.includes(i)||(this[i]=r[i])}get basename(){return typeof this.path=="string"?da.basename(this.path):void 0}set basename(t){fb(t,"basename"),cb(t,"basename"),this.path=da.join(this.dirname||"",t)}get dirname(){return typeof this.path=="string"?da.dirname(this.path):void 0}set dirname(t){cE(this.basename,"dirname"),this.path=da.join(t||"",this.basename)}get extname(){return typeof this.path=="string"?da.extname(this.path):void 0}set extname(t){if(cb(t,"extname"),cE(this.dirname,"extname"),t){if(t.codePointAt(0)!==46)throw new Error("`extname` must start with `.`");if(t.includes(".",1))throw new Error("`extname` cannot contain multiple dots")}this.path=da.join(this.dirname,this.stem+(t||""))}get path(){return this.history[this.history.length-1]}set path(t){sT(t)&&(t=bve(t)),fb(t,"path"),this.path!==t&&this.history.push(t)}get stem(){return typeof this.path=="string"?da.basename(this.path,this.extname):void 0}set stem(t){fb(t,"stem"),cb(t,"stem"),this.path=da.join(this.dirname||"",t+(this.extname||""))}fail(t,r,n){const i=this.message(t,r,n);throw i.fatal=!0,i}info(t,r,n){const i=this.message(t,r,n);return i.fatal=void 0,i}message(t,r,n){const i=new pn(t,r,n);return this.path&&(i.name=this.path+":"+i.name,i.file=this.path),i.fatal=!1,this.messages.push(i),i}toString(t){return this.value===void 0?"":typeof this.value=="string"?this.value:new TextDecoder(t||void 0).decode(this.value)}}function cb(e,t){if(e&&e.includes(da.sep))throw new Error("`"+t+"` cannot be a path: did not expect `"+da.sep+"`")}function fb(e,t){if(!e)throw new Error("`"+t+"` cannot be empty")}function cE(e,t){if(!e)throw new Error("Setting `"+t+"` requires `path` to be set too")}function wve(e){return!!(e&&typeof e=="object"&&"byteLength"in e&&"byteOffset"in e)}const Cve=function(e){const n=this.constructor.prototype,i=n[e],a=function(){return i.apply(a,arguments)};Object.setPrototypeOf(a,n);const o=Object.getOwnPropertyNames(i);for(const s of o){const l=Object.getOwnPropertyDescriptor(i,s);l&&Object.defineProperty(a,s,l)}return a},Tve={}.hasOwnProperty;class sk extends Cve{constructor(){super("copy"),this.Compiler=void 0,this.Parser=void 0,this.attachers=[],this.compiler=void 0,this.freezeIndex=-1,this.frozen=void 0,this.namespace={},this.parser=void 0,this.transformers=fve()}copy(){const t=new sk;let r=-1;for(;++r<this.attachers.length;){const n=this.attachers[r];t.use(...n)}return t.data(lb(!0,{},this.namespace)),t}data(t,r){return typeof t=="string"?arguments.length===2?(pb("data",this.frozen),this.namespace[t]=r,this):Tve.call(this.namespace,t)&&this.namespace[t]||void 0:t?(pb("data",this.frozen),this.namespace=t,this):this.namespace}freeze(){if(this.frozen)return this;const t=this;for(;++this.freezeIndex<this.attachers.length;){const[r,...n]=this.attachers[this.freezeIndex];if(n[0]===!1)continue;n[0]===!0&&(n[0]=void 0);const i=r.call(t,...n);typeof i=="function"&&this.transformers.use(i)}return this.frozen=!0,this.freezeIndex=Number.POSITIVE_INFINITY,this}parse(t){this.freeze();const r=Ag(t),n=this.parser||this.Parser;return db("parse",n),n(String(r),r)}process(t,r){const n=this;return this.freeze(),db("process",this.parser||this.Parser),hb("process",this.compiler||this.Compiler),r?i(void 0,r):new Promise(i);function i(a,o){const s=Ag(t),l=n.parse(s);n.run(l,s,function(c,f,d){if(c||!f||!d)return u(c);const h=f,p=n.stringify(h,d);kve(p)?d.value=p:d.result=p,u(c,d)});function u(c,f){c||!f?o(c):a?a(f):r(void 0,f)}}}processSync(t){let r=!1,n;return this.freeze(),db("processSync",this.parser||this.Parser),hb("processSync",this.compiler||this.Compiler),this.process(t,i),dE("processSync","process",r),n;function i(a,o){r=!0,nE(a),n=o}}run(t,r,n){fE(t),this.freeze();const i=this.transformers;return!n&&typeof r=="function"&&(n=r,r=void 0),n?a(void 0,n):new Promise(a);function a(o,s){const l=Ag(r);i.run(t,l,u);function u(c,f,d){const h=f||t;c?s(c):o?o(h):n(void 0,h,d)}}}runSync(t,r){let n=!1,i;return this.run(t,r,a),dE("runSync","run",n),i;function a(o,s){nE(o),i=s,n=!0}}stringify(t,r){this.freeze();const n=Ag(r),i=this.compiler||this.Compiler;return hb("stringify",i),fE(t),i(t,n)}use(t,...r){const n=this.attachers,i=this.namespace;if(pb("use",this.frozen),t!=null)if(typeof t=="function")l(t,r);else if(typeof t=="object")Array.isArray(t)?s(t):o(t);else throw new TypeError("Expected usable value, not `"+t+"`");return this;function a(u){if(typeof u=="function")l(u,[]);else if(typeof u=="object")if(Array.isArray(u)){const[c,...f]=u;l(c,f)}else o(u);else throw new TypeError("Expected usable value, not `"+u+"`")}function o(u){if(!("plugins"in u)&&!("settings"in u))throw new Error("Expected usable value but received an empty preset, which is probably a mistake: presets typically come with `plugins` and sometimes with `settings`, but this has neither");s(u.plugins),u.settings&&(i.settings=lb(!0,i.settings,u.settings))}function s(u){let c=-1;if(u!=null)if(Array.isArray(u))for(;++c<u.length;){const f=u[c];a(f)}else throw new TypeError("Expected a list of plugins, not `"+u+"`")}function l(u,c){let f=-1,d=-1;for(;++f<n.length;)if(n[f][0]===u){d=f;break}if(d===-1)n.push([u,...c]);else if(c.length>0){let[h,...p]=c;const v=n[d][1];oT(v)&&oT(h)&&(h=lb(!0,v,h)),n[d]=[u,h,...p]}}}}const Ave=new sk().freeze();function db(e,t){if(typeof t!="function")throw new TypeError("Cannot `"+e+"` without `parser`")}function hb(e,t){if(typeof t!="function")throw new TypeError("Cannot `"+e+"` without `compiler`")}function pb(e,t){if(t)throw new Error("Cannot call `"+e+"` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.")}function fE(e){if(!oT(e)||typeof e.type!="string")throw new TypeError("Expected node, got `"+e+"`")}function dE(e,t,r){if(!r)throw new Error("`"+e+"` finished async. Use `"+t+"` instead")}function Ag(e){return Mve(e)?e:new V6(e)}function Mve(e){return!!(e&&typeof e=="object"&&"message"in e&&"messages"in e)}function kve(e){return typeof e=="string"||Ive(e)}function Ive(e){return!!(e&&typeof e=="object"&&"byteLength"in e&&"byteOffset"in e)}const hE={}.hasOwnProperty,Pve="https://github.com/remarkjs/react-markdown/blob/main/changelog.md",pE=[],vE={allowDangerousHtml:!0},Dve=/^(https?|ircs?|mailto|xmpp)$/i,Rve=[{from:"astPlugins",id:"remove-buggy-html-in-markdown-parser"},{from:"allowDangerousHtml",id:"remove-buggy-html-in-markdown-parser"},{from:"allowNode",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"allowElement"},{from:"allowedTypes",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"allowedElements"},{from:"disallowedTypes",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"disallowedElements"},{from:"escapeHtml",id:"remove-buggy-html-in-markdown-parser"},{from:"includeElementIndex",id:"#remove-includeelementindex"},{from:"includeNodeIndex",id:"change-includenodeindex-to-includeelementindex"},{from:"linkTarget",id:"remove-linktarget"},{from:"plugins",id:"change-plugins-to-remarkplugins",to:"remarkPlugins"},{from:"rawSourcePos",id:"#remove-rawsourcepos"},{from:"renderers",id:"change-renderers-to-components",to:"components"},{from:"source",id:"change-source-to-children",to:"children"},{from:"sourcePos",id:"#remove-sourcepos"},{from:"transformImageUri",id:"#add-urltransform",to:"urlTransform"},{from:"transformLinkUri",id:"#add-urltransform",to:"urlTransform"}];function Lve(e){const t=e.allowedElements,r=e.allowElement,n=e.children||"",i=e.className,a=e.components,o=e.disallowedElements,s=e.rehypePlugins||pE,l=e.remarkPlugins||pE,u=e.remarkRehypeOptions?{...e.remarkRehypeOptions,...vE}:vE,c=e.skipHtml,f=e.unwrapDisallowed,d=e.urlTransform||Eve,h=Ave().use(ppe).use(l).use(uve,u).use(s),p=new V6;typeof n=="string"&&(p.value=n);for(const y of Rve)Object.hasOwn(e,y.from)&&(""+y.from+(y.to?"use `"+y.to+"` instead":"remove it")+Pve+y.id,void 0);const v=h.parse(p);let g=h.runSync(v,p);return i&&(g={type:"element",tagName:"div",properties:{className:i},children:g.type==="root"?g.children:[g]}),$6(g,m),Zfe(g,{Fragment:D.Fragment,components:a,ignoreInvalidStyle:!0,jsx:D.jsx,jsxs:D.jsxs,passKeys:!0,passNode:!0});function m(y,x,S){if(y.type==="raw"&&S&&typeof x=="number")return c?S.children.splice(x,1):S.children[x]={type:"text",value:y.value},x;if(y.type==="element"){let _;for(_ in ab)if(hE.call(ab,_)&&hE.call(y.properties,_)){const b=y.properties[_],w=ab[_];(w===null||w.includes(y.tagName))&&(y.properties[_]=d(String(b||""),_,y))}}if(y.type==="element"){let _=t?!t.includes(y.tagName):o?o.includes(y.tagName):!1;if(!_&&r&&typeof x=="number"&&(_=!r(y,x,S)),_&&S&&typeof x=="number")return f&&y.children?S.children.splice(x,1,...y.children):S.children.splice(x,1),x}}}function Eve(e){return pde(e,Dve)}function Ove(e,t){const r=t?-1:1;return function(n,i){const a=n[e],o=i[e];return a<o?r*-1:a>o?r*1:0}}function Nve(e,{hasTotalRow:t=!1,defaultSortKey:r="name"}={hasTotalRow:!1,defaultSortKey:"name"}){const[n,i]=O.useState(e),[a,o]=O.useState(!1),s=O.useRef(),l=c=>{const d=(t?e.slice(0,-1):[...e]).sort(Ove(c,c===s.current&&!a));i(t?[...d,...e.slice(-1)]:d)},u=O.useCallback(c=>{s.current||(s.current=r);const f=c.target.getAttribute("data-sortkey");if(f===s.current)if(a){o(!1),s.current=void 0,l(r);return}else o(!0);else a&&o(!1);l(f),s.current=f},[s,e,a]);return O.useEffect(()=>{e.length&&l(s.current||r)},[e]),{onTableHeadClick:u,sortedRows:n,currentSortField:s.current}}const dh=(e,t=0)=>{const r=Math.pow(10,t);return Math.round(e*r)/r};function zve({content:e,formatter:t,round:r,markdown:n}){return t?t(e):r?dh(e,r):n?D.jsx(Lve,{skipHtml:!1,children:e}):e}function qf({rows:e,structure:t,hasTotalRow:r,defaultSortKey:n}){const{onTableHeadClick:i,sortedRows:a,currentSortField:o}=Nve(e,{hasTotalRow:r,defaultSortKey:n});return D.jsx(RG,{component:Wf,children:D.jsxs(PG,{children:[D.jsx(LG,{children:D.jsx(Qy,{children:t.map(({title:s,key:l})=>D.jsx(zl,{"data-sortkey":l,onClick:i,sx:{cursor:"pointer",color:o===l?"primary.main":"text.primary"},children:s},`table-head-${l}`))})}),D.jsx(DG,{children:a.map((s,l)=>D.jsx(Qy,{children:t.map(({key:u,...c},f)=>D.jsx(zl,{children:D.jsx(zve,{content:s[u],...c})},`table-row=${f}`))},`${s.name}-${l}`))})]})})}function Bve({rows:e,tableStructure:t}){return t?D.jsx(qf,{rows:e,structure:t}):null}const $ve=({swarm:{extendedTables:e},ui:{extendedStats:t},url:{query:r}})=>{const n=r&&r.tab&&e&&e.find(({key:a})=>a===r.tab),i=r&&r.tab&&t&&t.find(({key:a})=>a===r.tab);return{tableStructure:n?n.structure.map(({key:a,...o})=>({key:vV(a),...o})):null,rows:i?i.data:[]}},Fve=Ln($ve)(Bve),Vve=[{key:"count",title:"# occurrences"},{key:"msg",title:"Message"},{key:"traceback",title:"Traceback"}];function G6({exceptions:e}){return D.jsx(qf,{rows:e,structure:Vve})}const Gve=({ui:{exceptions:e}})=>({exceptions:e}),Hve=Ln(Gve)(G6),Wve=[{key:"occurrences",title:"# Failures"},{key:"method",title:"Method"},{key:"name",title:"Name"},{key:"error",title:"Message",markdown:!0}];function H6({errors:e}){return D.jsx(qf,{rows:e,structure:Wve})}const jve=({ui:{errors:e}})=>({errors:e}),Uve=Ln(jve)(H6);function qve(){const e=Ys(({logViewer:{logs:t}})=>t);return D.jsxs(it,{children:[D.jsx(qe,{component:"h2",variant:"h4",children:"Logs"}),D.jsx("ul",{children:e.map((t,r)=>D.jsx("li",{children:t},`log-${r}`))})]})}function Yve({extendedCsvFiles:e,statsHistoryEnabled:t}){const r=Ys(({theme:{isDarkMode:n}})=>n);return D.jsxs(yG,{sx:{display:"flex",flexDirection:"column"},children:[D.jsx(tc,{children:D.jsx(on,{href:"/stats/requests/csv",children:"Download requests CSV"})}),t&&D.jsx(tc,{children:D.jsx(on,{href:"/stats/requests_full_history/csv",children:"Download full request statistics history CSV"})}),D.jsx(tc,{children:D.jsx(on,{href:"/stats/failures/csv",children:"Download failures CSV"})}),D.jsx(tc,{children:D.jsx(on,{href:"/exceptions/csv",children:"Download exceptions CSV"})}),D.jsx(tc,{children:D.jsx(on,{href:`/stats/report?theme=${r?Si.DARK:Si.LIGHT}`,target:"_blank",children:"Download Report"})}),e&&e.map(({href:n,title:i},a)=>D.jsx(tc,{children:D.jsx(on,{href:n,children:i})},`extended-csv-${a}`))]})}const Xve=({swarm:{extendedCsvFiles:e,statsHistoryEnabled:t}})=>({extendedCsvFiles:e,statsHistoryEnabled:t}),Zve=Ln(Xve)(Yve);var lk={},Kve=Ou;Object.defineProperty(lk,"__esModule",{value:!0});var W6=lk.default=void 0,Qve=Kve(Nu()),Jve=D,ege=(0,Qve.default)((0,Jve.jsx)("path",{d:"M14.67 5v14H9.33V5h5.34zm1 14H21V5h-5.33v14zm-7.34 0V5H3v14h5.33z"}),"ViewColumn");W6=lk.default=ege;function tge({structure:e,selectedColumns:t,addColumn:r,removeColumn:n}){const[i,a]=O.useState(null);return D.jsxs(fG,{direction:"row",justifyContent:"end",my:2,spacing:1,children:[D.jsx(qa,{onClick:o=>a(o.currentTarget),variant:"outlined",children:D.jsx(W6,{})}),D.jsx(_G,{anchorEl:i,anchorOrigin:{vertical:"bottom",horizontal:"left"},onClose:()=>a(null),open:!!i,children:D.jsx(hG,{sx:{p:2},children:e.map(({key:o,title:s})=>D.jsx(dG,{control:D.jsx(Ise,{checked:t.includes(o),onChange:()=>{t.includes(o)?n(o):r(o)}}),label:s},o))})})]})}function rge(e){const[t,r]=O.useState(e.map(o=>o.key));return{selectedColumns:t,addColumn:o=>{r([...t,o])},removeColumn:o=>{r(t.filter(s=>s!==o))},filteredStructure:(o=>o.filter(s=>t.includes(s.key)))(e)}}const nge=Ra.percentilesToStatistics?Ra.percentilesToStatistics.map(e=>({title:`${e*100}%ile (ms)`,key:`responseTimePercentile${e}`})):[],gE=[{key:"method",title:"Type"},{key:"name",title:"Name"},{key:"numRequests",title:"# Requests"},{key:"numFailures",title:"# Fails"},{key:"medianResponseTime",title:"Median (ms)",round:2},...nge,{key:"avgResponseTime",title:"Average (ms)",round:2},{key:"minResponseTime",title:"Min (ms)"},{key:"maxResponseTime",title:"Max (ms)"},{key:"avgContentLength",title:"Average size (bytes)",round:2},{key:"currentRps",title:"Current RPS",round:2},{key:"currentFailPerSec",title:"Current Failures/s",round:2}];function j6({stats:e}){const{selectedColumns:t,addColumn:r,removeColumn:n,filteredStructure:i}=rge(gE);return D.jsxs(D.Fragment,{children:[D.jsx(tge,{addColumn:r,removeColumn:n,selectedColumns:t,structure:gE}),D.jsx(qf,{hasTotalRow:!0,rows:e,structure:i})]})}const ige=({ui:{stats:e}})=>({stats:e}),age=Ln(ige)(j6);/*! *****************************************************************************
171
+ `},i),a}function uve(e,t){return e&&"run"in e?async function(r,n){const i=rE(r,t);await e.run(i,n)}:function(r){return rE(r,t||e)}}function nE(e){if(e)throw e}var Ym=Object.prototype.hasOwnProperty,F6=Object.prototype.toString,iE=Object.defineProperty,aE=Object.getOwnPropertyDescriptor,oE=function(t){return typeof Array.isArray=="function"?Array.isArray(t):F6.call(t)==="[object Array]"},sE=function(t){if(!t||F6.call(t)!=="[object Object]")return!1;var r=Ym.call(t,"constructor"),n=t.constructor&&t.constructor.prototype&&Ym.call(t.constructor.prototype,"isPrototypeOf");if(t.constructor&&!r&&!n)return!1;var i;for(i in t);return typeof i>"u"||Ym.call(t,i)},lE=function(t,r){iE&&r.name==="__proto__"?iE(t,r.name,{enumerable:!0,configurable:!0,value:r.newValue,writable:!0}):t[r.name]=r.newValue},uE=function(t,r){if(r==="__proto__")if(Ym.call(t,r)){if(aE)return aE(t,r).value}else return;return t[r]},cve=function e(){var t,r,n,i,a,o,s=arguments[0],l=1,u=arguments.length,c=!1;for(typeof s=="boolean"&&(c=s,s=arguments[1]||{},l=2),(s==null||typeof s!="object"&&typeof s!="function")&&(s={});l<u;++l)if(t=arguments[l],t!=null)for(r in t)n=uE(s,r),i=uE(t,r),s!==i&&(c&&i&&(sE(i)||(a=oE(i)))?(a?(a=!1,o=n&&oE(n)?n:[]):o=n&&sE(n)?n:{},lE(s,{name:r,newValue:e(c,o,i)})):typeof i<"u"&&lE(s,{name:r,newValue:i}));return s};const lb=dv(cve);function oT(e){if(typeof e!="object"||e===null)return!1;const t=Object.getPrototypeOf(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Symbol.toStringTag in e)&&!(Symbol.iterator in e)}function fve(){const e=[],t={run:r,use:n};return t;function r(...i){let a=-1;const o=i.pop();if(typeof o!="function")throw new TypeError("Expected function as last argument, not "+o);s(null,...i);function s(l,...u){const c=e[++a];let f=-1;if(l){o(l);return}for(;++f<i.length;)(u[f]===null||u[f]===void 0)&&(u[f]=i[f]);i=u,c?dve(c,s)(...u):o(null,...u)}}function n(i){if(typeof i!="function")throw new TypeError("Expected `middelware` to be a function, not "+i);return e.push(i),t}}function dve(e,t){let r;return n;function n(...o){const s=e.length>o.length;let l;s&&o.push(i);try{l=e.apply(this,o)}catch(u){const c=u;if(s&&r)throw c;return i(c)}s||(l instanceof Promise?l.then(a,i):l instanceof Error?i(l):a(l))}function i(o,...s){r||(r=!0,t(o,...s))}function a(o){i(null,o)}}const da={basename:hve,dirname:pve,extname:vve,join:gve,sep:"/"};function hve(e,t){if(t!==void 0&&typeof t!="string")throw new TypeError('"ext" argument must be a string');Mv(e);let r=0,n=-1,i=e.length,a;if(t===void 0||t.length===0||t.length>e.length){for(;i--;)if(e.codePointAt(i)===47){if(a){r=i+1;break}}else n<0&&(a=!0,n=i+1);return n<0?"":e.slice(r,n)}if(t===e)return"";let o=-1,s=t.length-1;for(;i--;)if(e.codePointAt(i)===47){if(a){r=i+1;break}}else o<0&&(a=!0,o=i+1),s>-1&&(e.codePointAt(i)===t.codePointAt(s--)?s<0&&(n=i):(s=-1,n=o));return r===n?n=o:n<0&&(n=e.length),e.slice(r,n)}function pve(e){if(Mv(e),e.length===0)return".";let t=-1,r=e.length,n;for(;--r;)if(e.codePointAt(r)===47){if(n){t=r;break}}else n||(n=!0);return t<0?e.codePointAt(0)===47?"/":".":t===1&&e.codePointAt(0)===47?"//":e.slice(0,t)}function vve(e){Mv(e);let t=e.length,r=-1,n=0,i=-1,a=0,o;for(;t--;){const s=e.codePointAt(t);if(s===47){if(o){n=t+1;break}continue}r<0&&(o=!0,r=t+1),s===46?i<0?i=t:a!==1&&(a=1):i>-1&&(a=-1)}return i<0||r<0||a===0||a===1&&i===r-1&&i===n+1?"":e.slice(i,r)}function gve(...e){let t=-1,r;for(;++t<e.length;)Mv(e[t]),e[t]&&(r=r===void 0?e[t]:r+"/"+e[t]);return r===void 0?".":mve(r)}function mve(e){Mv(e);const t=e.codePointAt(0)===47;let r=yve(e,!t);return r.length===0&&!t&&(r="."),r.length>0&&e.codePointAt(e.length-1)===47&&(r+="/"),t?"/"+r:r}function yve(e,t){let r="",n=0,i=-1,a=0,o=-1,s,l;for(;++o<=e.length;){if(o<e.length)s=e.codePointAt(o);else{if(s===47)break;s=47}if(s===47){if(!(i===o-1||a===1))if(i!==o-1&&a===2){if(r.length<2||n!==2||r.codePointAt(r.length-1)!==46||r.codePointAt(r.length-2)!==46){if(r.length>2){if(l=r.lastIndexOf("/"),l!==r.length-1){l<0?(r="",n=0):(r=r.slice(0,l),n=r.length-1-r.lastIndexOf("/")),i=o,a=0;continue}}else if(r.length>0){r="",n=0,i=o,a=0;continue}}t&&(r=r.length>0?r+"/..":"..",n=2)}else r.length>0?r+="/"+e.slice(i+1,o):r=e.slice(i+1,o),n=o-i-1;i=o,a=0}else s===46&&a>-1?a++:a=-1}return r}function Mv(e){if(typeof e!="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}const xve={cwd:Sve};function Sve(){return"/"}function sT(e){return!!(e!==null&&typeof e=="object"&&"href"in e&&e.href&&"protocol"in e&&e.protocol&&e.auth===void 0)}function bve(e){if(typeof e=="string")e=new URL(e);else if(!sT(e)){const t=new TypeError('The "path" argument must be of type string or an instance of URL. Received `'+e+"`");throw t.code="ERR_INVALID_ARG_TYPE",t}if(e.protocol!=="file:"){const t=new TypeError("The URL must be of scheme file");throw t.code="ERR_INVALID_URL_SCHEME",t}return _ve(e)}function _ve(e){if(e.hostname!==""){const n=new TypeError('File URL host must be "localhost" or empty on darwin');throw n.code="ERR_INVALID_FILE_URL_HOST",n}const t=e.pathname;let r=-1;for(;++r<t.length;)if(t.codePointAt(r)===37&&t.codePointAt(r+1)===50){const n=t.codePointAt(r+2);if(n===70||n===102){const i=new TypeError("File URL path must not include encoded / characters");throw i.code="ERR_INVALID_FILE_URL_PATH",i}}return decodeURIComponent(t)}const ub=["history","path","basename","stem","extname","dirname"];class V6{constructor(t){let r;t?sT(t)?r={path:t}:typeof t=="string"||wve(t)?r={value:t}:r=t:r={},this.cwd=xve.cwd(),this.data={},this.history=[],this.messages=[],this.value,this.map,this.result,this.stored;let n=-1;for(;++n<ub.length;){const a=ub[n];a in r&&r[a]!==void 0&&r[a]!==null&&(this[a]=a==="history"?[...r[a]]:r[a])}let i;for(i in r)ub.includes(i)||(this[i]=r[i])}get basename(){return typeof this.path=="string"?da.basename(this.path):void 0}set basename(t){fb(t,"basename"),cb(t,"basename"),this.path=da.join(this.dirname||"",t)}get dirname(){return typeof this.path=="string"?da.dirname(this.path):void 0}set dirname(t){cE(this.basename,"dirname"),this.path=da.join(t||"",this.basename)}get extname(){return typeof this.path=="string"?da.extname(this.path):void 0}set extname(t){if(cb(t,"extname"),cE(this.dirname,"extname"),t){if(t.codePointAt(0)!==46)throw new Error("`extname` must start with `.`");if(t.includes(".",1))throw new Error("`extname` cannot contain multiple dots")}this.path=da.join(this.dirname,this.stem+(t||""))}get path(){return this.history[this.history.length-1]}set path(t){sT(t)&&(t=bve(t)),fb(t,"path"),this.path!==t&&this.history.push(t)}get stem(){return typeof this.path=="string"?da.basename(this.path,this.extname):void 0}set stem(t){fb(t,"stem"),cb(t,"stem"),this.path=da.join(this.dirname||"",t+(this.extname||""))}fail(t,r,n){const i=this.message(t,r,n);throw i.fatal=!0,i}info(t,r,n){const i=this.message(t,r,n);return i.fatal=void 0,i}message(t,r,n){const i=new pn(t,r,n);return this.path&&(i.name=this.path+":"+i.name,i.file=this.path),i.fatal=!1,this.messages.push(i),i}toString(t){return this.value===void 0?"":typeof this.value=="string"?this.value:new TextDecoder(t||void 0).decode(this.value)}}function cb(e,t){if(e&&e.includes(da.sep))throw new Error("`"+t+"` cannot be a path: did not expect `"+da.sep+"`")}function fb(e,t){if(!e)throw new Error("`"+t+"` cannot be empty")}function cE(e,t){if(!e)throw new Error("Setting `"+t+"` requires `path` to be set too")}function wve(e){return!!(e&&typeof e=="object"&&"byteLength"in e&&"byteOffset"in e)}const Cve=function(e){const n=this.constructor.prototype,i=n[e],a=function(){return i.apply(a,arguments)};Object.setPrototypeOf(a,n);const o=Object.getOwnPropertyNames(i);for(const s of o){const l=Object.getOwnPropertyDescriptor(i,s);l&&Object.defineProperty(a,s,l)}return a},Tve={}.hasOwnProperty;class sk extends Cve{constructor(){super("copy"),this.Compiler=void 0,this.Parser=void 0,this.attachers=[],this.compiler=void 0,this.freezeIndex=-1,this.frozen=void 0,this.namespace={},this.parser=void 0,this.transformers=fve()}copy(){const t=new sk;let r=-1;for(;++r<this.attachers.length;){const n=this.attachers[r];t.use(...n)}return t.data(lb(!0,{},this.namespace)),t}data(t,r){return typeof t=="string"?arguments.length===2?(pb("data",this.frozen),this.namespace[t]=r,this):Tve.call(this.namespace,t)&&this.namespace[t]||void 0:t?(pb("data",this.frozen),this.namespace=t,this):this.namespace}freeze(){if(this.frozen)return this;const t=this;for(;++this.freezeIndex<this.attachers.length;){const[r,...n]=this.attachers[this.freezeIndex];if(n[0]===!1)continue;n[0]===!0&&(n[0]=void 0);const i=r.call(t,...n);typeof i=="function"&&this.transformers.use(i)}return this.frozen=!0,this.freezeIndex=Number.POSITIVE_INFINITY,this}parse(t){this.freeze();const r=Ag(t),n=this.parser||this.Parser;return db("parse",n),n(String(r),r)}process(t,r){const n=this;return this.freeze(),db("process",this.parser||this.Parser),hb("process",this.compiler||this.Compiler),r?i(void 0,r):new Promise(i);function i(a,o){const s=Ag(t),l=n.parse(s);n.run(l,s,function(c,f,d){if(c||!f||!d)return u(c);const h=f,p=n.stringify(h,d);kve(p)?d.value=p:d.result=p,u(c,d)});function u(c,f){c||!f?o(c):a?a(f):r(void 0,f)}}}processSync(t){let r=!1,n;return this.freeze(),db("processSync",this.parser||this.Parser),hb("processSync",this.compiler||this.Compiler),this.process(t,i),dE("processSync","process",r),n;function i(a,o){r=!0,nE(a),n=o}}run(t,r,n){fE(t),this.freeze();const i=this.transformers;return!n&&typeof r=="function"&&(n=r,r=void 0),n?a(void 0,n):new Promise(a);function a(o,s){const l=Ag(r);i.run(t,l,u);function u(c,f,d){const h=f||t;c?s(c):o?o(h):n(void 0,h,d)}}}runSync(t,r){let n=!1,i;return this.run(t,r,a),dE("runSync","run",n),i;function a(o,s){nE(o),i=s,n=!0}}stringify(t,r){this.freeze();const n=Ag(r),i=this.compiler||this.Compiler;return hb("stringify",i),fE(t),i(t,n)}use(t,...r){const n=this.attachers,i=this.namespace;if(pb("use",this.frozen),t!=null)if(typeof t=="function")l(t,r);else if(typeof t=="object")Array.isArray(t)?s(t):o(t);else throw new TypeError("Expected usable value, not `"+t+"`");return this;function a(u){if(typeof u=="function")l(u,[]);else if(typeof u=="object")if(Array.isArray(u)){const[c,...f]=u;l(c,f)}else o(u);else throw new TypeError("Expected usable value, not `"+u+"`")}function o(u){if(!("plugins"in u)&&!("settings"in u))throw new Error("Expected usable value but received an empty preset, which is probably a mistake: presets typically come with `plugins` and sometimes with `settings`, but this has neither");s(u.plugins),u.settings&&(i.settings=lb(!0,i.settings,u.settings))}function s(u){let c=-1;if(u!=null)if(Array.isArray(u))for(;++c<u.length;){const f=u[c];a(f)}else throw new TypeError("Expected a list of plugins, not `"+u+"`")}function l(u,c){let f=-1,d=-1;for(;++f<n.length;)if(n[f][0]===u){d=f;break}if(d===-1)n.push([u,...c]);else if(c.length>0){let[h,...p]=c;const v=n[d][1];oT(v)&&oT(h)&&(h=lb(!0,v,h)),n[d]=[u,h,...p]}}}}const Ave=new sk().freeze();function db(e,t){if(typeof t!="function")throw new TypeError("Cannot `"+e+"` without `parser`")}function hb(e,t){if(typeof t!="function")throw new TypeError("Cannot `"+e+"` without `compiler`")}function pb(e,t){if(t)throw new Error("Cannot call `"+e+"` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.")}function fE(e){if(!oT(e)||typeof e.type!="string")throw new TypeError("Expected node, got `"+e+"`")}function dE(e,t,r){if(!r)throw new Error("`"+e+"` finished async. Use `"+t+"` instead")}function Ag(e){return Mve(e)?e:new V6(e)}function Mve(e){return!!(e&&typeof e=="object"&&"message"in e&&"messages"in e)}function kve(e){return typeof e=="string"||Ive(e)}function Ive(e){return!!(e&&typeof e=="object"&&"byteLength"in e&&"byteOffset"in e)}const hE={}.hasOwnProperty,Pve="https://github.com/remarkjs/react-markdown/blob/main/changelog.md",pE=[],vE={allowDangerousHtml:!0},Dve=/^(https?|ircs?|mailto|xmpp)$/i,Rve=[{from:"astPlugins",id:"remove-buggy-html-in-markdown-parser"},{from:"allowDangerousHtml",id:"remove-buggy-html-in-markdown-parser"},{from:"allowNode",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"allowElement"},{from:"allowedTypes",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"allowedElements"},{from:"disallowedTypes",id:"replace-allownode-allowedtypes-and-disallowedtypes",to:"disallowedElements"},{from:"escapeHtml",id:"remove-buggy-html-in-markdown-parser"},{from:"includeElementIndex",id:"#remove-includeelementindex"},{from:"includeNodeIndex",id:"change-includenodeindex-to-includeelementindex"},{from:"linkTarget",id:"remove-linktarget"},{from:"plugins",id:"change-plugins-to-remarkplugins",to:"remarkPlugins"},{from:"rawSourcePos",id:"#remove-rawsourcepos"},{from:"renderers",id:"change-renderers-to-components",to:"components"},{from:"source",id:"change-source-to-children",to:"children"},{from:"sourcePos",id:"#remove-sourcepos"},{from:"transformImageUri",id:"#add-urltransform",to:"urlTransform"},{from:"transformLinkUri",id:"#add-urltransform",to:"urlTransform"}];function Lve(e){const t=e.allowedElements,r=e.allowElement,n=e.children||"",i=e.className,a=e.components,o=e.disallowedElements,s=e.rehypePlugins||pE,l=e.remarkPlugins||pE,u=e.remarkRehypeOptions?{...e.remarkRehypeOptions,...vE}:vE,c=e.skipHtml,f=e.unwrapDisallowed,d=e.urlTransform||Eve,h=Ave().use(ppe).use(l).use(uve,u).use(s),p=new V6;typeof n=="string"&&(p.value=n);for(const y of Rve)Object.hasOwn(e,y.from)&&(""+y.from+(y.to?"use `"+y.to+"` instead":"remove it")+Pve+y.id,void 0);const v=h.parse(p);let g=h.runSync(v,p);return i&&(g={type:"element",tagName:"div",properties:{className:i},children:g.type==="root"?g.children:[g]}),$6(g,m),Zfe(g,{Fragment:D.Fragment,components:a,ignoreInvalidStyle:!0,jsx:D.jsx,jsxs:D.jsxs,passKeys:!0,passNode:!0});function m(y,x,S){if(y.type==="raw"&&S&&typeof x=="number")return c?S.children.splice(x,1):S.children[x]={type:"text",value:y.value},x;if(y.type==="element"){let _;for(_ in ab)if(hE.call(ab,_)&&hE.call(y.properties,_)){const b=y.properties[_],w=ab[_];(w===null||w.includes(y.tagName))&&(y.properties[_]=d(String(b||""),_,y))}}if(y.type==="element"){let _=t?!t.includes(y.tagName):o?o.includes(y.tagName):!1;if(!_&&r&&typeof x=="number"&&(_=!r(y,x,S)),_&&S&&typeof x=="number")return f&&y.children?S.children.splice(x,1,...y.children):S.children.splice(x,1),x}}}function Eve(e){return pde(e,Dve)}function Ove(e,t){const r=t?-1:1;return function(n,i){const a=n[e],o=i[e];return a<o?r*-1:a>o?r*1:0}}function Nve(e,{hasTotalRow:t=!1,defaultSortKey:r="name"}={hasTotalRow:!1,defaultSortKey:"name"}){const[n,i]=O.useState(e),[a,o]=O.useState(!1),s=O.useRef(),l=c=>{const d=(t?e.slice(0,-1):[...e]).sort(Ove(c,c===s.current&&!a));i(t?[...d,...e.slice(-1)]:d)},u=O.useCallback(c=>{s.current||(s.current=r);const f=c.target.getAttribute("data-sortkey");if(f===s.current)if(a){o(!1),s.current=void 0,l(r);return}else o(!0);else a&&o(!1);l(f),s.current=f},[s,e,a]);return O.useEffect(()=>{e.length&&l(s.current||r)},[e]),{onTableHeadClick:u,sortedRows:n,currentSortField:s.current}}const dh=(e,t=0)=>{const r=Math.pow(10,t);return Math.round(e*r)/r};function zve({content:e,formatter:t,round:r,markdown:n}){return t?t(e):r?dh(e,r):n?D.jsx(Lve,{skipHtml:!1,children:e}):e}function qf({rows:e,structure:t,hasTotalRow:r,defaultSortKey:n}){const{onTableHeadClick:i,sortedRows:a,currentSortField:o}=Nve(e,{hasTotalRow:r,defaultSortKey:n});return D.jsx(RG,{component:Wf,children:D.jsxs(PG,{children:[D.jsx(LG,{children:D.jsx(Qy,{children:t.map(({title:s,key:l})=>D.jsx(zl,{"data-sortkey":l,onClick:i,sx:{cursor:"pointer",color:o===l?"primary.main":"text.primary"},children:s},`table-head-${l}`))})}),D.jsx(DG,{children:a.map((s,l)=>D.jsx(Qy,{children:t.map(({key:u,...c},f)=>D.jsx(zl,{children:D.jsx(zve,{content:s[u],...c})},`table-row=${f}`))},`${s.name}-${l}`))})]})})}function Bve({rows:e,tableStructure:t}){return t?D.jsx(qf,{rows:e,structure:t}):null}const $ve=({swarm:{extendedTables:e},ui:{extendedStats:t},url:{query:r}})=>{const n=r&&r.tab&&e&&e.find(({key:a})=>a===r.tab),i=r&&r.tab&&t&&t.find(({key:a})=>a===r.tab);return{tableStructure:n?n.structure.map(({key:a,...o})=>({key:vV(a),...o})):null,rows:i?i.data:[]}},Fve=Ln($ve)(Bve),Vve=[{key:"count",title:"# occurrences"},{key:"msg",title:"Message",markdown:!0},{key:"traceback",title:"Traceback",markdown:!0}];function G6({exceptions:e}){return D.jsx(qf,{rows:e,structure:Vve})}const Gve=({ui:{exceptions:e}})=>({exceptions:e}),Hve=Ln(Gve)(G6),Wve=[{key:"occurrences",title:"# Failures"},{key:"method",title:"Method"},{key:"name",title:"Name"},{key:"error",title:"Message",markdown:!0}];function H6({errors:e}){return D.jsx(qf,{rows:e,structure:Wve})}const jve=({ui:{errors:e}})=>({errors:e}),Uve=Ln(jve)(H6);function qve(){const e=Ys(({logViewer:{logs:t}})=>t);return D.jsxs(it,{children:[D.jsx(qe,{component:"h2",variant:"h4",children:"Logs"}),D.jsx("ul",{children:e.map((t,r)=>D.jsx("li",{children:t},`log-${r}`))})]})}function Yve({extendedCsvFiles:e,statsHistoryEnabled:t}){const r=Ys(({theme:{isDarkMode:n}})=>n);return D.jsxs(yG,{sx:{display:"flex",flexDirection:"column"},children:[D.jsx(tc,{children:D.jsx(on,{href:"/stats/requests/csv",children:"Download requests CSV"})}),t&&D.jsx(tc,{children:D.jsx(on,{href:"/stats/requests_full_history/csv",children:"Download full request statistics history CSV"})}),D.jsx(tc,{children:D.jsx(on,{href:"/stats/failures/csv",children:"Download failures CSV"})}),D.jsx(tc,{children:D.jsx(on,{href:"/exceptions/csv",children:"Download exceptions CSV"})}),D.jsx(tc,{children:D.jsx(on,{href:`/stats/report?theme=${r?Si.DARK:Si.LIGHT}`,target:"_blank",children:"Download Report"})}),e&&e.map(({href:n,title:i},a)=>D.jsx(tc,{children:D.jsx(on,{href:n,children:i})},`extended-csv-${a}`))]})}const Xve=({swarm:{extendedCsvFiles:e,statsHistoryEnabled:t}})=>({extendedCsvFiles:e,statsHistoryEnabled:t}),Zve=Ln(Xve)(Yve);var lk={},Kve=Ou;Object.defineProperty(lk,"__esModule",{value:!0});var W6=lk.default=void 0,Qve=Kve(Nu()),Jve=D,ege=(0,Qve.default)((0,Jve.jsx)("path",{d:"M14.67 5v14H9.33V5h5.34zm1 14H21V5h-5.33v14zm-7.34 0V5H3v14h5.33z"}),"ViewColumn");W6=lk.default=ege;function tge({structure:e,selectedColumns:t,addColumn:r,removeColumn:n}){const[i,a]=O.useState(null);return D.jsxs(fG,{direction:"row",justifyContent:"end",my:2,spacing:1,children:[D.jsx(qa,{onClick:o=>a(o.currentTarget),variant:"outlined",children:D.jsx(W6,{})}),D.jsx(_G,{anchorEl:i,anchorOrigin:{vertical:"bottom",horizontal:"left"},onClose:()=>a(null),open:!!i,children:D.jsx(hG,{sx:{p:2},children:e.map(({key:o,title:s})=>D.jsx(dG,{control:D.jsx(Ise,{checked:t.includes(o),onChange:()=>{t.includes(o)?n(o):r(o)}}),label:s},o))})})]})}function rge(e){const[t,r]=O.useState(e.map(o=>o.key));return{selectedColumns:t,addColumn:o=>{r([...t,o])},removeColumn:o=>{r(t.filter(s=>s!==o))},filteredStructure:(o=>o.filter(s=>t.includes(s.key)))(e)}}const nge=Ra.percentilesToStatistics?Ra.percentilesToStatistics.map(e=>({title:`${e*100}%ile (ms)`,key:`responseTimePercentile${e}`})):[],gE=[{key:"method",title:"Type"},{key:"name",title:"Name"},{key:"numRequests",title:"# Requests"},{key:"numFailures",title:"# Fails"},{key:"medianResponseTime",title:"Median (ms)",round:2},...nge,{key:"avgResponseTime",title:"Average (ms)",round:2},{key:"minResponseTime",title:"Min (ms)"},{key:"maxResponseTime",title:"Max (ms)"},{key:"avgContentLength",title:"Average size (bytes)",round:2},{key:"currentRps",title:"Current RPS",round:2},{key:"currentFailPerSec",title:"Current Failures/s",round:2}];function j6({stats:e}){const{selectedColumns:t,addColumn:r,removeColumn:n,filteredStructure:i}=rge(gE);return D.jsxs(D.Fragment,{children:[D.jsx(tge,{addColumn:r,removeColumn:n,selectedColumns:t,structure:gE}),D.jsx(qf,{hasTotalRow:!0,rows:e,structure:i})]})}const ige=({ui:{stats:e}})=>({stats:e}),age=Ln(ige)(j6);/*! *****************************************************************************
172
172
  Copyright (c) Microsoft Corporation.
173
173
 
174
174
  Permission to use, copy, modify, and/or distribute this software for any
@@ -7,7 +7,7 @@
7
7
  <meta name="theme-color" content="#000000" />
8
8
 
9
9
  <title>Locust</title>
10
- <script type="module" crossorigin src="./assets/index-fd3e763b.js"></script>
10
+ <script type="module" crossorigin src="./assets/index-941b6e82.js"></script>
11
11
  </head>
12
12
  <body>
13
13
  <div id="root"></div>
@@ -7,7 +7,7 @@
7
7
  <meta name="theme-color" content="#000000" />
8
8
 
9
9
  <title>Locust</title>
10
- <script type="module" crossorigin src="./assets/index-fd3e763b.js"></script>
10
+ <script type="module" crossorigin src="./assets/index-941b6e82.js"></script>
11
11
  </head>
12
12
  <body>
13
13
  <div id="root"></div>
@@ -6,8 +6,8 @@ import { ISwarmException } from 'types/ui.types';
6
6
 
7
7
  const tableStructure = [
8
8
  { key: 'count', title: '# occurrences' },
9
- { key: 'msg', title: 'Message' },
10
- { key: 'traceback', title: 'Traceback' },
9
+ { key: 'msg', title: 'Message', markdown: true },
10
+ { key: 'traceback', title: 'Traceback', markdown: true },
11
11
  ];
12
12
 
13
13
  export function ExceptionsTable({ exceptions }: { exceptions: ISwarmException[] }) {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: locust
3
- Version: 2.24.1.dev23
3
+ Version: 2.24.2.dev8
4
4
  Summary: Developer friendly load testing framework
5
5
  License: MIT
6
6
  Project-URL: Homepage, https://github.com/locustio/locust
@@ -226,7 +226,7 @@ locust/webui/dist/auth.html
226
226
  locust/webui/dist/index.html
227
227
  locust/webui/dist/report.html
228
228
  locust/webui/dist/assets/favicon.ico
229
- locust/webui/dist/assets/index-fd3e763b.js
229
+ locust/webui/dist/assets/index-941b6e82.js
230
230
  locust/webui/dist/assets/logo.png
231
231
  locust/webui/public/report.html
232
232
  locust/webui/public/assets/favicon.ico
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
File without changes
File without changes
File without changes