#!/bin/bash ## Tests for `pave install` and `pave install-boot`. ## ## Boot triggers go into a fake root (PAVE_SYSROOT), and a fake `sudo` on PATH just runs its command, ## so the whole install flow runs as the current user. ## Installed triggers are then actually executed, to prove their quoting works; ## the goals dir has a space in its name to make that mean something. # shellcheck source=tests/testlib.bash source "${BASH_SOURCE[0]%/*}/testlib.bash" mkdir -p "$scratch/fakebin" printf '#!/bin/bash\n[ "$1" = -- ] && shift\nexec "$@"\n' >"$scratch/fakebin/sudo" chmod +x "$scratch/fakebin/sudo" export PATH="$scratch/fakebin:$PATH" export PAVE_SYSROOT="$scratch/root" G="$scratch/my goals" M="$scratch/marks" for phase in boot session login; do goals "$G/$phase.bash" <"$PAVE_SYSROOT/$p" fi done } # ---- systemd, plus the user triggers; then idempotence and repointing ---- fresh_root run/systemd/system/ pv install "$G" assert_eq "systemd: exit 0" 0 "$rc" assert_has "systemd: kind reported" "pave: boot trigger kind: systemd" unit="$PAVE_SYSROOT/etc/systemd/system/pave-boot.service" assert "systemd: unit has the payload" grep -qxF "ExecStart=\"$PAVE\" run \"$G\" boot" "$unit" assert_eq "systemd: unit enabled" ../pave-boot.service \ "$(readlink "$PAVE_SYSROOT/etc/systemd/system/multi-user.target.wants/pave-boot.service")" assert_eq "install runs the boot phase" "$G" "$(<"$M/boot")" desktop="$HOME/.config/autostart/pave-session.desktop" assert "xdg-autostart: desktop entry has the payload" grep -qxF "Exec=\"$PAVE\" run \"$G\" session" "$desktop" assert "profile: block added to ~/.profile" grep -qxF "\"$PAVE\" run \"$G\" login" "$HOME/.profile" rm -rf -- "$M" sh -c "$(sed -n 's/^ExecStart=//p' "$unit")" >/dev/null assert_eq "systemd: ExecStart line runs the boot phase" "$G" "$(<"$M/boot")" sh -c "$(sed -n 's/^Exec=//p' "$desktop")" >/dev/null assert_eq "xdg-autostart: Exec line runs the session phase" "$G" "$(<"$M/session")" sh -c ". \"\$HOME/.profile\"" >/dev/null assert_eq "profile: sourcing it runs the login phase" "$G" "$(<"$M/login")" pv install "$G" assert_eq "reinstall: exit 0" 0 "$rc" assert_count "reinstall: changes nothing" "pave: changed" 0 G2="$scratch/other-goals" goals "$G2/boot.bash" <<<'true' pv install "$G2" assert "repoint: unit follows the new goals dir" grep -qxF "ExecStart=\"$PAVE\" run \"$G2\" boot" "$unit" assert_eq "repoint: one profile block, updated" 1 "$(grep -c '>>> pave:trigger >>>' "$HOME/.profile")" assert "repoint: profile block follows" grep -qxF "\"$PAVE\" run \"$G2\" login" "$HOME/.profile" # ---- the login trigger goes where bash will read it ---- rm -f "$HOME/.profile" : >"$HOME/.bash_profile" pv install "$G" assert "profile: ~/.bash_profile used when it exists" grep -qF 'pave:trigger' "$HOME/.bash_profile" assert "profile: ~/.profile left alone then" test ! -e "$HOME/.profile" # ---- the other boot kinds ---- fresh_root etc/local.d/ pv install "$G" assert_has "openrc-local: kind reported" "pave: boot trigger kind: openrc-local" start="$PAVE_SYSROOT/etc/local.d/pave.start" assert_eq "openrc-local: executable" 755 "$(stat -c %a "$start")" rm -rf -- "$M" "$start" >/dev/null assert_eq "openrc-local: script runs the boot phase" "$G" "$(<"$M/boot")" fresh_root etc/rc.local etc/cron.d/ printf '#!/bin/sh -e\nexit 0\n' >"$PAVE_SYSROOT/etc/rc.local" pv install "$G" assert_has "rc-local: preferred over cron" "pave: boot trigger kind: rc-local" assert_eq "rc-local: made executable" 755 "$(stat -c %a "$PAVE_SYSROOT/etc/rc.local")" assert_eq "rc-local: block after the shebang, before exit" "#!/bin/sh -e" "$(head -n1 "$PAVE_SYSROOT/etc/rc.local")" assert_eq "rc-local: exit stays last" "exit 0" "$(tail -n1 "$PAVE_SYSROOT/etc/rc.local")" rm -rf -- "$M" "$PAVE_SYSROOT/etc/rc.local" >/dev/null assert_eq "rc-local: script runs the boot phase" "$G" "$(<"$M/boot")" fresh_root etc/cron.d/ pv install "$G" assert_has "cron-reboot: kind reported" "pave: boot trigger kind: cron-reboot" assert "cron-reboot: entry has the payload" grep -qxF "@reboot root \"$PAVE\" run \"$G\" boot" "$PAVE_SYSROOT/etc/cron.d/pave" # ---- refusals ---- fresh_root pv install-boot "$G" assert_eq "no boot hook: install-boot exit 10" 10 "$rc" assert_has "no boot hook: explained" "found no boot hook pave knows" pv install "$G" assert_eq "no boot hook: install exit 12" 12 "$rc" assert "no boot hook: user triggers still installed" test -f "$desktop" fresh_root run/systemd/system/ mkdir -p "$scratch/bad\$dir" pv install "$scratch/bad\$dir" assert_eq "unsafe path: exit 9" 9 "$rc" assert "unsafe path: nothing installed" test ! -e "$unit" pv install "$scratch/no-such-goals" assert_eq "missing goals dir: exit 5" 5 "$rc" pv install assert_eq "usage: exit 4" 4 "$rc" verdict