test: verify independent guests and recovery on private displays
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
# Graphics and recovery verification
|
||||
|
||||
Run from the checkout. Tools are temporary Nix development dependencies; no
|
||||
persistent host installation is required. The two-guest smoke test needs access
|
||||
to `/dev/kvm` and creates its own headless Wayland display, VM disks and sockets
|
||||
under a fresh `/tmp/hydra-smoke-*` directory. It never uses the inherited display,
|
||||
active TTY, existing guests or existing disks. Evidence remains in that directory;
|
||||
the script stops only its own verified QEMU instances on exit.
|
||||
|
||||
```sh
|
||||
python3 -m unittest discover -s tests -v
|
||||
nix-build dev/tools.nix -A viewer --no-out-link
|
||||
nix-build dev/tools.nix -A qemu --no-out-link
|
||||
nix-shell dev/tools.nix --run 'python3 dev/smoke.py'
|
||||
```
|
||||
|
||||
The smoke test builds a private input helper with an ordinary evdev/pc105 US
|
||||
keyboard map. It boots two tiny counter workloads from separate scratch qcow2
|
||||
disks, connects two fullscreen viewers, and checks reserved switching/recovery,
|
||||
manual USB selection, explicit reconnect and independent QMP lifecycles.
|
||||
Guest memory counters must advance and QEMU PIDs must remain unchanged through
|
||||
switching. Viewer protocol logs must show no reconnection during switching.
|
||||
A test-only `ToggleKeybinds` action and F12 marker establish native labwc
|
||||
keybinding inhibition before checking the production reserved bindings. Those
|
||||
extra controls are absent from the production session configuration. See the
|
||||
[labwc configuration manual](https://labwc.github.io/labwc-config.5.html) for
|
||||
`overrideInhibition` and the [actions manual](https://labwc.github.io/labwc-actions.5.html)
|
||||
for native `ToggleKeybinds` behavior.
|
||||
|
||||
USB acceptance checks the actual selector window title, holds the modifiers
|
||||
through opening, releases them inside the modal dialog, then switches again.
|
||||
QEMU's USB device list must stay unchanged without a selection. Both viewer
|
||||
USB filters deny automatic hotplug and connection redirection. This check does
|
||||
not attach a physical USB device or prove guest driver behavior.
|
||||
|
||||
The viewer adaptation handles only the configured manual USB accelerator before
|
||||
forwarding an event to the guest. Upstream keyboard grabs remove the GTK
|
||||
application accelerator group; without this adaptation, the configured USB
|
||||
shortcut reaches the viewer but does not open its selector.
|
||||
|
||||
## Installed guest workflow
|
||||
|
||||
`--iso` is optional. Attach or detach media only while the VM is stopped:
|
||||
|
||||
```sh
|
||||
bin/hydra add guest --iso /absolute/path/installer.iso
|
||||
bin/hydra start guest
|
||||
bin/hydra view guest
|
||||
# Shut down from inside the guest, then check it is stopped.
|
||||
bin/hydra status guest
|
||||
bin/hydra media guest --detach
|
||||
bin/hydra start guest
|
||||
```
|
||||
|
||||
For an existing stopped guest, `bin/hydra media guest --iso PATH` attaches
|
||||
installation/rescue media. A missing configured ISO prevents a new start with
|
||||
an actionable error; it does not prevent listing profiles, status, stopping a
|
||||
running guest, reconnecting a viewer or detaching the missing media. Media
|
||||
updates share the VM lifecycle lock and preserve its qcow2 disk. Abrupt stopping
|
||||
still requires `bin/hydra stop guest --force` and verified QMP identity.
|
||||
|
||||
## Display preferences and EDID
|
||||
|
||||
New developer profiles use user networking, 1280×800 and `refresh_millihz=0`.
|
||||
Zero omits the patched QEMU refresh property and remains compatible with stock
|
||||
QEMU. Hydra's installed defaults can use this flat `/etc/hydra/defaults.toml`:
|
||||
|
||||
```toml
|
||||
network = "bridge"
|
||||
bridge = "hydrabr0"
|
||||
width = 1920
|
||||
height = 1080
|
||||
refresh_millihz = 144000
|
||||
```
|
||||
|
||||
Only `add` reads distribution defaults. Explicit `--network`, `--bridge`,
|
||||
`--width`, `--height` and `--refresh-millihz` options win; existing profiles do
|
||||
not change. `--defaults PATH` selects another preferences file for development.
|
||||
Missing defaults use developer preferences; unknown or invalid fields fail
|
||||
before creating a profile. Dimensions are integers from 1 to 16384, refresh is
|
||||
an integer from 0 to 1000000 mHz. Nonzero refresh requires the tracked patched
|
||||
QEMU provided by `dev/tools.nix` and distribution packaging.
|
||||
|
||||
The patch keeps the requested refresh through frontend resizing and extends
|
||||
EDID monitor ranges to include the generated preferred mode. To verify the
|
||||
actual patched QEMU generator with the pinned source archive:
|
||||
|
||||
```sh
|
||||
qemu_source=$(nix-build dev/tools.nix -A qemu.src --no-out-link)
|
||||
nix-shell dev/tools.nix --run "python3 dev/check-edid.py '$qemu_source'"
|
||||
```
|
||||
|
||||
The probe applies the tracked patch to four relevant source files in a temporary
|
||||
directory, compiles the actual EDID and virtio GPU generator functions with a
|
||||
small dependency harness, and decodes the result. It checks 60/75 Hz fallback,
|
||||
144 Hz configuration, a conflicting 60 Hz frontend request, resized dimensions,
|
||||
checksums and monitor ranges. At 1920×1080/144000 mHz the preferred timing is
|
||||
143.997231 Hz after EDID clock rounding. This is an advertised guest mode,
|
||||
not measured frame delivery or proof of a 144 Hz physical output.
|
||||
|
||||
## Still requiring a dedicated physical session
|
||||
|
||||
- Physical reserved chords, brightness/backlight permissions and touchpad input.
|
||||
- Physical held keys/modifiers across guest switching, grabs and modal dialogs;
|
||||
guest key-up delivery, pointer grab release and absence of stuck modifiers.
|
||||
- Physical USB selection/redirection and guest drivers; no automatic redirection.
|
||||
- Toolbar behavior at physical screen edges and actual recovery shell usability.
|
||||
- ASUS output selection at 1920×1080/144 Hz, guest-reported display mode, delivered
|
||||
frame rate, hidden guest graphics continuity, tearing and switching latency.
|
||||
|
||||
Headless checks establish CPU workload continuity, protocol focus transitions
|
||||
and the exercised compositor actions. They cannot prove physical input or scanout.
|
||||
Reference in New Issue
Block a user