Skip to content

Scripting architecture

StormWeaver relies on scripts written in Lua for test scenarios and utility code for the scenarios.

The C++ code is just a framework, it provides a helper architecture and executes a main lua script. If that script does nothing, the program just exits after startup.

There are also helper functions/classes written in lua, using the C++ code. The goal of these is to simplify the development of test scenarios, while also allowing easy modification without rebuilding the main executable.

Folder structure

Lua scripts are stored in two directories:

  • scenarios is intended for specific test scenarios
  • scripts is intended for helper functions/classes usable by multiple scenarios

These directories are added to the search path at two locations:

  • Relative to the executable (which is bin/stormweaver, the directories have to be in the same folder as bin)
  • Relative to the current working directory

3rd party libraries

Additional, several 3rd party lua libraries are also included and are usable by scripts/scenarios. These are the following:

C++ binding

Stormweaver includes several classes/functions implemented in C++, which are usable in lua scripts. The complete list of these functions is available in the Lua C++ reference.

Scenario configuration

The argparse library is included, and the C++ runner forwards all arguments to the script, including the scenario filename.

The lua helpers already create a default parser using the global variable argparser, which includes handling the common arguments, so scenarios only have to set up additional scenario specific arguments.

Multi-threaded structure

StormWeaver is a multithreaded, concurrent test framework, while lua is a single threaded scripting language. To make the two work together, it uses multiple lua instances:

  • There's one "main" instance used for the scenario startup and setup
  • There's one instance per worker thread when running workloads
  • And any of the above threads also might start background workers, resulting in additional lua threads

The main thread and background workers are lua-first: there's a lua function (main in case of the main thread, user specified for the other) that gets executed, and when this function ends, the thread also exists.

The worker threads are hovever C++-first: the random workload is generated by a C++ runner, and it only executes lua functions when it is neccessary.

Limitations

To ensure that all threads have access to the same functions, the scenario file is loaded for all lua states.

This results in the following limitations:

  • the scenario script, and included other scripts get processed multiple times
  • anything that is executed directly by the script will be executed by all threads
  • while global variables will be available in all threads, their values will be different and won't be synced

In line with this, it is recommended that script/scenario files:

  • shouldn't rely on mutable global variables
  • shouldn't execute code directly in the source file, instead everything should go into the main functions