Fix Home action completion and test isolation
This commit is contained in:
@@ -2,25 +2,84 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
config_path="$repo_dir/config/dot/quickshell"
|
||||
state_home="$(mktemp -d /tmp/panama-control-center-state.XXXXXX)"
|
||||
shell_log="$state_home/quickshell.log"
|
||||
|
||||
fail() {
|
||||
printf 'Control Center services contract: %s\n' "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
qs_for_test() {
|
||||
QS_CONFIG_PATH="$config_path" XDG_STATE_HOME="$state_home" \
|
||||
qs -p "$config_path" "$@"
|
||||
}
|
||||
|
||||
stop_test_shell() {
|
||||
qs_for_test kill >/dev/null 2>&1 || true
|
||||
for _ in $(seq 1 80); do
|
||||
if ! qs_for_test list 2>/dev/null | rg '^Instance ' >/dev/null \
|
||||
&& ! qs_for_test ipc show >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
qs ipc call kdeconnect reset >/dev/null 2>&1 || true
|
||||
qs ipc call home-assistant reset >/dev/null 2>&1 || true
|
||||
qs ipc call status-events reset >/dev/null 2>&1 || true
|
||||
qs ipc call quicksettings close >/dev/null 2>&1 || true
|
||||
qs_for_test ipc call kdeconnect reset >/dev/null 2>&1 || true
|
||||
qs_for_test ipc call home-assistant reset >/dev/null 2>&1 || true
|
||||
qs_for_test ipc call status-events reset >/dev/null 2>&1 || true
|
||||
qs_for_test ipc call quicksettings close >/dev/null 2>&1 || true
|
||||
if stop_test_shell; then
|
||||
rm -rf "$state_home"
|
||||
else
|
||||
printf 'Control Center services contract: branch shell did not stop; retained %s\n' \
|
||||
"$state_home" >&2
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
qs ipc show | rg -q '^target kdeconnect$' \
|
||||
start_test_shell() {
|
||||
stop_test_shell || fail 'pre-existing branch shell did not stop cleanly'
|
||||
qs_for_test --daemonize >"$shell_log" 2>&1
|
||||
for _ in $(seq 1 80); do
|
||||
if qs_for_test ipc show 2>/dev/null | rg '^target home-assistant$' >/dev/null; then
|
||||
return
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
sed -n '1,200p' "$shell_log" >&2
|
||||
fail 'isolated branch shell did not start'
|
||||
}
|
||||
|
||||
wait_for_home_status() {
|
||||
local filter="$1"
|
||||
local message="$2"
|
||||
local status=""
|
||||
|
||||
for _ in $(seq 1 80); do
|
||||
status="$(qs_for_test ipc call home-assistant status)"
|
||||
if jq -e "$filter" <<<"$status" >/dev/null; then
|
||||
return
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
printf 'Last Home status: %s\n' "$status" >&2
|
||||
fail "$message"
|
||||
}
|
||||
|
||||
start_test_shell
|
||||
|
||||
qs_for_test ipc show | rg '^target kdeconnect$' >/dev/null \
|
||||
|| fail 'KDE Connect IPC target is missing'
|
||||
qs ipc show | rg -q '^target home-assistant$' \
|
||||
qs_for_test ipc show | rg '^target home-assistant$' >/dev/null \
|
||||
|| fail 'Home Assistant IPC target is missing'
|
||||
|
||||
qs ipc call kdeconnect fixture reachable >/dev/null
|
||||
qs_for_test ipc call kdeconnect fixture reachable >/dev/null
|
||||
jq -e '
|
||||
.fixture == true and
|
||||
.available == true and
|
||||
@@ -28,35 +87,35 @@ jq -e '
|
||||
.actionCount == 4 and
|
||||
.transferActive == false and
|
||||
.ongoingCount == 0
|
||||
' <<<"$(qs ipc call kdeconnect status)" >/dev/null \
|
||||
' <<<"$(qs_for_test ipc call kdeconnect status)" >/dev/null \
|
||||
|| fail 'reachable phone fixture is malformed'
|
||||
|
||||
qs ipc call kdeconnect fixture offline >/dev/null
|
||||
qs_for_test ipc call kdeconnect fixture offline >/dev/null
|
||||
jq -e '
|
||||
.fixture == true and
|
||||
.available == true and
|
||||
.reachable == false and
|
||||
.pairedCount == 1 and
|
||||
.ongoingCount == 0
|
||||
' <<<"$(qs ipc call kdeconnect status)" >/dev/null \
|
||||
' <<<"$(qs_for_test ipc call kdeconnect status)" >/dev/null \
|
||||
|| fail 'offline phone fixture is malformed'
|
||||
|
||||
qs ipc call kdeconnect fixture transfer >/dev/null
|
||||
qs_for_test ipc call kdeconnect fixture transfer >/dev/null
|
||||
jq -e '
|
||||
.fixture == true and
|
||||
.transferActive == true and
|
||||
.transferFileName == "Fixture document.pdf" and
|
||||
.ongoingCount == 1
|
||||
' <<<"$(qs ipc call kdeconnect status)" >/dev/null \
|
||||
' <<<"$(qs_for_test ipc call kdeconnect status)" >/dev/null \
|
||||
|| fail 'phone transfer did not enter Ongoing'
|
||||
|
||||
qs ipc call kdeconnect cancel >/dev/null
|
||||
qs_for_test ipc call kdeconnect cancel >/dev/null
|
||||
jq -e '.transferActive == false and .ongoingCount == 0' \
|
||||
<<<"$(qs ipc call kdeconnect status)" >/dev/null \
|
||||
<<<"$(qs_for_test ipc call kdeconnect status)" >/dev/null \
|
||||
|| fail 'phone transfer did not leave Ongoing'
|
||||
|
||||
qs ipc call home-assistant fixture ready >/dev/null
|
||||
home_ready="$(qs ipc call home-assistant status)"
|
||||
qs_for_test ipc call home-assistant fixture ready >/dev/null
|
||||
home_ready="$(qs_for_test ipc call home-assistant status)"
|
||||
jq -e '
|
||||
.fixture == true and
|
||||
.phase == "ready" and
|
||||
@@ -76,27 +135,57 @@ jq -e '
|
||||
"Bedroom"
|
||||
] and
|
||||
.stale == false and
|
||||
.busy == false and
|
||||
.lastError == ""
|
||||
' <<<"$home_ready" >/dev/null \
|
||||
|| fail 'ready Home fixture is malformed'
|
||||
|
||||
qs ipc call home-assistant brightness light.fixture_living 64 >/dev/null
|
||||
qs_for_test ipc call home-assistant brightness light.fixture_living 64 >/dev/null
|
||||
jq -e '
|
||||
.entities[] |
|
||||
select(.id == "light.fixture_living") |
|
||||
.active == true and .state == "on" and .brightnessPct == 64
|
||||
' <<<"$(qs ipc call home-assistant status)" >/dev/null \
|
||||
' <<<"$(qs_for_test ipc call home-assistant status)" >/dev/null \
|
||||
|| fail 'Home brightness fixture did not update local catalog state'
|
||||
|
||||
qs ipc call home-assistant toggle light.fixture_living >/dev/null
|
||||
qs_for_test ipc call home-assistant toggle light.fixture_living >/dev/null
|
||||
jq -e '
|
||||
.entities[] |
|
||||
select(.id == "light.fixture_living") |
|
||||
.active == false and .state == "off"
|
||||
' <<<"$(qs ipc call home-assistant status)" >/dev/null \
|
||||
' <<<"$(qs_for_test ipc call home-assistant status)" >/dev/null \
|
||||
|| fail 'Home toggle fixture did not update local catalog state'
|
||||
|
||||
qs ipc call home-assistant fixture missing-selected >/dev/null
|
||||
qs_for_test ipc call home-assistant fixture process-actions >/dev/null
|
||||
qs_for_test ipc call home-assistant brightness light.fixture_living 64 >/dev/null
|
||||
qs_for_test ipc call home-assistant toggle light.fixture_hall >/dev/null
|
||||
jq -e '
|
||||
.busy == true and
|
||||
.busyEntityIds == ["light.fixture_living", "light.fixture_hall"] and
|
||||
.pendingBrightness["light.fixture_living"] == 64
|
||||
' <<<"$(qs_for_test ipc call home-assistant status)" >/dev/null \
|
||||
|| fail 'process-backed Home actions did not remain per-entity busy'
|
||||
wait_for_home_status '
|
||||
.busy == false and
|
||||
.busyEntityIds == [] and
|
||||
.pendingBrightness == {} and
|
||||
(.entities[] | select(.id == "light.fixture_living") | .active == true and .brightnessPct == 64) and
|
||||
(.entities[] | select(.id == "light.fixture_hall") | .active == true)
|
||||
' 'process-backed Home actions did not complete in queue order'
|
||||
|
||||
qs_for_test ipc call home-assistant fixture process-no-output >/dev/null
|
||||
qs_for_test ipc call home-assistant toggle light.fixture_kitchen >/dev/null
|
||||
qs_for_test ipc call home-assistant toggle light.fixture_hall >/dev/null
|
||||
wait_for_home_status '
|
||||
.phase == "ready" and
|
||||
.busy == false and
|
||||
.busyEntityIds == [] and
|
||||
.entityErrors["light.fixture_kitchen"] == "action-failed" and
|
||||
(.entityErrors["light.fixture_hall"] // "") == "" and
|
||||
(.entities[] | select(.id == "light.fixture_hall") | .active == true)
|
||||
' 'nonzero no-output Home action did not fail safely and continue the queue'
|
||||
|
||||
qs_for_test ipc call home-assistant fixture missing-selected >/dev/null
|
||||
jq -e '
|
||||
.fixture == true and
|
||||
.phase == "ready" and
|
||||
@@ -111,10 +200,10 @@ jq -e '
|
||||
.active == false and
|
||||
.dimmable == false and
|
||||
.brightnessPct == 0)
|
||||
' <<<"$(qs ipc call home-assistant status)" >/dev/null \
|
||||
' <<<"$(qs_for_test ipc call home-assistant status)" >/dev/null \
|
||||
|| fail 'missing Home selection was not retained as unavailable'
|
||||
|
||||
qs ipc call home-assistant fixture action-error >/dev/null
|
||||
qs_for_test ipc call home-assistant fixture action-error >/dev/null
|
||||
jq -e '
|
||||
.fixture == true and
|
||||
.phase == "ready" and
|
||||
@@ -122,10 +211,10 @@ jq -e '
|
||||
.entityErrors["light.fixture_kitchen"] == "request-failed" and
|
||||
(.entityErrors["light.fixture_hall"] // "") == "" and
|
||||
.lastError == ""
|
||||
' <<<"$(qs ipc call home-assistant status)" >/dev/null \
|
||||
' <<<"$(qs_for_test ipc call home-assistant status)" >/dev/null \
|
||||
|| fail 'Home action error was not isolated to one entity'
|
||||
|
||||
qs ipc call home-assistant fixture stale >/dev/null
|
||||
qs_for_test ipc call home-assistant fixture stale >/dev/null
|
||||
jq -e '
|
||||
.fixture == true and
|
||||
.phase == "degraded" and
|
||||
@@ -134,10 +223,10 @@ jq -e '
|
||||
.visibleCount == 4 and
|
||||
.stale == true and
|
||||
.lastError == "unreachable"
|
||||
' <<<"$(qs ipc call home-assistant status)" >/dev/null \
|
||||
' <<<"$(qs_for_test ipc call home-assistant status)" >/dev/null \
|
||||
|| fail 'stale Home fixture did not retain entities'
|
||||
|
||||
qs ipc call home-assistant fixture unavailable >/dev/null
|
||||
qs_for_test ipc call home-assistant fixture unavailable >/dev/null
|
||||
jq -e '
|
||||
.fixture == true and
|
||||
.phase == "unavailable" and
|
||||
@@ -145,9 +234,11 @@ jq -e '
|
||||
.configuredCount == 0 and
|
||||
.visibleCount == 0 and
|
||||
.lastError == "not-configured"
|
||||
' <<<"$(qs ipc call home-assistant status)" >/dev/null \
|
||||
' <<<"$(qs_for_test ipc call home-assistant status)" >/dev/null \
|
||||
|| fail 'unavailable Home fixture is malformed'
|
||||
|
||||
trap - EXIT
|
||||
cleanup
|
||||
[[ ! -e "$state_home" ]] \
|
||||
|| fail 'temporary Home preferences state was not removed after shell exit'
|
||||
printf 'Control Center services contract: PASS\n'
|
||||
|
||||
Reference in New Issue
Block a user