From 7a313a96ee78a92f330b4e3c3b1d506e808c9f5f Mon Sep 17 00:00:00 2001 From: Rick Peters Date: Thu, 1 Oct 2026 21:03:20 +0200 Subject: [PATCH] tests: nvidia suite (fake NVIDIA PC), controller block, name-based menu rows; get-iso.sh uses CachyOS's own mirror and resumes; notes --- TESTPLAN.md | 29 +++++++++++ get-iso.sh | 6 ++- nvidia/TODO.md | 18 +++++++ scripts/vmprogress.sh | 6 +-- scripts/vmsuite.sh | 2 +- scripts/vmtest.sh | 4 +- share/vmtest/cli/60-c1-controllers.sh | 19 +++++++ share/vmtest/hw/40-h3-bios-dry-run.sh | 5 +- share/vmtest/menu/10-r1-menu.sh | 9 +++- share/vmtest/nvidia/10-n1-menu.sh | 18 +++++++ .../vmtest/nvidia/20-n2-n5-lifecycle.host.sh | 51 +++++++++++++++++++ share/vmtest/prelude.sh | 24 ++++++++- 12 files changed, 178 insertions(+), 13 deletions(-) create mode 100644 share/vmtest/cli/60-c1-controllers.sh create mode 100644 share/vmtest/nvidia/10-n1-menu.sh create mode 100644 share/vmtest/nvidia/20-n2-n5-lifecycle.host.sh diff --git a/TESTPLAN.md b/TESTPLAN.md index 940cfa4..80d01a0 100644 --- a/TESTPLAN.md +++ b/TESTPLAN.md @@ -64,6 +64,34 @@ change only shows right after Enter). ## F. Features per release +### F2.9.7 Gaming on NVIDIA (`feature/nvidia-gaming-fix`; suite `nvidia`, fake NVIDIA PC) + +gamescope's session is broken on NVIDIA (see `nvidia/HARDWARE-RESULTS.md`), so on an NVIDIA PC the conversion is replaced by +"Gaming on NVIDIA" (Steam on the Plasma desktop, started at login, optionally in Big Picture) and single user mode logs in to Plasma. +The VM has no NVIDIA GPU: `fake_nvidia` (`share/vmtest/prelude.sh`) fakes one through Steamify's `NVIDIA_DRM_DIR` test hook and installs +fake NVIDIA modules for every kernel. What no VM can show (real driver, the picture, Big Picture on a real GPU) is checked on the real PC. + +| # | Step | Expect | +|---|---|---| +| N1 | `--defaults --list` and `--backend status` with the fake GPU (`nvidia/10-n1-menu.sh`) | `nvidia`, `bigpicture` (parent `nvidia`), `single` offered and preselected; `gaming`, `boot`, `glyphs` hidden; without the fake GPU the conversion is offered and `nvidia` is not | +| N2 | `--defaults --options nvidia,bigpicture,single` (`nvidia/20-n2-n5-lifecycle.host.sh`) | exit 0; Steam installed; unit with `-gamepadui` enabled; `loginMode=emptySession`; parameters in `/etc/default/limine` and `/boot/limine.conf`; early-load file, hook and script; modules in the initramfs; SDDM enabled and `zzz-steamify-autologin.conf` (Plasma session) | +| N3 | reboot | Plasma straight in (no greeter), parameters on `/proc/cmdline`, the Steam unit started, `loginMode` kept | +| N4 | `--defaults --options notify` | exit 0; Steam removed (Steamify installed it), unit and autologin file gone, `loginMode` back to not set, parameters/early-load/hook gone, plasma-login-manager the login manager again | +| N5 | reboot | Plasma up through the test autologin, no NVIDIA parameters | +| N6 | real RTX 5080 PC | **done by hand 2026-10-01** (earlier prototype): Big Picture on the Plasma desktop smooth and clean; the apply/boot of the final component is the user's next step | + +### F2.9.7 Extended controller support (`feature/extended-controller-support`; suite `cli`, block `60-c1-controllers.sh`) + +Opt-in item: `xpadneo-dkms`, `xone-dkms` and `xone-dongle-firmware` from the CachyOS repo, DKMS-built for every kernel. The VM has no +dongle or controller: it covers the packages, the headers and the builds, not the hardware. + +| # | Step | Expect | +|---|---|---| +| C1 | `--defaults --options extended_controller_support` | exit 0; the three packages installed; `dkms status` shows xone and xpadneo installed for every kernel; the modules (`xone_dongle`, `hid_xpadneo`) exist for each | +| C2 | the same again | quiet, nothing installed again | +| C3 | `--defaults --options notify` | exit 0; the three packages removed again | +| C4 | real PC with the Xbox dongle | **by hand, 2026-10-01 earlier**: the dongle works with the AUR `xone-dkms-git` (modules `xone_dongle`, `xone_gip_gamepad` loaded); status counts `xone-dkms-git` as on | + ### F2.7.0 `--defaults --options` / `--boot` | # | Step | Expect | @@ -143,3 +171,4 @@ and started with `--fremont`. Automated: `scripts/vmtest.sh` (see the vm-install | 2026-09-29 | ISO `feat/steamify` + PR #3 (`/var/log`), dev `main` with the B1 boot entry check | B1-B8 | Limine 43 / GRUB 42 pass (boot entry check passes: `Limine`, `cachyos`). systemd-boot (reinstalled): 36 pass, 8 fail, all CEC: the driver download got HTTP 429 from GitHub (rate limit); boot entry check passes (`Linux Boot Manager`); `/var/log/steamify-install.log` and `steamify-bootentry.log` readable after boot | | 2026-09-29 | Steamify `release/2.9.1` (CEC driver cache), ISO `feat/steamify` (PRs #2, #3), dev `main` | everything automated incl. hw block 50 (CEC cache) and the B1 boot entry check | **341 pass, 0 fail** in 19 minutes (toggles 42 +1 expected skip, hw 77, cli 55, menu 36, installer 4, Limine 43, systemd-boot 42, GRUB 42) | | 2026-09-30 | Steamify 2.9.6 (`steamify-cachyos` main `d93f9ea`), the official ISO `steamify-cachyos-2.9.6-260930-x86_64.iso` from git.upriser.nl (sha256 `4a94f308…aec41`), dev `main`; on the PC, headless (`CI=1`/`VM_HEADLESS=1`), `MAX_PARALLEL=5` | everything automated: B1-B8 (3 loaders, `--install` from the new ISO), cli, menu, hw, installer, toggles (base VM from the same ISO with `VM_STEAMIFY=skip`) | **341 pass, 0 fail** (toggles 42 +1 expected skip, hw 77, cli 55, menu 36, installer 4, Limine 43, systemd-boot 42, GRUB 42). Found on the way (test setup, not Steamify or the ISO): with five VMs at once the loaders' first boot took longer than `waitssh` waited (5 min), so all three stopped with `FAIL no SSH` although the VMs were up; `waitssh` now waits up to 15 minutes and the loaders were run again (install kept) | +| 2026-10-01 | Steamify `feature/extended-controller-support` (7dae14c; on top of `feature/nvidia-gaming-fix` d0e4d8c, 2.9.7), plain CachyOS ISO 260809 (VM `~/vms/steamify-vm`, `vminstall.sh --iso`), dev `main` + the nvidia suite; on the PC (native CachyOS, KVM), headless | N1-N5 (new suite `nvidia`), C1-C3 (cli block 60), R1.1-R1.6/R1.10, H1-H5 and the CEC/CEC cache blocks, R2.1, toggles | **269 pass, 0 fail**: cli 65, nvidia 43, menu 37, hw 78, installer 4, toggles 42. Found on the way (test side, not Steamify): R1.1 and H3 pressed menu rows by number and the new Extended controller support row shifted them (now by name); the N4 check for the parameter in `/boot/limine.conf` must ignore snapper's snapshot entries, which keep the command line of their time. The kernel part (parameters, early-load file, hook, initramfs) behaves in a real Limine VM; the real driver and picture are only checked on the RTX 5080 PC | diff --git a/get-iso.sh b/get-iso.sh index a5282a2..c5639cc 100755 --- a/get-iso.sh +++ b/get-iso.sh @@ -4,7 +4,8 @@ set -euo pipefail cd "$(dirname "$0")" -mirror="${MIRROR:-https://nl.mirror.cx/cachyos}" +# CachyOS's own mirror: nl.mirror.cx gave about 1 MB/s here, this one 80 MB/s (MIRROR=... to use another). +mirror="${MIRROR:-https://mirror.cachyos.org}" # The download page embeds the current ISO URL; take the release from it. release="$(curl -fsL https://cachyos.org/download/ | @@ -22,8 +23,9 @@ if [[ -f cachyos.iso && "$(cat cachyos.iso.version 2>/dev/null)" != "$name" ]]; rm -f cachyos.iso fi -curl -fL -C - -o cachyos.iso "$url" +# The version is written before the download: a partial file of this release is resumed, not deleted as "an older release". echo "$name" > cachyos.iso.version +curl -fL -C - -o cachyos.iso "$url" echo "Verifying checksum..." curl -fsL "$url.sha256" | awk '{print $1" cachyos.iso"}' | sha256sum -c diff --git a/nvidia/TODO.md b/nvidia/TODO.md index 72ae893..6e7dff5 100644 --- a/nvidia/TODO.md +++ b/nvidia/TODO.md @@ -1,3 +1,21 @@ +# TODO: NVIDIA (status 2026-10-01, evening: READ THIS FIRST, the sections below are the older plan) + +The kernel-parameter fix did not cure gamescope's picture; the cause is NVIDIA's own bug (see `HARDWARE-RESULTS.md`). The product now does this +instead (branch `feature/nvidia-gaming-fix`, 2.9.7, still behind `.no-release-yet`): +- On an NVIDIA PC the SteamOS conversion (`gaming`, `boot`, `glyphs`) is hidden (shown only while already on, so it can be turned off). +- `nvidia` "Gaming on NVIDIA": Steam installed when missing, started at login on the Plasma desktop (user unit); sub-option `bigpicture` + (a checkbox, not yet the choice row "How should Steam start up: Normal / Big Picture"): `-gamepadui` + Plasma starts with an empty session. + RTX 20+ also keeps the old kernel parameters and early-load initramfs (user asked for it: "it may need it"). +- `single` (single user mode) also works there: its own SDDM autologin into the Plasma session (`zzz-steamify-autologin.conf`). +- Tested in VMs (QEMU/KVM, fake NVIDIA GPU through `NVIDIA_DRM_DIR`, fake modules): suite `nvidia`, TESTPLAN N1-N5, 43 pass; regression suites green. +- Tested by hand on the RTX 5080 (earlier prototypes): Big Picture in the normal Plasma session smooth and clean; autologin and the final component NOT yet run there. +Open: run the final wizard on the RTX 5080 PC (turn the conversion off, tick Gaming on NVIDIA + Single user mode, reboot); the real choice row +instead of the checkbox (the choice row is hard-wired to `boot` in the TUI, the app and `--boot`); games don't start fullscreen under Plasma +(idea: a KWin rule forcing fullscreen for `steam_app_*`, may bring the direct-scanout artifacts back: test on the PC); apps that start later +(CachyOS Hello) may still cover Big Picture; hint in the menu on why the item is missing while the conversion is on; changelog hashes; +screenshot retake and the ISO's installer page for the new rows before a release. Separate branch `feature/extended-controller-support` +(xone dongle + xpadneo, opt-in) is stacked on this one. + # TODO: NVIDIA fix for gaming mode Product code: branch `feature/nvidia-gaming-fix` in steamify-cachyos (github.com/theupriser/steamify-cachyos). These notes live here, in diff --git a/scripts/vmprogress.sh b/scripts/vmprogress.sh index ddd89ed..8bf5b01 100755 --- a/scripts/vmprogress.sh +++ b/scripts/vmprogress.sh @@ -1,15 +1,15 @@ #!/bin/bash # Progress of test jobs, one line per change (for a monitor; see the progress-report skill). -# scripts/vmprogress.sh [--once] [job...] jobs: limine systemd-boot grub limine-generic systemd-boot-generic grub-generic cli menu hw installer toggles (default all) +# scripts/vmprogress.sh [--once] [job...] jobs: limine systemd-boot grub limine-generic systemd-boot-generic grub-generic cli menu hw installer toggles nvidia (default all) # Per job (only a new step, a finished job or a FAIL counts as a change): state (install NN% / / done / -), checks passed/expected, failed. # Line: "HH:MM total P/E F failed ;; job | state | P/E | F failed ;; ...". Prints nothing while nothing # changes (checked every 30 s), "ALLDONE" and exits once every started job has its summary line. # Expected counts: the last complete run of each (AGENTS.md "State"); update them when checks are added. set -uo pipefail -declare -A expect=([limine]=43 [systemd-boot]=42 [grub]=42 [cli]=55 [menu]=36 [hw]=77 [installer]=4 [toggles]=42 [limine-generic]=25 [systemd-boot-generic]=25 [grub-generic]=25) +declare -A expect=([limine]=43 [systemd-boot]=42 [grub]=42 [cli]=65 [menu]=37 [hw]=78 [installer]=4 [toggles]=42 [nvidia]=43 [limine-generic]=25 [systemd-boot-generic]=25 [grub-generic]=25) once=false; jobs=() for a in "$@"; do [[ "$a" == --once ]] && once=true || jobs+=("$a"); done -[[ ${#jobs[@]} -gt 0 ]] || jobs=(limine systemd-boot grub limine-generic systemd-boot-generic grub-generic cli menu hw installer toggles) +[[ ${#jobs[@]} -gt 0 ]] || jobs=(limine systemd-boot grub limine-generic systemd-boot-generic grub-generic cli menu hw installer toggles nvidia) vms="$HOME/vms" status() { # status : "state|pass|fail|finished(0/1)|started(0/1)" diff --git a/scripts/vmsuite.sh b/scripts/vmsuite.sh index 94fc0a4..1fa7aa0 100755 --- a/scripts/vmsuite.sh +++ b/scripts/vmsuite.sh @@ -32,7 +32,7 @@ suite="${1:?usage: $0 [--window] | --prepare}" [[ "${2:-}" == --window ]] || export VM_HEADLESS=1 dir="$repo/share/vmtest/$suite" [[ -d "$dir" ]] || { echo "No suite $suite (folders in share/vmtest/)" >&2; exit 2; } -case "$suite" in cli) port=2301 ;; menu) port=2302 ;; hw) port=2303 ;; installer) port=2304 ;; toggles) port=2305 ;; *) port=2390 ;; esac +case "$suite" in cli) port=2301 ;; menu) port=2302 ;; hw) port=2303 ;; installer) port=2304 ;; toggles) port=2305 ;; nvidia) port=2306 ;; *) port=2390 ;; esac export VM_PORT="${VM_PORT:-$port}" export VM_DIR="$HOME/vms/run-$suite" export REPO="${REPO:-$repo/../steamify-cachyos}" diff --git a/scripts/vmtest.sh b/scripts/vmtest.sh index cff4a02..8de7126 100755 --- a/scripts/vmtest.sh +++ b/scripts/vmtest.sh @@ -6,7 +6,7 @@ # boot the boot loader test (limine, systemd-boot, grub), or name loaders # generic the plain-PC install check for every loader (vmbootloadertest.sh --quick --generic: a PC that is not a # Steam Machine must get no Steam Machine items and no DKMS modules); part of the default run -# cli, menu, hw, installer, toggles (folders in share/vmtest/) +# cli, menu, hw, installer, toggles, nvidia (folders in share/vmtest/) # --install install the boot loader VMs first from the newest Steamify ISO (asks before replacing a disk) # --window show the VMs' windows (default: headless; one shared Konsole follows ~/vms/test.log) # MAX_PARALLEL=3 (env) VMs at once (5 worked on a 9800X3D / 64 GB); the slowest suites start first @@ -42,7 +42,7 @@ if $screen; then fi if [[ ${#loaders[@]} -eq 0 && ${#suites[@]} -eq 0 ]] && ! $want_boot && ! $want_generic; then want_boot=true; want_generic=true - for d in cli menu hw installer toggles; do [[ -d "$repo/share/vmtest/$d" ]] && suites+=("$d"); done + for d in cli menu hw installer toggles nvidia; do [[ -d "$repo/share/vmtest/$d" ]] && suites+=("$d"); done fi # What the ISO advertises: the boot loaders calamares-online.sh keeps. advertised="$(sed -n 's/.*"bootloader:\([^"]*\)".*/\1/p' "$iso_repo/archiso/airootfs/usr/local/bin/calamares-online.sh" 2>/dev/null | head -n 1)" diff --git a/share/vmtest/cli/60-c1-controllers.sh b/share/vmtest/cli/60-c1-controllers.sh new file mode 100644 index 0000000..f602300 --- /dev/null +++ b/share/vmtest/cli/60-c1-controllers.sh @@ -0,0 +1,19 @@ +# C1-C3: extended controller support: the repo's DKMS drivers (xone + dongle firmware, xpadneo) are installed and built for every +# installed kernel; a second run is quiet; turning it off removes them again. The VM has no dongle or controller: this covers +# the packages, the headers and the DKMS builds, not the hardware. Covers TESTPLAN C1 (on), C2 (again), C3 (off). +info "applying extended_controller_support (kernel headers and DKMS builds for every kernel: a few minutes)..." +sf --defaults --options extended_controller_support > /tmp/c1.log; rc=$? +[[ $rc -eq 0 ]] && pass "C1 exit 0" || { fail "C1 exit $rc: $(tail -n 12 /tmp/c1.log)"; exit 0; } +pacman -Q xpadneo-dkms xone-dongle-firmware >/dev/null 2>&1 && pacman -Q xone-dkms >/dev/null 2>&1 && pass "C1 xpadneo-dkms, xone-dkms and xone-dongle-firmware are installed" || fail "C1 packages: $(pacman -Qq | grep -E 'xone|xpadneo' | tr '\n' ' ')" +expect_on extended_controller_support +for kd in /usr/lib/modules/*/; do + k="$(basename "$kd")"; [[ -d "$kd/kernel" ]] || continue + n="$(dkms status -k "$k" 2>/dev/null | grep -E 'xone|xpadneo' | grep -c installed)" + [[ "$n" -ge 2 ]] && pass "C1 $k: DKMS built xone and xpadneo ($n modules installed)" || fail "C1 $k: DKMS: $(dkms status -k "$k" 2>&1 | tr '\n' ';')" + modinfo -k "$k" xone_dongle >/dev/null 2>&1 && modinfo -k "$k" hid_xpadneo >/dev/null 2>&1 && pass "C1 $k: xone_dongle and hid_xpadneo modules exist" || fail "C1 $k: modules missing" +done +sf --defaults --options extended_controller_support | grep -qiE 'nothing|already|exit: 0' && pass "C2 a second run is quiet" || info "C2 second run: $(sf --defaults --options extended_controller_support | tail -n 3)" +sf --defaults --options notify > /tmp/c3.log; rc=$? +[[ $rc -eq 0 ]] && pass "C3 turn-off exit 0" || fail "C3 exit $rc: $(tail -n 8 /tmp/c3.log)" +pacman -Q xpadneo-dkms xone-dkms xone-dongle-firmware >/dev/null 2>&1 && fail "C3 packages are still installed" || pass "C3 the three packages are removed again" +expect_off extended_controller_support diff --git a/share/vmtest/hw/40-h3-bios-dry-run.sh b/share/vmtest/hw/40-h3-bios-dry-run.sh index 08bdbd2..1c3b271 100755 --- a/share/vmtest/hw/40-h3-bios-dry-run.sh +++ b/share/vmtest/hw/40-h3-bios-dry-run.sh @@ -1,5 +1,8 @@ # H3: BIOS update, the whole flow with WIZARD_BIOS_DRY_RUN=1 (never flashes). The VM reports an older BIOS. # env: BIOS_VERSION=F7F0107 -out=$(printf '11\n\ny\ny\nUPDATE\nm\nq\nn\n' | WIZARD_BIOS_DRY_RUN=1 bash /mnt/steamify.sh 2>&1 | sed 's/\x1b\[[0-9;]*m//g') +# The BIOS row's number by its name (a new menu item shifts the numbers). +n=$(printf 'q\n' | bash /mnt/steamify.sh 2>&1 | sed 's/\x1b\[[0-9;]*m//g' | sed -n 's/^ *\([0-9][0-9]*\) .*Update BIOS.*/\1/p' | head -n 1) +[[ -n "$n" ]] && pass "H3 Update BIOS is menu row $n" || { fail "H3 no Update BIOS row in the menu"; exit 0; } +out=$(printf "$n\n\ny\ny\nUPDATE\nm\nq\nn\n" | WIZARD_BIOS_DRY_RUN=1 bash /mnt/steamify.sh 2>&1 | sed 's/\x1b\[[0-9;]*m//g') grep -qi "dry run" <<< "$out" && pass "H3 the dry run went through" || fail "H3 no dry-run message: $(tail -n 3 <<< "$out" | tr '\n' ' ' | cut -c1-160)" grep -q '^\[ERROR\]' <<< "$out" && fail "H3 errors: $(grep -B4 -m1 '^\[ERROR\]' <<< "$out" | tr '\n' '|' | cut -c1-400)" || pass "H3 no errors" diff --git a/share/vmtest/menu/10-r1-menu.sh b/share/vmtest/menu/10-r1-menu.sh index eaefd7a..191a618 100755 --- a/share/vmtest/menu/10-r1-menu.sh +++ b/share/vmtest/menu/10-r1-menu.sh @@ -2,8 +2,13 @@ menu() { printf "$1" | bash /mnt/steamify.sh 2>&1 | sed 's/\x1b\[[0-9;]*m//g'; } # R1.1: first-run ticks: everything but Boot into desktop and BIOS out=$(menu 'q\n') -for n in 1 3 4 5 6 7 8 9 10; do grep -qE "^ +$n +[a-z-]+ +\[x\]" <<< "$out" && pass "R1.1 row $n ticked" || fail "R1.1 row $n not ticked"; done -grep -qE "^ +11 .*\[ \]" <<< "$out" && pass "R1.1 Update BIOS not ticked" || fail "R1.1 Update BIOS ticked" +# By name, not by row number (a new item shifts the numbers): the ticked ones, then the ones that are shown but never preselected. +for item in "SteamOS conversion" "SteamOS theme" "Steam Deck/Machine icons" "Single user mode" "Steamify shortcut" "Update notifications" "HDMI-CEC" "Steam Machine support" "Power-off fix"; do + grep -qE "^ +[0-9]+ +[a-z-]+ +\[x\] .*$item" <<< "$out" && pass "R1.1 $item ticked" || fail "R1.1 $item not ticked" +done +for item in "Extended controller support" "Update BIOS"; do + grep -qE "^ +[0-9]+ +[a-z-]+ +\[ \] .*$item" <<< "$out" && pass "R1.1 $item shown, not ticked" || fail "R1.1 $item missing or ticked" +done grep -q "Boot into: \[gamescope\]" <<< "$out" && pass "R1.1 boots into gamescope by default" || fail "R1.1 boot default is not gamescope" # R1.2: everything OK, back in the menu with all on info "applying Steamify (installs packages, builds kernel modules: a few minutes)..." diff --git a/share/vmtest/nvidia/10-n1-menu.sh b/share/vmtest/nvidia/10-n1-menu.sh new file mode 100644 index 0000000..d2bbf7c --- /dev/null +++ b/share/vmtest/nvidia/10-n1-menu.sh @@ -0,0 +1,18 @@ +# N1: an NVIDIA PC (fake GPU): the menu hides the SteamOS conversion and its gamescope options, shows Gaming on NVIDIA, its +# Big Picture option and Single user mode. Covers TESTPLAN N1. +fake_nvidia +out="$(sf --defaults --list)" +ids="$(python3 -c 'import json,sys; d=json.load(sys.stdin); print(" ".join(sorted(i["id"] for i in d)))' <<< "$out" 2>/dev/null)" +[[ -n "$ids" ]] && pass "N1 --defaults --list is valid JSON: $ids" || { fail "N1 --defaults --list is not JSON: $(echo "$out" | head -c 300)"; exit 0; } +for i in nvidia bigpicture single; do [[ " $ids " == *" $i "* ]] && pass "N1 $i is offered" || fail "N1 $i is missing"; done +for i in gaming boot glyphs; do [[ " $ids " == *" $i "* ]] && fail "N1 $i is offered on an NVIDIA PC" || pass "N1 $i is hidden"; done +python3 -c ' +import json,sys +d={i["id"]:i for i in json.load(sys.stdin)} +ok = d["bigpicture"]["parent"]=="nvidia" and d["nvidia"]["on"] and d["bigpicture"]["on"] and d["single"]["on"] +sys.exit(0 if ok else 1)' <<< "$out" && pass "N1 Big Picture is a sub-option of Gaming on NVIDIA, all three preselected" || fail "N1 parent or preselection wrong" +st="$(sf --backend status)" +python3 -c 'import json,sys; d=json.load(sys.stdin); ids=[i["id"] for i in d.get("items",d)]; sys.exit(1 if "gaming" in ids else 0)' <<< "$st" 2>/dev/null && pass "N1 --backend status (the app) has no conversion row" || fail "N1 --backend status lists the conversion" +# Without a NVIDIA GPU nothing changes: the conversion is offered, Gaming on NVIDIA is not. +out2="$(NVIDIA_DRM_DIR=/nonexistent sf --defaults --list)" +python3 -c 'import json,sys; ids=[i["id"] for i in json.load(sys.stdin)]; sys.exit(0 if "gaming" in ids and "nvidia" not in ids and "bigpicture" not in ids else 1)' <<< "$out2" && pass "N1 no NVIDIA GPU: the conversion is offered, Gaming on NVIDIA is not" || fail "N1 no-NVIDIA menu wrong" diff --git a/share/vmtest/nvidia/20-n2-n5-lifecycle.host.sh b/share/vmtest/nvidia/20-n2-n5-lifecycle.host.sh new file mode 100644 index 0000000..cc2b837 --- /dev/null +++ b/share/vmtest/nvidia/20-n2-n5-lifecycle.host.sh @@ -0,0 +1,51 @@ +# N2-N5: Gaming on NVIDIA + Big Picture + Single user mode on a fake NVIDIA PC, for real: pacman installs Steam, the SDDM autologin, +# the boot loader files and the initramfs, then a reboot into Plasma, then everything off again and a second reboot. +# Covers TESTPLAN N2 (apply), N3 (after the reboot), N4 (turn off), N5 (after the second reboot). +unit='~/.config/systemd/user/steamify-steam-autostart.service' +g() { guest "$@"; } +yes_() { [[ "$(g "$1 && echo YES || echo NO" | tail -n 1)" == YES ]]; } # a guest condition +info "N2 applying nvidia,bigpicture,single (Steam, SDDM, initramfs: several minutes)..." +rc="$(g 'fake_nvidia; sf --defaults --options nvidia,bigpicture,single > /tmp/n2.log; echo "rc=$?"' | tail -n 1)" +[[ "$rc" == rc=0 ]] && pass "N2 apply exit 0" || { fail "N2 apply: $rc: $(g 'tail -n 15 /tmp/n2.log')"; return 0 2>/dev/null || exit 0; } +yes_ 'pacman -Q steam >/dev/null 2>&1' && pass "N2 Steam is installed" || fail "N2 Steam missing" +yes_ "grep -qx 'ExecStart=/usr/bin/steam -gamepadui' $unit" && pass "N2 the autostart unit starts Steam with -gamepadui" || fail "N2 unit: $(g "cat $unit")" +yes_ 'systemctl --user is-enabled -q steamify-steam-autostart.service' && pass "N2 the unit is enabled" || fail "N2 unit not enabled" +[[ "$(g 'kreadconfig6 --file ksmserverrc --group General --key loginMode' | tail -n 1)" == emptySession ]] && pass "N2 Plasma starts with an empty session" || fail "N2 loginMode" +g 'is nvidia && is bigpicture && echo ON' | grep -qx ON && pass "N2 nvidia and bigpicture report on" || fail "N2 status functions" +yes_ "grep -q 'nvidia-drm.modeset=1 nvidia-drm.fbdev=1' /etc/default/limine" && pass "N2 the kernel parameters are in /etc/default/limine" || fail "N2 limine defaults" +yes_ "sudo grep -q 'nvidia-drm.fbdev=1' /boot/limine.conf" && pass "N2 and in the generated /boot/limine.conf" || fail "N2 limine.conf" +yes_ 'test -f /etc/mkinitcpio.conf.d/90-steamify-nvidia.conf && test -x /usr/local/libexec/steamify-nvidia-initramfs && test -f /etc/pacman.d/hooks/85-steamify-nvidia-initramfs.hook' && pass "N2 early-load file, hook and its script installed" || fail "N2 initramfs files" +yes_ 'sudo find /boot -name "initramfs*" -exec sh -c "lsinitcpio {} | grep -q nvidia" \; -print | grep -q .' && pass "N2 the NVIDIA modules are in the initramfs" || fail "N2 initramfs has no nvidia modules" +yes_ 'systemctl is-enabled -q sddm.service' && pass "N2 SDDM is the login manager" || fail "N2 sddm not enabled" +yes_ "grep -qx 'Session=plasma.desktop' /etc/sddm.conf.d/zzz-steamify-autologin.conf && grep -qx \"User=\$USER\" /etc/sddm.conf.d/zzz-steamify-autologin.conf" && pass "N2 SDDM autologin: the user into the Plasma session" || fail "N2 autologin file: $(g 'cat /etc/sddm.conf.d/zzz-steamify-autologin.conf')" +yes_ 'is single' && pass "N2 single user mode is on" || fail "N2 single not on" +g 'fake_nvidia; sf --defaults --options nvidia,bigpicture,single | tail -n 3' | grep -qiE 'nothing|already|exit: 0' && pass "N2 a second run is quiet" || info "N2 second run: $(g 'fake_nvidia; sf --defaults --options nvidia,bigpicture,single | tail -n 3')" + +reboot_guest && pass "N3 the VM is back after the reboot" || { fail "N3 no ssh after the reboot"; return 0 2>/dev/null || exit 0; } +up=""; for _ in $(seq 40); do vm_ssh "pgrep -u $VM_USER -x plasmashell" >/dev/null 2>&1 && { up=1; break; }; sleep 3; done +[[ -n "$up" ]] && pass "N3 Plasma straight after the boot (SDDM autologin, no greeter)" || fail "N3 no plasmashell after the reboot" +yes_ '! pgrep -x sddm-greeter >/dev/null' && pass "N3 no greeter running" || fail "N3 sddm-greeter is running" +yes_ 'grep -q "nvidia-drm.modeset=1" /proc/cmdline && grep -q "nvidia-drm.fbdev=1" /proc/cmdline' && pass "N3 the kernel parameters are on the running command line" || fail "N3 cmdline: $(g 'cat /proc/cmdline')" +yes_ 'systemctl is-active -q sddm.service' && pass "N3 sddm is the running display manager" || fail "N3 sddm not active" +yes_ 'journalctl --user -b --no-pager -u steamify-steam-autostart.service | grep -qiE "Started|Starting"' && pass "N3 the Steam autostart unit was started at login" || fail "N3 unit never started: $(g 'systemctl --user status steamify-steam-autostart.service 2>&1 | head -n 8')" +[[ "$(g 'kreadconfig6 --file ksmserverrc --group General --key loginMode' | tail -n 1)" == emptySession ]] && pass "N3 the empty session setting survived" || fail "N3 loginMode after the reboot" + +info "N4 turning everything off (only notify stays)..." +rc="$(g 'fake_nvidia; sf --defaults --options notify > /tmp/n4.log; echo "rc=$?"' | tail -n 1)" +[[ "$rc" == rc=0 ]] && pass "N4 turn-off exit 0" || { fail "N4 turn-off: $rc: $(g 'tail -n 15 /tmp/n4.log')"; return 0 2>/dev/null || exit 0; } +yes_ '! pacman -Q steam >/dev/null 2>&1' && pass "N4 Steam is removed again (Steamify installed it)" || fail "N4 Steam is still installed" +yes_ "! test -e $unit" && pass "N4 the autostart unit is gone" || fail "N4 unit still there" +[[ -z "$(g 'kreadconfig6 --file ksmserverrc --group General --key loginMode' | tail -n 1)" ]] && pass "N4 loginMode is back to not set" || fail "N4 loginMode: $(g 'kreadconfig6 --file ksmserverrc --group General --key loginMode')" +yes_ '! grep -q nvidia-drm /etc/default/limine' && pass "N4 the kernel parameters are gone from /etc/default/limine" || fail "N4 limine defaults still have them" +# Snapshot entries (snapper's, rootflags=.../.snapshots/N/snapshot) keep the command line of their time: a snapshot of the state with the +# parameters is meant to boot that state. Only the current boot entries count. +yes_ "! sudo grep 'cmdline:' /boot/limine.conf | grep -v '\.snapshots/' | grep -q nvidia-drm" && pass "N4 and from the current entries in /boot/limine.conf (snapshot entries keep their old command line)" || fail "N4 limine.conf still has them: $(g "sudo grep 'cmdline:' /boot/limine.conf | grep -v '\.snapshots/' | cut -c1-150" | tr '\n' '|')" +yes_ '! test -e /etc/mkinitcpio.conf.d/90-steamify-nvidia.conf && ! test -e /usr/local/libexec/steamify-nvidia-initramfs && ! test -e /etc/pacman.d/hooks/85-steamify-nvidia-initramfs.hook' && pass "N4 early-load file, hook and script removed" || fail "N4 initramfs files remain" +yes_ '! test -e /etc/sddm.conf.d/zzz-steamify-autologin.conf' && pass "N4 the SDDM autologin file is gone" || fail "N4 autologin file remains" +yes_ 'systemctl is-enabled -q plasmalogin.service && ! systemctl is-enabled -q sddm.service' && pass "N4 plasma-login-manager is the login manager again" || fail "N4 login manager: $(g 'systemctl show -p Id --value display-manager')" +yes_ '! is nvidia && ! is bigpicture && ! is single' && pass "N4 nvidia, bigpicture and single report off" || fail "N4 status still on" + +reboot_guest && pass "N5 the VM is back after the second reboot" || { fail "N5 no ssh after the second reboot"; return 0 2>/dev/null || exit 0; } +up=""; for _ in $(seq 40); do vm_ssh "pgrep -u $VM_USER -x plasmashell" >/dev/null 2>&1 && { up=1; break; }; sleep 3; done +[[ -n "$up" ]] && pass "N5 Plasma comes up (the test autologin of plasma-login-manager)" || fail "N5 no plasmashell after the second reboot" +yes_ '! grep -q "nvidia-drm" /proc/cmdline' && pass "N5 the kernel parameters are off the command line" || fail "N5 cmdline still has them" diff --git a/share/vmtest/prelude.sh b/share/vmtest/prelude.sh index 8652339..30adf76 100644 --- a/share/vmtest/prelude.sh +++ b/share/vmtest/prelude.sh @@ -6,7 +6,7 @@ pass() { echo "PASS $*"; }; fail() { echo "FAIL $*"; }; skip() { echo "SKIP $*"; sudo mountpoint -q /mnt || sudo mount -t 9p -o trans=virtio,version=9p2000.L repo /mnt cd /mnt || exit 1 export SCRIPT_DIR=/mnt # steamify.sh sets it; the libs alone read patches/ and services/ from it -for lib in common state packages login-manager single-user steam-desktop steam-machine fremont-poweroff vram-booster hdmi-refresh cec boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut steam-game update-notifier; do +for lib in common state packages login-manager single-user steam-desktop steam-machine fremont-poweroff vram-booster hdmi-refresh nvidia controllers cec boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut steam-game update-notifier; do # shellcheck source=/dev/null . "lib/$lib.sh" 2>/dev/null done @@ -15,4 +15,24 @@ sf() { bash /mnt/steamify.sh "$@" < /dev/null 2>&1 | sed 's/\x1b\[[0-9;]*m//g'; is() { "${1}_status" 2>/dev/null; } expect_on() { local i; for i in "$@"; do is "$i" && pass "$i is on" || fail "$i is off"; done; } expect_off() { local i; for i in "$@"; do is "$i" && fail "$i is on" || pass "$i is off"; done; } -ticks() { local i; for i in gaming theme glyphs single launcher notify vram cec machine poweroff boot; do is "$i" && printf '%s ' "$i"; done; echo; } +ticks() { local i; for i in gaming nvidia bigpicture theme glyphs single launcher notify vram cec machine poweroff boot; do is "$i" && printf '%s ' "$i"; done; echo; } +# fake_nvidia: an NVIDIA PC for the nvidia suite. A fake RTX 5080 in a fake DRM tree (NVIDIA_DRM_DIR is Steamify's test hook, exported +# here: call it in every guest command that runs the wizard) and fake NVIDIA modules for every installed kernel (renamed copies of a +# tiny module, then depmod), so `modinfo nvidia_drm` finds one and the initramfs build has modules to put in. +fake_nvidia() { + local d=/var/tmp/fake-drm k kd src ext m + mkdir -p "$d/card1/device" + echo 0x10de > "$d/card1/device/vendor"; echo 0x030000 > "$d/card1/device/class"; echo 0x2c02 > "$d/card1/device/device" + for kd in /usr/lib/modules/*/; do + k="$(basename "$kd")" + [[ -d "$kd/kernel" ]] || continue + src="$(find "$kd/kernel" -name 'dummy.ko*' | head -n 1)" + [[ -n "$src" ]] || { echo "no dummy module for $k"; continue; } + ext="${src##*dummy.ko}" + for m in nvidia nvidia-modeset nvidia-uvm nvidia-drm; do + [[ -e "$kd/kernel/drivers/video/$m.ko$ext" ]] || sudo install -Dm644 "$src" "$kd/kernel/drivers/video/$m.ko$ext" + done + sudo depmod -a "$k" + done + export NVIDIA_DRM_DIR="$d" +}