molotov

repository·main·Indexed 19 days ago

https://github.com/tarekziade/molotov

A 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.

Tokens
4.4K
Snippets
20
Records
28
Agent score
67%

What's inside molotov

  1. Overview of Molotov

    main
    Molotov is a simple Python 3.8+ tool designed for writing load tests. It is built on top of asyncio and uses aiohttp 3.x to handle asynchronous HTTP requests, making it suitable for high-concurrency performance testing.
  2. How scenarios work in Molotov

    main

    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.status
  3. Manage test lifecycles with fixture decorators

    main

    Molotov 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.
  4. Use gRPC for load testing

    main

    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
        pass
  5. Configure molotov.json for GitHub execution

    main

    The 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:

    • Key: The name of the test (e.g., test, big, scenario_two_once).
    • Value: An object containing the command-line options that will be passed to molotov for that specific test.
    {
      "test": { "option1": "value1" },
      "big": { "option2": "value2" },
      "scenario_two_once": { "option3": "value3" }
    }
  6. Quickstart with molostart

    main

    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/activate
  7. Register event handlers using the @molotov.events fixture

    main

    To 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
        pass
  8. Run molotov tests directly from a GitHub repository

    main

    You 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 test
  9. Extend Molotov behavior using the --use-extension option

    main

    You 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 -c
  10. Create a load test with the @scenario decorator

    main

    To 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()
  11. Run Molotov load tests in Docker

    main

    If 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