162 lines
5.7 KiB
Bash
Executable File
162 lines
5.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
service="$repo_dir/config/dot/quickshell/services/Wallpaper.qml"
|
|
fixture="$(mktemp -d /tmp/panama-wallpaper-service.XXXXXX)"
|
|
config_home="$fixture/config"
|
|
state_home="$fixture/state"
|
|
config_path="$config_home/quickshell"
|
|
harness="$config_path/wallpaper-service-harness.qml"
|
|
test_bin="$fixture/bin"
|
|
command_log="$fixture/commands.log"
|
|
active_state="$fixture/active.json"
|
|
control="$fixture/control"
|
|
shell_log="$fixture/quickshell.log"
|
|
harness_pid=""
|
|
|
|
fail() {
|
|
printf 'wallpaper service contract: %s\n' "$1" >&2
|
|
[[ -s "$shell_log" ]] && sed -n '1,180p' "$shell_log" >&2
|
|
exit 1
|
|
}
|
|
|
|
for needle in 'property var activeByOutput' 'function applyPolicy' 'function setSingle'; do
|
|
rg -Fq "$needle" "$service" || fail "Wallpaper service is missing $needle"
|
|
done
|
|
|
|
instances_for_harness() {
|
|
qs list --all 2>/dev/null | awk -v expected="$harness" '
|
|
/^Instance / { pid = "" }
|
|
/^[[:space:]]*Process ID:/ { pid = $3 }
|
|
/^[[:space:]]*Config path:/ {
|
|
path = $0
|
|
sub(/^[[:space:]]*Config path: /, "", path)
|
|
if (path == expected && pid ~ /^[0-9]+$/) print pid
|
|
}
|
|
'
|
|
}
|
|
|
|
cleanup() {
|
|
if [[ "$harness_pid" =~ ^[0-9]+$ ]] && kill -0 "$harness_pid" 2>/dev/null; then
|
|
kill "$harness_pid" 2>/dev/null || true
|
|
fi
|
|
rm -rf "$fixture"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
mkdir -p "$config_home/panama" "$state_home" "$test_bin"
|
|
cp -a "$repo_dir/config/dot/quickshell" "$config_path"
|
|
printf '%s\n' '{}' >"$config_home/panama/settings.json"
|
|
printf '%s\n' '{}' >"$active_state"
|
|
: >"$command_log"
|
|
: >"$control"
|
|
|
|
cat >"$test_bin/hyprctl" <<'EOF'
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
printf '%s' 'hyprctl' >>"$PANAMA_WALLPAPER_COMMAND_LOG"
|
|
printf ' %s' "$@" >>"$PANAMA_WALLPAPER_COMMAND_LOG"
|
|
printf '\n' >>"$PANAMA_WALLPAPER_COMMAND_LOG"
|
|
|
|
if [[ "${1:-}" == "hyprpaper" && "${2:-}" == "wallpaper" ]]; then
|
|
request="${3:-}"
|
|
output="${request%%,*}"
|
|
path="${request#*,}"
|
|
if [[ "$(<"$PANAMA_WALLPAPER_CONTROL")" == fail-second && "$output" == HDMI-A-1 ]]; then
|
|
exit 7
|
|
fi
|
|
next="$(jq -c --arg output "$output" --arg path "$path" '. + {($output):$path}' \
|
|
"$PANAMA_WALLPAPER_ACTIVE_STATE")"
|
|
printf '%s\n' "$next" >"$PANAMA_WALLPAPER_ACTIVE_STATE"
|
|
exit 0
|
|
fi
|
|
|
|
if [[ "${1:-}" == "hyprpaper" && "${2:-}" == "listactive" ]]; then
|
|
if [[ "$(<"$PANAMA_WALLPAPER_CONTROL")" == wrong ]]; then
|
|
printf 'DP-2: /images/wrong.jpg\nHDMI-A-1: /images/b.jpg\n'
|
|
exit 0
|
|
fi
|
|
jq -r 'to_entries[] | "\(.key): \(.value)"' "$PANAMA_WALLPAPER_ACTIVE_STATE"
|
|
exit 0
|
|
fi
|
|
|
|
exit 91
|
|
EOF
|
|
chmod +x "$test_bin/hyprctl"
|
|
|
|
qs_for_harness() {
|
|
env_args=(
|
|
XDG_CONFIG_HOME="$config_home"
|
|
XDG_STATE_HOME="$state_home"
|
|
PATH="$test_bin:$PATH"
|
|
PANAMA_WALLPAPER_COMMAND_LOG="$command_log"
|
|
PANAMA_WALLPAPER_ACTIVE_STATE="$active_state"
|
|
PANAMA_WALLPAPER_CONTROL="$control"
|
|
)
|
|
if [[ "$harness_pid" =~ ^[0-9]+$ && "${1:-}" == "ipc" ]]; then
|
|
env "${env_args[@]}" qs -p "$harness" ipc --pid "$harness_pid" "${@:2}"
|
|
else
|
|
env "${env_args[@]}" qs -p "$harness" "$@"
|
|
fi
|
|
}
|
|
|
|
wait_idle() {
|
|
local status=""
|
|
for _ in $(seq 1 80); do
|
|
status="$(qs_for_harness ipc call wallpaper-service-test status)"
|
|
[[ "$(jq -r '.busy' <<<"$status")" == false ]] && { printf '%s' "$status"; return; }
|
|
sleep 0.1
|
|
done
|
|
fail "wallpaper transaction did not settle: $status"
|
|
}
|
|
|
|
qs_for_harness --daemonize >"$shell_log" 2>&1 || fail 'isolated service harness did not launch'
|
|
for _ in $(seq 1 60); do
|
|
harness_pid="$(instances_for_harness | head -1)"
|
|
if [[ "$harness_pid" =~ ^[0-9]+$ ]] \
|
|
&& qs_for_harness ipc show 2>/dev/null | rg -q '^target wallpaper-service-test$'; then
|
|
break
|
|
fi
|
|
sleep 0.1
|
|
done
|
|
[[ "$harness_pid" =~ ^[0-9]+$ ]] || fail 'isolated service harness process did not start'
|
|
wait_idle >/dev/null
|
|
|
|
: >"$command_log"
|
|
printf '%s\n' '{}' >"$active_state"
|
|
qs_for_harness ipc call wallpaper-service-test applyPerMonitor >/dev/null
|
|
success="$(wait_idle)"
|
|
expected_calls=$'hyprctl hyprpaper wallpaper DP-2,/images/a.jpg\nhyprctl hyprpaper wallpaper HDMI-A-1,/images/b.jpg\nhyprctl hyprpaper listactive'
|
|
[[ "$(<"$command_log")" == "$expected_calls" ]] || fail "transaction argv/order was wrong: $(<"$command_log")"
|
|
jq -e '.lastError == "" and .mode == "per-monitor" and .path == "/images/a.jpg"
|
|
and .assignments == {"HDMI-A-1":"/images/b.jpg"}
|
|
and .activeByOutput == {"DP-2":"/images/a.jpg","HDMI-A-1":"/images/b.jpg"}' \
|
|
<<<"$success" >/dev/null || fail "verified policy was not persisted: $success"
|
|
|
|
printf 'wrong\n' >"$control"
|
|
: >"$command_log"
|
|
qs_for_harness ipc call wallpaper-service-test applySingle /images/c.jpg >/dev/null
|
|
wrong="$(wait_idle)"
|
|
jq -e '.path == "/images/a.jpg" and .mode == "per-monitor"
|
|
and .lastError == "Hyprpaper did not confirm that background."' \
|
|
<<<"$wrong" >/dev/null || fail "wrong readback persisted an unverified policy: $wrong"
|
|
|
|
printf 'fail-second\n' >"$control"
|
|
: >"$command_log"
|
|
qs_for_harness ipc call wallpaper-service-test applyPerMonitor >/dev/null
|
|
failed="$(wait_idle)"
|
|
jq -e '.path == "/images/a.jpg" and .mode == "per-monitor"
|
|
and .lastError == "Hyprpaper did not apply that background."' \
|
|
<<<"$failed" >/dev/null || fail "partial output failure changed policy: $failed"
|
|
[[ "$(tail -1 "$command_log")" == 'hyprctl hyprpaper wallpaper HDMI-A-1,/images/b.jpg' ]] \
|
|
|| fail 'transaction continued after the failed output'
|
|
|
|
if rg -n 'ReferenceError|TypeError|Binding loop|Unable to assign|Cannot assign' "$shell_log"; then
|
|
fail 'service harness emitted a QML runtime warning'
|
|
fi
|
|
|
|
printf 'wallpaper service contract: PASS\n'
|