Skip to main content

Async distributed load-testing framework contracts and runtime

Project description

vikhry

vikhry is an async distributed load-testing framework built for high concurrency, horizontal scaling, and workloads that need globally unique resources.

It combines:

  • a Python runtime for writing virtual-user scenarios;
  • an orchestrator that manages test lifecycle and aggregates metrics;
  • worker processes that execute VUs;
  • Redis as the shared coordination layer;
  • a built-in web UI served by the orchestrator.

Architecture

At a high level, vikhry has four runtime parts:

  1. orchestrator Handles the test state machine, exposes HTTP/WebSocket APIs, serves the UI, and coordinates workers.
  2. worker Runs VU tasks, processes orchestrator commands, publishes metrics, and manages acquired resources.
  3. redis Stores shared state, worker presence, user assignments, resources, and metric streams.
  4. ui A React frontend bundled into the Python package and served by the orchestrator.

Lifecycle flow:

IDLE -> PREPARING -> RUNNING -> STOPPING -> IDLE

Install and run

Install from PyPI:

pip install vikhry

Start local infrastructure:

vikhry infra up --worker-count 3 --scenario my_scenario:DemoVU

This command:

  • checks that Docker is available;
  • starts Redis in a Docker container;
  • starts the orchestrator;
  • starts the requested number of workers.

Open:

  • UI: http://127.0.0.1:8080/
  • API: http://127.0.0.1:8080

Stop everything:

vikhry infra down

Example test file

Create my_scenario.py:

from __future__ import annotations

from typing import Any

from vikhry import ReqwestClient, VU, between, resource, step


@resource(name="users")
async def create_user(resource_id: int | str, _ctx: object) -> dict[str, Any]:
    rid = str(resource_id)
    return {
        "resource_id": rid,
        "username": f"user_{rid}",
        "password": "password",
    }


class DemoVU(VU):
    http = ReqwestClient(timeout=5.0)

    async def on_init(self, base_url: str) -> None:
        self.http = self.http(base_url=base_url)

    async def on_start(self) -> None:
        self.user = await self.resources.acquire("users")

    async def on_stop(self) -> None:
        await self.resources.release("users", str(self.user["resource_id"]))

    @step(name="login", weight=1.0, every_s=between(10.0, 15.0), timeout=5.0)
    async def login(self) -> None:
        response = await self.http.post(
            "/auth",
            json={
                "username": self.user["username"],
                "password": self.user["password"],
            },
        )
        if response.status >= 400:
            raise RuntimeError(f"login returned HTTP {response.status}")

    @step(name="catalog", weight=3.0, requires=("login",), every_s=between(0.2, 1.0))
    async def catalog(self) -> None:
        response = await self.http.get("/catalog")
        if response.status >= 400:
            raise RuntimeError(f"catalog returned HTTP {response.status}")

Run it:

vikhry infra up --worker-count 3 --scenario my_scenario:DemoVU

Test authoring capabilities

vikhry scenarios are plain Python classes built on top of the VU DSL.

What you can define:

  • VU.on_init(...) Accept runtime parameters for each VU instance.
  • VU.on_start() / VU.on_stop() Allocate and release state or resources around the VU lifecycle.
  • @step(...) Define executable load steps.
  • @resource(name="...") Define global resource factories managed through Redis-backed pools.
  • ReqwestClient Use an async HTTP client for relative or absolute requests.
  • emit_metric(...) and @metric(...) Publish custom metrics in addition to automatic HTTP and step metrics.

Step controls:

  • weight Weighted random scheduling between eligible steps.
  • requires Declare prerequisites by step name.
  • every_s Throttle step execution to a fixed or randomized interval.
  • timeout Fail a step if it exceeds its maximum runtime.

Resource model:

  • resource factories create globally tracked objects;
  • workers acquire resources with self.resources.acquire(name);
  • workers release them with self.resources.release(name, resource_id).

Packaging and release

The Python package includes the built UI assets.

Build locally:

./scripts/build_frontend.sh
uv build

Release automation:

  • .github/workflows/release-artifacts.yml Builds the frontend, creates wheel and sdist, and publishes the package to PyPI using PYPI_TOKEN.
  • .github/workflows/docker-image.yml Builds and publishes the runtime Docker image to ghcr.io/<owner>/<repo> on every branch push.

The package version is taken from project.version in pyproject.toml.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vikhry-0.1.1.tar.gz (361.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vikhry-0.1.1-py3-none-any.whl (250.5 kB view details)

Uploaded Python 3

File details

Details for the file vikhry-0.1.1.tar.gz.

File metadata

  • Download URL: vikhry-0.1.1.tar.gz
  • Upload date:
  • Size: 361.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for vikhry-0.1.1.tar.gz
Algorithm Hash digest
SHA256 e56bd92ecd64a8d7dac12e2a314bf03ac82dbb7c9c113c39cb94c98896ac6f37
MD5 5e28955320189c306017bdfcdc94a7e7
BLAKE2b-256 6cc119d4dd34a8793dd27a7fea3a24eb162426635ff351b4146f40029dc3d7d4

See more details on using hashes here.

Provenance

The following attestation bundles were made for vikhry-0.1.1.tar.gz:

Publisher: release-artifacts.yml on gigimon/vikhry

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vikhry-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: vikhry-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 250.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for vikhry-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 35f27f5d45728709b4f29842a910d564909a17e16535fcd57c07c25525f941e4
MD5 23b2e0c152c3d21c27bd68cfa531c562
BLAKE2b-256 46c08e1ec61b26573d8f97f92e1732a19cffffb379634de8fbad519b26dfae84

See more details on using hashes here.

Provenance

The following attestation bundles were made for vikhry-0.1.1-py3-none-any.whl:

Publisher: release-artifacts.yml on gigimon/vikhry

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page