Skip to content

Install round-trip tests (systemd / launchd / Windows SCM)#82

Merged
hyperpolymath merged 1 commit into
claude/dreamy-carson-mTifqfrom
claude/install-roundtrip-tests
May 24, 2026
Merged

Install round-trip tests (systemd / launchd / Windows SCM)#82
hyperpolymath merged 1 commit into
claude/dreamy-carson-mTifqfrom
claude/install-roundtrip-tests

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Stacks on #81. Adds the round-trip tests that #81's README documented as "next step".

What's in this PR

Three platform-specific drivers that actually install → activate → stop → uninstall the service on the real service manager, complementing the lint-only checks in #81:

Driver Platform What it does
tests/install/roundtrip-linux.sh Linux systemctl --user enable --now round-trip. Also kills the unit's MainPID and asserts Restart=on-failure respawns it within RestartSec=5.
tests/install/roundtrip-macos.sh macOS launchctl bootstrap gui/$UID / bootout round-trip. Patches stub PATH= into the plist (launchd ignores user shell env).
tests/install/roundtrip-windows.ps1 Windows Creates throwaway local user (burble-ci-test) with random password, installs Windows Service non-interactively, asserts SCM state, uninstalls, removes user in finally{}.

Supporting bits

  • tests/install/stubs/{mix,deno} — sleep-forever stand-ins so spawned units satisfy systemd/launchd's "Active" check without needing the full Elixir/Deno toolchain in CI.

  • scripts/wsl-bolt-udp-forward.ps1 — new -Credential [PSCredential] parameter on -Install that skips the Get-Credential prompt when supplied. Human-interactive behaviour unchanged when omitted. This is what makes the Windows round-trip testable in CI at all.

  • .github/workflows/install-roundtrip.yml — three-OS matrix:

    • ubuntu-latest (with loginctl enable-linger $USER so user-systemd starts without a login session)
    • macos-14 (Apple Silicon)
    • windows-latest

    Path-filtered to install-machinery changes only, same as Add cross-platform background-service install (systemd/launchd/Windows) #81's install-tests.yml.

Safety

All drivers clean up after themselves on failure:

  • shell: trap 'ec=$?; cleanup; exit $ec' EXIT (captures real exit code before cleanup runs)
  • PowerShell: try { … } finally { Remove-LocalUser … }

Safe to run locally if you don't mind a brief service install on your box.

Things found while writing this

  • set -u + unset $USER killed the script on a stripped container — falls back to id -un now
  • The naïve trap 'cleanup' EXIT was swallowing the preflight's exit 2 — fixed with ec=$? capture
  • Shellcheck SC2154 false-positive on the ec=$? pattern inside the trap (disabled inline with a comment)

Test plan

  • CI green on all three jobs of install-roundtrip workflow
  • CI green on install-tests workflow (the new round-trip ps1 + sh files are now in its shellcheck/PSScriptAnalyzer scope too)
  • On your Windows + WSL setup: from inside WSL, tests/install/roundtrip-linux.sh should pass once you sudo loginctl enable-linger $USER && sleep 2. From elevated Windows PowerShell, tests\install\roundtrip-windows.ps1 should pass standalone (creates + removes its own user).
  • macOS coverage will only land via CI unless you also test on a Mac.

Out of scope (still NOT tested)

  • Whether UDP packets actually relay through the Windows forwarder (needs a real WSL distro on the runner — GH runners don't have one).
  • Whether mix phx.server itself comes up clean under systemd/launchd (covered by elixir-ci.yml, not the install machinery).

https://claude.ai/code/session_016BNGnVKCbN5FBXcTXRpDXy


Generated by Claude Code

Complements install-tests.yml (lint-only) with three drivers that
actually install→activate→stop→uninstall the service on the platform's
real service manager:

  tests/install/roundtrip-linux.sh    systemctl --user enable --now;
                                      also kills MainPID and asserts
                                      Restart=on-failure respawns
  tests/install/roundtrip-macos.sh    launchctl bootstrap gui/$UID
                                      with stub PATH= patched into the
                                      plist (launchd ignores user env)
  tests/install/roundtrip-windows.ps1 creates a throwaway local user,
                                      installs non-interactively via a
                                      new -Credential param on
                                      wsl-bolt-udp-forward.ps1, asserts
                                      SCM state, uninstalls, removes
                                      user in finally{}

tests/install/stubs/{mix,deno} are sleep-forever stand-ins so the
spawned units satisfy systemd/launchd's "Active" check without needing
the full Elixir/Deno toolchain in CI. Drivers all clean up after
themselves (trap EXIT preserves real exit code with `ec=$?` capture
before cleanup; try/finally on the Windows side).

scripts/wsl-bolt-udp-forward.ps1: new -Credential [PSCredential]
parameter on -Install. When supplied (CI), skips the Get-Credential
prompt. When omitted (default, human use), behaviour is unchanged.

.github/workflows/install-roundtrip.yml: three-OS matrix —
ubuntu-latest (with `loginctl enable-linger $USER` so user-systemd
starts without a login session), macos-14, windows-latest. Same
path-filter as install-tests.yml.

run.sh's shellcheck pass now covers the new round-trip drivers too;
caught the SC2154 false positive on `trap 'ec=$?; ...'` (disabled
inline) and the unset-$USER bug surfaced under `set -u` on stripped
containers.
@hyperpolymath hyperpolymath merged commit f99ff3a into claude/dreamy-carson-mTifq May 24, 2026
17 of 21 checks passed
@hyperpolymath hyperpolymath deleted the claude/install-roundtrip-tests branch May 24, 2026 05:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants