These docs are under active development and cover the v0.20 Kobicha security model.
On this page
reference 8 min read

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---@meta stubs covering the test framework, the TestContext (t:assert_eq, t:fail, …), the root Lab, and the json global. Less-trafficked methods are typed as any — 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:

  1. Discovery: walk <paths> for *.test.lua files.
  2. --filter substring match against test-root-relative path.
  3. --rerun-failed intersect with the prior failed set (zero-result clean exit if no prior state).
  4. --since mtime newer than the reference path.
  5. Per-test (within each file): meta.skip → instant skip.
  6. Per-test: meta.slow and --include-slow.
  7. Per-test: --no-tag (skip if any match).
  8. Per-test: --tag (run if any match).
  9. Per-test: --no-tag-meta KEY=VALUE (skip if meta[KEY] contains VALUE).
  10. 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