Writing mite journeys and scenarios¶
Data creation scenarios¶
For many workloads, it is necessary to populate a test environment with some data. For example, if we are performance testing a web appʼs signin, we need to seed the database with some usernames and passwords that we can use in our signin HTTP requests. In mite, this is accomplished by data creation scenarios.
Firstly, when running a data creation scenario, we need to activate
miteʼs recorder component. This will
write the data as it is created to a series of msgpack-format files
in a directory called recorder-data
. These files will become the
input for a datapool for the load test journeys (see below).
Secondly, we need to write some journey functions that use the appʼs HTTP APIs to create data. An example might be as follows:
import uuid
from mite_http import mite_http
@mite_http
async def create_user(context):
username = uuid.uuid4().hex
async with ctx.transaction("Create user"):
await ctx.http.post(ctx.config.get("app_url") + "/users/create",
json={"username": username, "password": "test1234"})
await ctx.send("data_created", name="users", data={"username": username})
We use the python standard library uuid module
to
generate random user names, and create the users with a fixed password.
We then send a message with the type data_created
and the name
users
. This will be read by the recorder process, which listens
to messages with type data_created
. It will read the name
of
all such messages. For each message, the data
is written as a
msgpack dictionary into the file recorder-data/{name}.msgpack
.
We create a scenario that runs this journey for a specific amount of
time at a specific rate, which will generate our test users. If we have
other types of data that need to be populated in the environment, we can
write multiple journeys and run them as part of the same scenario. By
giving a different name
to each kind of data we create, we will get
different output files for each type of data.
Note
The suggested approach to run the data creation journey for a specific time and TPS will generate an approximate number of test users. If precise control of the number of users generated is needed, you should instead use a (nonrecyclable) datapool as input to the creation scenario. The scenario will then be run once for each item in the data pool, creating a precisely specified number of users.
The next step is to create a data pool for the usernames:
from mite.datapools import RecyclableIterableDataPool
usernames = []
with open("recorder-data", "rb") as handle:
for msg in iter(Unpacker(handle, raw=False, use_list=False)):
usernames.append((msg["username"],))
username_datapool = RecyclableIterableDataPool(usernames)
Note
The datapool items (which are appended to the usernames
variable)
are tuples; this is required by miteʼs data pool framework.
Finally, we can use this datapool in our scenario:
@mite_http
async def signin(ctx, username):
async with ctx.transaction("Log in"):
await ctx.http.post(ctx.config.get("app_url") + "/login",
json={"username": username, "password": "test1234"})
def my_scenario():
return [["my_file:signin", usernames_datapool, lambda start, end: 100]]