Compare commits

..
Author SHA1 Message Date
theupriser 3d005b3412 Add headless UI toggle smoke test
Sync git.upriser.nl mirror / sync (push) Skipped
2026-10-05 11:35:01 +02:00
theupriser dd24eadad7 Add backend VM suite: Go and bash event streams must match 2026-10-05 11:16:38 +02:00
theupriser f5b3a54435 test: golden record.sh stops the apply stream after the plan event 2026-10-05 10:10:04 +02:00
theupriser 2659009a49 test: golden status and plan output of the bash backend in a bubblewrap sandbox 2026-10-05 09:58:23 +02:00
theupriser 2ac2b0d5ca docs: steamify-branch-cleanup: a released release/X.Y.Z branch is deleted once a tag or main contains it
Sync git.upriser.nl mirror / sync (push) Skipped
2026-10-02 14:41:40 +02:00
theupriser b3a58cf62c docs: CHANGELOG 0.5.0: the full test run, the ISO pipeline, tests moved here, the 2.11.0 test results
Sync git.upriser.nl mirror / sync (push) Skipped
2026-10-02 14:06:35 +02:00
theupriser 66ec27d4e2 test: vmstate reports Steam's autostart entry (silent/plain/none) instead of the old unit
Sync git.upriser.nl mirror / sync (push) Skipped
2026-10-02 09:28:05 +02:00
theupriser 899e9af06c test: the Steamify unit tests and the NVIDIA hardware test move here from steamify-cachyos (REPO points at the checkout)
Sync git.upriser.nl mirror / sync (push) Skipped
2026-10-02 07:53:25 +02:00
theupriser 660558ab45 notes: Steamify 2.10.0
Sync git.upriser.nl mirror / sync (push) Skipped
2026-10-01 21:05:27 +02:00
theupriser 5d168ea44f tests: nvidia suite (fake NVIDIA PC), controller block, name-based menu rows; get-iso.sh uses CachyOS's own mirror and resumes; notes
Sync git.upriser.nl mirror / sync (push) Skipped
2026-10-01 21:03:20 +02:00
theupriser fa67d65a96 nvidia: Plasma session with Big Picture autostart works
Sync git.upriser.nl mirror / sync (push) Skipped
2026-10-01 18:33:24 +02:00
theupriser cbd6920b96 nvidia: TTY-only KWin stutters, Big Picture in Plasma is perfect
Sync git.upriser.nl mirror / sync (push) Skipped
2026-10-01 18:26:25 +02:00
theupriser 74c859ef8d nvidia: direct scanout confirmed as the cause, a Plasma-less KWin session works
Sync git.upriser.nl mirror / sync (push) Skipped
2026-10-01 18:11:32 +02:00
theupriser 0052566ace nvidia: results of the hardware test on the RTX 5080 PC
Sync git.upriser.nl mirror / sync (push) Skipped
2026-10-01 18:02:17 +02:00
theupriser d045b82bae docs: nvidia/: TODO, research and test instructions for the NVIDIA fix (moved here from the steamify-cachyos branch); AGENTS.md: feature notes live in this repo
Sync git.upriser.nl mirror / sync (push) Skipped
2026-10-01 15:38:51 +02:00
theupriser 51c4fac70d docs: the ISO repo's PRs and vmisobuild.sh target master (feat/steamify is gone)
Sync git.upriser.nl mirror / sync (push) Skipped
2026-10-01 15:36:34 +02:00
theupriser 343ff1edda feat: vmtest.sh runs the plain-PC install check (generic) for every loader; vmprogress.sh knows the new jobs
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 14:47:40 +02:00
theupriser cb390c2dc0 docs: TESTPLAN results: the official 2.9.6 ISO, 341 pass, 0 fail
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 14:45:20 +02:00
theupriser b2eb003cc6 fix: the waitssh comment broke the one-line function (syntax error)
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 14:38:34 +02:00
theupriser d1dc96f29e fix: vmbootloadertest.sh waits up to 15 minutes for the first ssh (a first boot is slow with five VMs at once)
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 14:38:19 +02:00
theupriser d948227c19 docs: MAX_PARALLEL=5 ran fine on the 9800X3D (TODO R2 done, comments)
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 13:47:52 +02:00
theupriser 4824004215 docs: TODO: CI tests dropped (they run locally), the quick install test, new open items
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 13:46:43 +02:00
theupriser a1f8089c7c docs: the steamify-iso-release skill: dispatch-started build, steamify_ref, build badge and its secrets, replaced tags, parallel jobs on the runner
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 13:04:08 +02:00
theupriser d82d0f8b2f docs: the steamify-iso-release skill: daily names, kind input, replacement and retention, sync by workflow, always master
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 11:37:14 +02:00
theupriser 540139b967 feat: show progress while the tests run (install and steamify.sh heartbeats, unbuffered output)
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 10:51:24 +02:00
theupriser e929444399 fix: vminstall.sh is headless in CI (no display for QEMU's GTK window)
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 10:30:01 +02:00
theupriser 459832c3f5 feat: vmbootloadertest.sh --quick [--generic]: a Steam Machine gets all its items and modules, a plain PC none
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 10:12:35 +02:00
theupriser f6c87fddc7 fix: vmbootloadertest.sh --quick installs on a VM that reports Steam Machine hardware
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 10:11:00 +02:00
theupriser 913a8f0830 fix: vminstall.sh: show the QEMU, serial and install logs when the install fails
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 10:07:43 +02:00
theupriser 232c92fcd7 fix: vminstall.sh removes the read-only ISO files it extracted (failed as a non-root host)
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 09:50:28 +02:00
theupriser 092e888c3f fix: the VM's ssh key is looked up at every call (a clean host failed the first-boot check: common.sh was sourced before the key existed)
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 09:43:05 +02:00
theupriser fafa38fbb4 feat: vmbootloadertest.sh --quick: only what the ISO's install must get right (B1-B5)
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 09:38:30 +02:00
theupriser 6c0c80fb9a fix: a test that aborts fails (exit status of the piped block), vminstall reads the ISO with bsdtar (no loop partitions in CI containers)
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 09:02:16 +02:00
theupriser 80f4d68536 ci: sync the git.upriser.nl mirror on every branch and tag
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 08:54:35 +02:00
theupriser 594ce35cf8 feat: VM_INSTALL_MEM sets the RAM of the installer VM only
Sync git.upriser.nl mirror / sync (push) Skipped
2026-09-30 08:25:07 +02:00
theupriser 17ae88a4ad feat(ci): sync the git.upriser.nl mirror on every push to main and every tag
Sync git.upriser.nl mirror / sync (push) Skipped
GitHub workflow calls the mirror-sync API so the Gitea build starts at once instead of at the mirror's 10 minute interval (secrets GIT_UPRISER_URL, GIT_UPRISER_TOKEN; retried; skipped on Gitea itself). The steamify-iso-release skill uses the renamed secret and workflows.
2026-09-30 08:11:24 +02:00
theupriser a9f20d69bf docs: rename the local ISO checkout to steamify-cachyos-live-iso
- scripts and skills use ../steamify-cachyos-live-iso
- TODO item 4: the ISO comes from the git.upriser.nl release
2026-09-30 07:47:37 +02:00
theupriser 9a351ae639 docs: use the renamed steamify-cachyos-live-iso repo in vmtest-remote.sh and TODO
- vmtest-remote.sh: name the ISO repo checkout steamify-cachyos-live-iso
- TODO.md: gh run download points at theupriser/steamify-cachyos-live-iso
2026-09-30 07:45:35 +02:00
theupriser 0d0279bd20 docs: skills and AGENTS.md after 2026-09-29: the ISO release pipeline (new skill), boot entry check and install gotchas, monitor rules, freeing WSL disk, deleting merged branches 2026-09-29 23:05:29 +02:00
theupriser 195518f0da docs: wsl-build-host: a hand-built ISO is named local (releases come from a GitHub tag) 2026-09-29 22:19:51 +02:00
theupriser 0447f35e7d fix: boot check: the power-off fix is loaded, or was tried at boot and refused (journal); it grepped dmesg for systemd's error, which only sometimes lands there 2026-09-29 20:17:27 +02:00
theupriser d614539d9e docs: full run with Steamify release/2.9.1: 341 pass; the CEC driver cache done 2026-09-29 19:46:08 +02:00
theupriser 847b024803 fix: test prelude sets SCRIPT_DIR (the libs read patches/ from it); hw block 50 checks every run for errors 2026-09-29 19:24:25 +02:00
theupriser 8df2e23314 fix: hw block 50: the private cache folder is readable like /var/cache/steamify (mktemp's 700 hid it from the user) 2026-09-29 19:22:16 +02:00
theupriser e6119ca194 feat: hw block 50: the CEC driver cache (new pin downloads and removes the old file, cache hit, damaged file replaced), offline via file:// 2026-09-29 19:19:52 +02:00
theupriser 6aad17f55c feat: the VMs share the host's cache for Steamify's own downloads (/var/cache/steamify: the CEC driver once for every VM, GitHub rate-limits it) 2026-09-29 19:16:45 +02:00
theupriser e8c57827b1 docs: B1 boot entry check and the ISO's /var/log fix done; CEC driver download (GitHub 429) as the next item 2026-09-29 19:09:16 +02:00
theupriser 4209f9625b docs: TODO: WSL starting with Windows is not Steamify's work (removed R1d) 2026-09-29 18:58:10 +02:00
theupriser 07a7da1d67 docs: TODO: R1d (WSL with Windows) left for now 2026-09-29 18:57:57 +02:00
theupriser a34efb0547 fix: vminstall.sh stops waiting as soon as the live system reports a failed install (it waited 90 minutes) 2026-09-29 18:48:27 +02:00
theupriser 20373c9f05 fix: vmprogress.sh reports a failed install (it stayed at 'install' for 18 minutes) 2026-09-29 18:48:14 +02:00
theupriser 27b7445f63 feat: B1 check: booted through the loader's own EFI boot entry (BootCurrent, a real partition), after every reboot in the boot loader test 2026-09-29 18:13:16 +02:00
theupriser a82053d6bc docs: the first full run on the PC (328 pass, 18 min): TESTPLAN, TODO, AGENTS, wsl-build-host; vmsuite.sh writes its summary into its log 2026-09-29 18:05:10 +02:00
theupriser 37d65fc79d fix: vmprogress.sh: only a new step, a finished job or a FAIL is a change (not every PASS) 2026-09-29 17:50:41 +02:00
theupriser 5b867f8bd2 docs: progress-report: a stopped local command leaves its remote loop running (known_hosts during an install) 2026-09-29 17:31:35 +02:00
theupriser e583494aa6 fix: vmprogress.sh: a new install percentage alone is no change (one line per stage) 2026-09-29 17:23:42 +02:00
theupriser fd9ecf4b9f feat: progress-report skill and scripts/vmprogress.sh (a status line per change); referenced from the other skills and AGENTS.md 2026-09-29 17:07:52 +02:00
theupriser 4cc4046716 feat: vmview.py: a window with a headless VM's screen (QMP screendump every 2 s, view only) 2026-09-29 17:05:17 +02:00
theupriser 9d537406bb fix: vminstall.sh sets up the ISO's loop device under a lock (parallel installs collided) 2026-09-29 16:28:19 +02:00
theupriser 7dd659dc09 fix: vminstall.sh in parallel: a poweroff that drops ssh is no failure, wait only for its own VM 2026-09-29 16:17:53 +02:00
theupriser d5cfadf3bb fix: vminstall.sh never makes root the guest user (WSL runs as root): theupriser then 2026-09-29 15:49:29 +02:00
theupriser cb247b9cc3 docs: wsl-build-host skill, vminstall.sh without udisks (WSL), AGENTS.md/TODO WSL notes corrected
The WSL box has a desktop after all (WSLg windows on Windows), closing the
Arch window shuts it down, and vminstall.sh loop-mounts the ISO with losetup
as root when udisksctl is missing (R1c).
2026-09-29 15:40:03 +02:00
theupriser 6a53c957ba docs: AGENTS.md: state, where the tests run (PC, WSL2) and the ISO problems found 2026-09-29 15:31:57 +02:00
theupriser 63fd11829d docs: the agent hand-off file is AGENTS.md (was CLAUDE.md) 2026-09-29 15:29:49 +02:00
theupriser f03ad74295 docs: CLAUDE.md: this repo takes pushes straight to main 2026-09-29 15:29:08 +02:00
theupriser 0c84b8b926 feat: faster and parallel tests, a remote runner, and a CLAUDE.md hand-off
vmsuite.sh: the ssh-ready snapshot becomes one base image, every block gets a new qcow2 overlay
(no snapshot restore), each suite has its own VM directory and ssh port (2301-2305, boot loaders
2401-2403), the host's package cache is bound over pacman's, VM_MEM defaults to 4G for tests
(run.sh VM_MEM, default 8G). vmtest.sh runs up to MAX_PARALLEL=3 jobs at once, slowest first.
scripts/vmtest-remote.sh runs vmtest.sh on another machine (the PC) over ssh and prints the
summary. CLAUDE.md and the branch cleanup skill now live in the repo.

Not proven as a whole: three VMs at once and the base image work, but a complete parallel run to
the end has not finished yet (P1/P2 in TODO.md); the remote runner and WSL2 are untried (R1-R2).
2026-09-29 15:26:57 +02:00
theupriser ee20bd9825 feat: vmtest.sh runs everything: boot loaders plus the cli, menu, hw, installer and toggles suites
vmtest.sh [--install] [--window] [--screen] [boot|loader|suite...], a detached screen
session with --screen, the summary in ~/vms/last-test.txt, the rows that need a person
listed as SKIP. New: the installer suite (R2.1), the toggles suite (R1.8) and H3 (BIOS
dry-run, per-block '# env:' for the VM start). vmsuite.sh and vmbootloadertest.sh are
executable again.
2026-09-29 14:41:37 +02:00
theupriser 6d264acaf2 feat: the hw suite (H1, H4, H5, R1.7 CEC) and host-side suite blocks
vmsuite.sh runs NN-name.host.sh blocks on the host (reboot, scripts/vmcec.sh) with
prelude-host.sh; every block that applies Steamify says so first (INFO) so the shared
console is not silent for minutes. 68 checks pass.
2026-09-29 14:12:39 +02:00
theupriser b91ef9172e feat: the menu suite (R1.1-R1.6, R1.10) and one shared log Konsole for every test run
Scripted menu input and Steamify's own status functions, journals free of duplicates,
--backend status as JSON, an older item shown as (update). The test scripts append to
$TEST_LOG and share one Konsole (common.sh view_start) instead of opening one each;
vmsuite.sh streams its output (sed -u). 36 checks pass.
2026-09-29 13:53:35 +02:00
theupriser fe5251f758 feat: vmsuite.sh and the cli suite: G1-G3, F1-F7 of TESTPLAN.md as unattended checks
Each block in share/vmtest/<suite>/ starts from a fresh ssh-ready snapshot, gets a
Plasma session environment over ssh (the theme item needs one) and prints PASS/FAIL
lines. ONLY=<prefix> runs one block. 55 checks pass on the plain CachyOS VM.
2026-09-29 11:45:02 +02:00
theupriser 508eb68ed5 docs: vm-install skill, TESTPLAN section B and TODO for the boot loader test and the full automated suite 2026-09-29 11:23:50 +02:00
theupriser c91277abf0 feat: vmtest.sh: the boot loader test for every loader the ISO advertises
One VM per loader, Steam Machine (--fremont): Steamify's state as its menu sees it,
OS name untouched, loader identity, the DKMS modules for every kernel, Steamify's
loader-specific code (hdmi_remove_boot_param), a kernel update, and a reboot into
each of the two kernels. Headless by default with a log Konsole (--window shows
the VMs). Fails when an advertised loader has no test. Limine 41, systemd-boot 40,
GRUB 40 checks pass.
2026-09-29 11:23:50 +02:00
theupriser 8646b3c30a feat: vminstall.sh installs any boot loader and the Steamify ISO's Steamify step, with a package cache
VM_BOOTLOADER=limine|systemd-boot|grub, VM_STEAMIFY (steamify-install runs after
the headless installer, like Calamares does), VM_CACHE (host pacman cache shared
as 9p, default ~/vms/pkg-cache). run.sh --headless / VM_HEADLESS=1: no window.

Fixes found on the way: the live script deadlocked on is-system-running (it is
the running kernel-command-line.service) and now waits for pacman-init; the post
script kept forcing the Plasma login over Steamify's gaming-mode SDDM, gave
systemd-boot no timeout/default (it waited in the menu for ever), and left ufw
blocking the host's ssh; the first-boot check wanted plasmashell in gaming mode.
2026-09-29 11:23:50 +02:00
theupriser fa776b1761 docs: steam-machine-iso: vmreset.sh also stops the ISO VM 2026-09-28 18:27:52 +02:00
theupriser 0ae7cce488 fix: vmreset.sh works when the VM lives in the repo itself (cp of run.sh onto itself failed) 2026-09-28 18:27:27 +02:00
theupriser 7db82b6494 docs: steam-machine-iso: read an installed VM's disk while it runs; serial output 2026-09-28 18:12:18 +02:00
theupriser 52d5021d88 docs: steam-machine-iso: one log Konsole for every build 2026-09-28 17:45:00 +02:00
theupriser f19bcb9764 docs: steam-machine-iso: a package cache for the podman ISO build 2026-09-28 17:42:37 +02:00
theupriser 5954548247 fix: qmptype.py types > < ? { } 2026-09-28 17:37:51 +02:00
theupriser bc06bc2534 feat: vmisobuild.sh and the steam-machine-iso skill run build-calamares-modules.sh 2026-09-28 16:41:22 +02:00
theupriser 0052f1ba22 docs: note token-cheap ISO-VM testing (serial log, no screenshot polling) 2026-09-28 15:35:25 +02:00
theupriser 61442d7ef8 docs: packagechooser multi-select needs Shift/Ctrl-click 2026-09-28 13:45:09 +02:00
theupriser 6d73d49477 docs: steam-machine-iso: run Calamares in its own Konsole tab; watch for the live keyboard layout switching away from US 2026-09-28 13:42:23 +02:00
theupriser fe249e5108 docs: correction - packagechooser mode:optionalmultiple DOES multi-select (verified from global storage, not misleading label text) 2026-09-28 13:30:09 +02:00
theupriser 4398a2b85f docs: packagechooserq isn't installed on this Calamares build; packagechooser's mode:optionalmultiple is single-select regardless; QMP/Calamares live-testing gotchas 2026-09-28 13:24:36 +02:00
theupriser 081080b5f5 docs: ISO builds use 75% of host cores, not all-but-2 2026-09-28 13:04:04 +02:00
theupriser b6b35d41f1 docs: TESTPLAN: 2.8.0 --defaults --list tested 2026-09-28 12:44:50 +02:00
theupriser 3ccbb62bd2 feat: vmisobuild.sh (ISO build in the VM, package cache per VM), vmisoboot.sh (ISO VM for Calamares), qmpshot.py/qmpclick.py; run.sh VM_CACHE/VM_CPUS/VM_NOGL/VM_PORT 2026-09-28 11:40:21 +02:00
theupriser fec0ce5b8e docs: TESTPLAN: 2.7.0's Steam Machine checks carried over from 2.6.0 (code unchanged) 2026-09-28 10:56:17 +02:00
theupriser d0038916e9 docs: 2.7.0 regression results on the new VM; the first login's app is the newest release 2026-09-28 10:53:44 +02:00
theupriser 4905bba1f6 docs: vminstallsim.sh example uses --options 2026-09-28 10:08:27 +02:00
theupriser 60a2698d02 feat: scripts/vminstall.sh installs an ssh-ready test VM unattended; TESTPLAN.md; vm-install skill 2026-09-28 10:07:13 +02:00
theupriser 21547dd7bc docs: steam-machine-iso: one build at a time; vminstallsim.sh passes --defaults options 2026-09-27 22:00:32 +02:00
theupriser 96cae35c6b docs: steam-machine-iso: build-live-modules.sh in the build, the ISO's new name 2026-09-27 21:26:45 +02:00
theupriser e1dd75875b docs: steam-machine-iso: the Steamify step is added by calamares-online.sh 2026-09-27 20:06:26 +02:00
theupriser f8aac02d0a docs: steam-machine-iso: live-session quirks; scripts/qmptype.py types into the VM 2026-09-27 20:01:41 +02:00
theupriser 8d5cdaea99 docs: steam-machine-iso: the harmless chown error, the ISO test VM 2026-09-27 19:54:30 +02:00
theupriser f8e2473afa feat: steam-machine-iso skill (ISO build in podman on the Steam Machine, installer simulation, first-login test) and scripts/vminstallsim.sh 2026-09-27 19:53:23 +02:00
theupriser 088ee83350 VM on the Steam Machine: Arch OVMF paths, visible tests, and the steam-machine-testing skill 2026-09-27 17:00:10 +02:00
theupriser d626aafd84 docs: VM skill up to date with the menu (sub-options, HDMI-CEC, kernel pin) and today's pitfalls 2026-09-25 13:07:02 +02:00
theupriser 6da46fc10f docs: The test VM needs an x86_64 Linux host 2026-09-25 13:05:15 +02:00
theupriser 0464ede893 chore: Remove the Windows scripts; the test VM runs on Linux 2026-09-25 13:04:20 +02:00
theupriser 4aeb3de43f docs: run.sh --amd (venus on the AMD iGPU); gaming mode can't render in the VM, all tried 2026-09-25 12:54:27 +02:00
theupriser 04204f1b9d feat: vmcec.sh tests HDMI-CEC against a fake TV; vmwake.sh wakes the VM over QMP
run.sh opens a QMP socket; the skill documents the CEC test and its gotchas.
2026-09-25 11:14:00 +02:00
theupriser e04db1ec5f docs: VM skill: menu with sub-options, HDMI-CEC and faking it with vivid 2026-09-25 09:12:12 +02:00
theupriser a8d7554dce Merge pull request #1 from theupriser/feat/visible-vm-runs
Feat/visible vm runs
2026-09-24 13:09:16 +02:00
53 changed files with 223 additions and 480 deletions

No files matched your search

+2
View File
@@ -22,6 +22,7 @@ share/*
!share/vminstall-post.sh
!share/bootloader-test/
!share/vmtest/
!share/uitest/
# Belt and braces, anywhere in the tree
*.iso
@@ -34,3 +35,4 @@ share/*
*.tmp
host-keys.pub
__pycache__/
!share/golden/
+4
View File
@@ -4,6 +4,10 @@ All notable changes, per version and per commit. Versions follow
[Semantic Versioning](https://semver.org/) and were numbered from the start
of the history.
## Unreleased
- **feat: `share/golden/`: a no-VM sandbox (bubblewrap, fake `/etc` `/sys` `$HOME`, shim `pacman` `systemctl` `sudo` `uname` `modinfo`) and golden `--backend status` and apply `plan` output of the bash 2.11.1 backend for an AMD PC, an NVIDIA PC and a Steam Machine; `record.sh` records, `record.sh check` compares (the Go refactor's safety net)**
## 0.5.0 - 2026-10-02
The whole automated test (boot loaders plus suites), the Steamify ISO pipeline,
+1 -1
View File
@@ -5,7 +5,7 @@
pass() { echo "PASS $*"; }; fail() { echo "FAIL $*"; }
sudo mountpoint -q /mnt || sudo mount -t 9p -o trans=virtio,version=9p2000.L repo /mnt
cd /mnt || exit 1
for lib in $(grep -oP '^for lib in \K.*(?=; do$)' steamify.sh); do
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
# shellcheck source=/dev/null
. "lib/$lib.sh" 2>/dev/null
done
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":["gaming","boot"]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":["gaming"]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":[]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":[]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":[]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":["gaming","single"]}
+1
View File
@@ -0,0 +1 @@
{"version":"2.12.0","firstRun":true,"steamMachine":false,"kernel":"7.0.0-fixture-cachyos","pinnedKernel":"7.1.6-1","cecDevices":"","leds":0,"bios":null,"items":[{"id":"gaming","label":"SteamOS conversion","hint":"boot into gaming mode, Steam on the desktop","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"boot","label":"Boot into the desktop instead of gaming mode","hint":"","kind":"choice","parent":"gaming","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true},{"id":"silent","label":"Start Steam silently in desktop mode","hint":"in the tray at login on the desktop, no window","kind":"toggle","parent":"gaming","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true},{"id":"glyphs","label":"Install Steam Deck/Machine icons","hint":"Deck button icons in gaming mode","kind":"toggle","parent":"gaming","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"theme","label":"Install SteamOS theme","hint":"Vapor look (cachyos-vapor)","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"single","label":"Single user mode","hint":"no password, lock screen or log out (SDDM)","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"launcher","label":"Steamify shortcut","hint":"the app on the desktop, Steamify Terminal in the launcher","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"notify","label":"Update notifications","hint":"a notification when there's a new Steamify, never updates by itself","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"extended_controller_support","label":"Extended controller support","hint":"Xbox wireless dongle (xone), Xbox controllers over Bluetooth (xpadneo)","kind":"toggle","parent":"","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true},{"id":"cec","label":"HDMI-CEC","hint":"use Steam with the TV remote, TV on/off with the PC (experimental)","kind":"toggle","parent":"","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true}]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":[]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":[]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":[]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":["nvidia","bigpicture"]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":[]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":["single"]}
@@ -0,0 +1 @@
{"version":"2.12.0","firstRun":true,"steamMachine":false,"kernel":"7.0.0-fixture-cachyos","pinnedKernel":"7.1.6-1","cecDevices":"","leds":0,"bios":null,"items":[{"id":"nvidia","label":"Gaming on NVIDIA","hint":"Steam on the desktop, started at login","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"bigpicture","label":"Steam starts in Big Picture","hint":"the controller-friendly Steam (untick: Steam's normal window)","kind":"toggle","parent":"nvidia","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"nvsilent","label":"Start Steam silently","hint":"in the tray at login, no window (untick: Steam's normal window)","kind":"toggle","parent":"nvidia","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true},{"id":"theme","label":"Install SteamOS theme","hint":"Vapor look (cachyos-vapor)","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"single","label":"Single user mode","hint":"no password, lock screen or log out (SDDM)","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"launcher","label":"Steamify shortcut","hint":"the app on the desktop, Steamify Terminal in the launcher","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"notify","label":"Update notifications","hint":"a notification when there's a new Steamify, never updates by itself","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"extended_controller_support","label":"Extended controller support","hint":"Xbox wireless dongle (xone), Xbox controllers over Bluetooth (xpadneo)","kind":"toggle","parent":"","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true},{"id":"cec","label":"HDMI-CEC","hint":"use Steam with the TV remote, TV on/off with the PC (experimental)","kind":"toggle","parent":"","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true}]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":["gaming","boot"]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":["gaming"]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":[]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":[]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":["machine","poweroff"]}
@@ -0,0 +1 @@
{"event":"plan","disable":[],"enable":["gaming","single"]}
@@ -0,0 +1 @@
{"version":"2.12.0","firstRun":true,"steamMachine":true,"kernel":"7.0.0-fixture-cachyos","pinnedKernel":"7.1.6-1","cecDevices":"","leds":0,"bios":{"current":"unknown","newest":"","selectable":false,"dryRun":false},"items":[{"id":"gaming","label":"SteamOS conversion","hint":"boot into gaming mode, Steam on the desktop","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"boot","label":"Boot into the desktop instead of gaming mode","hint":"","kind":"choice","parent":"gaming","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true},{"id":"silent","label":"Start Steam silently in desktop mode","hint":"in the tray at login on the desktop, no window","kind":"toggle","parent":"gaming","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true},{"id":"glyphs","label":"Install Steam Deck/Machine icons","hint":"Deck button icons in gaming mode","kind":"toggle","parent":"gaming","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"theme","label":"Install SteamOS theme","hint":"Vapor look (cachyos-vapor)","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"single","label":"Single user mode","hint":"no password, lock screen or log out (SDDM)","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"launcher","label":"Steamify shortcut","hint":"the app on the desktop, Steamify Terminal in the launcher","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"notify","label":"Update notifications","hint":"a notification when there's a new Steamify, never updates by itself","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"extended_controller_support","label":"Extended controller support","hint":"Xbox wireless dongle (xone), Xbox controllers over Bluetooth (xpadneo)","kind":"toggle","parent":"","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":true},{"id":"cec","label":"HDMI-CEC","hint":"use Steam with the TV remote, TV on/off with the PC (experimental)","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"machine","label":"Steam Machine support","hint":"LED bar driver, hardware settings in Steam","kind":"toggle","parent":"","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"poweroff","label":"Power-off fix","hint":"the Steam Machine stays off after shutting down","kind":"toggle","parent":"machine","needs":"","on":false,"wanted":true,"update":false,"new":false,"selectable":true},{"id":"bios","label":"Update BIOS","hint":"now unknown, newest unknown (offline?)","kind":"action","parent":"machine","needs":"","on":false,"wanted":false,"update":false,"new":false,"selectable":false}]}
@@ -0,0 +1,3 @@
NAME="CachyOS Linux"
ID=cachyos
ID_LIKE=arch
+2
View File
@@ -0,0 +1,2 @@
sddm
plasma-desktop
@@ -0,0 +1 @@
PRIME B650
@@ -0,0 +1 @@
ASUSTeK
@@ -0,0 +1,3 @@
NAME="CachyOS Linux"
ID=cachyos
ID_LIKE=arch
+1
View File
@@ -0,0 +1 @@
nvidia_drm
+3
View File
@@ -0,0 +1,3 @@
sddm
plasma-desktop
nvidia-utils
@@ -0,0 +1 @@
PRIME B650
@@ -0,0 +1 @@
ASUSTeK
@@ -0,0 +1 @@
0x030000
@@ -0,0 +1 @@
0x10de
@@ -0,0 +1,3 @@
NAME="CachyOS Linux"
ID=cachyos
ID_LIKE=arch
@@ -0,0 +1,2 @@
sddm
plasma-desktop
@@ -0,0 +1 @@
Fremont
@@ -0,0 +1 @@
Valve
+33
View File
@@ -0,0 +1,33 @@
#!/bin/bash
# Record what the bash backend (steamify.sh in $REPO) prints, per fixture, into share/golden/expected/.
# share/golden/record.sh record all | share/golden/record.sh check compare with the recorded files
set -uo pipefail
here="$(cd "$(dirname "$0")" && pwd)"
export REPO="${REPO:-$here/../../../steamify-cachyos}"; REPO="$(cd "$REPO" && pwd)"
backend="${BACKEND:-bash $REPO/steamify.sh}"
mode="${1:-record}"; failures=0; work="$(mktemp -d)"; trap 'rm -rf "$work"' EXIT
# case name -> backend arguments
# status: the whole output. plan-*: only the first line of the apply stream (the plan event, where the rules live);
# the steps after it need the real system (the VM suite), they are not stable with a fake sudo.
cases=("status:--backend status"
"plan-gaming:--backend apply gaming"
"plan-gaming-desktop:--backend apply --boot desktop gaming boot"
"plan-single:--backend apply single"
"plan-poweroff:--backend apply poweroff"
"plan-nothing:--backend apply"
"plan-nvidia:--backend apply nvidia bigpicture")
for fixture in "$here"/fixtures/*/; do
name="$(basename "$fixture")"
for entry in "${cases[@]}"; do
label="${entry%%:*}"; arguments="${entry#*:}"
expected="$here/expected/$name.$label.json"; mkdir -p "$here/expected"
if [[ "$label" == plan-* ]]; then # the plan event comes first; then the steps run for real, so stop after a moment
timeout -s KILL 5 "$here/sandbox.sh" "$fixture" $backend $arguments > "$work/stream" 2>&1
actual="$(head -n 1 "$work/stream")"
else actual="$("$here/sandbox.sh" "$fixture" $backend $arguments 2>&1)"; fi
if [[ "$mode" == record ]]; then printf '%s\n' "$actual" > "$expected"; echo "recorded $expected"
elif ! diff -u "$expected" <(printf '%s\n' "$actual"); then echo "FAIL $name $label"; failures=$((failures+1))
else echo "PASS $name $label"; fi
done
done
exit $failures
+32
View File
@@ -0,0 +1,32 @@
#!/bin/bash
# Run a command in a throw-away copy of a machine described by a fixture folder (no VM, no root).
# share/golden/sandbox.sh <fixture> <command>...
# <fixture>/etc/**, <fixture>/sys/**, <fixture>/usr/** : files shown at those places (the rest of /etc and /sys is empty)
# <fixture>/home/ : the user's home (fresh copy each run)
# <fixture>/packages, enabled-units, active-units : answers of the fake pacman and systemctl (shims/)
# <fixture>/env : optional VAR=value lines for the command
# Needs bubblewrap. $GOLDEN_LOG collects the writes the shims were asked to make.
set -euo pipefail
here="$(cd "$(dirname "$0")" && pwd)"
fixture="$(cd "${1:?usage: $0 <fixture> <command>...}" && pwd)"; shift
work="$(mktemp -d)"; trap 'rm -rf "$work"' EXIT
mkdir -p "$work/home" "$work/fixture"
cp -a "$fixture/." "$work/fixture/"
[[ -d "$fixture/home" ]] && cp -a "$fixture/home/." "$work/home/"
arguments=(--die-with-parent --unshare-pid --ro-bind / / --dev /dev --proc /proc --tmpfs /tmp --tmpfs /sys --tmpfs /etc
--bind "$work/home" "$HOME" --bind "$work/fixture" /mnt --ro-bind "$here/shims" /media)
[[ -n "${REPO:-}" ]] && arguments+=(--ro-bind "$REPO" "$REPO")
for keep in passwd group nsswitch.conf ld.so.cache ld.so.conf ld.so.conf.d localtime alternatives resolv.conf hostname; do
[[ -e "/etc/$keep" ]] && arguments+=(--ro-bind "/etc/$keep" "/etc/$keep")
done
for root in etc sys; do
[[ -d "$fixture/$root" ]] || continue
while IFS= read -r -d '' file; do
arguments+=(--ro-bind "$work/fixture/${file#"$fixture/"}" "/${file#"$fixture/"}")
done < <(find "$fixture/$root" -type f -print0)
done
environment=(--setenv FIXTURE /mnt --setenv PATH "/media:$PATH" --setenv GOLDEN_LOG "${GOLDEN_LOG:-/mnt/writes.log}")
[[ -f "$fixture/env" ]] && while IFS= read -r line; do
[[ "$line" == *=* ]] && environment+=(--setenv "${line%%=*}" "${line#*=}")
done < "$fixture/env"
exec bwrap "${arguments[@]}" "${environment[@]}" "$@"
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash
# Fake modinfo: modules listed in $FIXTURE/modules exist.
for module in "$@"; do [[ "$module" == -* ]] || grep -qx -- "$module" "$FIXTURE/modules" 2>/dev/null || exit 1; done
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
# Fake pacman for the golden sandbox: the installed packages are listed in $FIXTURE/packages (one name per line).
# Only the queries the status code makes: -Q/-Qq <pkg>, -T <pkg>..., -Qi <pkg>. Writes (-S, -U, -R) are logged and succeed.
list="$FIXTURE/packages"; touch "$list" 2>/dev/null
case "$1" in
-T) shift; for package in "$@"; do grep -qx -- "$package" "$list" || echo "$package"; done; [[ $# -gt 0 ]] ;;
-Q|-Qq|-Qi|-Qs) shift; status=0; for package in "$@"; do [[ "$package" == -* ]] && continue; grep -qx -- "$package" "$list" || status=1; done; exit $status ;;
-Ss|-Si) exit 1 ;;
*) echo "pacman $*" >> "${GOLDEN_LOG:-/dev/null}"; exit 0 ;;
esac
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash
# Fake sudo: logs the command and succeeds; nothing runs.
while [[ "$1" == -* ]]; do shift; done
echo "sudo $*" >> "${GOLDEN_LOG:-/dev/null}"
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
# Fake systemctl: enabled units listed in $FIXTURE/enabled-units, active ones in $FIXTURE/active-units.
# Queries answer from those lists; everything else is logged and succeeds.
verb=""; units=()
for argument in "$@"; do
[[ "$argument" == -* ]] && continue
if [[ -z "$verb" ]]; then verb="$argument"; else units+=("$argument"); fi
done
case "$verb" in
is-enabled) for unit in "${units[@]}"; do grep -qx -- "$unit" "$FIXTURE/enabled-units" 2>/dev/null || { echo disabled; exit 1; }; done; echo enabled ;;
is-active) for unit in "${units[@]}"; do grep -qx -- "$unit" "$FIXTURE/active-units" 2>/dev/null || { echo inactive; exit 3; }; done; echo active ;;
*) echo "systemctl $*" >> "${GOLDEN_LOG:-/dev/null}"; exit 0 ;;
esac
+2
View File
@@ -0,0 +1,2 @@
#!/bin/bash
if [[ "$1" == -r ]]; then echo 7.0.0-fixture-cachyos; else command uname "$@"; fi
+42
View File
@@ -0,0 +1,42 @@
import sys, os, importlib.machinery, importlib.util, json
os.environ["QT_QPA_PLATFORM"] = "offscreen"
sys.argv = ["steamify-ui"]
loader = importlib.machinery.SourceFileLoader("ui", sys.argv[0] if False else os.environ["UI"])
spec = importlib.util.spec_from_loader("ui", loader); ui = importlib.util.module_from_spec(spec); loader.exec_module(ui)
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtCore import QTimer, QObject, QMetaObject, Q_ARG, Qt
app = QGuiApplication(sys.argv)
backend = ui.Backend(ui.find_script()); pad = ui.Gamepad(); engine = QQmlApplicationEngine()
engine.setInitialProperties({"backend": backend, "gamepad": pad, "fullscreen": False, "fromSteam": False, "iconUrl": ""})
engine.load(os.path.join(ui.HERE, "qml", "Main.qml"))
assert engine.rootObjects(), "QML did not load"
root = engine.rootObjects()[0]; backend.refresh()
def find_state():
for o in root.findChildren(QObject):
if o.property("want") is not None and o.property("resolution") is not None: return o
state = None
def step():
global state
state = find_state(); assert state, "no AppState"
def want(): return {k for k, v in state.property("want").toVariant().items() if v} if hasattr(state.property("want"),"toVariant") else {k for k,v in state.property("want").items() if v}
def toggle(i): QMetaObject.invokeMethod(state, "toggle", Qt.DirectConnection, Q_ARG("QVariant", i))
def vis():
r = state.property("resolution"); r = r.toVariant() if hasattr(r,"toVariant") else r
return set(r["visible"])
def plan():
r = state.property("resolution"); r = r.toVariant() if hasattr(r,"toVariant") else r
return [(p["id"], p["action"]) for p in r["plan"]]
print("start want", want(), "plan", plan(), "canApply", state.property("canApply"))
assert want() == {"theme"}
toggle("single"); print("after single", want(), plan())
assert want() == {"theme", "single", "gaming"} and plan() == [("gaming","on"),("single","on")]
assert "silent" in vis() and "poweroff" not in vis()
toggle("machine"); print("after machine", want(), vis())
assert "poweroff" in want() and "poweroff" in vis()
toggle("gaming"); print("after gaming off", want())
assert want() == {"theme", "machine", "poweroff"}
assert state.property("canApply") is True
print("UI OK"); app.quit()
QTimer.singleShot(4000, step)
sys.exit(app.exec())
@@ -0,0 +1,30 @@
# Go core (REFACTOR-2.12 phase 0/1): `steamify --backend apply` through the Go binary must emit the
# same event stream as the bash backend: enable two small items, then turn them off again, once with
# each backend, in the same VM. Needs the binary built in the repo (make build -> bin/steamify).
GO=/mnt/bin/steamify
[[ -x $GO ]] || { fail "no $GO (run make build in steamify-cachyos)"; exit 0; }
export STEAMIFY_NO_DOWNLOAD=1
backend_run() { # backend_run <label> <command...>: the event stream of one apply, log lines dropped
# Only the structure (plan, start, done, finished): the log lines of the first run hold pacman's install output, which the
# second run on the same machine does not repeat.
"$@" 2>&1 < /dev/null | sed 's/\x1b\[[0-9;]*m//g' | grep -v '^{"event":"log"'
}
status_json() { "$@" --backend status 2>/dev/null; }
info "status through both backends"
bash_status=$(bash /mnt/steamify.sh --backend status 2>/dev/null); go_status=$($GO --backend status 2>/dev/null)
[[ -n $bash_status && "$bash_status" == "$go_status" ]] && pass "status identical" || fail "status differs"
for step in "launcher notify" ""; do
# shellcheck disable=SC2086
bash_events=$(backend_run bash /mnt/steamify.sh --backend apply $step)
# put the machine back for the Go run
# shellcheck disable=SC2086
if [[ -n $step ]]; then backend_run bash /mnt/steamify.sh --backend apply >/dev/null; else backend_run bash /mnt/steamify.sh --backend apply launcher notify >/dev/null; fi
# shellcheck disable=SC2086
go_events=$(backend_run $GO --backend apply $step)
label="apply ${step:-nothing (turn off)}"
if [[ "$bash_events" == "$go_events" ]]; then pass "$label: same event stream ($(wc -l <<< "$bash_events") lines)"
else fail "$label: streams differ: $(diff <(echo "$bash_events") <(echo "$go_events") | head -6 | tr '\n' '|')"; fi
done
grep -q '"finished"' <<< "$go_events" && pass "Go run finished" || fail "no finished event: $(tail -n 2 <<< "$go_events")"
+1 -1
View File
@@ -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 $(grep -oP '^for lib in \K.*(?=; do$)' steamify.sh); 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
-170
View File
@@ -1,170 +0,0 @@
== pc first run
wanted: gaming glyphs theme single launcher notify
disable:
enable: gaming glyphs theme single launcher notify
== pc first run, untick gaming
wanted: theme launcher notify
disable:
enable: theme launcher notify
== pc single on
wanted: gaming theme single launcher notify
disable:
enable: gaming theme single launcher notify
== pc single then gaming off
wanted: theme launcher notify
disable:
enable: theme launcher notify
== pc boot desktop
wanted: gaming boot glyphs theme single launcher notify
disable:
enable: gaming boot glyphs theme single launcher notify
== pc boot desktop then gaming off
wanted: theme launcher notify
disable:
enable: theme launcher notify
== pc silent only
wanted: gaming silent glyphs theme single launcher notify
disable:
enable: gaming silent glyphs theme single launcher notify
== pc all on, theme off
wanted: gaming boot silent glyphs single launcher notify
disable: theme
enable: gaming silent notify
== pc launcher off
wanted:
disable: launcher
enable:
== pc steamgame on without launcher
wanted: theme launcher steamgame notify
disable:
enable: theme launcher steamgame notify
== machine first run
wanted: gaming glyphs theme single launcher steamgame notify vram cec machine poweroff
disable:
enable: gaming glyphs theme single launcher steamgame notify vram cec machine poweroff
== machine silent hidden until boot desktop
wanted: gaming silent glyphs theme single launcher notify vram machine
disable:
enable: gaming silent glyphs theme single launcher notify vram machine
== machine boot desktop keeps silent
wanted: gaming boot silent glyphs theme single launcher notify vram machine
disable:
enable: gaming boot silent glyphs theme single launcher notify vram machine
== machine off
wanted: gaming glyphs theme single launcher notify vram
disable: poweroff machine
enable: gaming glyphs theme single launcher notify vram
== machine poweroff off
wanted: gaming glyphs theme single launcher notify vram machine
disable: poweroff
enable: gaming glyphs theme single launcher notify vram machine
== machine poweroff on brings machine
wanted: gaming glyphs theme single launcher notify vram machine poweroff
disable:
enable: gaming glyphs theme single launcher notify vram machine poweroff
== machine kpin removal
wanted: gaming glyphs theme single launcher notify vram machine poweroff
disable: kpin
enable: gaming glyphs theme single launcher notify vram machine poweroff
== nvidia first run
wanted: nvidia bigpicture theme single launcher notify
disable:
enable: nvidia bigpicture theme single launcher notify
== nvidia bigpicture off
wanted: nvidia theme single launcher notify
disable: bigpicture
enable: nvidia theme single launcher notify
== nvidia nvsilent on
wanted: nvidia nvsilent theme single launcher notify
disable: bigpicture
enable: nvidia nvsilent theme single launcher notify
== nvidia nvsilent then bigpicture
wanted: nvidia bigpicture theme single launcher notify
disable:
enable: nvidia bigpicture theme single launcher notify
== nvidia off
wanted: theme single launcher notify
disable: nvsilent bigpicture nvidia
enable: theme single launcher notify
== nvidia single
wanted: nvidia bigpicture theme launcher notify
disable:
enable: nvidia bigpicture theme launcher notify
== nvidia gaming already on
wanted: nvidia theme launcher notify
disable: gaming
enable: nvidia theme launcher notify
== outdated features
wanted: gaming glyphs theme single launcher notify
disable:
enable: gaming glyphs single launcher notify
== reapply (a)
wanted: gaming glyphs theme single launcher notify
disable:
enable: gaming glyphs theme single launcher notify
== backend_apply single
{"event":"plan","disable":[],"enable":["gaming","single"]}
== backend_apply boot
{"event":"plan","disable":[],"enable":[]}
== backend_apply poweroff
{"event":"plan","disable":[],"enable":["machine","poweroff"]}
== backend_apply silent
{"event":"plan","disable":[],"enable":["gaming","silent"]}
== backend_apply kpin
{"event":"plan","disable":[],"enable":[]}
== backend_apply gaming boot
{"event":"plan","disable":[],"enable":["gaming","boot"]}
== backend_apply launcher steamgame
{"event":"plan","disable":[],"enable":["launcher","steamgame"]}
== backend_apply nvidia bigpicture
{"event":"plan","disable":[],"enable":["nvidia","bigpicture"]}
== backend_apply nvidia nvsilent
{"event":"plan","disable":[],"enable":["nvidia","nvsilent"]}
== backend_apply nvidia bigpicture nvsilent
{"event":"plan","disable":[],"enable":["nvidia","bigpicture"]}
== backend_apply nvidia single
{"event":"plan","disable":[],"enable":["single"]}
== backend_apply nvidia boot
{"event":"plan","disable":[],"enable":[]}
== defaults_list []
{"hideWhen":"","hint":"boot into gaming mode, Steam on the desktop","id":"gaming","kind":"toggle","label":"SteamOS conversion","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"","id":"boot","kind":"choice","label":"Boot into the desktop instead of gaming mode","needs":"","on":false,"parent":"gaming","selectable":true}
{"hideWhen":"","hint":"in the tray at login on the desktop, no window","id":"silent","kind":"toggle","label":"Start Steam silently in desktop mode","needs":"","on":false,"parent":"gaming","selectable":true}
{"hideWhen":"","hint":"Deck button icons in gaming mode","id":"glyphs","kind":"toggle","label":"Install Steam Deck/Machine icons","needs":"","on":true,"parent":"gaming","selectable":true}
{"hideWhen":"","hint":"Vapor look (cachyos-vapor)","id":"theme","kind":"toggle","label":"Install SteamOS theme","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"no password, lock screen or log out (SDDM)","id":"single","kind":"toggle","label":"Single user mode","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"the app on the desktop, Steamify Terminal in the launcher","id":"launcher","kind":"toggle","label":"Steamify shortcut","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"a notification when there's a new Steamify, never updates by itself","id":"notify","kind":"toggle","label":"Update notifications","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"Xbox wireless dongle (xone), Xbox controllers over Bluetooth (xpadneo)","id":"extended_controller_support","kind":"toggle","label":"Extended controller support","needs":"","on":false,"parent":"","selectable":true}
{"hideWhen":"","hint":"use Steam with the TV remote, TV on/off with the PC (experimental)","id":"cec","kind":"toggle","label":"HDMI-CEC","needs":"","on":false,"parent":"","selectable":true}
== backend_status []
{"bios":null,"firstRun":true,"items":[{"hint":"boot into gaming mode, Steam on the desktop","id":"gaming","kind":"toggle","label":"SteamOS conversion","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"","id":"boot","kind":"choice","label":"Boot into the desktop instead of gaming mode","needs":"","new":false,"on":false,"parent":"gaming","selectable":true,"update":false,"wanted":false},{"hint":"in the tray at login on the desktop, no window","id":"silent","kind":"toggle","label":"Start Steam silently in desktop mode","needs":"","new":false,"on":false,"parent":"gaming","selectable":true,"update":false,"wanted":false},{"hint":"Deck button icons in gaming mode","id":"glyphs","kind":"toggle","label":"Install Steam Deck/Machine icons","needs":"","new":false,"on":false,"parent":"gaming","selectable":true,"update":false,"wanted":true},{"hint":"Vapor look (cachyos-vapor)","id":"theme","kind":"toggle","label":"Install SteamOS theme","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"no password, lock screen or log out (SDDM)","id":"single","kind":"toggle","label":"Single user mode","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"the app on the desktop, Steamify Terminal in the launcher","id":"launcher","kind":"toggle","label":"Steamify shortcut","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"a notification when there's a new Steamify, never updates by itself","id":"notify","kind":"toggle","label":"Update notifications","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"Xbox wireless dongle (xone), Xbox controllers over Bluetooth (xpadneo)","id":"extended_controller_support","kind":"toggle","label":"Extended controller support","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":false},{"hint":"use Steam with the TV remote, TV on/off with the PC (experimental)","id":"cec","kind":"toggle","label":"HDMI-CEC","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":false}],"pinnedKernel":"7.1.6-1","steamMachine":false,"version":"0.0.0"}
== defaults_list [fremont steam vram]
{"hideWhen":"","hint":"boot into gaming mode, Steam on the desktop","id":"gaming","kind":"toggle","label":"SteamOS conversion","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"","id":"boot","kind":"choice","label":"Boot into the desktop instead of gaming mode","needs":"","on":false,"parent":"gaming","selectable":true}
{"hideWhen":"","hint":"in the tray at login on the desktop, no window","id":"silent","kind":"toggle","label":"Start Steam silently in desktop mode","needs":"","on":false,"parent":"gaming","selectable":true}
{"hideWhen":"","hint":"Deck button icons in gaming mode","id":"glyphs","kind":"toggle","label":"Install Steam Deck/Machine icons","needs":"","on":true,"parent":"gaming","selectable":true}
{"hideWhen":"","hint":"Vapor look (cachyos-vapor)","id":"theme","kind":"toggle","label":"Install SteamOS theme","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"no password, lock screen or log out (SDDM)","id":"single","kind":"toggle","label":"Single user mode","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"the app on the desktop, Steamify Terminal in the launcher","id":"launcher","kind":"toggle","label":"Steamify shortcut","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"Steamify in your Steam library, for the controller and gaming mode","id":"steamgame","kind":"toggle","label":"Add as non-Steam game","needs":"","on":true,"parent":"launcher","selectable":true}
{"hideWhen":"","hint":"a notification when there's a new Steamify, never updates by itself","id":"notify","kind":"toggle","label":"Update notifications","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"Xbox wireless dongle (xone), Xbox controllers over Bluetooth (xpadneo)","id":"extended_controller_support","kind":"toggle","label":"Extended controller support","needs":"","on":false,"parent":"","selectable":true}
{"hideWhen":"","hint":"the game in front keeps its VRAM, background apps make room","id":"vram","kind":"toggle","label":"VRAM booster","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"use Steam with the TV remote, TV on/off with the PC (experimental)","id":"cec","kind":"toggle","label":"HDMI-CEC","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"LED bar driver, hardware settings in Steam","id":"machine","kind":"toggle","label":"Steam Machine support","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"the Steam Machine stays off after shutting down","id":"poweroff","kind":"toggle","label":"Power-off fix","needs":"","on":true,"parent":"machine","selectable":true}
== backend_status [fremont steam vram]
{"bios":null,"firstRun":true,"items":[{"hint":"boot into gaming mode, Steam on the desktop","id":"gaming","kind":"toggle","label":"SteamOS conversion","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"","id":"boot","kind":"choice","label":"Boot into the desktop instead of gaming mode","needs":"","new":false,"on":false,"parent":"gaming","selectable":true,"update":false,"wanted":false},{"hint":"in the tray at login on the desktop, no window","id":"silent","kind":"toggle","label":"Start Steam silently in desktop mode","needs":"","new":false,"on":false,"parent":"gaming","selectable":true,"update":false,"wanted":false},{"hint":"Deck button icons in gaming mode","id":"glyphs","kind":"toggle","label":"Install Steam Deck/Machine icons","needs":"","new":false,"on":false,"parent":"gaming","selectable":true,"update":false,"wanted":true},{"hint":"Vapor look (cachyos-vapor)","id":"theme","kind":"toggle","label":"Install SteamOS theme","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"no password, lock screen or log out (SDDM)","id":"single","kind":"toggle","label":"Single user mode","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"the app on the desktop, Steamify Terminal in the launcher","id":"launcher","kind":"toggle","label":"Steamify shortcut","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"Steamify in your Steam library, for the controller and gaming mode","id":"steamgame","kind":"toggle","label":"Add as non-Steam game","needs":"","new":false,"on":false,"parent":"launcher","selectable":true,"update":false,"wanted":true},{"hint":"a notification when there's a new Steamify, never updates by itself","id":"notify","kind":"toggle","label":"Update notifications","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"Xbox wireless dongle (xone), Xbox controllers over Bluetooth (xpadneo)","id":"extended_controller_support","kind":"toggle","label":"Extended controller support","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":false},{"hint":"the game in front keeps its VRAM, background apps make room","id":"vram","kind":"toggle","label":"VRAM booster","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"use Steam with the TV remote, TV on/off with the PC (experimental)","id":"cec","kind":"toggle","label":"HDMI-CEC","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"LED bar driver, hardware settings in Steam","id":"machine","kind":"toggle","label":"Steam Machine support","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"the Steam Machine stays off after shutting down","id":"poweroff","kind":"toggle","label":"Power-off fix","needs":"","new":false,"on":false,"parent":"machine","selectable":true,"update":false,"wanted":true}],"pinnedKernel":"7.1.6-1","steamMachine":true,"version":"0.0.0"}
== defaults_list [nvidia steam]
{"hideWhen":"","hint":"Steam on the desktop, started at login","id":"nvidia","kind":"toggle","label":"Gaming on NVIDIA","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"the controller-friendly Steam (untick: Steam's normal window)","id":"bigpicture","kind":"toggle","label":"Steam starts in Big Picture","needs":"","on":true,"parent":"nvidia","selectable":true}
{"hideWhen":"bigpicture","hint":"in the tray at login, no window (untick: Steam's normal window)","id":"nvsilent","kind":"toggle","label":"Start Steam silently","needs":"","on":false,"parent":"nvidia","selectable":true}
{"hideWhen":"","hint":"Vapor look (cachyos-vapor)","id":"theme","kind":"toggle","label":"Install SteamOS theme","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"no password, lock screen or log out (SDDM)","id":"single","kind":"toggle","label":"Single user mode","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"the app on the desktop, Steamify Terminal in the launcher","id":"launcher","kind":"toggle","label":"Steamify shortcut","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"a notification when there's a new Steamify, never updates by itself","id":"notify","kind":"toggle","label":"Update notifications","needs":"","on":true,"parent":"","selectable":true}
{"hideWhen":"","hint":"Xbox wireless dongle (xone), Xbox controllers over Bluetooth (xpadneo)","id":"extended_controller_support","kind":"toggle","label":"Extended controller support","needs":"","on":false,"parent":"","selectable":true}
{"hideWhen":"","hint":"use Steam with the TV remote, TV on/off with the PC (experimental)","id":"cec","kind":"toggle","label":"HDMI-CEC","needs":"","on":false,"parent":"","selectable":true}
== backend_status [nvidia steam]
{"bios":null,"firstRun":true,"items":[{"hint":"Steam on the desktop, started at login","id":"nvidia","kind":"toggle","label":"Gaming on NVIDIA","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"the controller-friendly Steam (untick: Steam's normal window)","id":"bigpicture","kind":"toggle","label":"Steam starts in Big Picture","needs":"","new":false,"on":false,"parent":"nvidia","selectable":true,"update":false,"wanted":true},{"hint":"in the tray at login, no window (untick: Steam's normal window)","id":"nvsilent","kind":"toggle","label":"Start Steam silently","needs":"","new":false,"on":false,"parent":"nvidia","selectable":true,"update":false,"wanted":false},{"hint":"Vapor look (cachyos-vapor)","id":"theme","kind":"toggle","label":"Install SteamOS theme","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"no password, lock screen or log out (SDDM)","id":"single","kind":"toggle","label":"Single user mode","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"the app on the desktop, Steamify Terminal in the launcher","id":"launcher","kind":"toggle","label":"Steamify shortcut","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"a notification when there's a new Steamify, never updates by itself","id":"notify","kind":"toggle","label":"Update notifications","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":true},{"hint":"Xbox wireless dongle (xone), Xbox controllers over Bluetooth (xpadneo)","id":"extended_controller_support","kind":"toggle","label":"Extended controller support","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":false},{"hint":"use Steam with the TV remote, TV on/off with the PC (experimental)","id":"cec","kind":"toggle","label":"HDMI-CEC","needs":"","new":false,"on":false,"parent":"","selectable":true,"update":false,"wanted":false}],"pinnedKernel":"7.1.6-1","steamMachine":false,"version":"0.0.0"}
-135
View File
@@ -1,135 +0,0 @@
#!/bin/bash
# Golden-output test for the menu rules (lib/menu.sh, lib/backend.sh): what
# toggling does to WANTED, what plan_changes picks, and the JSON the app and
# the installer read. Hardware and package state are stubbed, so no root, VM
# or hardware is needed.
# bash tests/menu-test.sh compare with menu-test.golden
# bash tests/menu-test.sh --update rewrite the golden file (review the diff!)
# The Steamify checkout (REPO, default: the steamify-cachyos next to this repo)
REPO="${REPO:-$(cd "$(dirname "$0")/../../steamify-cachyos" && pwd)}"; HERE="$(cd "$(dirname "$0")" && pwd)"; cd "$REPO" || exit 1
T="$(mktemp -d)"; trap 'rm -rf "$T"' EXIT
SCRIPT_DIR="$PWD"; HOME="$T/home"; mkdir -p "$HOME"
VERSION=0.0.0
for lib in $(grep -oP '^for lib in \K.*(?=; do$)' steamify.sh); do
source "lib/$lib.sh"
done
info() { :; }; ok() { :; }; warn() { :; }; err() { :; }
# From the entry point.
RESTART_FOR_LOGIN=false; restart_needed() { return 1; }
# Hardware profile and what is "on", set per scenario.
HW=""; ON=""
has() { [[ " $HW " == *" $1 "* ]]; }
nvidia_present() { has nvidia; }
nvidia_available() { has nvidia; }
bigpicture_available() { has nvidia; }
machine_available() { has fremont; }
detect_valve_fremont() { has fremont; }
vram_available() { has vram; }
vram_selectable() { return 0; }
steamgame_available() { has steam; }
kpin_available() { has fremont && [[ " $ON " == *" kpin "* ]]; }
hdmi_available() { return 1; }
bios_available() { return 1; }
bios_selectable() { return 1; }
cec_repair() { return 1; }
launcher_repair() { return 1; }
bios_lookup_newest() { :; }
kernel_overview() { :; }
os_version_refresh() { :; }
for c in "${COMPONENTS[@]}"; do
eval "${c}_status() { [[ \" \$ON \" == *\" $c \"* ]]; }"
done
show() {
# show <label>: WANTED as the ticked ids, then the plan.
local c w=""
for c in "${COMPONENTS[@]}"; do [[ "${WANTED[$c]:-0}" == 1 ]] && w+=" $c"; done
echo "$1"
echo " wanted:$w"
plan_changes
echo " disable: ${TO_DISABLE[*]:-}"
echo " enable: ${TO_ENABLE[*]:-}"
}
scenario() {
# scenario <name> <hardware> <on> [toggle...]
local name="$1"; HW="$2"; ON="$3"; shift 3
rm -rf "$STATE_DIR"; REAPPLY=false
detect_components
local t
for t in "$@"; do toggle_component "$t"; done
show "== $name"
}
run() {
scenario "pc first run" "" ""
scenario "pc first run, untick gaming" "" "" gaming
scenario "pc single on" "" "" gaming single
scenario "pc single then gaming off" "" "" single gaming
scenario "pc boot desktop" "" "" boot
scenario "pc boot desktop then gaming off" "" "" boot gaming
scenario "pc silent only" "" "gaming" silent
scenario "pc all on, theme off" "" "gaming boot silent theme glyphs single launcher steamgame notify" theme
scenario "pc launcher off" "" "launcher steamgame" launcher
scenario "pc steamgame on without launcher" "steam" "" gaming launcher steamgame
scenario "machine first run" "fremont steam vram" ""
scenario "machine silent hidden until boot desktop" "fremont steam vram" "gaming silent"
scenario "machine boot desktop keeps silent" "fremont steam vram" "gaming silent" boot
scenario "machine off" "fremont steam vram" "gaming machine poweroff" machine
scenario "machine poweroff off" "fremont steam vram" "gaming machine poweroff" poweroff
scenario "machine poweroff on brings machine" "fremont steam vram" "gaming" poweroff
scenario "machine kpin removal" "fremont steam vram" "gaming machine poweroff kpin"
scenario "nvidia first run" "nvidia steam" ""
scenario "nvidia bigpicture off" "nvidia steam" "nvidia bigpicture" bigpicture
scenario "nvidia nvsilent on" "nvidia steam" "nvidia bigpicture" nvsilent
scenario "nvidia nvsilent then bigpicture" "nvidia steam" "nvidia" nvsilent bigpicture
scenario "nvidia off" "nvidia steam" "nvidia bigpicture nvsilent" nvidia
scenario "nvidia single" "nvidia steam" "" single
scenario "nvidia gaming already on" "nvidia steam" "gaming" gaming
# Feature versions: an old record is ticked and re-applied.
HW=""; ON="gaming theme"; rm -rf "$STATE_DIR"; REAPPLY=false
state_set features gaming 2.1.0; state_set features theme 2.1.0
detect_components; show "== outdated features"
REAPPLY=true; ON="gaming theme launcher"; detect_components; show "== reapply (a)"
REAPPLY=false
# The app's own rules (backend_apply's normalisation) go through the same plan.
HW="fremont steam vram"; ON=""; rm -rf "$STATE_DIR"
detect_components
local sel
for sel in "single" "boot" "poweroff" "silent" "kpin" "gaming boot" "launcher steamgame"; do
echo "== backend_apply $sel"
backend_sudo() { return 0; }
backend_run_component() { return 0; }
# shellcheck disable=SC2086
backend_apply $sel | jq -c 'select(.event == "plan")'
done
HW="nvidia steam"; ON=""; detect_components
for sel in "bigpicture" "nvsilent" "bigpicture nvsilent" "single" "boot"; do
echo "== backend_apply nvidia $sel"
# shellcheck disable=SC2086
backend_apply $sel | jq -c 'select(.event == "plan")'
done
# JSON for the app and the installer page.
local hw
for hw in "" "fremont steam vram" "nvidia steam"; do
HW="$hw"; ON=""; rm -rf "$STATE_DIR"; detect_components
echo "== defaults_list [$hw]"
defaults_list | jq -S -c '.[]'
echo "== backend_status [$hw]"
backend_status | jq -S -c 'del(.kernel, .cecDevices, .leds)'
done
}
if [[ "${1:-}" == --update ]]; then
run > "$HERE/menu-test.golden" 2>&1
echo "wrote $HERE/menu-test.golden ($(wc -l < "$HERE/menu-test.golden") lines)"
elif diff -u "$HERE/menu-test.golden" <(run 2>&1); then
echo "ok menu rules, plan and JSON match the golden file"
else
echo "FAIL menu rules changed (diff above; --update if intended)"; exit 1
fi
-161
View File
@@ -1,161 +0,0 @@
"""Unit tests of the Python helpers in steamify-cachyos/patches (stdlib only).
Run through tests/python-test.sh (REPO = the Steamify checkout), or:
REPO=../steamify-cachyos python3 -m unittest tests/patches_test.py -v
"""
import contextlib
import importlib.util
import io
import os
import struct
import tempfile
import unittest
from unittest import mock
REPO = os.environ.get("REPO") or os.path.join(os.path.dirname(__file__), "..", "..", "steamify-cachyos")
def load(name, filename):
spec = importlib.util.spec_from_file_location(name, os.path.join(REPO, "patches", filename))
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod
shortcuts = load("steam_shortcuts", "steam-shortcuts.py")
notifier = load("steamify_notifier", "steamify-notifier.py")
class VdfTests(unittest.TestCase):
def test_roundtrip(self):
root = [("shortcuts", [("0", [("appid", 123), ("AppName", "A"), ("tags", [])])])]
self.assertEqual(shortcuts.parse(shortcuts.dump(root)), root)
def test_empty_data_is_an_empty_list(self):
self.assertEqual(shortcuts.parse(b""), [("shortcuts", [])])
def test_unknown_type_is_an_error(self):
with self.assertRaises(ValueError):
shortcuts.parse(b"\x07key\0")
def test_ints_are_unsigned_32_bit(self):
data = shortcuts.dump([("n", -1)])
self.assertEqual(struct.unpack_from("<I", data, 3)[0], 0xFFFFFFFF)
def test_keys_match_regardless_of_case(self):
entry = [("AppName", "x")]
self.assertEqual(shortcuts.get(entry, "appname"), "x")
shortcuts.put(entry, "APPNAME", "y")
self.assertEqual(entry, [("AppName", "y")])
def test_ours(self):
exe = "/home/u/.local/share/steamify/bin/run-app"
self.assertTrue(shortcuts.ours([("Exe", f'"{exe}"')], exe))
# An older install's start script counts as ours: updated, not doubled.
self.assertTrue(shortcuts.ours([("Exe", '"/home/u/.local/share/cachyos-gamescope-boot/bin/run-app"')], exe))
self.assertFalse(shortcuts.ours([("Exe", '"/usr/bin/other"')], exe))
self.assertFalse(shortcuts.ours([("Exe", '"/home/u/games/run-app"')], exe))
class ShortcutsCommandTests(unittest.TestCase):
def setUp(self):
self.dir = tempfile.TemporaryDirectory()
self.addCleanup(self.dir.cleanup)
self.vdf = os.path.join(self.dir.name, "userdata", "1", "config", "shortcuts.vdf")
self.exe = "/home/u/.local/share/steamify/bin/run-app"
def run_cmd(self, *args):
out = io.StringIO()
with contextlib.redirect_stdout(out), contextlib.redirect_stderr(io.StringIO()):
rc = shortcuts.main(["steam-shortcuts.py", *args])
return rc, out.getvalue().strip()
def entries(self):
return shortcuts.shortcuts(shortcuts.load(self.vdf))
def test_add_creates_the_file_and_an_entry(self):
rc, out = self.run_cmd("add", self.vdf, "Steamify", self.exe, "/icon.png", "steamify.desktop")
self.assertEqual(rc, 0)
self.assertTrue(out.startswith("added "))
(_, entry), = self.entries()
self.assertEqual(shortcuts.get(entry, "AppName"), "Steamify")
self.assertEqual(shortcuts.get(entry, "Exe"), f'"{self.exe}"')
# Steam's id for a shortcut has the top bit set.
self.assertGreaterEqual(shortcuts.get(entry, "appid"), 0x80000000)
self.assertEqual(out, f"added {shortcuts.get(entry, 'appid')}")
def test_add_twice_updates_instead_of_doubling(self):
self.run_cmd("add", self.vdf, "Steamify", self.exe, "/a.png", "a.desktop")
rc, out = self.run_cmd("add", self.vdf, "Steamify 2", self.exe, "/b.png", "b.desktop")
self.assertTrue(out.startswith("updated "))
entries = self.entries()
self.assertEqual(len(entries), 1)
self.assertEqual(shortcuts.get(entries[0][1], "AppName"), "Steamify 2")
self.assertEqual(shortcuts.get(entries[0][1], "icon"), "/b.png")
def test_other_entries_are_kept(self):
self.run_cmd("add", self.vdf, "Other", "/usr/bin/other", "", "")
self.run_cmd("add", self.vdf, "Steamify", self.exe, "", "")
self.assertEqual(len(self.entries()), 2)
self.assertEqual([k for k, _ in self.entries()], ["0", "1"])
def test_find(self):
self.assertEqual(self.run_cmd("find", self.vdf, self.exe)[0], 1)
_, out = self.run_cmd("add", self.vdf, "Steamify", self.exe, "", "")
rc, found = self.run_cmd("find", self.vdf, self.exe)
self.assertEqual((rc, found), (0, out.split()[1]))
def test_remove_by_appid_renumbers(self):
self.run_cmd("add", self.vdf, "Other", "/usr/bin/other", "", "")
_, out = self.run_cmd("add", self.vdf, "Steamify", self.exe, "", "")
self.assertEqual(self.run_cmd("remove", self.vdf, out.split()[1])[0], 0)
entries = self.entries()
self.assertEqual([k for k, _ in entries], ["0"])
self.assertEqual(shortcuts.get(entries[0][1], "AppName"), "Other")
def test_remove_of_nothing_leaves_the_file_alone(self):
self.run_cmd("add", self.vdf, "Steamify", self.exe, "", "")
with open(self.vdf, "rb") as f:
before = f.read()
self.assertEqual(self.run_cmd("remove", self.vdf, "999")[0], 0)
with open(self.vdf, "rb") as f:
self.assertEqual(f.read(), before)
def test_unknown_command(self):
self.assertEqual(self.run_cmd("bogus", self.vdf)[0], 2)
class NotifierTests(unittest.TestCase):
def test_version(self):
self.assertEqual(notifier.version("v2.11.1"), (2, 11, 1))
self.assertEqual(notifier.version("2.9.0"), (2, 9, 0))
self.assertIsNone(notifier.version("nightly"))
def test_versions_compare_as_numbers(self):
self.assertGreater(notifier.version("2.10.0"), notifier.version("2.9.0"))
def pending(self, new, seen="", skipped=""):
values = {"seen": seen, "skipped": skipped}
with mock.patch.object(notifier, "state", lambda key: values[key]):
return notifier.pending(new)
def test_newer_than_seen(self):
self.assertTrue(self.pending("2.12.0", seen="2.11.1"))
def test_same_or_older_is_not_pending(self):
self.assertFalse(self.pending("2.11.1", seen="2.11.1"))
self.assertFalse(self.pending("2.9.0", seen="2.11.1"))
def test_skipped_version_is_not_pending(self):
self.assertFalse(self.pending("2.12.0", seen="2.11.1", skipped="2.12.0"))
def test_nothing_seen_yet(self):
self.assertTrue(self.pending("2.12.0", seen=""))
def test_unparsable_tag_is_not_pending(self):
# A release tag like "nightly" must not crash the daily check.
self.assertFalse(self.pending("nightly", seen="2.11.1"))
if __name__ == "__main__":
unittest.main()
-12
View File
@@ -1,12 +0,0 @@
#!/bin/bash
# Unit tests of the Python helpers in steamify-cachyos/patches (steam-shortcuts.py,
# steamify-notifier.py). No root, VM or hardware needed: bash tests/python-test.sh
# The Steamify checkout (REPO, default: the steamify-cachyos next to this repo)
REPO="${REPO:-$(cd "$(dirname "$0")/../../steamify-cachyos" && pwd)}"
export REPO
cd "$(dirname "$0")/.." || exit 1
if python3 -B -m unittest tests/patches_test.py 2>&1 | tail -n 25 | tee /dev/stderr | grep -q '^OK'; then
echo "ok Python helpers"
else
echo "FAIL Python helpers"; exit 1
fi