Expand description
cargo ktstr export — package a registered test as a self-extracting
.run file that reproduces the scenario on bare metal without a VM.
export_test is the entry point invoked from the test binary’s
#[ctor] dispatch (see
crate::test_support::dispatch::maybe_dispatch_export) when
cargo ktstr export exec’s the binary with
--ktstr-export-test=NAME. The export pipeline locates the named
test in the KTSTR_TESTS distributed slice, gathers the
binaries it needs (the running test binary itself via
current_exe(), the scheduler binary, and per-test include
files), tarballs them with gzip, and emits a single shell script:
#!/bin/bash
... preamble: root check, prereq check, sched_ext conflict check,
topology check, arg parsing, mktemp+trap, archive extract,
scheduler launch, test run ...
__ARCHIVE__
<base64-encoded gzipped tarball>The result is chmod +x so the operator can ./repro.run
directly on a target host. ktstr run --ktstr-test-fn <name> is
the same dispatch the in-guest test harness already uses
(test_support::eval invokes it after VM boot), so the bare-metal
path reuses every existing test entry — no separate registry, no
rebuilt scenarios.
§Why bare-metal repro?
The framework’s primary execution path runs every test inside a
KVM VM. That gets us deterministic topology, fast spin-up, and
kernel/scheduler isolation; it also abstracts away from real
hardware. When a test fails on bare metal but passes in the VM
(or vice versa) the operator wants to bisect. A self-contained
.run file means they can hand the failing test to any host with
a compatible kernel and topology, run it without re-building the
workspace, and capture the output through ordinary stdout/stderr
channels.
§Out of scope
host_onlytests: they orchestrate cargo invocations and nested VMs themselves; running them outside the framework’s harness isn’t useful.bpf_map_writetests: they need the framework’s runtime probe-based map-write surface, not yet replicated outside the VM dispatch.KernelBuiltinschedulers: they activate via shell commands (enable/disableslots on the spec) rather than launching a userspace binary. The preamble doesn’t generate those commands in v1; export rejects the variant with an actionable error.
§Include-file directories
The framework’s full include-file resolver (re-exported as
crate::cli::resolve_include_files) walks directories
recursively and produces an archive_path/host_path map that
preserves directory structure. Export uses a simpler subset:
every included entry must be a regular file, and the archive
layout flattens by basename to include/<basename>. Directory
specs error with EISDIR. Recursive directory packaging is a v2
enhancement.
§Bash-only
The preamble’s heredoc shebang names /bin/bash and uses
features bash carries — indexed-array syntax
(RUN_ARGS=(...), ${RUN_ARGS[@]} expansion) and
set -o pipefail (the o-form syntax). Bourne / dash /
busybox sh would mis-parse the script; the operator must run
on a host with bash installed.
Functions§
- export_
test - Build a self-extracting
.runfile for the given test.