Merge pull request #10246 from omacom/add-openclaw-ai-app
Add OpenClaw as a desktop app and a coding agent
This commit is contained in:
17 files changed
+1088
-6
No files matched your search
@@ -542,3 +542,68 @@ fi
|
||||
grep -F "missing is not installed" "$test_tmp/missing-output" >/dev/null ||
|
||||
fail "agent launcher explains when the default command is missing"
|
||||
pass "agent launcher reports a missing default command"
|
||||
|
||||
# OpenClaw comes from its pacman package, not mise: choosing it must route
|
||||
# through omarchy-install-openclaw-cli and never touch a mise environment.
|
||||
cat >"$mock_bin/omarchy-pkg-present" <<'SH'
|
||||
#!/bin/bash
|
||||
[[ $1 == openclaw && ${OMARCHY_TEST_OPENCLAW_INSTALLED:-false} == "true" ]]
|
||||
SH
|
||||
cat >"$mock_bin/omarchy-pkg-add" <<'SH'
|
||||
#!/bin/bash
|
||||
printf '%s\n' "pkg-add $*" >>"$OMARCHY_TEST_STUB_LOG"
|
||||
SH
|
||||
cat >"$mock_bin/omarchy-launch-openclaw" <<'SH'
|
||||
#!/bin/bash
|
||||
printf '%s\0' omarchy-launch-openclaw "$@" >"$OMARCHY_TEST_AGENT_INLINE_LOG"
|
||||
SH
|
||||
cat >"$mock_bin/openclaw" <<'SH'
|
||||
#!/bin/bash
|
||||
exit 0
|
||||
SH
|
||||
chmod +x "$mock_bin/omarchy-pkg-present" "$mock_bin/omarchy-pkg-add" \
|
||||
"$mock_bin/omarchy-launch-openclaw" "$mock_bin/openclaw"
|
||||
|
||||
: >"$launch_log"
|
||||
: >"$terminal_log"
|
||||
: >"$mise_history"
|
||||
OMARCHY_TEST_OPENCLAW_INSTALLED=true omarchy-default-agent openclaw
|
||||
read -r chosen <"$agent_file"
|
||||
[[ $chosen == openclaw ]] || fail "choosing OpenClaw records it as the default agent"
|
||||
mapfile -d '' -t launch_args <"$launch_log"
|
||||
[[ ${launch_args[*]} == "--app-id=org.omarchy.agent omarchy-launch-openclaw --tui" ]] ||
|
||||
fail "choosing OpenClaw launches its terminal UI"
|
||||
[[ ! -s $terminal_log ]] || fail "an installed OpenClaw needs no install terminal"
|
||||
! grep -q 'use -g openclaw' "$mise_history" || fail "OpenClaw never installs through mise"
|
||||
pass "choosing OpenClaw uses the package and launches its terminal UI"
|
||||
|
||||
: >"$terminal_log"
|
||||
OMARCHY_TEST_OPENCLAW_INSTALLED=false omarchy-default-agent openclaw
|
||||
mapfile -d '' -t terminal_args <"$terminal_log"
|
||||
[[ ${terminal_args[*]} == "omarchy-default-agent --install openclaw" ]] ||
|
||||
fail "a missing OpenClaw routes through the install terminal"
|
||||
pass "a missing OpenClaw routes through the install terminal"
|
||||
|
||||
: >"$stub_log"
|
||||
: >"$inline_log"
|
||||
OMARCHY_TEST_OPENCLAW_INSTALLED=false omarchy-default-agent --install openclaw >/dev/null
|
||||
grep -Fx "pkg-add openclaw" "$stub_log" >/dev/null ||
|
||||
fail "installing OpenClaw as default agent adds its package"
|
||||
mapfile -d '' -t inline_args <"$inline_log"
|
||||
[[ ${inline_args[*]} == "omarchy-launch-openclaw --tui" ]] ||
|
||||
fail "installing OpenClaw as default agent hands over to its terminal UI"
|
||||
pass "installing OpenClaw as default agent adds its package"
|
||||
|
||||
: >"$launch_log"
|
||||
omarchy agent prompt "Review this project"
|
||||
mapfile -d '' -t launch_args <"$launch_log"
|
||||
# Element-wise: the prompt must travel as one argv entry, which a space-joined
|
||||
# comparison could not tell apart from a prompt split into words.
|
||||
[[ ${#launch_args[@]} == 5 &&
|
||||
${launch_args[0]} == "--app-id=org.omarchy.agent" &&
|
||||
${launch_args[1]} == "omarchy-launch-openclaw" &&
|
||||
${launch_args[2]} == "--tui" &&
|
||||
${launch_args[3]} == "--message" &&
|
||||
${launch_args[4]} == "Review this project" ]] ||
|
||||
fail "OpenClaw receives prompts through --message" "argv: ${launch_args[*]}"
|
||||
pass "OpenClaw receives prompts through --message"
|
||||
Executable
+189
@@ -0,0 +1,189 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||
|
||||
tmp_dir="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp_dir"' EXIT
|
||||
|
||||
mkdir -p "$tmp_dir/bin" "$tmp_dir/home"
|
||||
export TEST_LOG="$tmp_dir/log"
|
||||
export PATH="$tmp_dir/bin:$PATH"
|
||||
export HOME="$tmp_dir/home"
|
||||
|
||||
for stub in omarchy-launch-webapp omarchy-launch-floating-terminal-with-presentation omarchy-openclaw-onboard; do
|
||||
cat >"$tmp_dir/bin/$stub" <<SCRIPT
|
||||
#!/bin/bash
|
||||
printf '$stub:%s\n' "\$*" >>"\$TEST_LOG"
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/$stub"
|
||||
done
|
||||
|
||||
# The retry loop sleeps between polls; a no-op keeps the suite fast.
|
||||
printf '#!/bin/bash\n' >"$tmp_dir/bin/sleep"
|
||||
chmod +x "$tmp_dir/bin/sleep"
|
||||
|
||||
# The launcher asks systemd whether the gateway unit is enabled; a flag file
|
||||
# stands in for the user manager.
|
||||
cat >"$tmp_dir/bin/systemctl" <<SCRIPT
|
||||
#!/bin/bash
|
||||
printf 'systemctl:%s\\n' "\$*" >>"\$TEST_LOG"
|
||||
[[ \$* == *is-enabled* ]] && [[ -f $tmp_dir/gateway-enabled ]]
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/systemctl"
|
||||
|
||||
# A machine that never onboarded gets the wizard, not a dashboard probe.
|
||||
"$ROOT/bin/omarchy-launch-openclaw"
|
||||
|
||||
# Through omarchy-openclaw-onboard, never bare `openclaw onboard`, which as of
|
||||
# 2026.9.1 ends in a browser tab with a foreground gateway and never returns.
|
||||
grep -q '^omarchy-launch-floating-terminal-with-presentation:omarchy-openclaw-onboard && \[\[ -f \$HOME/.openclaw/openclaw.json \]\] && omarchy-launch-openclaw$' "$TEST_LOG" ||
|
||||
fail "OpenClaw launch hands a never-onboarded machine to the wizard" "$(grep floating "$TEST_LOG")"
|
||||
! grep -q '^omarchy-launch-webapp:' "$TEST_LOG" ||
|
||||
fail "OpenClaw launch hands a never-onboarded machine to the wizard" "webapp opened anyway"
|
||||
pass "OpenClaw launch hands a never-onboarded machine to the wizard"
|
||||
|
||||
mkdir -p "$HOME/.openclaw"
|
||||
touch "$HOME/.openclaw/openclaw.json"
|
||||
|
||||
# A running gateway answers the first probe; its handoff URL opens as the app.
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
[[ $* == *--json* ]] &&
|
||||
echo '{"ok":true,"url":"http://127.0.0.1:18789/?token=shared","browserUrl":"http://127.0.0.1:18789/#handoff"}'
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
"$ROOT/bin/omarchy-launch-openclaw"
|
||||
|
||||
grep -q '^omarchy-launch-webapp:http://127.0.0.1:18789/#handoff$' "$TEST_LOG" ||
|
||||
fail "OpenClaw launch opens the running gateway's handoff URL"
|
||||
pass "OpenClaw launch opens the running gateway's handoff URL"
|
||||
|
||||
# A machine whose gateway unit was never enabled (never installed, or an
|
||||
# install that died after writing the unit) gets `gateway install --force`,
|
||||
# then is polled until the dashboard answers. Never `dashboard --yes`: since
|
||||
# 2026.9.1 that neither installs nor starts anything and, once the gateway is
|
||||
# up, pushes a one-time pairing URL into the clipboard.
|
||||
cat >"$tmp_dir/bin/openclaw" <<SCRIPT
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\\n' "\$*" >>"\$TEST_LOG"
|
||||
if [[ \$* == *--json* ]]; then
|
||||
[[ -f $tmp_dir/gateway-up ]] || { echo '{"ok":false,"reason":"Gateway is not running."}'; exit 1; }
|
||||
echo '{"ok":true,"browserUrl":"http://127.0.0.1:18789/#cold-start"}'
|
||||
elif [[ \$1 == gateway ]]; then
|
||||
touch "$tmp_dir/gateway-up"
|
||||
fi
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
rm -f "$tmp_dir/gateway-up" "$tmp_dir/gateway-enabled"
|
||||
mkdir -p "$HOME/.config/systemd/user"
|
||||
touch "$HOME/.config/systemd/user/openclaw-gateway.service"
|
||||
: >"$TEST_LOG"
|
||||
"$ROOT/bin/omarchy-launch-openclaw"
|
||||
|
||||
grep -q '^openclaw:gateway install --force$' "$TEST_LOG" ||
|
||||
fail "OpenClaw launch installs a never-enabled gateway before opening the app"
|
||||
! grep -q '^openclaw:gateway start$' "$TEST_LOG" ||
|
||||
fail "OpenClaw launch installs a never-enabled gateway before opening the app" "started the half-installed unit instead"
|
||||
grep -q '^omarchy-launch-webapp:http://127.0.0.1:18789/#cold-start$' "$TEST_LOG" ||
|
||||
fail "OpenClaw launch installs a never-enabled gateway before opening the app" "webapp never opened"
|
||||
pass "OpenClaw launch installs a never-enabled gateway before opening the app"
|
||||
|
||||
# An enabled but stopped unit is started, not reinstalled.
|
||||
touch "$tmp_dir/gateway-enabled"
|
||||
rm -f "$tmp_dir/gateway-up"
|
||||
: >"$TEST_LOG"
|
||||
"$ROOT/bin/omarchy-launch-openclaw"
|
||||
|
||||
grep -q '^openclaw:gateway start$' "$TEST_LOG" ||
|
||||
fail "OpenClaw launch starts a stopped gateway before opening the app"
|
||||
! grep -q '^openclaw:gateway install' "$TEST_LOG" ||
|
||||
fail "OpenClaw launch starts a stopped gateway before opening the app" "reinstalled the unit"
|
||||
! grep -q -- '--yes' "$TEST_LOG" ||
|
||||
fail "OpenClaw launch starts a stopped gateway before opening the app" "fell back to dashboard --yes"
|
||||
grep -q '^omarchy-launch-webapp:http://127.0.0.1:18789/#cold-start$' "$TEST_LOG" ||
|
||||
fail "OpenClaw launch starts a stopped gateway before opening the app" "webapp never opened"
|
||||
pass "OpenClaw launch starts a stopped gateway before opening the app"
|
||||
rm -f "$tmp_dir/gateway-enabled"
|
||||
|
||||
# A dashboard probe that hangs is cut off, so the launch still fails cleanly
|
||||
# instead of sitting forever behind an app-grid icon with no terminal.
|
||||
cat >"$tmp_dir/bin/timeout" <<SCRIPT
|
||||
#!/bin/bash
|
||||
printf 'timeout:%s\\n' "\$1" >>"\$TEST_LOG"
|
||||
exit 124
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/timeout"
|
||||
: >"$TEST_LOG"
|
||||
rc=0
|
||||
"$ROOT/bin/omarchy-launch-openclaw" >/dev/null 2>&1 || rc=$?
|
||||
[[ $rc != 0 ]] || fail "OpenClaw launch bounds a hanging dashboard probe"
|
||||
grep -q '^timeout:10$' "$TEST_LOG" || fail "OpenClaw launch bounds a hanging dashboard probe" "probe ran without a timeout"
|
||||
pass "OpenClaw launch bounds a hanging dashboard probe"
|
||||
rm -f "$tmp_dir/bin/timeout"
|
||||
|
||||
# A gateway that never answers fails the launch instead of opening a dead page.
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
[[ $* == *--json* ]] && exit 1
|
||||
exit 0
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
webapp_calls_before=$(grep -c '^omarchy-launch-webapp:' "$TEST_LOG" || true)
|
||||
rc=0
|
||||
"$ROOT/bin/omarchy-launch-openclaw" >/dev/null 2>&1 || rc=$?
|
||||
webapp_calls_after=$(grep -c '^omarchy-launch-webapp:' "$TEST_LOG" || true)
|
||||
|
||||
[[ $rc != 0 ]] || fail "OpenClaw launch fails cleanly when the gateway never comes up"
|
||||
[[ $webapp_calls_before == "$webapp_calls_after" ]] ||
|
||||
fail "OpenClaw launch fails cleanly when the gateway never comes up" "webapp opened anyway"
|
||||
pass "OpenClaw launch fails cleanly when the gateway never comes up"
|
||||
|
||||
# --tui runs onboarding in the terminal it is already in, then attaches to the
|
||||
# gateway with `openclaw tui` -- never the embedded chat, which the running
|
||||
# gateway's state-directory lock would refuse.
|
||||
rm -f "$HOME/.openclaw/openclaw.json"
|
||||
cat >"$tmp_dir/bin/omarchy-openclaw-onboard" <<SCRIPT
|
||||
#!/bin/bash
|
||||
printf 'omarchy-openclaw-onboard:%s\n' "\$*" >>"\$TEST_LOG"
|
||||
mkdir -p "\$HOME/.openclaw" && touch "\$HOME/.openclaw/openclaw.json"
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/omarchy-openclaw-onboard"
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
[[ $* == *--json* ]] && echo '{"ok":true,"browserUrl":"http://127.0.0.1:18789/#tui"}'
|
||||
exit 0
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
floating_calls_before=$(grep -c '^omarchy-launch-floating-terminal-with-presentation:' "$TEST_LOG" || true)
|
||||
"$ROOT/bin/omarchy-launch-openclaw" --tui
|
||||
|
||||
grep -q '^omarchy-openclaw-onboard:$' "$TEST_LOG" ||
|
||||
fail "--tui onboards in the current terminal" "$(grep 'onboard' "$TEST_LOG")"
|
||||
floating_calls_after=$(grep -c '^omarchy-launch-floating-terminal-with-presentation:' "$TEST_LOG" || true)
|
||||
[[ $floating_calls_before == "$floating_calls_after" ]] ||
|
||||
fail "--tui onboards in the current terminal" "spawned a floating terminal"
|
||||
grep -q '^openclaw:tui$' "$TEST_LOG" || fail "--tui attaches to the gateway"
|
||||
pass "--tui onboards in place and attaches to the gateway"
|
||||
|
||||
# The stub also logs argv one entry per line, so a prompt split into words
|
||||
# would show up as extra lines rather than pass a space-joined comparison.
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
[[ $1 == tui ]] && printf 'argv:[%s]\n' "$@" >>"$TEST_LOG"
|
||||
[[ $* == *--json* ]] && echo '{"ok":true,"browserUrl":"http://127.0.0.1:18789/#tui"}'
|
||||
exit 0
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
: >"$TEST_LOG"
|
||||
"$ROOT/bin/omarchy-launch-openclaw" --tui --message "Review this project"
|
||||
[[ $(grep -c '^argv:' "$TEST_LOG") == 3 ]] && grep -q '^argv:\[Review this project\]$' "$TEST_LOG" ||
|
||||
fail "--tui seeds the session through --message" "$(grep '^argv:' "$TEST_LOG" | tr '\n' ' ')"
|
||||
! grep -q '^omarchy-launch-webapp:' "$TEST_LOG" ||
|
||||
fail "--tui seeds the session through --message" "webapp opened instead"
|
||||
pass "--tui seeds the session through --message"
|
||||
@@ -225,6 +225,7 @@ const expectedAgents = {
|
||||
codex: { icon: '\ue905', iconFont: 'omarchy', label: 'Codex' },
|
||||
grok: { icon: '\ue904', iconFont: 'omarchy', label: 'Grok' },
|
||||
hermes: { icon: '\ue90a', iconFont: 'omarchy', label: 'Hermes' },
|
||||
openclaw: { icon: '\ue90c', iconFont: 'omarchy', label: 'OpenClaw' },
|
||||
copilot: { icon: '', label: 'Copilot' },
|
||||
crush: { icon: '', label: 'Crush' },
|
||||
}
|
||||
@@ -245,7 +246,7 @@ assertDeepEqual(
|
||||
defaultItems
|
||||
.filter(item => item.parent === 'setup.default.agent')
|
||||
.map(item => item.label),
|
||||
['Antigravity', 'Claude', 'Codex', 'Copilot', 'Crush', 'Grok', 'Hermes', 'omp', 'OpenCode', 'Ori', 'Pi'],
|
||||
['Antigravity', 'Claude', 'Codex', 'Copilot', 'Crush', 'Grok', 'Hermes', 'omp', 'OpenClaw', 'OpenCode', 'Ori', 'Pi'],
|
||||
'menu sorts coding agents alphabetically'
|
||||
)
|
||||
const expectedDefaults = {
|
||||
@@ -637,5 +638,5 @@ assert(
|
||||
JS
|
||||
|
||||
font_charset=$(fc-query --format='%{charset}' "$ROOT/default/fonts/omarchy/omarchy.ttf")
|
||||
[[ $font_charset == *"e900-e90a"* ]] || fail "Omarchy icon font includes every custom menu glyph"
|
||||
[[ $font_charset == *"e900-e90a"* && $font_charset == *"e90c"* ]] || fail "Omarchy icon font includes every custom menu glyph"
|
||||
pass "Omarchy icon font includes the official agent marks"
|
||||
Executable
+288
@@ -0,0 +1,288 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||
|
||||
tmp_dir="$(mktemp -d)"
|
||||
trap 'rm -rf "$tmp_dir"' EXIT
|
||||
|
||||
mkdir -p "$tmp_dir/bin" "$tmp_dir/home"
|
||||
export TEST_LOG="$tmp_dir/log"
|
||||
export PATH="$tmp_dir/bin:$PATH"
|
||||
export HOME="$tmp_dir/home"
|
||||
export OMARCHY_OPENCLAW_ONBOARD_SETTLE_SECONDS=0
|
||||
unit="$HOME/.config/systemd/user/openclaw-gateway.service"
|
||||
export unit
|
||||
|
||||
# systemd and ss stand in for themselves. Once the wizard has written the unit
|
||||
# it is running as pid 4242, and that same process holds the gateway port
|
||||
# unless a test plants a different listener (an orphan) in $listener_file.
|
||||
listener_file="$tmp_dir/listener"
|
||||
export listener_file
|
||||
cat >"$tmp_dir/bin/systemctl" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'systemctl:%s\n' "$*" >>"$TEST_LOG"
|
||||
if [[ $* == *MainPID* ]]; then
|
||||
[[ -f $unit ]] && echo 4242 || echo 0
|
||||
exit 0
|
||||
fi
|
||||
[[ $* == *is-active* ]] && [[ -f $unit ]]
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/systemctl"
|
||||
cat >"$tmp_dir/bin/ss" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
pid=
|
||||
[[ -f $listener_file ]] && pid=$(cat "$listener_file")
|
||||
[[ -z $pid && -f $unit ]] && pid=4242
|
||||
[[ -n $pid ]] && echo "LISTEN 0 511 127.0.0.1:18789 0.0.0.0:* users:((\"node\",pid=$pid,fd=3))"
|
||||
exit 0
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/ss"
|
||||
export OMARCHY_OPENCLAW_ONBOARD_GATEWAY_TIMEOUT=1
|
||||
|
||||
# A wizard that configures OpenClaw, prints its outro, and then lingers forever
|
||||
# on an open handle: the 2026.9.1 --skip-ui behaviour. It "installs the
|
||||
# gateway" by writing the config a moment in, so the gateway only starts
|
||||
# answering partway through, never at once.
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
case $1 in
|
||||
onboard)
|
||||
( sleep 1; mkdir -p "$HOME/.openclaw" "${unit%/*}"; touch "$HOME/.openclaw/openclaw.json" "$unit" ) &
|
||||
trap 'echo terminated >>"$TEST_LOG"; exit 143' TERM
|
||||
while :; do sleep 0.2; done
|
||||
;;
|
||||
dashboard)
|
||||
[[ -f $HOME/.openclaw/openclaw.json ]] && echo '{"ok":true,"port":18789}' || { echo '{"ok":false}'; exit 1; }
|
||||
;;
|
||||
esac
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
|
||||
start=$SECONDS
|
||||
rc=0
|
||||
"$ROOT/bin/omarchy-openclaw-onboard" </dev/null >/dev/null 2>&1 || rc=$?
|
||||
elapsed=$((SECONDS - start))
|
||||
|
||||
grep -q '^openclaw:onboard --flow quickstart --install-daemon --skip-ui$' "$TEST_LOG" ||
|
||||
fail "onboarding runs the classic quickstart wizard with the service install" "$(grep '^openclaw:onboard' "$TEST_LOG" || true)"
|
||||
pass "onboarding runs the classic quickstart wizard with the service install"
|
||||
|
||||
[[ $rc == 0 ]] || fail "a wizard that lingers after the gateway is up is stopped and counts as success" "rc=$rc"
|
||||
grep -q '^terminated$' "$TEST_LOG" ||
|
||||
fail "a wizard that lingers after the gateway is up is stopped and counts as success" "wizard was never signalled"
|
||||
(( elapsed < 30 )) || fail "a wizard that lingers after the gateway is up is stopped and counts as success" "took ${elapsed}s"
|
||||
pass "a wizard that lingers after the gateway is up is stopped and counts as success"
|
||||
|
||||
# The wizard only starts being stopped once the gateway actually answers: a
|
||||
# stub that never writes the config is left alone and must be ended by its own
|
||||
# exit, not the watcher.
|
||||
: >"$TEST_LOG"
|
||||
rm -rf "$HOME/.openclaw" "$unit" "$listener_file"
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
[[ $1 == onboard ]] && { echo "Skipped for now."; exit 3; }
|
||||
echo '{"ok":false}'; exit 1
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
rc=0
|
||||
"$ROOT/bin/omarchy-openclaw-onboard" </dev/null >/dev/null 2>&1 || rc=$?
|
||||
[[ $rc == 3 ]] || fail "an abandoned wizard passes its exit code through" "rc=$rc"
|
||||
[[ ! -f $HOME/.openclaw/openclaw.json ]] || fail "an abandoned wizard passes its exit code through" "config appeared"
|
||||
! grep -q '^terminated$' "$TEST_LOG" || fail "an abandoned wizard passes its exit code through" "watcher signalled it anyway"
|
||||
pass "an abandoned wizard passes its exit code through"
|
||||
|
||||
# A wizard that finishes and exits on its own is simply waited for.
|
||||
: >"$TEST_LOG"
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
[[ $1 == onboard ]] && { mkdir -p "$HOME/.openclaw"; touch "$HOME/.openclaw/openclaw.json"; exit 0; }
|
||||
echo '{"ok":true,"port":18789}'
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
rc=0
|
||||
"$ROOT/bin/omarchy-openclaw-onboard" </dev/null >/dev/null 2>&1 || rc=$?
|
||||
[[ $rc == 0 ]] || fail "a wizard that exits cleanly is waited for" "rc=$rc"
|
||||
pass "a wizard that exits cleanly is waited for"
|
||||
|
||||
# Input reaches the wizard: it runs in the foreground, not backgrounded (which
|
||||
# would stop it on SIGTTIN the moment it read stdin).
|
||||
: >"$TEST_LOG"
|
||||
rm -rf "$HOME/.openclaw" "$unit" "$listener_file"
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
case $1 in
|
||||
onboard)
|
||||
read -r answer
|
||||
printf 'answer:%s\n' "$answer" >>"$TEST_LOG"
|
||||
mkdir -p "$HOME/.openclaw"; touch "$HOME/.openclaw/openclaw.json"
|
||||
exit 0
|
||||
;;
|
||||
dashboard) echo '{"ok":true,"port":18789}' ;;
|
||||
esac
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
printf 'gpt-5\n' | "$ROOT/bin/omarchy-openclaw-onboard" >/dev/null 2>&1
|
||||
grep -q '^answer:gpt-5$' "$TEST_LOG" ||
|
||||
fail "the wizard reads terminal input" "$(grep '^answer' "$TEST_LOG" || echo 'no input reached it')"
|
||||
pass "the wizard reads terminal input"
|
||||
|
||||
# An already-configured machine whose gateway answers is not onboarded again:
|
||||
# the wizard's repair pass would otherwise be stopped mid-prompt the moment
|
||||
# the watcher saw the pre-existing gateway.
|
||||
: >"$TEST_LOG"
|
||||
mkdir -p "$HOME/.openclaw" && touch "$HOME/.openclaw/openclaw.json"
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
[[ $1 == onboard ]] && { echo wizard-ran >>"$TEST_LOG"; exit 0; }
|
||||
echo '{"ok":true,"port":18789}'
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
rc=0
|
||||
"$ROOT/bin/omarchy-openclaw-onboard" </dev/null >/dev/null 2>&1 || rc=$?
|
||||
[[ $rc == 0 ]] || fail "an already-running OpenClaw is left alone" "rc=$rc"
|
||||
! grep -q '^wizard-ran$' "$TEST_LOG" || fail "an already-running OpenClaw is left alone" "wizard ran anyway"
|
||||
pass "an already-running OpenClaw is left alone"
|
||||
|
||||
# Setup applied but the gateway never answers: the wizard would linger
|
||||
# forever, so it is stopped after the deadline and that is reported as failure.
|
||||
: >"$TEST_LOG"
|
||||
rm -rf "$HOME/.openclaw" "$unit" "$listener_file"
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
case $1 in
|
||||
onboard)
|
||||
mkdir -p "$HOME/.openclaw"; touch "$HOME/.openclaw/openclaw.json"
|
||||
trap 'echo terminated >>"$TEST_LOG"; exit 143' TERM
|
||||
while :; do sleep 0.2; done
|
||||
;;
|
||||
dashboard) echo '{"ok":false}'; exit 1 ;;
|
||||
esac
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
start=$SECONDS
|
||||
rc=0
|
||||
err=$("$ROOT/bin/omarchy-openclaw-onboard" </dev/null 2>&1 >/dev/null) || rc=$?
|
||||
elapsed=$((SECONDS - start))
|
||||
[[ $rc == 1 ]] || fail "a gateway that never comes up ends the wait with a failure" "rc=$rc"
|
||||
grep -q '^terminated$' "$TEST_LOG" || fail "a gateway that never comes up ends the wait with a failure" "wizard left running"
|
||||
[[ $err == *"gateway status"* ]] || fail "a gateway that never comes up ends the wait with a failure" "no diagnostic: $err"
|
||||
(( elapsed < 30 )) || fail "a gateway that never comes up ends the wait with a failure" "took ${elapsed}s"
|
||||
pass "a gateway that never comes up ends the wait with a failure"
|
||||
|
||||
# A signal at this script alone takes the wizard down with it.
|
||||
: >"$TEST_LOG"
|
||||
rm -rf "$HOME/.openclaw" "$unit" "$listener_file"
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
case $1 in
|
||||
onboard) trap 'echo terminated >>"$TEST_LOG"; exit 143' TERM; while :; do sleep 0.2; done ;;
|
||||
dashboard) echo '{"ok":false}'; exit 1 ;;
|
||||
esac
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
"$ROOT/bin/omarchy-openclaw-onboard" </dev/null >/dev/null 2>&1 &
|
||||
wrapper=$!
|
||||
sleep 1
|
||||
kill -TERM "$wrapper"
|
||||
wait "$wrapper" 2>/dev/null || true
|
||||
sleep 1
|
||||
grep -q '^terminated$' "$TEST_LOG" || fail "stopping the wrapper stops the wizard" "wizard survived"
|
||||
! pgrep -f "$tmp_dir/bin/openclaw onboard" >/dev/null || fail "stopping the wrapper stops the wizard" "wizard process still alive"
|
||||
pass "stopping the wrapper stops the wizard"
|
||||
|
||||
# A config left by an earlier, incomplete setup does not start the gateway
|
||||
# deadline: only this run applying setup does. The wizard here takes longer
|
||||
# than the deadline at its prompts, never touches the old config, and must be
|
||||
# left to finish on its own.
|
||||
: >"$TEST_LOG"
|
||||
mkdir -p "$HOME/.openclaw" && touch "$HOME/.openclaw/openclaw.json"
|
||||
sleep 1
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
case $1 in
|
||||
onboard) trap 'echo terminated >>"$TEST_LOG"; exit 143' TERM; sleep 4; echo finished >>"$TEST_LOG"; exit 0 ;;
|
||||
dashboard) echo '{"ok":false}'; exit 1 ;;
|
||||
esac
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
rc=0
|
||||
"$ROOT/bin/omarchy-openclaw-onboard" </dev/null >/dev/null 2>&1 || rc=$?
|
||||
[[ $rc == 0 ]] || fail "a stale config does not start the gateway deadline" "rc=$rc"
|
||||
grep -q '^finished$' "$TEST_LOG" || fail "a stale config does not start the gateway deadline" "wizard was cut short"
|
||||
! grep -q '^terminated$' "$TEST_LOG" || fail "a stale config does not start the gateway deadline" "wizard was signalled"
|
||||
pass "a stale config does not start the gateway deadline"
|
||||
|
||||
# ...while the same stale config being rewritten by this run does arm it.
|
||||
: >"$TEST_LOG"
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
case $1 in
|
||||
onboard) touch "$HOME/.openclaw/openclaw.json"; trap 'echo terminated >>"$TEST_LOG"; exit 143' TERM; while :; do sleep 0.2; done ;;
|
||||
dashboard) echo '{"ok":false}'; exit 1 ;;
|
||||
esac
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
rc=0
|
||||
"$ROOT/bin/omarchy-openclaw-onboard" </dev/null >/dev/null 2>&1 || rc=$?
|
||||
[[ $rc == 1 ]] || fail "a config rewritten by this run arms the gateway deadline" "rc=$rc"
|
||||
grep -q '^terminated$' "$TEST_LOG" || fail "a config rewritten by this run arms the gateway deadline" "wizard left running"
|
||||
pass "a config rewritten by this run arms the gateway deadline"
|
||||
|
||||
# A gateway that answers while no config exists is not this run's: with no
|
||||
# config `openclaw dashboard --json` still probes the default port, so a
|
||||
# process left behind by something else (an earlier guided onboarding's
|
||||
# foreground gateway) would otherwise end a wizard still at its first prompt.
|
||||
: >"$TEST_LOG"
|
||||
rm -rf "$HOME/.openclaw" "$unit" "$listener_file"
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
case $1 in
|
||||
onboard) trap 'echo terminated >>"$TEST_LOG"; exit 143' TERM; sleep 4; echo finished >>"$TEST_LOG"; exit 0 ;;
|
||||
dashboard) echo '{"ok":true,"port":18789}' ;;
|
||||
esac
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
rc=0
|
||||
"$ROOT/bin/omarchy-openclaw-onboard" </dev/null >/dev/null 2>&1 || rc=$?
|
||||
[[ $rc == 0 ]] || fail "an orphaned gateway answering with no config does not end the wizard" "rc=$rc"
|
||||
grep -q '^finished$' "$TEST_LOG" || fail "an orphaned gateway answering with no config does not end the wizard" "wizard was cut short"
|
||||
! grep -q '^terminated$' "$TEST_LOG" || fail "an orphaned gateway answering with no config does not end the wizard" "wizard was signalled"
|
||||
pass "an orphaned gateway answering with no config does not end the wizard"
|
||||
|
||||
# And after setup, an orphan still bound to the port is not success even
|
||||
# while the unit reports active: Type=simple counts it active from the fork,
|
||||
# before it has discovered the port is taken. The port's owner has to be the
|
||||
# unit's own main process. Here it never is, so the deadline ends the wait as
|
||||
# a failure rather than opening the app on the orphan.
|
||||
: >"$TEST_LOG"
|
||||
rm -rf "$HOME/.openclaw" "$unit" "$listener_file"
|
||||
echo 999 >"$listener_file"
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
case $1 in
|
||||
onboard) mkdir -p "$HOME/.openclaw" "${unit%/*}"; touch "$HOME/.openclaw/openclaw.json" "$unit"; trap 'echo terminated >>"$TEST_LOG"; exit 143' TERM; while :; do sleep 0.2; done ;;
|
||||
dashboard) echo '{"ok":true,"port":18789}' ;;
|
||||
esac
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
rc=0
|
||||
"$ROOT/bin/omarchy-openclaw-onboard" </dev/null >/dev/null 2>&1 || rc=$?
|
||||
[[ $rc == 1 ]] || fail "an orphan holding the port is not mistaken for the active unit" "rc=$rc"
|
||||
grep -q '^terminated$' "$TEST_LOG" || fail "an orphan holding the port is not mistaken for the active unit" "wizard left running"
|
||||
grep -q '^systemctl:--user show -p MainPID --value openclaw-gateway.service$' "$TEST_LOG" ||
|
||||
fail "an orphan holding the port is not mistaken for the active unit" "unit ownership never checked"
|
||||
pass "an orphan holding the port is not mistaken for the active unit"
|
||||
rm -f "$listener_file"
|
||||
@@ -93,3 +93,161 @@ ollama_row=$(grep '^ "remove.ai.ollama":' "$ROOT/default/omarchy/omarchy-menu.j
|
||||
[[ $ollama_row == *'"when":"omarchy-pkg-present ollama"'* ]] ||
|
||||
fail "Ollama removal is offered only where the package is installed" "$ollama_row"
|
||||
pass "Ollama removal is offered only where the package is installed"
|
||||
|
||||
# OpenClaw's gateway unit and web app launcher are the app's own; the agent
|
||||
# state in ~/.openclaw is the user's. systemctl and openclaw are stubbed so the
|
||||
# sandbox never reaches the real user manager or a real gateway.
|
||||
cat >"$tmp_dir/bin/systemctl" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'systemctl:%s\n' "$*" >>"$TEST_LOG"
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/systemctl"
|
||||
|
||||
# Default openclaw stub: the packaged CLI predates `gateway uninstall`, so the
|
||||
# remover has to fall back to its manual systemd path.
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
exit 1
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
|
||||
fresh_openclaw_home() {
|
||||
fresh_home
|
||||
mkdir -p "$HOME/.config/systemd/user/default.target.wants" "$HOME/.openclaw" \
|
||||
"$HOME/.local/share/applications" "$HOME/.local/share/icons/hicolor/256x256/apps"
|
||||
touch "$HOME/.config/systemd/user/openclaw-gateway.service" \
|
||||
"$HOME/.config/systemd/user/openclaw-gateway.service.bak" \
|
||||
"$HOME/.config/systemd/user/openclaw-node.service" \
|
||||
"$HOME/.openclaw/openclaw.json" \
|
||||
"$HOME/.local/share/applications/OpenClaw.desktop" \
|
||||
"$HOME/.local/share/icons/hicolor/256x256/apps/openclaw.png"
|
||||
ln -s ../openclaw-gateway.service \
|
||||
"$HOME/.config/systemd/user/default.target.wants/openclaw-gateway.service"
|
||||
ln -s ../openclaw-node.service \
|
||||
"$HOME/.config/systemd/user/default.target.wants/openclaw-node.service"
|
||||
}
|
||||
|
||||
# gum would ask about ~/.openclaw; the tests never run on a terminal, so it
|
||||
# must not even be reached. Logging it proves that.
|
||||
cat >"$tmp_dir/bin/gum" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'gum:%s\n' "$*" >>"$TEST_LOG"
|
||||
exit 0
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/gum"
|
||||
|
||||
fresh_openclaw_home
|
||||
"$ROOT/bin/omarchy-remove-ai-openclaw" >/dev/null
|
||||
|
||||
for gone in .config/systemd/user/openclaw-gateway.service \
|
||||
.config/systemd/user/openclaw-gateway.service.bak \
|
||||
.config/systemd/user/default.target.wants/openclaw-gateway.service \
|
||||
.config/systemd/user/openclaw-node.service \
|
||||
.config/systemd/user/default.target.wants/openclaw-node.service \
|
||||
.local/share/applications/OpenClaw.desktop \
|
||||
.local/share/icons/hicolor/256x256/apps/openclaw.png; do
|
||||
[[ ! -e $HOME/$gone && ! -L $HOME/$gone ]] || fail "OpenClaw removal deletes the service and launcher it installed" "$gone"
|
||||
done
|
||||
pass "OpenClaw removal deletes the service and launcher it installed"
|
||||
|
||||
grep -q '^systemctl:--user disable --now openclaw-gateway.service$' "$TEST_LOG" ||
|
||||
fail "OpenClaw removal stops the gateway service"
|
||||
grep -q '^systemctl:--user disable --now openclaw-node.service$' "$TEST_LOG" ||
|
||||
fail "OpenClaw removal stops the gateway service" "node host service left running"
|
||||
for unit in openclaw-gateway.service openclaw-node.service; do
|
||||
grep -q "^systemctl:--user reset-failed $unit\$" "$TEST_LOG" ||
|
||||
fail "OpenClaw removal stops the gateway service" "$unit left in systemd's failed list"
|
||||
done
|
||||
pass "OpenClaw removal stops the gateway service"
|
||||
|
||||
# Without a terminal there is nobody to ask, so the state stays and gum is
|
||||
# never invoked (a gum that answered "yes" on its own would be a data loss).
|
||||
[[ -f $HOME/.openclaw/openclaw.json ]] || fail "OpenClaw removal keeps the user's agent state"
|
||||
! grep -q '^gum:' "$TEST_LOG" ||
|
||||
fail "OpenClaw removal keeps the user's agent state" "asked about ~/.openclaw without a terminal"
|
||||
pass "OpenClaw removal keeps the user's agent state"
|
||||
|
||||
# A CLI that knows `gateway uninstall` owns the teardown; the manual systemd
|
||||
# fallback must not run.
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
rm -f "$HOME/.config/systemd/user/openclaw-$1.service" \
|
||||
"$HOME/.config/systemd/user/default.target.wants/openclaw-$1.service"
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
|
||||
: >"$TEST_LOG"
|
||||
fresh_openclaw_home
|
||||
"$ROOT/bin/omarchy-remove-ai-openclaw" >/dev/null
|
||||
|
||||
grep -q '^openclaw:gateway uninstall$' "$TEST_LOG" ||
|
||||
fail "OpenClaw removal prefers upstream's own gateway teardown"
|
||||
grep -q '^openclaw:node uninstall$' "$TEST_LOG" ||
|
||||
fail "OpenClaw removal prefers upstream's own gateway teardown" "node host not handed to upstream"
|
||||
! grep -q '^systemctl:--user disable' "$TEST_LOG" ||
|
||||
fail "OpenClaw removal prefers upstream's own gateway teardown" "manual disable ran too"
|
||||
pass "OpenClaw removal prefers upstream's own gateway teardown"
|
||||
|
||||
# Without the unit file there is nothing of ours registered, so systemd stays untouched.
|
||||
systemctl_calls_before=$(grep -c '^systemctl:' "$TEST_LOG" || true)
|
||||
fresh_home
|
||||
"$ROOT/bin/omarchy-remove-ai-openclaw" >/dev/null
|
||||
systemctl_calls_after=$(grep -c '^systemctl:' "$TEST_LOG" || true)
|
||||
|
||||
[[ $systemctl_calls_before == "$systemctl_calls_after" ]] ||
|
||||
fail "OpenClaw removal leaves systemd alone when onboarding never ran"
|
||||
pass "OpenClaw removal leaves systemd alone when onboarding never ran"
|
||||
|
||||
# A gateway that will not stop aborts the removal before the package drop:
|
||||
# pacman would otherwise strand the live process on deleted code.
|
||||
cat >"$tmp_dir/bin/openclaw" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'openclaw:%s\n' "$*" >>"$TEST_LOG"
|
||||
exit 1
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/openclaw"
|
||||
cat >"$tmp_dir/bin/systemctl" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'systemctl:%s\n' "$*" >>"$TEST_LOG"
|
||||
[[ $2 == disable ]] && exit 1
|
||||
[[ $2 == is-active ]] && exit 0
|
||||
exit 0
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/systemctl"
|
||||
|
||||
drop_calls_before=$(grep -c '^drop:openclaw$' "$TEST_LOG" || true)
|
||||
fresh_openclaw_home
|
||||
rc=0
|
||||
"$ROOT/bin/omarchy-remove-ai-openclaw" >/dev/null 2>&1 || rc=$?
|
||||
drop_calls_after=$(grep -c '^drop:openclaw$' "$TEST_LOG" || true)
|
||||
|
||||
[[ $rc != 0 ]] || fail "OpenClaw removal aborts when the gateway cannot be stopped"
|
||||
[[ -f $HOME/.config/systemd/user/openclaw-gateway.service ]] ||
|
||||
fail "OpenClaw removal aborts when the gateway cannot be stopped" "unit file deleted"
|
||||
[[ $drop_calls_before == "$drop_calls_after" ]] ||
|
||||
fail "OpenClaw removal aborts when the gateway cannot be stopped" "package dropped anyway"
|
||||
pass "OpenClaw removal aborts when the gateway cannot be stopped"
|
||||
|
||||
# An unreachable user manager is not a stopped gateway: every probe failing
|
||||
# with no answer must still abort, not read as "confirmed inactive".
|
||||
cat >"$tmp_dir/bin/systemctl" <<'SCRIPT'
|
||||
#!/bin/bash
|
||||
printf 'systemctl:%s\n' "$*" >>"$TEST_LOG"
|
||||
echo "Failed to connect to user scope bus" >&2
|
||||
exit 1
|
||||
SCRIPT
|
||||
chmod +x "$tmp_dir/bin/systemctl"
|
||||
|
||||
: >"$TEST_LOG"
|
||||
fresh_openclaw_home
|
||||
rc=0
|
||||
"$ROOT/bin/omarchy-remove-ai-openclaw" >/dev/null 2>&1 || rc=$?
|
||||
|
||||
[[ $rc != 0 ]] || fail "OpenClaw removal aborts when systemd cannot be reached"
|
||||
[[ -f $HOME/.config/systemd/user/openclaw-gateway.service ]] ||
|
||||
fail "OpenClaw removal aborts when systemd cannot be reached" "unit file deleted"
|
||||
! grep -q '^drop:openclaw$' "$TEST_LOG" ||
|
||||
fail "OpenClaw removal aborts when systemd cannot be reached" "package dropped anyway"
|
||||
pass "OpenClaw removal aborts when systemd cannot be reached"
|
||||
Reference in new issue
Block a user