Overview of Molotov
mainasyncio and uses aiohttp 3.x to handle asynchronous HTTP requests, making it suitable for high-concurrency performance testing.repository·main·Indexed 19 days ago
https://github.com/tarekziade/molotovA lightweight Python-based load testing tool built for asynchronous performance testing using asyncio and aiohttp. It supports HTTP and gRPC load testing, featuring a CLI for execution, a scenario-based testing model with weighted selection, and a comprehensive set of lifecycle hooks and event handlers. Molotov also provides Docker integration and the moloslave command for running tests directly from GitHub repositories.
asyncio and uses aiohttp 3.x to handle asynchronous HTTP requests, making it suitable for high-concurrency performance testing.A scenario represents a realistic interaction with a service. To define one, decorate an async function with @scenario.
Each scenario receives a session instance, which is used to perform asynchronous requests (e.g., using session.get()).
Scenario Weights:
You can assign a weight to each scenario using @scenario(weight=N). Molotov uses these weights to determine the probability of a scenario being selected by a worker using the formula:
scenario_weight / sum(scenario weights).
Note that weights do not need to sum to 100.
from molotov import scenario
@scenario(weight=100)
async def _test(session):
async with session.get('https://example.com') as resp:
assert resp.status == 200, resp.statusMolotov provides a suite of decorators to hook into different stages of the test lifecycle. These allow you to run setup or teardown logic at various granularities (global, session, or individual test level).
Available lifecycle hooks:
global_setup: Runs once at the very beginning of the entire test suite.setup: Runs before each individual scenario.setup_session: Runs at the start of a test session.teardown: Runs after each individual scenario.teardown_session: Runs at the end of a test session.global_teardown: Runs once at the very end of the entire test suite.Since version 2.7, Molotov supports gRPC load testing. To use gRPC instead of HTTP, specify session_kind='grpc' in the @scenario decorator.
When a scenario is selected, Molotov creates a gRPC client using the standard grpcio library. Each worker is assigned one session that is reused for every scenario run performed by that worker.
import molotov
@molotov.scenario(session_kind='grpc')
async def grpc_scenario(session):
# session is a gRPC client
passThe molotov.json file is used to define which tests should be run when using moloslave. Each entry in the JSON object represents a test case.
Structure:
test, big, scenario_two_once).{
"test": { "option1": "value1" },
"big": { "option2": "value2" },
"scenario_two_once": { "option3": "value3" }
}Use the molostart command to generate a default Molotov project layout, including a Makefile, a template loadtest.py, and a molotov.json configuration file. This is the fastest way to set up a testing environment.
After running molostart, use make build to create a local virtualenv with Molotov installed, then activate it to begin testing.
$ molostart
# Follow prompts to set target directory
$ cd /tmp/mytest
$ make build
$ source venv/bin/activateTo react to specific lifecycle events during a load test, you can register one or more functions by decorating them with the molotov.events fixture. These functions will be automatically called by the framework when the corresponding event is triggered.
@molotov.events
def my_event_handler(event_name, **kwargs):
# Handle the event here
passYou can execute molotov tests directly from a GitHub repository by placing a molotov.json configuration file at the root of that repository. This file must contain a list of tests, where each test is defined by a name and its associated command-line options.
To run the tests, use the moloslave command followed by the repository URL and the specific test name defined in your JSON file.
$ moloslave https://github.com/tarekziade/molotov testYou can extend Molotov's functionality by loading arbitrary Python modules that contain fixtures or event listeners. This is achieved using the --use-extension CLI option. Extensions are ideal for implementing reusable behaviors across different load tests, such as custom metrics collection or specialized setup/teardown logic.
To use an extension, pass the path to the Python module containing your extension code to the --use-extension flag when running the molotov command.
$ molotov --use-extension path/to/extension.py --max-runs 10 loadtest.py -cTo write a load test in Molotov, create a Python module containing coroutines decorated with @scenario. Each decorated function receives a session object as its argument, which is an instance of aiohttp.ClientSession.
Workers will execute these scenarios indefinitely until the test duration expires or the maximum number of runs is reached. Workers pick scenarios randomly based on their defined weights.
import molotov
@molotov.scenario
async def scenario_one(session):
async with session.get('http://example.com') as response:
await response.text()
@molotov.scenario(weight=60)
async def scenario_two(session):
async with session.get('http://example.com/api') as response:
await response.json()To install molotov, ensure you are using Python 3.7 or a newer version and have pip installed. You can then install the package using the following command:
$ pip install molotovIf your test is hosted on a public GitHub repository, you can run it inside a Docker container using the official tarekziade/molotov image. The container uses Moloslave to execute the specified test from the provided repository.
You must configure the following environment variables:
TEST_REPO: The URL of the public Git repository containing your tests.TEST_NAME: The specific name of the test to execute within that repository.Use the -i flag to ensure the container runs in interactive mode.
docker run -i --rm -e TEST_REPO=https://github.com/tarekziade/molotov -e TEST_NAME=test tarekziade/molotov:latest