Compare commits

..
3 Commits
53 changed files with 480 additions and 223 deletions

No files matched your search

-2
View File
@@ -22,7 +22,6 @@ share/*
!share/vminstall-post.sh !share/vminstall-post.sh
!share/bootloader-test/ !share/bootloader-test/
!share/vmtest/ !share/vmtest/
!share/uitest/
# Belt and braces, anywhere in the tree # Belt and braces, anywhere in the tree
*.iso *.iso
@@ -35,4 +34,3 @@ share/*
*.tmp *.tmp
host-keys.pub host-keys.pub
__pycache__/ __pycache__/
!share/golden/
-4
View File
@@ -4,10 +4,6 @@ All notable changes, per version and per commit. Versions follow
[Semantic Versioning](https://semver.org/) and were numbered from the start [Semantic Versioning](https://semver.org/) and were numbered from the start
of the history. 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 ## 0.5.0 - 2026-10-02
The whole automated test (boot loaders plus suites), the Steamify ISO pipeline, 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 $*"; } pass() { echo "PASS $*"; }; fail() { echo "FAIL $*"; }
sudo mountpoint -q /mnt || sudo mount -t 9p -o trans=virtio,version=9p2000.L repo /mnt sudo mountpoint -q /mnt || sudo mount -t 9p -o trans=virtio,version=9p2000.L repo /mnt
cd /mnt || exit 1 cd /mnt || exit 1
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 $(grep -oP '^for lib in \K.*(?=; do$)' steamify.sh); do
# shellcheck source=/dev/null # shellcheck source=/dev/null
. "lib/$lib.sh" 2>/dev/null . "lib/$lib.sh" 2>/dev/null
done done
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":["gaming","boot"]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":["gaming"]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":[]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":[]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":[]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":["gaming","single"]}
-1
View File
@@ -1 +0,0 @@
{"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}]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":[]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":[]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":[]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":["nvidia","bigpicture"]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":[]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":["single"]}
@@ -1 +0,0 @@
{"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}]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":["gaming","boot"]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":["gaming"]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":[]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":[]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":["machine","poweroff"]}
@@ -1 +0,0 @@
{"event":"plan","disable":[],"enable":["gaming","single"]}
@@ -1 +0,0 @@
{"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}]}
@@ -1,3 +0,0 @@
NAME="CachyOS Linux"
ID=cachyos
ID_LIKE=arch
-2
View File
@@ -1,2 +0,0 @@
sddm
plasma-desktop
@@ -1 +0,0 @@
PRIME B650
@@ -1 +0,0 @@
ASUSTeK
@@ -1,3 +0,0 @@
NAME="CachyOS Linux"
ID=cachyos
ID_LIKE=arch
-1
View File
@@ -1 +0,0 @@
nvidia_drm
-3
View File
@@ -1,3 +0,0 @@
sddm
plasma-desktop
nvidia-utils
@@ -1 +0,0 @@
PRIME B650
@@ -1 +0,0 @@
ASUSTeK
@@ -1 +0,0 @@
0x030000
@@ -1 +0,0 @@
0x10de
@@ -1,3 +0,0 @@
NAME="CachyOS Linux"
ID=cachyos
ID_LIKE=arch
@@ -1,2 +0,0 @@
sddm
plasma-desktop
@@ -1 +0,0 @@
Fremont
@@ -1 +0,0 @@
Valve
-33
View File
@@ -1,33 +0,0 @@
#!/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
@@ -1,32 +0,0 @@
#!/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
@@ -1,3 +0,0 @@
#!/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
@@ -1,10 +0,0 @@
#!/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
@@ -1,4 +0,0 @@
#!/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
@@ -1,13 +0,0 @@
#!/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
@@ -1,2 +0,0 @@
#!/bin/bash
if [[ "$1" == -r ]]; then echo 7.0.0-fixture-cachyos; else command uname "$@"; fi
-42
View File
@@ -1,42 +0,0 @@
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())
@@ -1,30 +0,0 @@
# 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 sudo mountpoint -q /mnt || sudo mount -t 9p -o trans=virtio,version=9p2000.L repo /mnt
cd /mnt || exit 1 cd /mnt || exit 1
export SCRIPT_DIR=/mnt # steamify.sh sets it; the libs alone read patches/ and services/ from it 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 nvidia controllers cec boot-session vapor-theme steamos-extras bios desktop-shortcut wizard-shortcut steam-game update-notifier; do for lib in $(grep -oP '^for lib in \K.*(?=; do$)' steamify.sh); do
# shellcheck source=/dev/null # shellcheck source=/dev/null
. "lib/$lib.sh" 2>/dev/null . "lib/$lib.sh" 2>/dev/null
done done
+170
View File
@@ -0,0 +1,170 @@
== 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
@@ -0,0 +1,135 @@
#!/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
@@ -0,0 +1,161 @@
"""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
@@ -0,0 +1,12 @@
#!/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