Files
coredesktop/tests/update.bats
T
davidandClaude Opus 5.5 c6a6bac84a
shellcheck / shellcheck (push) Successful in 13s
Merge branch 'main' of https://gitea.federated.computer/Federated_Computer/coredesktop
Brings in the shellcheck lint and bats tests. Both sides fixed the same
shellcheck warnings; this keeps the remote's versions of 20-aur.sh,
80-gnome-extensions.sh and .shellcheckrc, which silence false positives
per line rather than for the whole repo.

The Gitea workflow now runs make lint, so it checks the same scripts as
the Makefile, and the README points contributors at make check. The test
helper's REPO, used only by the .bats files, is marked for shellcheck,
and the update test expects the pull to be fast-forward only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 07:25:07 -06:00

144 lines
3.7 KiB
Bash

#!/usr/bin/env bats
load test_helper
# Each test runs the real update script from a fake CoreDesktop checkout in the
# test's HOME, with fake hooks in updates.d/ that log to $RAN when they run.
setup() {
# A checkout with nothing but the update script and the files it installs
common_setup
CD="$HOME/.local/share/coredesktop"
mkdir -p "$CD/updates.d" "$HOME/.local/bin"
cp "$REPO/update" "$CD/update"
for script in refresh sibling version configure audit; do
echo '#!/bin/bash' > "$CD/$script"
done
export RAN="$BATS_TEST_TMPDIR/ran"
unset UPDATE_REEXECED UPDATE_PULL_FAILED UPDATE_FORCE
stub clear
stub git 'exit "${GIT_STATUS:-0}"'
stub sudo 'exit "${SUDO_STATUS:-0}"'
stub df 'printf "Avail\n%s\n" "${DF_AVAIL:-104857600}"'
# Let go of bats' output pipes so the sudo keepalive's leftover sleep
# doesn't keep the test waiting
stub sleep 'exec > /dev/null 2>&1 3>&-; exec /usr/bin/sleep "$@"'
}
# hook NAME BODY: add updates.d/NAME.sh with BODY as its run_update
hook() {
printf '#!/bin/bash\nrun_update() {\n%s\n}\n' "$2" > "$CD/updates.d/$1.sh"
}
ran() {
[ "$(cat "$RAN" 2> /dev/null)" = "$(printf '%s\n' "$@")" ]
}
@test "update pulls, installs its scripts, and runs every hook in order" {
hook 20-b 'echo b >> "$RAN"'
hook 10-a 'echo a >> "$RAN"'
run "$CD/update"
[ "$status" -eq 0 ]
[[ "$output" == *"Done."* ]]
called git -C "$CD" pull --ff-only
ran a b
for script in update refresh sibling version configure audit; do
[ -x "$HOME/.local/bin/$script" ]
done
}
@test "update pulls only once, before re-running its new copy" {
hook 10-a 'echo a >> "$RAN"'
run "$CD/update"
[ "$status" -eq 0 ]
[ "$(grep -c '^git ' "$STUB_LOG")" -eq 1 ]
ran a
}
@test "a failing hook doesn't stop the hooks after it" {
hook 10-a 'echo a >> "$RAN"'
hook 20-b 'echo b >> "$RAN"; return 1'
hook 30-c 'echo c >> "$RAN"'
run "$CD/update"
[ "$status" -eq 1 ]
[[ "$output" == *"Done, with errors in: 20-b.sh"* ]]
ran a b c
}
@test "a hook that exits doesn't end the update" {
hook 10-a 'echo a >> "$RAN"; exit 0'
hook 20-b 'echo b >> "$RAN"'
run "$CD/update"
[ "$status" -eq 0 ]
ran a b
}
@test "a hook using set -e fails at its first failing command" {
hook 10-a 'set -e; echo a >> "$RAN"; false; echo after >> "$RAN"'
hook 20-b 'echo b >> "$RAN"'
run "$CD/update"
[ "$status" -eq 1 ]
[[ "$output" == *"errors in: 10-a.sh"* ]]
ran a b
}
@test "a hook's is_installed and functions don't leak into the next hook" {
printf '%s\n' '#!/bin/bash' 'is_installed() { false; }' \
'run_update() { echo a >> "$RAN"; }' > "$CD/updates.d/10-a.sh"
# 10-a's is_installed must not stop 20-b, and its run_update must not run
# again for 30-c, which has none
printf '%s\n' '#!/bin/bash' 'run_update() { echo b >> "$RAN"; }' \
> "$CD/updates.d/20-b.sh"
printf '%s\n' '#!/bin/bash' 'true' > "$CD/updates.d/30-c.sh"
run "$CD/update"
[ "$status" -eq 0 ]
ran b
}
@test "update runs the hooks on disk when git pull fails, and reports it" {
export GIT_STATUS=1
hook 10-a 'echo a >> "$RAN"'
run "$CD/update"
[ "$status" -eq 1 ]
[[ "$output" == *"could not pull"* ]]
[[ "$output" == *"errors in: git pull"* ]]
ran a
}
@test "update stops before any hook when / is low on space" {
export DF_AVAIL=1048576
hook 10-a 'echo a >> "$RAN"'
run "$CD/update"
[ "$status" -eq 1 ]
[[ "$output" == *"needs at least 10 GiB"* ]]
[ ! -e "$RAN" ]
}
@test "UPDATE_FORCE skips the free space check" {
export DF_AVAIL=1048576 UPDATE_FORCE=1
hook 10-a 'echo a >> "$RAN"'
run "$CD/update"
[ "$status" -eq 0 ]
ran a
}
@test "update stops when sudo fails" {
export SUDO_STATUS=1
hook 10-a 'echo a >> "$RAN"'
run "$CD/update"
[ "$status" -eq 1 ]
[ ! -e "$RAN" ]
}