On this page
- Module functions
- provium.create(profile)
- provium.fixture(name)
- provium.shutdown_all()
- provium.pack(fmt, ...)
- provium.unpack(fmt, data)
- VM methods
- vm:boot(opts?)
- vm:exec(cmd)
- vm:json(cmd)
- vm:write_file(path, data)
- vm:read_file(path)
- vm:dmesg(pattern?)
- vm:mount_vfs()
- vm:wait_until(fn, opts?)
- vm:shutdown()
- vm:kill()
- Syscalls
- vm:syscall(nr, arg1, ..., arg6)
- vm:syscall_buf(nr, buf_arg_index, buf_data, arg1, ...)
- vm:syscall_bufs(nr, bufs_table, arg1, ...)
- vm:syscall_ptr(nr, bufs_table, ptrs_table, arg1, ...)
- Ioctls
- vm:ioctl(fd, cmd, data?)
- vm:ioctl_buf(fd, cmd, struct_data, specs)
- Background jobs
- vm:background(cmd)
- vm:job_wait(job, timeout?)
- vm:job_kill(job)
- Workers
- vm:spawn(opts?)
- worker:kill()
- Assertions
- assert(condition, message?)
- assert_eq(expected, actual, message?)
- assert_contains(haystack, needle, message?)
- Sub-tests
- test(name, fn)
- todo(reason?)
Lua API Reference
Module functions
Functions on the global provium table.
provium.create(profile)
Creates a VM from a named profile. Does not boot it.
local vm = provium.create("minimal")
Parameters: profile (string) — profile name from provium.toml.
Returns: VM userdata.
provium.fixture(name)
Resumes a VM from a cached fixture snapshot. Builds the fixture lazily on first call.
local vm = provium.fixture("kacs")
Parameters: name (string) — fixture name (matches fixtures/name.lua).
Returns: VM userdata (booted and ready).
provium.shutdown_all()
Gracefully shuts down all VMs created in the current test.
provium.shutdown_all()
provium.pack(fmt, ...)
Packs values into a binary string. Little-endian byte order.
local data = provium.pack("u32 u32 u64", 1, 42, 0)
Format types: u8, u16, i16, u32, i32, u64, i64
Returns: Binary string.
provium.unpack(fmt, data)
Unpacks values from a binary string.
local a, b = provium.unpack("u32 u32", data)
Returns: One value per format specifier.
VM methods
Methods on VM userdata returned by provium.create() or provium.fixture(). Workers returned by vm:spawn() support the same methods except boot, shutdown, and spawn.
vm:boot(opts?)
Starts the VM. Blocks until the agent is ready.
vm:boot({memory = "1G", cpus = 2})
| Option | Type | Default | Description |
|---|---|---|---|
memory |
string | "512M" |
VM memory ("512M", "1G", "2G") |
cpus |
number | 1 |
Virtual CPUs |
files |
table | nil |
Guest path → host path mapping for file injection |
disks |
table | nil |
Additional block devices: {path, format, readonly} |
vm:exec(cmd)
Runs a shell command. Returns a result table.
local r = vm:exec("uname -r")
Returns: {ok, exit_code, stdout, stderr} — stdout and stderr are string wrappers with .value, .contains(s), .starts_with(s), .trim().
vm:json(cmd)
Runs a command and parses stdout as JSON. Raises an error if the command fails or JSON is invalid.
local data = vm:json("cat /etc/config.json")
Returns: Lua table (nested tables and arrays).
vm:write_file(path, data)
Writes a string to a file in the guest.
vm:write_file("/tmp/test.txt", "hello")
vm:read_file(path)
Reads a file from the guest.
local data = vm:read_file("/etc/hostname")
Returns: File contents as a string.
vm:dmesg(pattern?)
Returns kernel log output. With a pattern, filters through grep.
local log = vm:dmesg("kacs:")
Returns: String.
vm:mount_vfs()
Mounts proc, sysfs, securityfs, and devtmpfs. Idempotent.
vm:mount_vfs()
vm:wait_until(fn, opts?)
Polls a callback until it returns true or timeout expires.
vm:wait_until(function()
return vm:exec("test -f /tmp/ready").ok
end, {timeout = 5, interval = 0.5, desc = "ready"})
| Option | Type | Default | Description |
|---|---|---|---|
timeout |
number | 10 |
Seconds before raising an error |
interval |
number | 0.5 |
Seconds between polls |
desc |
string | "condition" |
Description for timeout error |
vm:shutdown()
Gracefully shuts down the VM. Waits up to 10 seconds, then force-kills.
vm:kill()
Forcefully terminates the QEMU process.
Syscalls
vm:syscall(nr, arg1, ..., arg6)
Executes a raw syscall with up to 6 integer arguments.
local fd = vm:syscall(1000, 0, 0x0008)
Returns: Syscall return value (int64).
vm:syscall_buf(nr, buf_arg_index, buf_data, arg1, ...)
Syscall with one buffer argument. The argument at buf_arg_index is replaced with a pointer to buf_data in guest memory.
local ret = vm:syscall_buf(1003, 0, spec_data, 0, #spec_data)
Returns: Syscall return value.
vm:syscall_bufs(nr, bufs_table, arg1, ...)
Syscall with multiple buffer arguments. bufs_table maps argument indices to buffer data.
local ret, buf1_out, buf2_out = vm:syscall_bufs(1022,
{[1] = path, [3] = sd_data},
-100, 0, 0x07, 0, #sd_data, 0)
Returns: Syscall return value, then output buffers in argument-index order.
vm:syscall_ptr(nr, bufs_table, ptrs_table, arg1, ...)
Syscall with buffer arguments and embedded pointer patching.
local ret, buf_out, ptr_out = vm:syscall_ptr(1023,
{[0] = args_data},
{{buf_idx = 0, ptr_offset = 8, data_len = #sd, data = sd}},
0)
Pointer spec fields: buf_idx, ptr_offset, data_len, output (boolean), data (string).
Returns: Syscall return value, buffer outputs, pointer outputs.
Ioctls
vm:ioctl(fd, cmd, data?)
Executes an ioctl on a guest file descriptor.
local ret, out = vm:ioctl(fd, 0xC0104B00, args)
Returns: Result value, output data (or nil).
vm:ioctl_buf(fd, cmd, struct_data, specs)
Ioctl with embedded buffer pointer patching.
local ret, struct_out, data = vm:ioctl_buf(fd, cmd, args, {
{ptr_offset = 8, buf_len = 256, output = true},
})
Spec fields: ptr_offset, buf_len, output (boolean), data (string).
Returns: Result value, struct output, then output buffers.
Background jobs
vm:background(cmd)
Starts a command in the background.
local job = vm:background("sleep 10")
Returns: {id, pid} table.
vm:job_wait(job, timeout?)
Waits for a background job. Timeout is in seconds (0 = poll).
local r = vm:job_wait(job, 5)
Returns: {exit_code, stdout, stderr, running}.
vm:job_kill(job)
Kills a background job and returns its result.
local r = vm:job_kill(job)
Workers
vm:spawn(opts?)
Forks the guest agent. Returns a worker with the same methods as a VM.
local worker = vm:spawn()
local thread_worker = vm:spawn({thread = true})
| Option | Type | Default | Description |
|---|---|---|---|
thread |
boolean | false |
Use clone(CLONE_THREAD) instead of fork |
Returns: Worker userdata.
worker:kill()
Closes the worker connection. The worker process exits.
Assertions
assert(condition, message?)
Enhanced assert. Raises an error if condition is falsy.
assert_eq(expected, actual, message?)
Equality check. Shows both values on failure.
assert_contains(haystack, needle, message?)
Substring check. Shows the haystack and needle on failure.
Sub-tests
test(name, fn)
Runs a named sub-test with isolated failure handling.
test("my test", function()
assert(true)
end)
todo(reason?)
Marks the current test as not yet implemented (skip, not fail).
test("future work", function()
todo("waiting on feature X")
end)