balter 0.1.1

A load/stress testing framework.
Documentation

Balter

Balter, short for Build A Load TestER, is a load/stress testing framework for Rust designed to be flexible, efficient, and simple to use. Balter aims to minimize the conceptual overhead of load testing, and builds off of Tokio and the async ecosystem.

  • See the How To Use section for a guide on how to get started.
  • See the Limitations section for current things to be aware of (this is Beta software).
  • See the Developer Notes section for tips on modifying Balter.

Features

  • Run a given Scenario at a specific Transactions Per Second (TPS).
  • Run a given Scenario to saturate the target (increase TPS until error rate is 3%).
  • Distributed Scenario running; spin up multiple instances and they will coordinate [Experimental]

WIP

  • More robust distributed logic
  • mTLS
  • Peer discovery via DNS
  • Autoscaling hooks

Limitations

Balter is a Beta framework, which means there are some rough edges. This section lists the most important to be aware of. These are issues that are being worked on (with haste!) so hopefully this section will be gone soon :)

  • The current statistical engine powering the TPS and Saturate functionality is not perfect

    • It cannot handle changing loads well. It finds a set point and then sits there.
    • A highly variable measurement may cause it to find a bad set point.
  • The distributed functionality is experimental.

    • Inefficient Gossip protocol being used
    • No transaction security (no TLS, mTLS, or WSS) - use at your own risk (and in a private VPC)
    • Likely to run into weird error cases

How To Use

Balter is simple to get set up with. If you want to run a load test with a single Server, you include balter = 0.1 in your Cargo.toml, and then:

use balter::prelude::*;

#[tokio::main]
async fn main() {
    my_scenario
        .tps(500)
        .duration(Duration::from_secs(30))
        .await;

    // OR

    my_scenario()
        .saturate()
        .duration(Duration::from_secs(30))
        .await;
}

#[scenario]
fn my_scenario() {
    my_transaction().await;
}

#[transaction]
fn my_transaction() -> Result<_, _> {
    // Some request logic
}

Developer Notes

The Balter repository is set up to be easy to get started with development. It uses Nix to facilitate the environment setup via shell.nix (if you haven't yet drank the Nixaide, open up that file and it will give you an idea of the programs you'll want). The two most important for testing are just and cpulimit which are both used for running the test environment. (Just simplifies running the test scripts, but isn't actually needed)

Balter currently has most of its testing as integration tests, run via just {test name} which calls the test scripts in test-scripts/. Unfortunately, cpulimit is going to be based on the computer you're running on, so it might require tweaking some values in the test-scripts/. For a basic test to get you started, just basic-saturate will do.

The various integration test scripts all start up a mock-service (code in mock-service/) which is a simple HTTP server with a few endpoints to make it easier to test various functionality. /api_10ms is an endpoint which takes 10ms to respond. /api_max_tps is an endpoint which has a set MAX_TPS it accepts before responding with errors (and also coincidentally takes 10ms to respond).