@@ -139,6 +139,49 @@ LOGINCTL
139139 fi
140140 }
141141
142+ assert_exec_arg() {
143+ local unit_path="$1"
144+ local index="$2"
145+ local expected="$3"
146+ local exec_line=""
147+ local actual=""
148+ exec_line=$(grep -m1 "^ExecStart=" "$unit_path" || true)
149+ if [ -z "$exec_line" ]; then
150+ echo "Missing ExecStart in $unit_path"
151+ exit 1
152+ fi
153+ exec_line="${exec_line#ExecStart=}"
154+ actual=$(echo "$exec_line" | awk -v field="$index" "{print \$field}")
155+ actual="${actual%\"}"
156+ actual="${actual#\"}"
157+ if [ "$actual" != "$expected" ]; then
158+ echo "Expected ExecStart arg $index to be $expected, got $actual"
159+ cat "$unit_path"
160+ exit 1
161+ fi
162+ }
163+
164+ assert_env_value() {
165+ local unit_path="$1"
166+ local key="$2"
167+ local expected="$3"
168+ if ! grep -Fxq "Environment=${key}=${expected}" "$unit_path"; then
169+ echo "Expected Environment=${key}=${expected} in $unit_path"
170+ cat "$unit_path"
171+ exit 1
172+ fi
173+ }
174+
175+ assert_no_env_key() {
176+ local unit_path="$1"
177+ local key="$2"
178+ if grep -q "^Environment=${key}=" "$unit_path"; then
179+ echo "Expected no Environment=${key}= line in $unit_path"
180+ cat "$unit_path"
181+ exit 1
182+ fi
183+ }
184+
142185 # Each flow: install service with one variant, run doctor from the other,
143186 # and verify ExecStart entrypoint switches accordingly.
144187 run_flow() {
@@ -191,4 +234,83 @@ LOGINCTL
191234 "$git_entry" \
192235 "$npm_bin doctor --repair --force --yes" \
193236 "$npm_entry"
237+
238+ run_wrapper_flow() {
239+ local name="wrapper-persistence"
240+ local install_log="/tmp/openclaw-doctor-switch-${name}-install.log"
241+ local reinstall_log="/tmp/openclaw-doctor-switch-${name}-reinstall.log"
242+ local env_repair_log="/tmp/openclaw-doctor-switch-${name}-env-repair.log"
243+ local doctor_log="/tmp/openclaw-doctor-switch-${name}-doctor.log"
244+ local clear_log="/tmp/openclaw-doctor-switch-${name}-clear.log"
245+ local command_timeout="${OPENCLAW_DOCKER_DOCTOR_SWITCH_COMMAND_TIMEOUT:-300s}"
246+
247+ echo "== Flow: $name =="
248+ home_dir=$(mktemp -d "/tmp/openclaw-switch-${name}.XXXXXX")
249+ export HOME="$home_dir"
250+ export USER="testuser"
251+ mkdir -p "$HOME/.local/bin"
252+ local wrapper="$HOME/.local/bin/openclaw-wrapper"
253+ cat > "$wrapper" <<WRAPPER
254+ #!/usr/bin/env bash
255+ set -euo pipefail
256+ printf "%s\n" "\$@" >> "$HOME/openclaw-wrapper-argv.log"
257+ exec "$npm_bin" "\$@"
258+ WRAPPER
259+ chmod +x "$wrapper"
260+
261+ local unit_path="$HOME/.config/systemd/user/openclaw-gateway.service"
262+
263+ if ! timeout "$command_timeout" "$npm_bin" gateway install --wrapper "$wrapper" --force >"$install_log" 2>&1; then
264+ cat "$install_log"
265+ exit 1
266+ fi
267+ assert_exec_arg "$unit_path" 1 "$wrapper"
268+ assert_exec_arg "$unit_path" 2 "gateway"
269+ assert_env_value "$unit_path" "OPENCLAW_WRAPPER" "$wrapper"
270+
271+ if ! timeout "$command_timeout" "$npm_bin" gateway install --force >"$reinstall_log" 2>&1; then
272+ cat "$reinstall_log"
273+ exit 1
274+ fi
275+ assert_exec_arg "$unit_path" 1 "$wrapper"
276+ assert_exec_arg "$unit_path" 2 "gateway"
277+ assert_env_value "$unit_path" "OPENCLAW_WRAPPER" "$wrapper"
278+
279+ sed -i "/^Environment=OPENCLAW_WRAPPER=/d" "$unit_path"
280+ if ! timeout "$command_timeout" "$npm_bin" gateway install --wrapper "$wrapper" >"$env_repair_log" 2>&1; then
281+ cat "$env_repair_log"
282+ exit 1
283+ fi
284+ assert_exec_arg "$unit_path" 1 "$wrapper"
285+ assert_env_value "$unit_path" "OPENCLAW_WRAPPER" "$wrapper"
286+
287+ sed -i "s#^Environment=OPENCLAW_WRAPPER=.*#Environment=OPENCLAW_WRAPPER=/tmp/stale-openclaw-wrapper#" "$unit_path"
288+ if ! timeout "$command_timeout" "$npm_bin" gateway install --wrapper "$wrapper" >"$env_repair_log" 2>&1; then
289+ cat "$env_repair_log"
290+ exit 1
291+ fi
292+ assert_exec_arg "$unit_path" 1 "$wrapper"
293+ assert_env_value "$unit_path" "OPENCLAW_WRAPPER" "$wrapper"
294+
295+ if ! timeout "$command_timeout" node "$git_cli" doctor --repair --force --yes >"$doctor_log" 2>&1; then
296+ cat "$doctor_log"
297+ exit 1
298+ fi
299+ if ! grep -Fq "Gateway service invokes OPENCLAW_WRAPPER:" "$doctor_log"; then
300+ echo "Expected doctor to report active wrapper"
301+ cat "$doctor_log"
302+ exit 1
303+ fi
304+ assert_exec_arg "$unit_path" 1 "$wrapper"
305+ assert_env_value "$unit_path" "OPENCLAW_WRAPPER" "$wrapper"
306+
307+ if ! timeout "$command_timeout" env OPENCLAW_WRAPPER= "$npm_bin" gateway install --force >"$clear_log" 2>&1; then
308+ cat "$clear_log"
309+ exit 1
310+ fi
311+ assert_no_env_key "$unit_path" "OPENCLAW_WRAPPER"
312+ assert_entrypoint "$unit_path" "$npm_entry"
313+ }
314+
315+ run_wrapper_flow
194316'
0 commit comments