On this page
- Synopsis
- Top-level flags
- Discovery and selection
- VMM and resources
- Lifecycle
- Output
- Observability
- Subcommands
- provium repl <PROFILE> [--name <NAME>] [--fixture <PATH>]
- provium fixture list
- provium fixture build <PATH>
- provium fixture rebuild <PATH>
- provium fixture clean
- provium fixture stale
- provium list [--fixtures]
- provium lsp-setup [DIR] [--force]
- Exit codes
- Environment variables
- Output shape
- Plain text (default)
- JSON (--json)
- Msgpack events (--events-stdout)
- Filter precedence
- See also
CLI
Provium's CLI surface is the single binary provium. By default it discovers *.test.lua files under the given paths and runs them; subcommands cover REPL, fixture management, and listing.
Synopsis
provium [PATHS]... [FLAGS]
provium repl <PROFILE> [--name <NAME>] [--fixture <PATH>]
provium fixture list
provium fixture build <PATH>
provium fixture rebuild <PATH>
provium fixture clean
provium fixture stale
provium list [--fixtures]
provium lsp-setup [DIR] [--force]
If no paths are given, the current directory is scanned recursively.
Top-level flags
Discovery and selection
| Flag | Type | Default | Description |
|---|---|---|---|
--config <PATH> |
path | provium.toml |
Config file location. |
--filter <STR> |
string | none | Only run files whose test-root-relative path contains this substring. |
--include-slow |
flag | off | Include meta.slow tests (default skips them). |
--tag <TAG> |
string, repeatable | none | Run only tests with one of these tags. OR'd. |
--no-tag <TAG> |
string, repeatable | none | Skip tests with any of these tags. Wins over --tag. |
--tag-meta <KEY=VALUE> |
string, repeatable | none | Run only tests where meta[KEY] contains VALUE. Multi-flag same KEY = OR within key; different KEYs = AND across keys. Useful for filtering on arbitrary fields like subsystems. |
--no-tag-meta <KEY=VALUE> |
string, repeatable | none | Skip tests where meta[KEY] contains VALUE. Same key/value semantics as --tag-meta. Wins over --tag-meta. |
--rerun-failed |
flag | off | Run only files that failed in the last run. Reads from ~/.cache/provium/rerun.json. |
--since <PATH> |
path | none | Run only files whose mtime is newer than this reference file. |
--watch |
flag | off | Re-run on file change (poll every 500 ms). |
VMM and resources
| Flag | Type | Default | Description |
|---|---|---|---|
--vmm <CHOICE> |
qemu / local |
qemu |
VMM backend. local is for dev runs without KVM — does not actually boot a kernel. |
--mem <BYTES> |
size string "4G" |
80 % of host RAM | Pool memory budget. |
--cpus <N> |
int | host online CPUs | Pool vCPU budget. |
--cpu-overcommit <F> |
float | 1.0 |
Multiplier on --cpus. Clamped to [0.5, 8.0]. |
--no-preflight |
flag | off | Skip the startup /dev/kvm / iproute2 / nft / qemu / CAP_NET_ADMIN checks. |
--no-ksm |
flag | off | Skip Kernel Same-page Merging tuning at startup. |
Lifecycle
| Flag | Type | Default | Description |
|---|---|---|---|
--timeout <DUR> |
seconds-int or duration string | 300 (5 min) |
Per-file wall-clock timeout. 0 disables. Accepts "500ms", "30s", "10m", "2h". |
--fail-fast |
flag | off | Stop after the first failed file. |
Output
| Flag | Type | Default | Description |
|---|---|---|---|
-v, --verbose |
flag | off | Show passing tests too. Mutually exclusive with --quiet. |
-q, --quiet |
flag | off | Show only failures. Mutually exclusive with --verbose. |
--json |
flag | off | Line-delimited JSON output, one object per file. Mutually exclusive with --events-stdout. |
Observability
| Flag | Type | Description |
|---|---|---|
--save-events <PATH> |
path | Persist the event stream to PATH as length-prefixed msgpack frames. Compatible with provium-coverage --from PATH. |
--events-stdout |
flag | Emit msgpack event frames on stdout; the human/JSON renderer redirects to stderr. Mutually exclusive with --json. |
--events-socket <PATH> |
path | Multiplex the event stream over a Unix socket. The binary listens, accepts connections, fans out frames. Reused across --watch iterations. |
--coverage |
flag | Pipe the buffered event stream into provium-coverage (must be on PATH) after the run. |
Subcommands
When a subcommand is given, the test-runner mode is suppressed.
provium repl <PROFILE> [--name <NAME>] [--fixture <PATH>]
Boot a VM and drop into an interactive Lua REPL against it.
| Arg / flag | Description |
|---|---|
<PROFILE> |
Profile name from provium.toml. Optional when --fixture is given. |
--name <NAME> |
VM name. Defaults to repl. |
--fixture <PATH> |
Resume from a fixture instead of cold-booting. |
If --fixture is set without a profile arg, the first profile in provium.toml (sorted by name) is used.
provium fixture list
Show every cached entry with size and key.
provium fixture build <PATH>
Force a build for the named fixture (test-root-relative path, no .fixture.lua suffix). If the fixture is already cached, prints already built: <path> and exits.
provium fixture rebuild <PATH>
Evict the existing cache entry and rebuild. Both single-VM (.snap) and lab (.lab/) layouts are evicted.
provium fixture clean
Wipe the entire cache directory.
provium fixture stale
List .fixture.lua files whose source hash (folded with kernel + initrd identifiers and any external host-file deps declared via vm:push_file / lab:depends_on_file) doesn't correspond to any cached entry. Useful for "what would provium rebuild on the next run?"
provium list [--fixtures]
List discovered tests (default) or fixtures (--fixtures) without running anything. Useful for piping into xargs or for CI dry-runs.
provium lsp-setup [DIR] [--force]
Drop Lua Language Server definitions into a test directory so test, provium, wait_until, json, and the rest of the harness globals stop showing up as undefined in your editor.
Writes:
<DIR>/.provium-meta/types.lua—---@metastubs covering the test framework, theTestContext(t:assert_eq,t:fail, …), the rootLab, and thejsonglobal. Less-trafficked methods are typed asany— the goal is silencing diagnostics, not full IDE intellisense.<DIR>/.luarc.json— config pointing the LSP at.provium-meta/.
DIR defaults to the current directory. If .luarc.json already exists, the command refuses to overwrite and prints the snippet to merge in by hand; pass --force to replace it.
Skips pre-flight checks (/dev/kvm, iproute2, nft) so it runs cleanly on machines without test prerequisites — useful from a dev laptop separate from the test host.
After running, reload your editor's Lua server. To extend the types further (e.g. richer completion on a specific userdata you use a lot), edit .provium-meta/types.lua directly.
Exit codes
| Code | Meaning |
|---|---|
0 |
Every file passed (or skipped). |
1 |
At least one file did not finish cleanly (failed test, panicked runner, timed-out file). With --coverage, also reflects the coverage post-run's exit code if it failed. |
2 |
Internal error — config load failure, pre-flight failure, panic in the dispatcher. |
The exit code is intentionally clamped to 0/1/2 rather than reflecting the number of failed files, so shell scripts don't have to worry about overflow at the 256-file mark or accidentally interpret failed_count == 2 as the internal-error sentinel.
Environment variables
| Variable | Effect |
|---|---|
PROVIUM_TEST_FILTER |
JSON object set by the binary at startup carrying --include-slow / --tag / --no-tag / --tag-meta / --no-tag-meta so the runner picks them up. Test code does not set this directly. |
PROVIUM_OVERLAY |
Path to the agent-overlay cpio. Overrides the binary-relative path-walk; lower priority than the per-profile agent_overlay_path config field. Useful for distribution-installed Provium where the overlay isn't co-located with the binary. |
PROVIUM_RERUN_STATE |
Override the path of the rerun-state file (default: ~/.cache/provium/rerun.json, or /tmp/provium-rerun.json if $HOME is unset). |
PROVIUM_COVERAGE_TMP |
Set by --coverage to point at the temp event file the post-run hook will read. Cleared after the hook completes. |
PROVIUM_COVERAGE_USER_FILE |
Set when --coverage reuses an explicit --save-events path so the post-run hook does NOT delete it. |
PROVIUM_COVERAGE_MARKER |
Marker file --coverage uses to recognise its own temp file (vs an externally-set PROVIUM_COVERAGE_TMP pointing at user data). |
HOME |
Used to compute the default rerun-state path. |
PATH |
Searched for qemu-system-x86_64, ip, tc, nft, tcpdump, and (on --coverage) provium-coverage. |
Output shape
Plain text (default)
PASS tests/smoke.test.lua (3 passed, 0 failed, 0 skipped)
FAIL tests/networking/partition.test.lua (2 passed, 1 failed, 0 skipped)
FAIL split-brain
client A could not reach client B after partition
TIME tests/long.test.lua (1 passed, 0 failed, 0 skipped)
3 file(s); 6 passed, 1 failed, 0 skipped; 12.34s
-v adds PASS <name> / SKIP <name> lines for each test. -q suppresses everything except the file-status line for files with failures and the summary.
JSON (--json)
One object per file, line-delimited. Schema:
{
"path": "tests/smoke.test.lua",
"timeout": "in_time",
"passed": true,
"chunk_error": null,
"tests": [
{"name": "boots", "status": "passed", "message": null, "log": []},
{"name": "fails", "status": "failed", "message": "1 ~= 2", "log": []}
]
}
status is one of "passed", "failed", "skipped". timeout is "in_time" or "timed_out".
Msgpack events (--events-stdout)
Length-prefixed msgpack frames, one per EventFrame (see events). When --events-stdout is set, the human-readable / JSON renderer redirects to stderr so consumers piping provium --events-stdout | provium-coverage don't see human text interleaved into their msgpack parser.
Filter precedence
Multiple selection flags compose:
- Discovery: walk
<paths>for*.test.luafiles. --filtersubstring match against test-root-relative path.--rerun-failedintersect with the prior failed set (zero-result clean exit if no prior state).--sincemtime newer than the reference path.- Per-test (within each file):
meta.skip→ instant skip. - Per-test:
meta.slowand--include-slow. - Per-test:
--no-tag(skip if any match). - Per-test:
--tag(run if any match). - Per-test:
--no-tag-meta KEY=VALUE(skip ifmeta[KEY]contains VALUE). - Per-test:
--tag-meta KEY=VALUE(run if all KEYs have at least one matching VALUE).
--watch mode rediscovers from scratch every iteration; --rerun-failed is automatically dropped under --watch so file-edit detection works as expected.
See also
- provium.toml reference — config-file fields.
- Events — wire format of the msgpack event stream.
- Running tests — patterns for the CLI.