Under the hood
Testing the whole system in a VM
wolvm boots the ISO, goes through the installer and drives the installed desktop, step by step.
On this page
What it is
wolvm does for the whole operating system what a browser test runner does for a web page: boot the ISO, click through the installer, restart into the installed disk, open apps, take snapshots and collect the journal.
Why
A fixed script says pass or fail. To find out why a screen is black, a person or an agent needs to act, look and decide the next step, with pictures and logs from the same machine. A release is only published after its ISO passed this.
How
This page is for people who build or test WolOS. The command reference is in the wolos-iso repository (tests/README-wolvm.md).
Reference
What a browser test runner gives a web app (open the page, click, wait for text, screenshot,
read the console), wolvm gives the whole OS: boot the ISO, go through the installer, reboot
into the installed disk, log in, open apps, collect the journal. Code and command reference:
wolos-iso/tests/wolvm/wolvm and wolos-iso/tests/README-wolvm.md. Decision: ADR 0029 (one
build path; an ISO is released only after its VM test passed). What it drives in this repository:
the installer (crates/shell/src/ui/installer.rs, crates/controller/src/install.rs), first boot
and the desktop as shipped.
Why
- One step at a time. The fixed scripts (
tests/test-installer.sh,tests/test-install.sh) pass or fail as a whole. To find out why a screen is black or a button does nothing, an agent needs to act, look, and decide the next action, the way a person sits at the VM. - Pixels and facts together. A screenshot says what a person sees; the journal,
systemctl --failedand/proc/cmdlinesay why. wolvm gives both, from the same VM, at any step. - Retry without starting over. A whole-VM snapshot (RAM, disk, UEFI vars, TPM) taken before a risky step takes about 4 s to restore, so an agent tries another path instead of re-booting and re-installing (minutes).
- No special image. The released ISO is tested as it ships. Everything wolvm needs from the
guest is already there: systemd-boot reads extra kernel words from SMBIOS, systemd reads
credentials from SMBIOS, and
qemu-guest-agentis in the package list.
How it works
| Piece | Mechanism |
|---|---|
| VM | QEMU q35 + OVMF, KVM when /dev/kvm is usable, daemonized; one dir per VM in $WOLVM_HOME/vms/NAME (vm.json config, run.json state) |
| Disks | disk.qcow2 and the UEFI vars as vars.qcow2: every writable image supports internal snapshots. Test disks (--drive, raw, never converted: their bytes are compared afterwards), the ISO as a USB-stick-like disk (--iso-bus virtio), offline (--no-net) |
| Secure Boot on/off | set --secureboot on|off flips SecureBootEnable in the vars with virt-fw-vars (keys stay): install with enforcement off, boot with it on |
| Screen | QMP screendump (PNG; PPM + a stdlib PNG writer as fallback). The pointer moves 1 px and back first, so a compositor that only flushes damage repaints |
| Keyboard, pointer | QMP send-key (qcodes, US layout for type), input-send-event absolute moves on a usb-tablet for click |
| Serial | console=ttyS0 via SMBIOS type 11 io.systemd.boot.kernel-cmdline-extra (live and installed); a socket chardev with a log file; wait-text reads the log since the last start |
| Shell in the guest | the QEMU guest agent (guest-exec, root, output captured); with --ssh, sshd with a per-VM key passed as the credential ssh.authorized_keys.root; ssh-open starts sshd and opens port 22 for that boot (the image ships both closed) |
| Snapshots | running: HMP savevm/loadvm (whole VM, swtpm state included); stopped: qemu-img snapshot on disk and vars |
| Journeys | YAML subset or JSON list of steps; a screenshot after each; journey.jsonl; report.md + index.html |
| TPM, Secure Boot | swtpm per VM (--tpm); --secureboot = OVMF secboot code + Microsoft/Red Hat keys enrolled with virt-fw-vars (SMBIOS cmdline extras are ignored then: use the agent) |
| MOK screens | mok-esp.sh (signed shim + an unenrolled loader) and journeys/mok-screen.yaml: shim's Security Violation box, then MokManager; firmware text also lands on the serial console |
| Unattended | --append "wolos.autoinstall=/dev/vda ..." (files/usr/lib/wolos/autoinstall); with --direct the ISO's kernel boots with exactly our cmdline |
The journey, boot to apps
- Boot the ISO.
wolvm new w --iso wolos.iso --tpm && wolvm start w.wolvm wait-text w "Welcome to"(systemd on the serial console),wolvm wait-agent w,wolvm wait-stable w,wolvm screenshot w now.png. - Drive the installer. Read the screenshot, act (
key tab,key ret,click X Y,type "name"),wait-stable, screenshot again.snapshot savebefore the disk page. Ask the installer what it did:wolvm ssh w 'journalctl -b -t wol-installer -n 50'. Or unattended:--direct --append "wolos.autoinstall=/dev/vda wolos.autologin=yes"andwait-text "wolos-install: done". - Reboot into the installed disk. After the power-off:
wolvm set w --boot disk(oreject+ reboot from the guest),wolvm start w. The installed system boots from its own ESP; the SMBIOS console words still apply, so serial and agent work there too. - Unlock and log in. Screenshot: the unlock or login screen;
typethe passphrase or password andkey ret. Check:wolvm ssh w 'loginctl list-sessions'. - Open apps.
key super/ the search bar,type terminal,key ret; screenshot; check withwolvm ssh w 'pgrep -a wol-'. - Collect.
wolvm logs w -n 1000 -o journal.txt,wolvm ssh w 'systemctl --failed',wolvm report DIRfor a person.
A path that works goes into a journey file (tests/wolvm/journeys/*.yaml) so the next run is
wolvm journey w FILE and a report.
How an agent reads a screen and picks the next key
- Take the screenshot after
wait-stable; open it with the Read tool (the image is shown). - Say what is there: the page title, which control has the focus ring, dialogs, error text.
- Pick the smallest action that moves forward: Enter on the focused default button; Tab to move focus; a click on a button centre read off the image (wolvm clicks in image pixels).
- Screenshot again and compare: if nothing changed, the action was wrong or the app is busy (check the journal before trying again). Restore the snapshot rather than stacking guesses.
- Text in a picture is not proof of state: confirm with a command in the guest when it matters
(disk layout:
lsblk -f; boot entries:bootctl list; session:loginctl).
Limits
- Runs on Linux hosts with QEMU (the forge); from Windows go through
forge.sh runandscp. typeknows the US layout only; the guest keyboard layout must be US while typing.virtio-glscreendumps can fail ("no surface"); wolvm fails then rather than return an old frame.- With Secure Boot on, no serial console unless the image's own entry has one.
- v0.11.5's ISO is not signed, so under Secure Boot the firmware refuses it before any WolOS code runs; the MOK path is exercised with the signed shim on a prepared disk instead.
Reference synced from wonderlandos/wolos docs/modules/vm-e2e.md.