Configuration parameters
StormWeaver reads a small TOML config file plus a handful of CLI flags. Scenario code (Python, not a config layer) decides how to combine them - scenarios/ci/basic.py uses args.install_dir or config.pgroot, giving the CLI flag precedence; your own scenarios can do whatever makes sense for them.
TOML config file
Default path config/stormweaver.toml, overridable with -c/--config. Parsed by stormweaver.Config (python/stormweaver/config.py), which only reads a [default] table:
[default]
pgroot = "" # PostgreSQL installation directory
datadir_root = "datadirs" # root directory for generated PostgreSQL data directories
port_start = 15432 # first port a scenario should use
port_end = 15531 # last port a scenario should use
Config.datadir(name) returns <datadir_root>/datadir_<name>. Unknown keys are ignored; there is no environment-variable overlay or --include search path in the current config loader - a scenario is free to add its own argparse flags or env var reads.
CLI arguments
stormweaver <scenario> [options], defined in python/stormweaver/cli.py:
| Flag | Purpose | Default |
|---|---|---|
scenario (positional) |
Path to the scenario .py file |
required |
-c, --config |
Path to the TOML config file | config/stormweaver.toml |
-i, --install-dir |
PostgreSQL installation directory, passed to args.install_dir |
"" |
-v, --verbose |
Debug-level logging | off |
-q, --quiet |
Warning-level logging only | off |
-v and -q are mutually exclusive; the default log level is INFO.
PostgreSQL defaults
sw.Postgres runs initdb with no extra options, then appends to postgresql.conf: the chosen port, and unix_socket_directories pointed at the data directory (to avoid needing /run/postgresql). Everything else is PostgreSQL's own initdb defaults - add whatever else you need with pg.add_config({...}):
Action configuration
Actions read their knobs from sw.AllConfig (WorkloadParams.action_config),
not from the TOML file - see Writing scenarios for how
a scenario builds one. The transaction action (see
Transactions) reads AllConfig.transaction
(TransactionConfig):
| Knob | Default | Meaning |
|---|---|---|
transaction.min_sub_actions |
2 | Minimum number of sub-actions run inside one transaction |
transaction.max_sub_actions |
10 | Maximum number of sub-actions run inside one transaction |
transaction.commit_prob |
95 | Percent chance the transaction ends with COMMIT instead of ROLLBACK |
transaction.rollback_to_savepoint_prob |
10 | Percent chance, per successful sub-action in savepoint mode, of rewinding to a random earlier savepoint |
transaction.error_mode |
"savepoint" |
"savepoint" rolls back to a per-sub-action savepoint on failure; "abort" rolls back the whole transaction on the first failure |
transaction.mysql_ddl_mode |
"mirror" |
"mirror" keeps DDL in the pool and models MySQL's implicit commit truthfully; "exclude" filters DDL out so MySQL transactions stay DML-only |
transaction.isolation_weights.server_default |
1 | Relative weight for leaving the isolation level at the server default |
transaction.isolation_weights.read_committed |
1 | Relative weight for READ COMMITTED |
transaction.isolation_weights.repeatable_read |
1 | Relative weight for REPEATABLE READ |
transaction.isolation_weights.serializable |
1 | Relative weight for SERIALIZABLE |
The transaction action's own selection frequency is not a config field -
it's the registry weight, same as any other action: registry.get("transaction").weight
to tune it, registry.remove("transaction") to disable it.
Build-time configuration
See Building from source for CMake presets (debug, asan-ubsan, tsan) and the Conan cppstd=gnu23 profile requirement.