Files
Nomarchy/docs/TESTING.md
Bernardo Magri 0cd6212b9c
All checks were successful
Check / eval (push) Successful in 3m49s
tools: preview the plymouth splash unprivileged; #137 attempt 1 reverted
Answering "how do I give you root": you don't. tools/plymouth-preview.sh
renders the splash — LUKS dialog included — into X11 windows in ~10s with
no reboot, no root and no DRM:

- unshare -rm = user + mount namespace; every mount dies with it.
- /run/plymouth is BOTH the socket dir and the compiled-in plugin path
  (`strings plymouthd` → /run/plymouth/plugins/), so we bind a writable dir
  over it AND recreate its symlinks — miss those and plymouth can't find
  x11.so, silently skips X11 and reaches for a tty.
- never pass --tty (main.c:2133 takes the X11 path only while default_tty
  is unset); /dev/dri is masked so a preview physically cannot mode-set a
  real output — which matters on a docked session (#127).
- PLY_CREATE_FAKE_MULTI_HEAD_SETUP fakes 800x600 + 640x480 heads.
- debug wants plymouth.debug=stream: — `file:` buffers and yields nothing.

What it proved immediately: with a STABLE two-head canvas the current theme
centres correctly on both heads. So the geometry is fine and #137 really is
the timing bug (positions frozen at parse time vs a canvas that resizes
when a head arrives) — recorded in the item.

And it caught my own fix: hoisting positions into layout() rendered the
background on both heads and nothing else — no logo, no bar — with NO parse
error logged. Reverted rather than shipped, because that script draws the
passphrase box on an encrypted machine. #137 carries the failure, the prime
suspect (plymouth script scope: assignment lands in `local` unless the name
already exists) and the fast edit/render loop for the next attempt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 12:42:31 +01:00

165 lines
8.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Testing Nomarchy
How to verify changes actually work — from cheap eval checks to booting the
full desktop. Adapted from the previous Nomarchy iteration's agent docs.
**The honesty rule (for humans and AI agents alike):** for Waybar, Hyprland,
or any visual change, the only reliable check is booting the live ISO. If
you can't boot it (e.g. you're on macOS or have no KVM), **say so** rather
than claiming success. "All Nix files parse" is not "the bar renders."
## 1. Cheap checks (always do these first)
```sh
nix flake check --no-build # full module-system evaluation, no builds
nix-instantiate --parse <file> # syntax-only, works even on macOS
git ls-files '*.py' | xargs python3 -m py_compile # all tracked Python
bash -n <script>.sh # shell syntax (tools/, installer bits)
```
`nix flake check` needs a Linux machine (or a Linux builder) since all
outputs are `x86_64-linux`. It catches type errors, missing options, and
bad merges — most breakage stops here. It also evaluates the downstream
template through `lib.mkFlake` (including a real nixos-hardware profile),
so template/wrapper drift fails fast too.
## 1b. CI (automatic on push)
Every push to `main`/`v1` runs `.gitea/workflows/check.yml`: the §1
cheap checks (flake eval, Python + shell syntax) on the Gitea instance.
That's the **eval tier only** — the runner is a docker container without
KVM, so the `checks.*` VM suite and real builds stay local (this file)
until a KVM-capable runner is registered; the workflow carries a
commented `vm-checks` job ready for that day. A green CI run is *not* "it
renders" (the honesty rule below still applies) — it means "nobody broke
evaluation".
## 2. Build and boot the live ISO
```sh
# Build + boot in QEMU, one command:
tools/test-live-iso.sh
# Or by hand:
nix build .#nixosConfigurations.nomarchy-live.config.system.build.isoImage
# → result/iso/*.iso — dd it to a USB stick for real hardware
```
The script prefers UEFI (OVMF) with a legacy-BIOS fallback, uses KVM when
`/dev/kvm` is readable, and boots with `virtio-vga-gl` + `gl=on`
**Hyprland (and the desktop session) need real OpenGL in the guest**; without it the
session may not start.
### What the live environment gives you
- Auto-login as `nomarchy` (no password, passwordless sudo), greetd →
Hyprland via `initial_session`; logging out lands on tuigreet.
- The flake is seeded writable at `~/.nomarchy` (from the read-only
`/etc/nomarchy` copy) — `$NOMARCHY_PATH` already points there.
- Locked flake inputs are pinned into the ISO store, so a
`home-manager switch` for the **already-active / default theme** works
**without a network**. Switching to an arbitrary other preset can still
need downloads (that preset's HM generation is not in the pin) — the
tool should fail with an offline-oriented message (#113).
## 3. Verification checklist
Work through these in order; each one exercises a different layer.
| # | Check | Verifies |
|---|---|---|
| 1 | Boots to Hyprland with the default theme wallpaper visible (Boreal) | greetd autologin, awww, session start |
| 2 | Waybar shows at top, themed (blue accent on dark) | HM waybar module, palette baking |
| 3 | `SUPER+Return` opens Kitty with the default theme colors (Boreal) | terminal default, ANSI palette |
| 4 | `btop` in the terminal is themed | per-theme asset baking |
| 5 | `nomarchy-state-sync list` prints 24 presets | package, baked themes dir |
| 6 | `nomarchy-state-sync apply boreal` (or re-apply the **current** theme) offline → switch succeeds. Applying a *different* preset may need a network — the ISO pins the default theme's generation, not every preset (#113) | state write + offline rebuild contract |
| 7 | `SUPER+SHIFT+T` cycles wallpapers instantly (try `tokyo-night` for 4, or `boreal` for its set) | the runtime wallpaper path |
| 8 | `nomarchy-state-sync apply summer-night` → after the switch the bar has its own identity (light bar, different styling) | whole-swap waybar.css assets |
| 9 | Open a GTK app — dark theme matching the palette | Stylix layer |
| 10 | `home-manager generations` lists one generation per theme change; activating an older one rolls the theme back | atomicity / rollback story |
Items 6 and 8 are the big ones — they prove the all-Home-Manager theming
model end to end.
## 4. Testing the installer
One command runs the whole offline regression:
```sh
tools/test-install.sh
```
It builds the ISO, boots it in QEMU **with networking disabled**, runs an
unattended LUKS+swap install onto a blank disk via the installer's
`NOMARCHY_UNATTENDED=1` mode (config delivered on a small vfat disk —
typing long commands into a guest drops keystrokes), waits for the
installer's poweroff, then boots the installed disk, enters the
passphrase, and screenshots the first boot. The machine-checkable parts
(install completes, disk boots) fail the script; the visual verdict —
**themed desktop, no autogenerated-config banner, no login prompt** — is
yours, from `first-boot.png`. The helpers it builds on live in
`tools/vm/` (QMP key injection, GL-safe VNC screenshots) and work for any
manual VM poking; `tools/vm/gap-analysis.py` is the maintainer tool for
diagnosing offline installs that try to build from source.
To test by hand instead, replicate what `tools/test-install.sh` does: the
unattended env it uses is in the script, and the same flow works
interactively from the live terminal. If the desktop comes up unthemed,
read `/var/log/nomarchy-hm-preactivate.log` on the installed system.
`tools/plymouth-preview.sh` renders the **boot splash** — including the LUKS
password dialog — into X11 windows in about ten seconds: no reboot, no root,
and no DRM. It runs plymouthd inside `unshare -rm` (a user + mount namespace),
binds a writable dir over `/run/plymouth` (which is both the daemon's socket
dir *and* its compiled-in plugin path), masks `/dev/dri` so a preview can never
mode-set a real output, and sets `PLY_CREATE_FAKE_MULTI_HEAD_SETUP` for plymouth's
built-in fake dual head. Pass it a theme store path to iterate on the script
without a rebuild. Use it before touching `modules/nixos/plymouth/`: that script
draws the passphrase box, a failure there is silent (the plugin logs
`starting boot animation` and no error), and "type your LUKS password blind" is
a bad way to find out. Its limit: the fake heads exist from the start, so it
cannot reproduce a head arriving *mid-splash* (#137).
Two full-desktop VM harnesses (softGL Hyprland, too heavy for `checks.*`)
live next to the scripts: `tools/theme-shot.nix` (themed-desktop
screenshots) and `tools/monitor-fallback.nix` (KVM display transitions:
atomic dock handoff, internal-first undock, and low-level lid-inhibitor
lifecycle). The latter restores the DRM output before deleting QEMU's final
synthetic headless output; physical cable-removal timing is a V3 check because
Hyprland's headless backend otherwise aborts in a VM-only zero-output state.
## 5. VM-specific gotchas
- **No KVM** (e.g. nested without acceleration): everything works but
`home-manager switch` will be painfully slow. Don't read slowness as
breakage.
- **Black screen / session exits**: almost always missing guest GL. Use the
script's qemu flags; on real hardware check `journalctl -b -u greetd`.
- **Tiny resolution**: the live config forces `monitor = ,highres,auto,1`;
if QEMU still picks 1024×768, resize the window — Hyprland follows.
- **Display menu + QEMU**: System Display mode list is sorted by **pixel
area** (highest first). After a pick, the toast shows hyprctls reported
size. In a **fixed-size** QEMU/viewer window, a higher guest mode still
*looks* smaller (more pixels in the same window) — that is viewer scaling,
not an inverted apply. Trust hyprctl / the toast numbers.
- **First theme switch is the slowest**: it evaluates the flake on a RAM
disk. Subsequent switches reuse the eval cache.
- **Menu geometry does not survive the guest**: the rofi picker draws with
icons at roughly a quarter of `ui.iconSize` and rows short enough that a
6-row root clips its last entry behind a scrollbar (`lines = 8` should
fit it). Menu screenshots are evidence for **which rows appear**, never
for spacing, icon size or label truncation — measure text against the
40% window width instead, or check on hardware (BACKLOG #132).
## 6. When something fails
- Session/login problems: `journalctl -b -u greetd`, then `journalctl
--user -b`.
- Theme switch failures: run `nomarchy-state-sync apply <x>` from a
terminal — the home-manager output streams there. The state file is
written *before* the rebuild, so after fixing you can just re-run
`home-manager switch --flake ~/.nomarchy`.
- Report results faithfully: what booted, what rendered, what you could
not verify and why.