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.
Failed openvmm-vmm-tests jobs upload Petri's test_results directory,
including guest and VMM logs, screenshots, and watchdog inspection data.
These seven-day artifacts are named
openvmm-vmm-tests-<os>-<backend>-<run-id>-<run-attempt>, so a successful rerun
does not replace the failed attempt's diagnostics. Linux collects them from
openvmm/target/vmm_tests/test_results; Windows uses
<runner-temp>/<backend>/test_results.
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.
The separate
adversarial.yml workflow runs
Copilot-driven campaigns only on trusted manual dispatches or schedules from
dev. It is not part of pull-request CI. The workflow's dedicated
nvx-adversarial-controller runner must already have an authenticated Copilot
CLI and an administrator-owned executor wrapper named by the
NVX_ADVERSARIAL_EXECUTOR repository variable. The workflow does not install
Copilot or initiate login.
The wrapper provisions a distinct disposable KVM, MSHV, or WHP target with no production or GitHub credentials and forwards only the typed executor protocol. Existing persistent microVM and performance runners are not valid adversarial targets. Loss of the target heartbeat, a policy oracle, or a teardown/post-campaign boot failure fails the job and requires quarantine and reimage.
Normal Actions artifacts contain only the guest-text-free public summary, catalogued case identifiers, and replay manifest. The external provisioner must collect controller transcripts and complete target logs into access-controlled security storage. See Copilot-driven adversarial testing for the architecture and operational contract.