locust 2.14.3.dev29__tar.gz → 2.15.1__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 (217) hide show
  1. {locust-2.14.3.dev29 → locust-2.15.1}/CHANGELOG.md +30 -1
  2. {locust-2.14.3.dev29 → locust-2.15.1}/PKG-INFO +9 -4
  3. {locust-2.14.3.dev29 → locust-2.15.1}/README.md +8 -3
  4. {locust-2.14.3.dev29 → locust-2.15.1}/docs/changelog.rst +11 -2
  5. {locust-2.14.3.dev29 → locust-2.15.1}/docs/configuration.rst +2 -0
  6. locust-2.15.1/locust/_version.py +4 -0
  7. {locust-2.14.3.dev29 → locust-2.15.1}/locust/env.py +0 -1
  8. {locust-2.14.3.dev29 → locust-2.15.1}/locust/html.py +3 -0
  9. {locust-2.14.3.dev29 → locust-2.15.1}/locust/main.py +19 -1
  10. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/locust.js +7 -7
  11. {locust-2.14.3.dev29 → locust-2.15.1}/locust/stats.py +6 -2
  12. {locust-2.14.3.dev29 → locust-2.15.1}/locust/templates/index.html +3 -1
  13. {locust-2.14.3.dev29 → locust-2.15.1}/locust/templates/report.html +5 -3
  14. locust-2.15.1/locust/templates/stats_data.html +10 -0
  15. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_dispatch.py +0 -2
  16. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_main.py +49 -0
  17. {locust-2.14.3.dev29 → locust-2.15.1}/locust/web.py +13 -6
  18. {locust-2.14.3.dev29 → locust-2.15.1}/locust.egg-info/PKG-INFO +9 -4
  19. {locust-2.14.3.dev29 → locust-2.15.1}/tox.ini +1 -1
  20. locust-2.14.3.dev29/locust/_version.py +0 -4
  21. locust-2.14.3.dev29/locust/templates/stats_data.html +0 -10
  22. {locust-2.14.3.dev29 → locust-2.15.1}/.coveragerc +0 -0
  23. {locust-2.14.3.dev29 → locust-2.15.1}/.dockerignore +0 -0
  24. {locust-2.14.3.dev29 → locust-2.15.1}/.git-blame-ignore-revs +0 -0
  25. {locust-2.14.3.dev29 → locust-2.15.1}/.gitattributes +0 -0
  26. {locust-2.14.3.dev29 → locust-2.15.1}/.github/CONTRIBUTING.md +0 -0
  27. {locust-2.14.3.dev29 → locust-2.15.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  28. {locust-2.14.3.dev29 → locust-2.15.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  29. {locust-2.14.3.dev29 → locust-2.15.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  30. {locust-2.14.3.dev29 → locust-2.15.1}/.github/workflows/stale.yml +0 -0
  31. {locust-2.14.3.dev29 → locust-2.15.1}/.github/workflows/tests.yml +0 -0
  32. {locust-2.14.3.dev29 → locust-2.15.1}/.gitignore +0 -0
  33. {locust-2.14.3.dev29 → locust-2.15.1}/.readthedocs.yml +0 -0
  34. {locust-2.14.3.dev29 → locust-2.15.1}/.vscode/launch.json +0 -0
  35. {locust-2.14.3.dev29 → locust-2.15.1}/.vscode/launch_locust.json +0 -0
  36. {locust-2.14.3.dev29 → locust-2.15.1}/.vscode/settings.json +0 -0
  37. {locust-2.14.3.dev29 → locust-2.15.1}/Dockerfile +0 -0
  38. {locust-2.14.3.dev29 → locust-2.15.1}/LICENSE +0 -0
  39. {locust-2.14.3.dev29 → locust-2.15.1}/MANIFEST.in +0 -0
  40. {locust-2.14.3.dev29 → locust-2.15.1}/Makefile +0 -0
  41. {locust-2.14.3.dev29 → locust-2.15.1}/README +0 -0
  42. {locust-2.14.3.dev29 → locust-2.15.1}/Vagrantfile +0 -0
  43. {locust-2.14.3.dev29 → locust-2.15.1}/benchmarks/dispatch.py +0 -0
  44. {locust-2.14.3.dev29 → locust-2.15.1}/codecov.yml +0 -0
  45. {locust-2.14.3.dev29 → locust-2.15.1}/docs/_static/theme-overrides.css +0 -0
  46. {locust-2.14.3.dev29 → locust-2.15.1}/docs/api.rst +0 -0
  47. {locust-2.14.3.dev29 → locust-2.15.1}/docs/conf.py +0 -0
  48. {locust-2.14.3.dev29 → locust-2.15.1}/docs/custom-load-shape.rst +0 -0
  49. {locust-2.14.3.dev29 → locust-2.15.1}/docs/developing-locust.rst +0 -0
  50. {locust-2.14.3.dev29 → locust-2.15.1}/docs/extending-locust.rst +0 -0
  51. {locust-2.14.3.dev29 → locust-2.15.1}/docs/further-reading.rst +0 -0
  52. {locust-2.14.3.dev29 → locust-2.15.1}/docs/history.rst +0 -0
  53. {locust-2.14.3.dev29 → locust-2.15.1}/docs/images/number_of_users.png +0 -0
  54. {locust-2.14.3.dev29 → locust-2.15.1}/docs/images/response_times.png +0 -0
  55. {locust-2.14.3.dev29 → locust-2.15.1}/docs/images/total_requests_per_second.png +0 -0
  56. {locust-2.14.3.dev29 → locust-2.15.1}/docs/images/userclass_picker_example.png +0 -0
  57. {locust-2.14.3.dev29 → locust-2.15.1}/docs/images/webui-running-statistics.png +0 -0
  58. {locust-2.14.3.dev29 → locust-2.15.1}/docs/images/webui-splash-screenshot.png +0 -0
  59. {locust-2.14.3.dev29 → locust-2.15.1}/docs/increase-performance.rst +0 -0
  60. {locust-2.14.3.dev29 → locust-2.15.1}/docs/index.rst +0 -0
  61. {locust-2.14.3.dev29 → locust-2.15.1}/docs/installation.rst +0 -0
  62. {locust-2.14.3.dev29 → locust-2.15.1}/docs/logging.rst +0 -0
  63. {locust-2.14.3.dev29 → locust-2.15.1}/docs/quickstart.rst +0 -0
  64. {locust-2.14.3.dev29 → locust-2.15.1}/docs/requirements.txt +0 -0
  65. {locust-2.14.3.dev29 → locust-2.15.1}/docs/retrieving-stats.rst +0 -0
  66. {locust-2.14.3.dev29 → locust-2.15.1}/docs/running-cloud-integration.rst +0 -0
  67. {locust-2.14.3.dev29 → locust-2.15.1}/docs/running-distributed.rst +0 -0
  68. {locust-2.14.3.dev29 → locust-2.15.1}/docs/running-in-debugger.rst +0 -0
  69. {locust-2.14.3.dev29 → locust-2.15.1}/docs/running-in-docker.rst +0 -0
  70. {locust-2.14.3.dev29 → locust-2.15.1}/docs/running-without-web-ui.rst +0 -0
  71. {locust-2.14.3.dev29 → locust-2.15.1}/docs/tasksets.rst +0 -0
  72. {locust-2.14.3.dev29 → locust-2.15.1}/docs/testing-other-systems.rst +0 -0
  73. {locust-2.14.3.dev29 → locust-2.15.1}/docs/use-as-lib.rst +0 -0
  74. {locust-2.14.3.dev29 → locust-2.15.1}/docs/what-is-locust.rst +0 -0
  75. {locust-2.14.3.dev29 → locust-2.15.1}/docs/writing-a-locustfile.rst +0 -0
  76. {locust-2.14.3.dev29 → locust-2.15.1}/examples/add_command_line_argument.py +0 -0
  77. {locust-2.14.3.dev29 → locust-2.15.1}/examples/basic.py +0 -0
  78. {locust-2.14.3.dev29 → locust-2.15.1}/examples/browse_docs_sequence_test.py +0 -0
  79. {locust-2.14.3.dev29 → locust-2.15.1}/examples/browse_docs_test.py +0 -0
  80. {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_messages.py +0 -0
  81. {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_shape/double_wave.py +0 -0
  82. {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_shape/stages.py +0 -0
  83. {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_shape/staging_user_classes.py +0 -0
  84. {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_shape/step_load.py +0 -0
  85. {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_shape/wait_user_count.py +0 -0
  86. {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_wait_function.py +0 -0
  87. {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_xmlrpc_client/server.py +0 -0
  88. {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_xmlrpc_client/xmlrpc_locustfile.py +0 -0
  89. {locust-2.14.3.dev29 → locust-2.15.1}/examples/debugging.py +0 -0
  90. {locust-2.14.3.dev29 → locust-2.15.1}/examples/debugging_advanced.py +0 -0
  91. {locust-2.14.3.dev29 → locust-2.15.1}/examples/docker-compose/docker-compose.yml +0 -0
  92. {locust-2.14.3.dev29 → locust-2.15.1}/examples/dynamic_user_credentials.py +0 -0
  93. {locust-2.14.3.dev29 → locust-2.15.1}/examples/events.py +0 -0
  94. {locust-2.14.3.dev29 → locust-2.15.1}/examples/extend_web_ui/extend.py +0 -0
  95. {locust-2.14.3.dev29 → locust-2.15.1}/examples/extend_web_ui/static/custom-stats-table.css +0 -0
  96. {locust-2.14.3.dev29 → locust-2.15.1}/examples/extend_web_ui/static/extend.js +0 -0
  97. {locust-2.14.3.dev29 → locust-2.15.1}/examples/extend_web_ui/templates/extend.html +0 -0
  98. {locust-2.14.3.dev29 → locust-2.15.1}/examples/fast_http_locust.py +0 -0
  99. {locust-2.14.3.dev29 → locust-2.15.1}/examples/grpc/grpc_user.py +0 -0
  100. {locust-2.14.3.dev29 → locust-2.15.1}/examples/grpc/hello.proto +0 -0
  101. {locust-2.14.3.dev29 → locust-2.15.1}/examples/grpc/hello_pb2.py +0 -0
  102. {locust-2.14.3.dev29 → locust-2.15.1}/examples/grpc/hello_pb2_grpc.py +0 -0
  103. {locust-2.14.3.dev29 → locust-2.15.1}/examples/grpc/hello_server.py +0 -0
  104. {locust-2.14.3.dev29 → locust-2.15.1}/examples/grpc/locustfile.py +0 -0
  105. {locust-2.14.3.dev29 → locust-2.15.1}/examples/locustfile.py +0 -0
  106. {locust-2.14.3.dev29 → locust-2.15.1}/examples/manual_stats_reporting.py +0 -0
  107. {locust-2.14.3.dev29 → locust-2.15.1}/examples/multiple_hosts.py +0 -0
  108. {locust-2.14.3.dev29 → locust-2.15.1}/examples/nested_inline_tasksets.py +0 -0
  109. {locust-2.14.3.dev29 → locust-2.15.1}/examples/rest.py +0 -0
  110. {locust-2.14.3.dev29 → locust-2.15.1}/examples/sdk_session_patching/session_patch_locustfile.py +0 -0
  111. {locust-2.14.3.dev29 → locust-2.15.1}/examples/semaphore_wait.py +0 -0
  112. {locust-2.14.3.dev29 → locust-2.15.1}/examples/stop_on_threshold.py +0 -0
  113. {locust-2.14.3.dev29 → locust-2.15.1}/examples/terraform/aws/README.md +0 -0
  114. {locust-2.14.3.dev29 → locust-2.15.1}/examples/terraform/aws/data_subnet.tf +0 -0
  115. {locust-2.14.3.dev29 → locust-2.15.1}/examples/terraform/aws/main.tf +0 -0
  116. {locust-2.14.3.dev29 → locust-2.15.1}/examples/terraform/aws/output.tf +0 -0
  117. {locust-2.14.3.dev29 → locust-2.15.1}/examples/terraform/aws/plan/basic.py +0 -0
  118. {locust-2.14.3.dev29 → locust-2.15.1}/examples/terraform/aws/provisioner.tf +0 -0
  119. {locust-2.14.3.dev29 → locust-2.15.1}/examples/terraform/aws/variables.tf +0 -0
  120. {locust-2.14.3.dev29 → locust-2.15.1}/examples/test_data_management.py +0 -0
  121. {locust-2.14.3.dev29 → locust-2.15.1}/examples/use_as_lib.py +0 -0
  122. {locust-2.14.3.dev29 → locust-2.15.1}/examples/vagrant/README.md +0 -0
  123. {locust-2.14.3.dev29 → locust-2.15.1}/examples/vagrant/supervisord.conf +0 -0
  124. {locust-2.14.3.dev29 → locust-2.15.1}/examples/vagrant/vagrant.sh +0 -0
  125. {locust-2.14.3.dev29 → locust-2.15.1}/examples/worker_index.py +0 -0
  126. {locust-2.14.3.dev29 → locust-2.15.1}/generate_changelog.py +0 -0
  127. {locust-2.14.3.dev29 → locust-2.15.1}/locust/__init__.py +0 -0
  128. {locust-2.14.3.dev29 → locust-2.15.1}/locust/__main__.py +0 -0
  129. {locust-2.14.3.dev29 → locust-2.15.1}/locust/argument_parser.py +0 -0
  130. {locust-2.14.3.dev29 → locust-2.15.1}/locust/clients.py +0 -0
  131. {locust-2.14.3.dev29 → locust-2.15.1}/locust/contrib/__init__.py +0 -0
  132. {locust-2.14.3.dev29 → locust-2.15.1}/locust/contrib/fasthttp.py +0 -0
  133. {locust-2.14.3.dev29 → locust-2.15.1}/locust/debug.py +0 -0
  134. {locust-2.14.3.dev29 → locust-2.15.1}/locust/dispatch.py +0 -0
  135. {locust-2.14.3.dev29 → locust-2.15.1}/locust/event.py +0 -0
  136. {locust-2.14.3.dev29 → locust-2.15.1}/locust/exception.py +0 -0
  137. {locust-2.14.3.dev29 → locust-2.15.1}/locust/input_events.py +0 -0
  138. {locust-2.14.3.dev29 → locust-2.15.1}/locust/log.py +0 -0
  139. {locust-2.14.3.dev29 → locust-2.15.1}/locust/py.typed +0 -0
  140. {locust-2.14.3.dev29 → locust-2.15.1}/locust/rpc/__init__.py +0 -0
  141. {locust-2.14.3.dev29 → locust-2.15.1}/locust/rpc/protocol.py +0 -0
  142. {locust-2.14.3.dev29 → locust-2.15.1}/locust/rpc/zmqrpc.py +0 -0
  143. {locust-2.14.3.dev29 → locust-2.15.1}/locust/runners.py +0 -0
  144. {locust-2.14.3.dev29 → locust-2.15.1}/locust/shape.py +0 -0
  145. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/chart.js +0 -0
  146. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/css/application.css +0 -0
  147. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/css/application.css.map +0 -0
  148. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/css/tables.css +0 -0
  149. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/css/tables.css.map +0 -0
  150. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/echarts.common.min.js +0 -0
  151. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/img/favicon.ico +0 -0
  152. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/img/logo.png +0 -0
  153. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/img/ui-screenshot-charts.png +0 -0
  154. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/img/ui-screenshot-start-test.png +0 -0
  155. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/img/ui-screenshot-stats.png +0 -0
  156. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/img/ui-screenshot-workers.png +0 -0
  157. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/jquery-1.11.3.min.js +0 -0
  158. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/jquery.jqote2.min.js +0 -0
  159. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/jquery.tools.min.js +0 -0
  160. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/sass/_base.sass +0 -0
  161. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/sass/_mixins.sass +0 -0
  162. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/sass/application.sass +0 -0
  163. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/sass/tables.sass +0 -0
  164. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/tasks.js +0 -0
  165. {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/vintage.js +0 -0
  166. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/__init__.py +0 -0
  167. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/fake_module1_for_env_test.py +0 -0
  168. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/fake_module2_for_env_test.py +0 -0
  169. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/mock_locustfile.py +0 -0
  170. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/mock_logging.py +0 -0
  171. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_env.py +0 -0
  172. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_fasthttp.py +0 -0
  173. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_http.py +0 -0
  174. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_load_locustfile.py +0 -0
  175. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_locust_class.py +0 -0
  176. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_log.py +0 -0
  177. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_old_wait_api.py +0 -0
  178. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_parser.py +0 -0
  179. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_runners.py +0 -0
  180. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_sequential_taskset.py +0 -0
  181. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_stats.py +0 -0
  182. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_tags.py +0 -0
  183. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_taskratio.py +0 -0
  184. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_users.py +0 -0
  185. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_util.py +0 -0
  186. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_wait_time.py +0 -0
  187. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_web.py +0 -0
  188. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_zmqrpc.py +0 -0
  189. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/testcases.py +0 -0
  190. {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/util.py +0 -0
  191. {locust-2.14.3.dev29 → locust-2.15.1}/locust/user/__init__.py +0 -0
  192. {locust-2.14.3.dev29 → locust-2.15.1}/locust/user/inspectuser.py +0 -0
  193. {locust-2.14.3.dev29 → locust-2.15.1}/locust/user/sequential_taskset.py +0 -0
  194. {locust-2.14.3.dev29 → locust-2.15.1}/locust/user/task.py +0 -0
  195. {locust-2.14.3.dev29 → locust-2.15.1}/locust/user/users.py +0 -0
  196. {locust-2.14.3.dev29 → locust-2.15.1}/locust/user/wait_time.py +0 -0
  197. {locust-2.14.3.dev29 → locust-2.15.1}/locust/util/__init__.py +0 -0
  198. {locust-2.14.3.dev29 → locust-2.15.1}/locust/util/cache.py +0 -0
  199. {locust-2.14.3.dev29 → locust-2.15.1}/locust/util/deprecation.py +0 -0
  200. {locust-2.14.3.dev29 → locust-2.15.1}/locust/util/exception_handler.py +0 -0
  201. {locust-2.14.3.dev29 → locust-2.15.1}/locust/util/load_locustfile.py +0 -0
  202. {locust-2.14.3.dev29 → locust-2.15.1}/locust/util/rounding.py +0 -0
  203. {locust-2.14.3.dev29 → locust-2.15.1}/locust/util/timespan.py +0 -0
  204. {locust-2.14.3.dev29 → locust-2.15.1}/locust.egg-info/SOURCES.txt +0 -0
  205. {locust-2.14.3.dev29 → locust-2.15.1}/locust.egg-info/dependency_links.txt +0 -0
  206. {locust-2.14.3.dev29 → locust-2.15.1}/locust.egg-info/entry_points.txt +0 -0
  207. {locust-2.14.3.dev29 → locust-2.15.1}/locust.egg-info/not-zip-safe +0 -0
  208. {locust-2.14.3.dev29 → locust-2.15.1}/locust.egg-info/requires.txt +0 -0
  209. {locust-2.14.3.dev29 → locust-2.15.1}/locust.egg-info/top_level.txt +0 -0
  210. {locust-2.14.3.dev29 → locust-2.15.1}/pyproject.toml +0 -0
  211. {locust-2.14.3.dev29 → locust-2.15.1}/scripts/locustfile.py +0 -0
  212. {locust-2.14.3.dev29 → locust-2.15.1}/scripts/run-disributed-headless.sh +0 -0
  213. {locust-2.14.3.dev29 → locust-2.15.1}/scripts/run-disributed-web.sh +0 -0
  214. {locust-2.14.3.dev29 → locust-2.15.1}/scripts/run-local-headless.sh +0 -0
  215. {locust-2.14.3.dev29 → locust-2.15.1}/scripts/run-local-web.sh +0 -0
  216. {locust-2.14.3.dev29 → locust-2.15.1}/setup.cfg +0 -0
  217. {locust-2.14.3.dev29 → locust-2.15.1}/setup.py +0 -0
@@ -1,6 +1,35 @@
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.15.0](https://github.com/locustio/locust/tree/2.15.0) (2023-03-01)
5
+
6
+ [Full Changelog](https://github.com/locustio/locust/compare/2.15.0...2.15.0)
7
+
8
+ **Closed issues:**
9
+
10
+ - locust k8s operator [\#2188](https://github.com/locustio/locust/issues/2188)
11
+
12
+ ## [2.15.0](https://github.com/locustio/locust/tree/2.15.0) (2023-02-28)
13
+
14
+ [Full Changelog](https://github.com/locustio/locust/compare/2.14.2...2.15.0)
15
+
16
+ **Fixed bugs:**
17
+
18
+ - "Download as PNG" text gets cut off [\#2307](https://github.com/locustio/locust/issues/2307)
19
+ - New worker fails to connect until master restart [\#2302](https://github.com/locustio/locust/issues/2302)
20
+
21
+ **Merged pull requests:**
22
+
23
+ - Fix locustio/locust\#2302 unknown worker spawning message [\#2309](https://github.com/locustio/locust/pull/2309) ([ykvch](https://github.com/ykvch))
24
+ - Prevent Download as PNG text from getting cut off [\#2308](https://github.com/locustio/locust/pull/2308) ([allison-strandberg](https://github.com/allison-strandberg))
25
+ - Remove request\_success and request\_failure event handlers [\#2306](https://github.com/locustio/locust/pull/2306) ([cyberw](https://github.com/cyberw))
26
+ - Remove verbose FastHttpUser error messages [\#2301](https://github.com/locustio/locust/pull/2301) ([cyberw](https://github.com/cyberw))
27
+ - fix: docs describing running without web UI had improper flag -f. Cor… [\#2297](https://github.com/locustio/locust/pull/2297) ([adriangonciarz](https://github.com/adriangonciarz))
28
+ - Update performance estimates for modern Python and hardware [\#2295](https://github.com/locustio/locust/pull/2295) ([cyberw](https://github.com/cyberw))
29
+ - docs \(\#2188\): Add Locust Kubernetes Operator [\#2288](https://github.com/locustio/locust/pull/2288) ([AbdelrhmanHamouda](https://github.com/AbdelrhmanHamouda))
30
+ - add events when initialize Environment [\#2285](https://github.com/locustio/locust/pull/2285) ([keegoo](https://github.com/keegoo))
31
+ - add is\_secret option for custom args to be shown in the web UI masked [\#2284](https://github.com/locustio/locust/pull/2284) ([mzhukovs](https://github.com/mzhukovs))
32
+
4
33
  ## [2.14.2](https://github.com/locustio/locust/tree/2.14.2) (2023-01-04)
5
34
 
6
35
  [Full Changelog](https://github.com/locustio/locust/compare/2.14.1...2.14.2)
@@ -1096,7 +1125,7 @@ The most important changes can also be found in [the documentation](https://docs
1096
1125
  **Merged pull requests:**
1097
1126
 
1098
1127
  - Remove Bad Apostrophe [\#1411](https://github.com/locustio/locust/pull/1411) ([curtisgibby](https://github.com/curtisgibby))
1099
- - update \_\_init\_\_ file [\#1409](https://github.com/locustio/locust/pull/1409) ([manifiko](https://github.com/manifiko))
1128
+ - update \_\_init\_\_ file [\#1409](https://github.com/locustio/locust/pull/1409) ([iamtechnomage](https://github.com/iamtechnomage))
1100
1129
  - Rename 3 remaining instances of slave to worker [\#1400](https://github.com/locustio/locust/pull/1400) ([ibrahima](https://github.com/ibrahima))
1101
1130
  - The format for providing host can be confusing at times [\#1398](https://github.com/locustio/locust/pull/1398) ([jo19in1](https://github.com/jo19in1))
1102
1131
  - Ability to control the Locust process' exit code [\#1396](https://github.com/locustio/locust/pull/1396) ([heyman](https://github.com/heyman))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: locust
3
- Version: 2.14.3.dev29
3
+ Version: 2.15.1
4
4
  Summary: Developer friendly load testing framework
5
5
  Home-page: https://locust.io/
6
6
  License: MIT
@@ -30,13 +30,13 @@ License-File: LICENSE
30
30
 
31
31
  # Locust
32
32
 
33
- [![Support Ukraine Badge](https://bit.ly/support-ukraine-now)](https://github.com/support-ukraine/support-ukraine)
34
33
  [![PyPI](https://img.shields.io/pypi/v/locust.svg)](https://pypi.org/project/locust/)
35
34
  [![PyPI](https://img.shields.io/pypi/pyversions/locust.svg)](https://pypi.org/project/locust/)
36
35
  [![Build Status](https://github.com/locustio/locust/workflows/Tests/badge.svg)](https://github.com/locustio/locust/actions?query=workflow%3ATests)
37
36
  [![codecov](https://codecov.io/gh/locustio/locust/branch/master/graph/badge.svg)](https://codecov.io/gh/locustio/locust)
38
37
  [![license](https://img.shields.io/github/license/locustio/locust.svg)](https://github.com/locustio/locust/blob/master/LICENSE)
39
38
  [![GitHub contributors](https://img.shields.io/github/contributors/locustio/locust.svg)](https://github.com/locustio/locust/graphs/contributors)
39
+ [![Support Ukraine Badge](https://bit.ly/support-ukraine-now)](https://github.com/support-ukraine/support-ukraine)
40
40
 
41
41
  Locust is an easy to use, scriptable and scalable performance testing tool. You define the behaviour of your users in regular Python code, instead of being constrained by a UI or domain specific language that only pretends to be real code. This makes Locust infinitely expandable and very developer friendly.
42
42
 
@@ -84,7 +84,12 @@ Even though Locust primarily works with web sites/services, it can be used to te
84
84
 
85
85
  ## Hackable
86
86
 
87
- Locust's code base is intentionally kept small and doesn't solve everything out of the box. Instead, we try to make it easy to adapt to any situation you may come across, using regular Python code. If you want to [send reporting data to that database & graphing system you like](https://github.com/SvenskaSpel/locust-plugins/blob/master/locust_plugins/dashboards/README.md), [wrap calls to a REST API](https://github.com/SvenskaSpel/locust-plugins/blob/master/examples/rest_ex.py) to handle the particulars of your system or run a [totally custom load pattern](https://docs.locust.io/en/latest/custom-load-shape.html#custom-load-shape), there is nothing stopping you!
87
+ Locust's code base is intentionally kept small and doesn't solve everything out of the box. Instead, we try to make it easy to adapt to any situation you may come across, using regular Python code. There is nothing stopping you from:
88
+
89
+ * [Send real time reporting data to TimescaleDB and visualize it in Grafana](https://github.com/SvenskaSpel/locust-plugins/blob/master/locust_plugins/dashboards/README.md)
90
+ * [Wrap calls to handle the peculiarities of your REST API](https://github.com/SvenskaSpel/locust-plugins/blob/8af21862d8129a5c3b17559677fe92192e312d8f/examples/rest_ex.py#L87)
91
+ * [Use a totally custom load shape/profile](https://docs.locust.io/en/latest/custom-load-shape.html#custom-load-shape)
92
+ * ...
88
93
 
89
94
  ## Links
90
95
 
@@ -96,7 +101,7 @@ Locust's code base is intentionally kept small and doesn't solve everything out
96
101
 
97
102
  ## Authors
98
103
 
99
- * [Carl Bystr](http://cgbystrom.com) ([@cgbystrom](https://twitter.com/cgbystrom) on Twitter)
104
+ * [Carl Byström](http://cgbystrom.com) ([@cgbystrom](https://twitter.com/cgbystrom) on Twitter)
100
105
  * [Jonatan Heyman](http://heyman.info) ([@jonatanheyman](https://twitter.com/jonatanheyman) on Twitter)
101
106
  * [Joakim Hamrén](https://github.com/Jahaja) ([@Jahaaja](https://twitter.com/Jahaaja) on Twitter)
102
107
  * [Hugo Heyman](https://github.com/HeyHugo) ([@hugoheyman](https://twitter.com/hugoheyman) on Twitter)
@@ -1,12 +1,12 @@
1
1
  # Locust
2
2
 
3
- [![Support Ukraine Badge](https://bit.ly/support-ukraine-now)](https://github.com/support-ukraine/support-ukraine)
4
3
  [![PyPI](https://img.shields.io/pypi/v/locust.svg)](https://pypi.org/project/locust/)
5
4
  [![PyPI](https://img.shields.io/pypi/pyversions/locust.svg)](https://pypi.org/project/locust/)
6
5
  [![Build Status](https://github.com/locustio/locust/workflows/Tests/badge.svg)](https://github.com/locustio/locust/actions?query=workflow%3ATests)
7
6
  [![codecov](https://codecov.io/gh/locustio/locust/branch/master/graph/badge.svg)](https://codecov.io/gh/locustio/locust)
8
7
  [![license](https://img.shields.io/github/license/locustio/locust.svg)](https://github.com/locustio/locust/blob/master/LICENSE)
9
8
  [![GitHub contributors](https://img.shields.io/github/contributors/locustio/locust.svg)](https://github.com/locustio/locust/graphs/contributors)
9
+ [![Support Ukraine Badge](https://bit.ly/support-ukraine-now)](https://github.com/support-ukraine/support-ukraine)
10
10
 
11
11
  Locust is an easy to use, scriptable and scalable performance testing tool. You define the behaviour of your users in regular Python code, instead of being constrained by a UI or domain specific language that only pretends to be real code. This makes Locust infinitely expandable and very developer friendly.
12
12
 
@@ -54,7 +54,12 @@ Even though Locust primarily works with web sites/services, it can be used to te
54
54
 
55
55
  ## Hackable
56
56
 
57
- Locust's code base is intentionally kept small and doesn't solve everything out of the box. Instead, we try to make it easy to adapt to any situation you may come across, using regular Python code. If you want to [send reporting data to that database & graphing system you like](https://github.com/SvenskaSpel/locust-plugins/blob/master/locust_plugins/dashboards/README.md), [wrap calls to a REST API](https://github.com/SvenskaSpel/locust-plugins/blob/master/examples/rest_ex.py) to handle the particulars of your system or run a [totally custom load pattern](https://docs.locust.io/en/latest/custom-load-shape.html#custom-load-shape), there is nothing stopping you!
57
+ Locust's code base is intentionally kept small and doesn't solve everything out of the box. Instead, we try to make it easy to adapt to any situation you may come across, using regular Python code. There is nothing stopping you from:
58
+
59
+ * [Send real time reporting data to TimescaleDB and visualize it in Grafana](https://github.com/SvenskaSpel/locust-plugins/blob/master/locust_plugins/dashboards/README.md)
60
+ * [Wrap calls to handle the peculiarities of your REST API](https://github.com/SvenskaSpel/locust-plugins/blob/8af21862d8129a5c3b17559677fe92192e312d8f/examples/rest_ex.py#L87)
61
+ * [Use a totally custom load shape/profile](https://docs.locust.io/en/latest/custom-load-shape.html#custom-load-shape)
62
+ * ...
58
63
 
59
64
  ## Links
60
65
 
@@ -66,7 +71,7 @@ Locust's code base is intentionally kept small and doesn't solve everything out
66
71
 
67
72
  ## Authors
68
73
 
69
- * [Carl Bystr](http://cgbystrom.com) ([@cgbystrom](https://twitter.com/cgbystrom) on Twitter)
74
+ * [Carl Byström](http://cgbystrom.com) ([@cgbystrom](https://twitter.com/cgbystrom) on Twitter)
70
75
  * [Jonatan Heyman](http://heyman.info) ([@jonatanheyman](https://twitter.com/jonatanheyman) on Twitter)
71
76
  * [Joakim Hamrén](https://github.com/Jahaja) ([@Jahaaja](https://twitter.com/Jahaaja) on Twitter)
72
77
  * [Hugo Heyman](https://github.com/HeyHugo) ([@hugoheyman](https://twitter.com/hugoheyman) on Twitter)
@@ -4,9 +4,18 @@ 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.15.1
8
+ ======
9
+ * Add PERCENTILES_TO_CHART param in stats.py to make the Response Time Chart configurable https://github.com/locustio/locust/pull/2313
10
+
11
+ 2.15.0
12
+ ======
13
+ * Add is_secret option for custom args to be shown in the web UI masked https://github.com/locustio/locust/pull/2284
14
+ * Breaking change: Remove deprecated request_success and request_failure event handlers (unified request handler was introduced in 1.5) https://github.com/locustio/locust/pull/2306
15
+
7
16
  2.14.2
8
17
  ======
9
- * Re-add py.typed marker file to package (it was missing in 2.14.1) #2282
18
+ * Re-add py.typed marker file to package (it was missing in 2.14.1) https://github.com/locustio/locust/pull/2282
10
19
 
11
20
  2.14.1
12
21
  ======
@@ -18,7 +27,7 @@ For full details of the Locust changelog, please see https://github.com/locustio
18
27
 
19
28
  2.13.2
20
29
  ======
21
- * Fix: Ask worker to reconnect if master gets a broken RPC message by @marcinh in #2271
30
+ * Fix: Ask worker to reconnect if master gets a broken RPC message by @marcinh in https://github.com/locustio/locust/pull/2271
22
31
 
23
32
  2.13.1
24
33
  ======
@@ -201,4 +201,6 @@ The list of statistics parameters that can be modified is:
201
201
  +-------------------------------------------+--------------------------------------------------------------------------------------+
202
202
  | PERCENTILES_TO_REPORT | The list of response time percentiles to be calculated & reported |
203
203
  +-------------------------------------------+--------------------------------------------------------------------------------------+
204
+ | PERCENTILES_TO_CHART | The list of response time percentiles for response time chart |
205
+ +-------------------------------------------+--------------------------------------------------------------------------------------+
204
206
 
@@ -0,0 +1,4 @@
1
+ # file generated by setuptools_scm
2
+ # don't change, don't track in version control
3
+ __version__ = version = '2.15.1'
4
+ __version_tuple__ = version_tuple = (2, 15, 1)
@@ -41,7 +41,6 @@ class Environment:
41
41
  available_user_classes: Optional[Dict[str, User]] = None,
42
42
  available_shape_classes: Optional[Dict[str, LoadTestShape]] = None,
43
43
  ):
44
-
45
44
  self.runner: Optional[Runner] = None
46
45
  """Reference to the :class:`Runner <locust.runners.Runner>` instance"""
47
46
 
@@ -4,6 +4,7 @@ import pathlib
4
4
  import datetime
5
5
  from itertools import chain
6
6
  from .stats import sort_stats
7
+ from . import stats as stats_module
7
8
  from .user.inspectuser import get_ratio
8
9
  from html import escape
9
10
  from json import dumps
@@ -94,6 +95,8 @@ def get_html_report(environment, show_download_link=True):
94
95
  show_download_link=show_download_link,
95
96
  locustfile=environment.locustfile,
96
97
  tasks=dumps(task_data),
98
+ percentile1=stats_module.PERCENTILES_TO_CHART[0],
99
+ percentile2=stats_module.PERCENTILES_TO_CHART[1],
97
100
  )
98
101
 
99
102
  return res
@@ -100,6 +100,24 @@ def main():
100
100
  user_classes[key] = value
101
101
  available_user_classes[key] = value
102
102
 
103
+ if len(stats.PERCENTILES_TO_CHART) != 2:
104
+ logging.error("stats.PERCENTILES_TO_CHART parameter should be 2 parameters \n")
105
+ sys.exit(1)
106
+
107
+ def is_valid_percentile(parameter):
108
+ try:
109
+ if 0 < float(parameter) < 1:
110
+ return True
111
+ return False
112
+ except ValueError:
113
+ return False
114
+
115
+ for percentile in stats.PERCENTILES_TO_CHART:
116
+ if not is_valid_percentile(percentile):
117
+ logging.error(
118
+ "stats.PERCENTILES_TO_CHART parameter need to be float and value between. 0 < percentile < 1 Eg 0.95\n"
119
+ )
120
+ sys.exit(1)
103
121
  # parse all command line options
104
122
  options = parse_options()
105
123
 
@@ -160,7 +178,6 @@ def main():
160
178
  user_classes = list(user_classes.values())
161
179
 
162
180
  if os.name != "nt" and not options.master:
163
-
164
181
  try:
165
182
  import resource
166
183
 
@@ -180,6 +197,7 @@ See https://github.com/locustio/locust/wiki/Installation#increasing-maximum-numb
180
197
 
181
198
  # create locust Environment
182
199
  locustfile_path = None if not locustfile else os.path.basename(locustfile)
200
+
183
201
  environment = create_environment(
184
202
  user_classes,
185
203
  options,
@@ -219,8 +219,8 @@ function update_stats_charts(){
219
219
  responseTimeChart.chart.setOption({
220
220
  xAxis: {data: stats_history["time"]},
221
221
  series: [
222
- {data: stats_history["response_time_percentile_50"], markLine: createMarkLine()},
223
- {data: stats_history["response_time_percentile_95"]},
222
+ {data: stats_history["response_time_percentile_1"], markLine: createMarkLine()},
223
+ {data: stats_history["response_time_percentile_2"]},
224
224
  ]
225
225
  });
226
226
 
@@ -235,7 +235,7 @@ function update_stats_charts(){
235
235
 
236
236
  // init charts
237
237
  var rpsChart = new LocustLineChart($(".charts-container"), "Total Requests per Second", ["RPS", "Failures/s"], "reqs/s", ['#00ca5a', '#ff6d6d']);
238
- var responseTimeChart = new LocustLineChart($(".charts-container"), "Response Times (ms)", ["Median Response Time", "95% percentile"], "ms");
238
+ var responseTimeChart = new LocustLineChart($(".charts-container"), "Response Times (ms)", [(percentile1 * 100).toString() + "th percentile" , (percentile2 * 100).toString() + "th percentile"], "ms");
239
239
  var usersChart = new LocustLineChart($(".charts-container"), "Number of Users", ["Users"], "users");
240
240
  charts.push(rpsChart, responseTimeChart, usersChart);
241
241
  echarts.connect([rpsChart.chart,responseTimeChart.chart,usersChart.chart])
@@ -264,8 +264,8 @@ function updateStats() {
264
264
  stats_history["user_count"].push({"value": null});
265
265
  stats_history["current_rps"].push({"value": null});
266
266
  stats_history["current_fail_per_sec"].push({"value": null});
267
- stats_history["response_time_percentile_50"].push({"value": null});
268
- stats_history["response_time_percentile_95"].push({"value": null});
267
+ stats_history["response_time_percentile_1"].push({"value": null});
268
+ stats_history["response_time_percentile_2"].push({"value": null});
269
269
  }
270
270
 
271
271
  // update stats chart to ensure the stop spacing appears as part
@@ -301,8 +301,8 @@ function updateStats() {
301
301
  stats_history["user_count"].push({"value": report.user_count});
302
302
  stats_history["current_rps"].push({"value": total.current_rps, "users": report.user_count});
303
303
  stats_history["current_fail_per_sec"].push({"value": total.current_fail_per_sec, "users": report.user_count});
304
- stats_history["response_time_percentile_50"].push({"value": report.current_response_time_percentile_50, "users": report.user_count});
305
- stats_history["response_time_percentile_95"].push({"value": report.current_response_time_percentile_95, "users": report.user_count});
304
+ stats_history["response_time_percentile_1"].push({"value": report.current_response_time_percentile_1, "users": report.user_count});
305
+ stats_history["response_time_percentile_2"].push({"value": report.current_response_time_percentile_2, "users": report.user_count});
306
306
  update_stats_charts();
307
307
 
308
308
  } catch(i){
@@ -133,6 +133,8 @@ CachedResponseTimes = namedtuple("CachedResponseTimes", ["response_times", "num_
133
133
 
134
134
  PERCENTILES_TO_REPORT = [0.50, 0.66, 0.75, 0.80, 0.90, 0.95, 0.98, 0.99, 0.999, 0.9999, 1.0]
135
135
 
136
+ PERCENTILES_TO_CHART = [0.50, 0.95]
137
+
136
138
 
137
139
  class RequestStatsAdditionError(Exception):
138
140
  pass
@@ -888,8 +890,10 @@ def stats_history(runner: "Runner") -> None:
888
890
  "time": datetime.datetime.now(tz=datetime.timezone.utc).strftime("%H:%M:%S"),
889
891
  "current_rps": stats.total.current_rps or 0,
890
892
  "current_fail_per_sec": stats.total.current_fail_per_sec or 0,
891
- "response_time_percentile_95": stats.total.get_current_response_time_percentile(0.95) or 0,
892
- "response_time_percentile_50": stats.total.get_current_response_time_percentile(0.5) or 0,
893
+ "response_time_percentile_1": stats.total.get_current_response_time_percentile(PERCENTILES_TO_CHART[0])
894
+ or 0,
895
+ "response_time_percentile_2": stats.total.get_current_response_time_percentile(PERCENTILES_TO_CHART[1])
896
+ or 0,
893
897
  "user_count": runner.user_count or 0,
894
898
  }
895
899
  stats.history.append(r)
@@ -180,7 +180,7 @@
180
180
  <tr>
181
181
  <th class="stats_label" href="#" data-sortkey="method">Type</th>
182
182
  <th class="stats_label" href="#" data-sortkey="name">Name</th>
183
- <th class="stats_label numeric nowrap" href="#" data-sortkey="num_requests" title="Number of successful requests"># Requests</th>
183
+ <th class="stats_label numeric nowrap" href="#" data-sortkey="num_requests" title="Number of requests"># Requests</th>
184
184
  <th class="stats_label numeric nowrap" href="#" data-sortkey="num_failures" title="Number of failures"># Fails</th>
185
185
  <th class="stats_label numeric" href="#" data-sortkey="median_response_time" title="Median response time">Median (ms)</th>
186
186
  <th class="stats_label numeric" href="#" data-sortkey="ninetieth_response_time" title="Ninetieth percentile response time, because the response time greater than 100ms is rounded, you may see it greater than the max response time">90%ile (ms)</th>
@@ -357,6 +357,8 @@
357
357
  ]]>
358
358
  </script>
359
359
  <script type="text/javascript">
360
+ var percentile1 = {{ percentile1|tojson }};
361
+ var percentile2 = {{ percentile2|tojson }};
360
362
  {% include 'stats_data.html' %}
361
363
  </script>
362
364
  <script type="text/javascript" src="./static/chart.js?v={{ version }}"></script>
@@ -198,8 +198,10 @@
198
198
 
199
199
  <script>
200
200
  {% include 'stats_data.html' %}
201
+ var percentile1 = {{ percentile1|tojson }}
202
+ var percentile2 = {{ percentile2|tojson }}
201
203
  var rpsChart = new LocustLineChart($(".charts-container"), "Total Requests per Second", ["RPS", "Failures/s"], "reqs/s", ['#00ca5a', '#ff6d6d']);
202
- var responseTimeChart = new LocustLineChart($(".charts-container"), "Response Times (ms)", ["Median Response Time", "95% percentile"], "ms");
204
+ var responseTimeChart = new LocustLineChart($(".charts-container"), "Response Times (ms)", [(percentile1*100).toString() + "th percentile" , (percentile2*100).toString() + "th percentile"], "ms");
203
205
  var usersChart = new LocustLineChart($(".charts-container"), "Number of Users", ["Users"], "users");
204
206
 
205
207
  if(stats_history["time"].length > 0){
@@ -214,8 +216,8 @@
214
216
  responseTimeChart.chart.setOption({
215
217
  xAxis: {data: stats_history["time"]},
216
218
  series: [
217
- {data: stats_history["response_time_percentile_50"]},
218
- {data: stats_history["response_time_percentile_95"]},
219
+ {data: stats_history["response_time_percentile_1"]},
220
+ {data: stats_history["response_time_percentile_2"]},
219
221
  ]
220
222
  });
221
223
 
@@ -0,0 +1,10 @@
1
+ {% set time_data = [] %}{% set user_count_data = [] %}{% set current_rps_data = [] %}{% set current_fail_per_sec_data = [] %}{% set response_time_percentile_2_data = [] %}{% set response_time_percentile_1_data = [] %}{% for r in history %}{% do time_data.append(r.time) %}{% do user_count_data.append({"value": r.user_count}) %}{% do current_rps_data.append({"value": r.current_rps, "users": r.user_count}) %}{% do current_fail_per_sec_data.append({"value": r.current_fail_per_sec, "users": r.user_count}) %}{% do response_time_percentile_2_data.append({"value": r.response_time_percentile_2, "users": r.user_count}) %}{% do response_time_percentile_1_data.append({"value": r.response_time_percentile_1, "users": r.user_count}) %}{% endfor %}
2
+ var stats_history = {
3
+ "time": {{ time_data | tojson }}.map(server_time => new Date(new Date().setUTCHours(...(server_time.split(":")))).toLocaleTimeString()),
4
+ "user_count": {{ user_count_data | tojson }},
5
+ "current_rps": {{ current_rps_data | tojson }},
6
+ "current_fail_per_sec": {{ current_fail_per_sec_data | tojson }},
7
+ "response_time_percentile_1": {{ response_time_percentile_1_data | tojson }},
8
+ "response_time_percentile_2": {{ response_time_percentile_2_data | tojson }},
9
+ "markers": [],
10
+ };
@@ -3555,7 +3555,6 @@ class TestRampUpUsersFromZeroWithFixed(unittest.TestCase):
3555
3555
  [(1, 1, 1, 1, 1), (200, 0, 0, 0, 0)],
3556
3556
  [(1, 1, 1, 1, 1), (0, 0, 0, 0, 0)],
3557
3557
  ]:
3558
-
3559
3558
  u1_weight, u2_weight, u3_weight, u4_weight, u5_weight = weights
3560
3559
  u1_fixed_count, u2_fixed_count, u3_fixed_count, u4_fixed_count, u5_fixed_count = fixed_counts
3561
3560
 
@@ -3589,7 +3588,6 @@ class TestRampUpUsersFromZeroWithFixed(unittest.TestCase):
3589
3588
 
3590
3589
  for down_to_count in down_counts:
3591
3590
  for target_user_count in target_user_counts:
3592
-
3593
3591
  # Ramp-up to go to `target_user_count` #########
3594
3592
 
3595
3593
  users_dispatcher.new_dispatch(target_user_count=target_user_count, spawn_rate=1)
@@ -1,6 +1,7 @@
1
1
  import json
2
2
  import os
3
3
  import platform
4
+
4
5
  import pty
5
6
  import signal
6
7
  import subprocess
@@ -191,6 +192,54 @@ class StandaloneIntegrationTests(ProcessIntegrationTest):
191
192
  self.assertIn("Shutting down (exit code 0)", stderr)
192
193
  self.assertEqual(0, proc.returncode)
193
194
 
195
+ def test_percentile_parameter(self):
196
+ port = get_free_tcp_port()
197
+ with temporary_file(
198
+ content=textwrap.dedent(
199
+ """
200
+ from locust import User, task, constant, events
201
+ from locust.stats import PERCENTILES_TO_CHART
202
+ PERCENTILES_TO_CHART[0] = 0.9
203
+ PERCENTILES_TO_CHART[1] = 0.4
204
+ class TestUser(User):
205
+ wait_time = constant(3)
206
+ @task
207
+ def my_task(self):
208
+ print("running my_task()")
209
+ """
210
+ )
211
+ ) as file_path:
212
+ proc = subprocess.Popen(
213
+ ["locust", "-f", file_path, "--web-port", str(port), "--autostart"], stdout=PIPE, stderr=PIPE, text=True
214
+ )
215
+ gevent.sleep(1)
216
+ response = requests.get(f"http://localhost:{port}/")
217
+ self.assertEqual(200, response.status_code)
218
+ proc.send_signal(signal.SIGTERM)
219
+ stdout, stderr = proc.communicate()
220
+ self.assertIn("Starting web interface at", stderr)
221
+
222
+ def test_invalid_percentile_parameter(self):
223
+ with temporary_file(
224
+ content=textwrap.dedent(
225
+ """
226
+ from locust import User, task, constant, events
227
+ from locust.stats import PERCENTILES_TO_CHART
228
+ PERCENTILES_TO_CHART[0] = 1.2
229
+ class TestUser(User):
230
+ wait_time = constant(3)
231
+ @task
232
+ def my_task(self):
233
+ print("running my_task()")
234
+ """
235
+ )
236
+ ) as file_path:
237
+ proc = subprocess.Popen(["locust", "-f", file_path, "--autostart"], stdout=PIPE, stderr=PIPE, text=True)
238
+ gevent.sleep(1)
239
+ stdout, stderr = proc.communicate()
240
+ self.assertIn("parameter need to be float and value between. 0 < percentile < 1 Eg 0.95", stderr)
241
+ self.assertEqual(1, proc.returncode)
242
+
194
243
  def test_webserver_multiple_locustfiles(self):
195
244
  with mock_locustfile(content=MOCK_LOCUSTFILE_CONTENT_A) as mocked1:
196
245
  with mock_locustfile(content=MOCK_LOCUSTFILE_CONTENT_B) as mocked2:
@@ -3,6 +3,7 @@ import csv
3
3
  import logging
4
4
  import os.path
5
5
  from functools import wraps
6
+
6
7
  from html import escape
7
8
  from io import StringIO
8
9
  from json import dumps
@@ -339,8 +340,8 @@ class WebUI:
339
340
  "errors": errors,
340
341
  "total_rps": 0.0,
341
342
  "fail_ratio": 0.0,
342
- "current_response_time_percentile_95": None,
343
- "current_response_time_percentile_50": None,
343
+ "current_response_time_percentile_1": None,
344
+ "current_response_time_percentile_2": None,
344
345
  "state": STATE_MISSING,
345
346
  "user_count": 0,
346
347
  }
@@ -388,11 +389,15 @@ class WebUI:
388
389
  report["total_rps"] = stats[len(stats) - 1]["current_rps"]
389
390
  report["fail_ratio"] = environment.runner.stats.total.fail_ratio
390
391
  report[
391
- "current_response_time_percentile_95"
392
- ] = environment.runner.stats.total.get_current_response_time_percentile(0.95)
392
+ "current_response_time_percentile_1"
393
+ ] = environment.runner.stats.total.get_current_response_time_percentile(
394
+ stats_module.PERCENTILES_TO_CHART[0]
395
+ )
393
396
  report[
394
- "current_response_time_percentile_50"
395
- ] = environment.runner.stats.total.get_current_response_time_percentile(0.5)
397
+ "current_response_time_percentile_2"
398
+ ] = environment.runner.stats.total.get_current_response_time_percentile(
399
+ stats_module.PERCENTILES_TO_CHART[1]
400
+ )
396
401
 
397
402
  if isinstance(environment.runner, MasterRunner):
398
403
  workers = []
@@ -555,6 +560,8 @@ class WebUI:
555
560
  "show_userclass_picker": self.userclass_picker_is_active,
556
561
  "available_user_classes": available_user_classes,
557
562
  "available_shape_classes": available_shape_classes,
563
+ "percentile1": stats_module.PERCENTILES_TO_CHART[0],
564
+ "percentile2": stats_module.PERCENTILES_TO_CHART[1],
558
565
  }
559
566
 
560
567
  def _update_shape_class(self, shape_class_name):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: locust
3
- Version: 2.14.3.dev29
3
+ Version: 2.15.1
4
4
  Summary: Developer friendly load testing framework
5
5
  Home-page: https://locust.io/
6
6
  License: MIT
@@ -30,13 +30,13 @@ License-File: LICENSE
30
30
 
31
31
  # Locust
32
32
 
33
- [![Support Ukraine Badge](https://bit.ly/support-ukraine-now)](https://github.com/support-ukraine/support-ukraine)
34
33
  [![PyPI](https://img.shields.io/pypi/v/locust.svg)](https://pypi.org/project/locust/)
35
34
  [![PyPI](https://img.shields.io/pypi/pyversions/locust.svg)](https://pypi.org/project/locust/)
36
35
  [![Build Status](https://github.com/locustio/locust/workflows/Tests/badge.svg)](https://github.com/locustio/locust/actions?query=workflow%3ATests)
37
36
  [![codecov](https://codecov.io/gh/locustio/locust/branch/master/graph/badge.svg)](https://codecov.io/gh/locustio/locust)
38
37
  [![license](https://img.shields.io/github/license/locustio/locust.svg)](https://github.com/locustio/locust/blob/master/LICENSE)
39
38
  [![GitHub contributors](https://img.shields.io/github/contributors/locustio/locust.svg)](https://github.com/locustio/locust/graphs/contributors)
39
+ [![Support Ukraine Badge](https://bit.ly/support-ukraine-now)](https://github.com/support-ukraine/support-ukraine)
40
40
 
41
41
  Locust is an easy to use, scriptable and scalable performance testing tool. You define the behaviour of your users in regular Python code, instead of being constrained by a UI or domain specific language that only pretends to be real code. This makes Locust infinitely expandable and very developer friendly.
42
42
 
@@ -84,7 +84,12 @@ Even though Locust primarily works with web sites/services, it can be used to te
84
84
 
85
85
  ## Hackable
86
86
 
87
- Locust's code base is intentionally kept small and doesn't solve everything out of the box. Instead, we try to make it easy to adapt to any situation you may come across, using regular Python code. If you want to [send reporting data to that database & graphing system you like](https://github.com/SvenskaSpel/locust-plugins/blob/master/locust_plugins/dashboards/README.md), [wrap calls to a REST API](https://github.com/SvenskaSpel/locust-plugins/blob/master/examples/rest_ex.py) to handle the particulars of your system or run a [totally custom load pattern](https://docs.locust.io/en/latest/custom-load-shape.html#custom-load-shape), there is nothing stopping you!
87
+ Locust's code base is intentionally kept small and doesn't solve everything out of the box. Instead, we try to make it easy to adapt to any situation you may come across, using regular Python code. There is nothing stopping you from:
88
+
89
+ * [Send real time reporting data to TimescaleDB and visualize it in Grafana](https://github.com/SvenskaSpel/locust-plugins/blob/master/locust_plugins/dashboards/README.md)
90
+ * [Wrap calls to handle the peculiarities of your REST API](https://github.com/SvenskaSpel/locust-plugins/blob/8af21862d8129a5c3b17559677fe92192e312d8f/examples/rest_ex.py#L87)
91
+ * [Use a totally custom load shape/profile](https://docs.locust.io/en/latest/custom-load-shape.html#custom-load-shape)
92
+ * ...
88
93
 
89
94
  ## Links
90
95
 
@@ -96,7 +101,7 @@ Locust's code base is intentionally kept small and doesn't solve everything out
96
101
 
97
102
  ## Authors
98
103
 
99
- * [Carl Bystr](http://cgbystrom.com) ([@cgbystrom](https://twitter.com/cgbystrom) on Twitter)
104
+ * [Carl Byström](http://cgbystrom.com) ([@cgbystrom](https://twitter.com/cgbystrom) on Twitter)
100
105
  * [Jonatan Heyman](http://heyman.info) ([@jonatanheyman](https://twitter.com/jonatanheyman) on Twitter)
101
106
  * [Joakim Hamrén](https://github.com/Jahaja) ([@Jahaaja](https://twitter.com/Jahaaja) on Twitter)
102
107
  * [Hugo Heyman](https://github.com/HeyHugo) ([@hugoheyman](https://twitter.com/hugoheyman) on Twitter)
@@ -36,7 +36,7 @@ commands =
36
36
  bash -ec 'PYTHONUNBUFFERED=1 python3 examples/debugging_advanced.py | grep done'
37
37
 
38
38
  [testenv:black]
39
- deps = black==22.12.0
39
+ deps = black==23.1.0
40
40
  commands = black --check .
41
41
 
42
42
  [testenv:flake8]
@@ -1,4 +0,0 @@
1
- # file generated by setuptools_scm
2
- # don't change, don't track in version control
3
- __version__ = version = '2.14.3.dev29'
4
- __version_tuple__ = version_tuple = (2, 14, 3, 'dev29')
@@ -1,10 +0,0 @@
1
- {% set time_data = [] %}{% set user_count_data = [] %}{% set current_rps_data = [] %}{% set current_fail_per_sec_data = [] %}{% set response_time_percentile_50_data = [] %}{% set response_time_percentile_95_data = [] %}{% for r in history %}{% do time_data.append(r.time) %}{% do user_count_data.append({"value": r.user_count}) %}{% do current_rps_data.append({"value": r.current_rps, "users": r.user_count}) %}{% do current_fail_per_sec_data.append({"value": r.current_fail_per_sec, "users": r.user_count}) %}{% do response_time_percentile_50_data.append({"value": r.response_time_percentile_50, "users": r.user_count}) %}{% do response_time_percentile_95_data.append({"value": r.response_time_percentile_95, "users": r.user_count}) %}{% endfor %}
2
- var stats_history = {
3
- "time": {{ time_data | tojson }}.map(server_time => new Date(new Date().setUTCHours(...(server_time.split(":")))).toLocaleTimeString()),
4
- "user_count": {{ user_count_data | tojson }},
5
- "current_rps": {{ current_rps_data | tojson }},
6
- "current_fail_per_sec": {{ current_fail_per_sec_data | tojson }},
7
- "response_time_percentile_50": {{ response_time_percentile_50_data | tojson }},
8
- "response_time_percentile_95": {{ response_time_percentile_95_data | tojson }},
9
- "markers": [],
10
- };
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