Basically, all load test scenarios in Chaperon operate on Chaperon.Session
structs.
Built-in actions, such as for making HTTP and WebSocket requests can be found in the Chaperon.Action.
module namespace but are accessible via helper functions in the Chaperon.Session
module.
To view chaperon's API documentation, run mix docs
and then open doc/index.html
.
Let's say we want to write a WebSocket load test that connects to a server and sends a message, then awaits a response and we track the duration of all of those ping/pong iterations. We'll write the ping pong logic inside a module that implements the Chaperon.Scenario
behavior by exposing a run/1
function. The init/1
function is optional and can be defined to perform some initial setup logic before running the scenario.
defmodule Scenario.WS.PingPong do
use Chaperon.Scenario
def init(session) do
# We can add custom session setup logic in an `init/1` function, if we need to.
# Returns {:ok, session} or {:error, reason} (see `Chaperon.Session` module)
session
|> ws_connect("/ping/pong")
|> ok
end
def run(session) do
# Accessing config values using the `Session.config/2` helper function.
# Alternatively we could have just accessed `session.config.ping_pong.iterations`
# but using the helper function as we do here gives us better error messages
# in case we didn't define the config value for this session.
iterations = session |> config([:ping_pong, :iterations])
# This will call `ping_pong/1` repeatedly for `iterations` amount of times
# and record the duration of calling it in a histogram
session
|> repeat_traced(:ping_pong, iterations)
|> log_info("PingPong finished after #{iterations} iterations")
end
def ping_pong(session) do
session
|> ws_send("ping")
|> ws_await_recv("pong") # await until "pong" message is received via WS
end
def teardown(session) do
# We can also define a `teardown/1` function which then gets called with our
# session after we successfully ran our `run/1` defined above.
# This is useful for cleaning up resources or performing other logic after
# we've run our load test scenario.
# Note that any actions in this code will not be traced and no metrics for
# them will be recorded in the final metrics histogram output.
session
|> ws_close
end
end
Once we've defined the Scenario logic above, we define the load test configuration in another module that uses the Chaperon.LoadTest
module to define everything we need to run the load test.
We provide a default config that is used by all load test scenarios we want to run as part of the load test, which in this case is just the PingPong
scenario we wrote.
defmodule LoadTest.PingPong do
use Chaperon.LoadTest
def default_config, do: %{
base_url: "http://localhost:5000"
}
# run 100 PingPong sessions (each with 10 iterations) across the cluster
# `scenario/0` is expected to return a list of 2-tuples (`{scenario_module, config}`)
# for each load test.
# `scenario_module` can be `{concurrency, scenario_module}` if running multiple
# concurrent instances of the scenario is needed
def scenarios, do: [
{{100, Scenario.WS.PingPong}, %{
ping_pong: %{
iterations: 10
}
}}
]
end
Check out the more in-depth tutorial using more advanced features.
You can also take a look at the examples/
directory for more example load tests.