Add power profiles to Power & Lock
The same Power Saver / Balanced / Performance choice GNOME's Power panel offers, and the daemon behind it was already running here -- it simply had no control anywhere in Panama. This machine has been sitting on "performance" with nothing to say so. Talks to the net.hadess.PowerProfiles interface rather than to a binary. Fedora 44 implements it with tuned-ppd instead of power-profiles-daemon, and powerprofilesctl is not installed at all, so anything shelling out to that command would have found nothing while the service was right there. Setting a profile needs no privileges: the daemon accepts a property write from the active session user. Not a stored preference. The daemon owns the profile, it survives Panama restarts, and anything else on the system can change it, so a copy in settings.json would drift -- the same reasoning as monitor brightness. PerformanceDegraded is surfaced because it is what makes the setting a lie: a thermally throttled machine reports "performance" while behaving otherwise, and that is worth saying out loud. The contract stubs busctl, because the real daemon is a system service shared with everything else on the machine and a test that flipped the daily driver to power-saver and then died would leave it there. It pins the parsing in particular: busctl renders the Profiles property flat, so profile names and driver names arrive in one stream, and a pattern loose enough to match both reports the driver as an extra profile. On this machine the driver is called "tuned", which reads exactly like a plausible fourth profile -- verified the contract catches that, and catches an unvalidated name reaching the system service. Claude-Session: https://claude.ai/code/session_01BRvzt4H8XXLPVH5MyYdk9L
This commit is contained in:
Executable
+103
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# panama-power-profile reads and sets the system power profile.
|
||||
#
|
||||
# Runs against a stubbed busctl. The real daemon is a SYSTEM service shared with
|
||||
# everything else on the machine, and a test that flipped the daily driver into
|
||||
# power-saver and crashed before restoring would leave it there.
|
||||
#
|
||||
# The parsing is the fragile part. busctl renders the Profiles property flat:
|
||||
#
|
||||
# v aa{sv} 3 2 "Profile" s "power-saver" "Driver" s "tuned" 2 "Profile" ...
|
||||
#
|
||||
# so profile names and driver names sit in the same stream. A pattern loose
|
||||
# enough to match both reports the driver as an extra profile -- and on this
|
||||
# machine the driver is literally called "tuned", which reads exactly like a
|
||||
# plausible fourth profile.
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
helper="$repo_dir/config/dot/quickshell/scripts/panama-power-profile"
|
||||
|
||||
fail() {
|
||||
printf 'power profile contract: %s\n' "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
stub_dir="$(mktemp -d /tmp/panama-power.XXXXXX)"
|
||||
trap 'rm -rf "$stub_dir"' EXIT
|
||||
|
||||
cat >"$stub_dir/busctl" <<'STUB'
|
||||
#!/usr/bin/env bash
|
||||
# Records set-property calls so the test can assert what was written.
|
||||
case "${1:-}" in
|
||||
status)
|
||||
[[ "${PANAMA_POWER_FAKE:-up}" == "down" ]] && exit 1
|
||||
exit 0 ;;
|
||||
get-property)
|
||||
case "${5:-}" in
|
||||
ActiveProfile) printf 's "performance"\n' ;;
|
||||
PerformanceDegraded) printf 's "%s"\n' "${PANAMA_POWER_DEGRADED:-}" ;;
|
||||
Profiles)
|
||||
if [[ "${PANAMA_POWER_FAKE:-up}" == "empty" ]]; then
|
||||
printf 'v aa{sv} 0\n'
|
||||
else
|
||||
printf 'v aa{sv} 3 2 "Profile" s "power-saver" "Driver" s "tuned" 2 "Profile" s "balanced" "Driver" s "tuned" 2 "Profile" s "performance" "Driver" s "tuned"\n'
|
||||
fi ;;
|
||||
esac
|
||||
exit 0 ;;
|
||||
set-property)
|
||||
printf '%s\n' "${!#}" >>"$PANAMA_POWER_SET_LOG"
|
||||
exit 0 ;;
|
||||
esac
|
||||
exit 0
|
||||
STUB
|
||||
chmod +x "$stub_dir/busctl"
|
||||
|
||||
export PANAMA_POWER_SET_LOG="$stub_dir/sets.log"
|
||||
: >"$PANAMA_POWER_SET_LOG"
|
||||
|
||||
run() { PATH="$stub_dir:$PATH" "$helper" "$@"; }
|
||||
|
||||
# ── Parsing ──────────────────────────────────────────────────────────────────
|
||||
out="$(run list)"
|
||||
jq -e . >/dev/null 2>&1 <<<"$out" || fail "list did not emit JSON: $out"
|
||||
|
||||
[[ "$(jq -r '.profiles | length' <<<"$out")" == "3" ]] \
|
||||
|| fail "expected exactly three profiles; a fourth usually means the Driver value was parsed as one: $out"
|
||||
|
||||
jq -e '.profiles == ["power-saver", "balanced", "performance"]' >/dev/null <<<"$out" \
|
||||
|| fail "profiles were parsed wrongly or reordered: $out"
|
||||
|
||||
jq -e '.profiles | index("tuned") == null' >/dev/null <<<"$out" \
|
||||
|| fail 'the driver name "tuned" was reported as a profile'
|
||||
|
||||
[[ "$(jq -r '.active' <<<"$out")" == "performance" ]] \
|
||||
|| fail "the active profile was not read: $out"
|
||||
|
||||
# ── Degradation is surfaced, since it makes the active profile a lie ─────────
|
||||
out="$(PANAMA_POWER_DEGRADED="lap-detected" run list)"
|
||||
[[ "$(jq -r '.degraded' <<<"$out")" == "lap-detected" ]] \
|
||||
|| fail "a degraded performance state was not reported: $out"
|
||||
|
||||
# ── Setting ──────────────────────────────────────────────────────────────────
|
||||
run set balanced
|
||||
[[ "$(tail -1 "$PANAMA_POWER_SET_LOG")" == "balanced" ]] \
|
||||
|| fail "set did not write the requested profile: $(cat "$PANAMA_POWER_SET_LOG")"
|
||||
|
||||
before="$(wc -l <"$PANAMA_POWER_SET_LOG")"
|
||||
run set 'evil; rm -rf /' 2>/dev/null
|
||||
[[ "$(wc -l <"$PANAMA_POWER_SET_LOG")" == "$before" ]] \
|
||||
|| fail 'a profile name with shell metacharacters reached the system service'
|
||||
|
||||
# ── No daemon, and a daemon with nothing to offer, are both states ───────────
|
||||
out="$(PANAMA_POWER_FAKE=down run list)"
|
||||
jq -e '.profiles == [] and .error != ""' >/dev/null <<<"$out" \
|
||||
|| fail "a missing power daemon must be reported with a reason: $out"
|
||||
|
||||
out="$(PANAMA_POWER_FAKE=empty run list)"
|
||||
jq -e '.profiles == [] and .error != ""' >/dev/null <<<"$out" \
|
||||
|| fail "a daemon offering no profiles must be reported, not shown as an empty card: $out"
|
||||
|
||||
printf 'power profile contract: PASS\n'
|
||||
Reference in New Issue
Block a user