The GitHub Actions workflow has two microVM test layers on Azure-hosted
self-hosted KVM, MSHV, and WHP virtual machines. Each backend has a pool of
three runners labeled by operating system, backend, and virtual-machine.
Jobs target the shared backend labels so any available matching runner can
execute them. This allows the backend lanes to execute concurrently without
binding a workload to a specific host. openvmm-vmm-tests builds its Xen PVH
probe entirely from the OpenVMM checkout and exercises OpenVMM lifecycle,
TTRPC, and snapshot contracts without restoring NVX guest artifacts.
openvmm-unit-tests runs the OpenVMM unit and documentation tests independently
on the same backend matrix.
The nvx-microvm-tests-{kvm,mshv,whp} jobs consume the NVX Linux kernel and
Alpine initramfs and exercise Linux, SMP, virtio, sandbox, and snapshot behavior
through the public OpenVMM CLI. Failure logs from the NVX layer are uploaded per
backend.
The restore-processor scenario also rejects Linux TSC instability diagnostics,
even if the requested CPUs came online, so clock skew cannot silently pass by
falling back to a different clocksource.
The restore-tsc-sync scenario repeats the 1/2/4/8-CPU restore sequence with
the test-only kernel option clearcpuid=tsc_adjust. Linux normally skips its
cross-CPU TSC warp test when IA32_TSC_ADJUST is available and consistent
within a package. This scenario verifies that the feature is masked, forcing
the live CPU-online check even on those hosts, while retaining the existing
TSC-instability guard. It does not force a fallback clocksource or retry failed
restores. Its logs are kept in a separate restore-tsc-sync subdirectory.
Run it alone on Windows with:
python scripts\nvx.py test-microvm --backend whp --scenario restore-tsc-syncThis regression targets the WHP clock instability tracked in #19; a passing frozen-counter check is not sufficient to validate a fix.
The console-exit scenario delays host console reads for two seconds after
snapshot restore to exercise output backpressure. For each requested processor
count it requires byte-exact delivery of a 64 KiB payload and the final marker,
and preserves guest exit statuses 0 and 37. This checks both device and host-relay
draining without adding sleeps to the measured benchmark workloads.
The harness waits for the output reader's EOF notification even after the
process exits, so delayed final output chunks cannot create a false failure.
Shared guest artifacts are built with Docker on a GitHub-hosted Ubuntu runner.
OpenVMM release executables and provenance are built once by the independently
addressable build-openvmm-linux-gnu, build-openvmm-linux-musl, and
build-openvmm-windows-msvc producer jobs. KVM workloads and MSHV microVM tests
consume the GNU artifact, MSHV platform workloads consume the musl artifact,
and WHP workloads consume the Windows MSVC artifact. Each workload can start
after its compatible OpenVMM producer and the shared guest-artifact job finish,
without waiting for unrelated OpenVMM targets.
The producer handoff uses one-day workflow artifacts rather than caches. Each
consumer downloads both the normalized executable and its build provenance,
then restores executable permissions on Linux. Once the required artifacts are
ready, benchmarks run in parallel with the NVX test layer and use any available
runner in the matching backend pool. All three use virtual-machine performance
series and the constrained eight-CPU affinity policy. Development releases and
performance baseline updates still require every applicable test and benchmark
lane to pass. The workflow uses the read-only OpenVMM deploy key stored in the
OPENVMM_DEPLOY_KEY Actions secret to fetch the private submodule at its pinned
commit. Shared guest binaries and development release packages move through
short-lived workflow artifacts alongside the OpenVMM handoff and benchmark
results. Caches only accelerate reproducible build inputs and outputs; consumers
do not depend on them as a handoff.
Pull requests gate regressions against recent matching-platform history, and
successful pushes to dev append their p50 values under data/. Metadata-only
performance jobs use GitHub-hosted Ubuntu runners. Provisioning instructions
are in the runner bootstrap guide.
Persistent runners accept pushes and same-repository pull requests only. Fork pull requests run the GitHub-hosted validation jobs but do not execute code on the Azure runner fleet. A maintainer must stage an external contribution on a trusted repository branch before running the backend matrices.