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.
- {locust-2.14.3.dev29 → locust-2.15.1}/CHANGELOG.md +30 -1
- {locust-2.14.3.dev29 → locust-2.15.1}/PKG-INFO +9 -4
- {locust-2.14.3.dev29 → locust-2.15.1}/README.md +8 -3
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/changelog.rst +11 -2
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/configuration.rst +2 -0
- locust-2.15.1/locust/_version.py +4 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/env.py +0 -1
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/html.py +3 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/main.py +19 -1
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/locust.js +7 -7
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/stats.py +6 -2
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/templates/index.html +3 -1
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/templates/report.html +5 -3
- locust-2.15.1/locust/templates/stats_data.html +10 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_dispatch.py +0 -2
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_main.py +49 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/web.py +13 -6
- {locust-2.14.3.dev29 → locust-2.15.1}/locust.egg-info/PKG-INFO +9 -4
- {locust-2.14.3.dev29 → locust-2.15.1}/tox.ini +1 -1
- locust-2.14.3.dev29/locust/_version.py +0 -4
- locust-2.14.3.dev29/locust/templates/stats_data.html +0 -10
- {locust-2.14.3.dev29 → locust-2.15.1}/.coveragerc +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/.dockerignore +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/.git-blame-ignore-revs +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/.gitattributes +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/.github/CONTRIBUTING.md +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/.github/workflows/stale.yml +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/.github/workflows/tests.yml +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/.gitignore +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/.readthedocs.yml +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/.vscode/launch.json +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/.vscode/launch_locust.json +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/.vscode/settings.json +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/Dockerfile +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/LICENSE +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/MANIFEST.in +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/Makefile +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/README +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/Vagrantfile +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/benchmarks/dispatch.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/codecov.yml +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/_static/theme-overrides.css +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/api.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/conf.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/custom-load-shape.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/developing-locust.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/extending-locust.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/further-reading.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/history.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/images/number_of_users.png +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/images/response_times.png +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/images/total_requests_per_second.png +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/images/userclass_picker_example.png +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/images/webui-running-statistics.png +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/images/webui-splash-screenshot.png +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/increase-performance.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/index.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/installation.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/logging.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/quickstart.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/requirements.txt +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/retrieving-stats.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/running-cloud-integration.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/running-distributed.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/running-in-debugger.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/running-in-docker.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/running-without-web-ui.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/tasksets.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/testing-other-systems.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/use-as-lib.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/what-is-locust.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/docs/writing-a-locustfile.rst +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/add_command_line_argument.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/basic.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/browse_docs_sequence_test.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/browse_docs_test.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_messages.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_shape/double_wave.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_shape/stages.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_shape/staging_user_classes.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_shape/step_load.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_shape/wait_user_count.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_wait_function.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_xmlrpc_client/server.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/custom_xmlrpc_client/xmlrpc_locustfile.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/debugging.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/debugging_advanced.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/docker-compose/docker-compose.yml +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/dynamic_user_credentials.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/events.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/extend_web_ui/extend.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/extend_web_ui/static/custom-stats-table.css +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/extend_web_ui/static/extend.js +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/extend_web_ui/templates/extend.html +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/fast_http_locust.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/grpc/grpc_user.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/grpc/hello.proto +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/grpc/hello_pb2.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/grpc/hello_pb2_grpc.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/grpc/hello_server.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/grpc/locustfile.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/locustfile.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/manual_stats_reporting.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/multiple_hosts.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/nested_inline_tasksets.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/rest.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/sdk_session_patching/session_patch_locustfile.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/semaphore_wait.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/stop_on_threshold.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/terraform/aws/README.md +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/terraform/aws/data_subnet.tf +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/terraform/aws/main.tf +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/terraform/aws/output.tf +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/terraform/aws/plan/basic.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/terraform/aws/provisioner.tf +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/terraform/aws/variables.tf +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/test_data_management.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/use_as_lib.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/vagrant/README.md +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/vagrant/supervisord.conf +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/vagrant/vagrant.sh +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/examples/worker_index.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/generate_changelog.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/__init__.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/__main__.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/argument_parser.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/clients.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/contrib/__init__.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/contrib/fasthttp.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/debug.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/dispatch.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/event.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/exception.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/input_events.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/log.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/py.typed +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/rpc/__init__.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/rpc/protocol.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/rpc/zmqrpc.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/runners.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/shape.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/chart.js +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/css/application.css +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/css/application.css.map +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/css/tables.css +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/css/tables.css.map +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/echarts.common.min.js +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/img/favicon.ico +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/img/logo.png +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/img/ui-screenshot-charts.png +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/img/ui-screenshot-start-test.png +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/img/ui-screenshot-stats.png +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/img/ui-screenshot-workers.png +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/jquery-1.11.3.min.js +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/jquery.jqote2.min.js +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/jquery.tools.min.js +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/sass/_base.sass +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/sass/_mixins.sass +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/sass/application.sass +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/sass/tables.sass +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/tasks.js +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/static/vintage.js +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/__init__.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/fake_module1_for_env_test.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/fake_module2_for_env_test.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/mock_locustfile.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/mock_logging.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_env.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_fasthttp.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_http.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_load_locustfile.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_locust_class.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_log.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_old_wait_api.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_parser.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_runners.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_sequential_taskset.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_stats.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_tags.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_taskratio.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_users.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_util.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_wait_time.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_web.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/test_zmqrpc.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/testcases.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/test/util.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/user/__init__.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/user/inspectuser.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/user/sequential_taskset.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/user/task.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/user/users.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/user/wait_time.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/util/__init__.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/util/cache.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/util/deprecation.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/util/exception_handler.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/util/load_locustfile.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/util/rounding.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust/util/timespan.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust.egg-info/SOURCES.txt +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust.egg-info/dependency_links.txt +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust.egg-info/entry_points.txt +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust.egg-info/not-zip-safe +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust.egg-info/requires.txt +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/locust.egg-info/top_level.txt +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/pyproject.toml +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/scripts/locustfile.py +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/scripts/run-disributed-headless.sh +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/scripts/run-disributed-web.sh +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/scripts/run-local-headless.sh +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/scripts/run-local-web.sh +0 -0
- {locust-2.14.3.dev29 → locust-2.15.1}/setup.cfg +0 -0
- {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) ([
|
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.
|
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
|
-
[](https://github.com/support-ukraine/support-ukraine)
|
34
33
|
[](https://pypi.org/project/locust/)
|
35
34
|
[](https://pypi.org/project/locust/)
|
36
35
|
[](https://github.com/locustio/locust/actions?query=workflow%3ATests)
|
37
36
|
[](https://codecov.io/gh/locustio/locust)
|
38
37
|
[](https://github.com/locustio/locust/blob/master/LICENSE)
|
39
38
|
[](https://github.com/locustio/locust/graphs/contributors)
|
39
|
+
[](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.
|
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
|
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
|
-
[](https://github.com/support-ukraine/support-ukraine)
|
4
3
|
[](https://pypi.org/project/locust/)
|
5
4
|
[](https://pypi.org/project/locust/)
|
6
5
|
[](https://github.com/locustio/locust/actions?query=workflow%3ATests)
|
7
6
|
[](https://codecov.io/gh/locustio/locust)
|
8
7
|
[](https://github.com/locustio/locust/blob/master/LICENSE)
|
9
8
|
[](https://github.com/locustio/locust/graphs/contributors)
|
9
|
+
[](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.
|
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
|
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)
|
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
|
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
|
|
@@ -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["
|
223
|
-
{data: stats_history["
|
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)", ["
|
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["
|
268
|
-
stats_history["
|
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["
|
305
|
-
stats_history["
|
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
|
-
"
|
892
|
-
|
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
|
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)", ["
|
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["
|
218
|
-
{data: stats_history["
|
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
|
-
"
|
343
|
-
"
|
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
|
-
"
|
392
|
-
] = environment.runner.stats.total.get_current_response_time_percentile(
|
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
|
-
"
|
395
|
-
] = environment.runner.stats.total.get_current_response_time_percentile(
|
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.
|
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
|
-
[](https://github.com/support-ukraine/support-ukraine)
|
34
33
|
[](https://pypi.org/project/locust/)
|
35
34
|
[](https://pypi.org/project/locust/)
|
36
35
|
[](https://github.com/locustio/locust/actions?query=workflow%3ATests)
|
37
36
|
[](https://codecov.io/gh/locustio/locust)
|
38
37
|
[](https://github.com/locustio/locust/blob/master/LICENSE)
|
39
38
|
[](https://github.com/locustio/locust/graphs/contributors)
|
39
|
+
[](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.
|
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
|
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,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
|
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
|