Wren Linux

wren-linux / tools / test-early-upgrade.sh

#!/bin/bash
# Checks apt_early_upgrade (lib/apt.sh, run by install-base.sh before the packages are installed):
# online, it updates the package lists and upgrades what is installed without asking anything;
# offline, it does nothing and says so; a failing update or upgrade is a warning, not the end of
# the install; and a kernel newer than the running one is reported (a reboot is due), by the
# variable WREN_NEW_KERNEL. Pretend sudo, apt-get and ip; nothing of this computer is changed.
# Run by test.sh, or:  bash tools/test-early-upgrade.sh
# shellcheck disable=SC2016  # the pretend programs expand their own variables
HERE=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
T=$(mktemp -d) || { echo "  FAIL  couldn't make a temp folder (is /tmp full?)"; exit 1; }
trap 'rm -rf "$T"' EXIT
fails=0
check() { # DESCRIPTION CONDITION-COMMAND...
    local what=$1
    shift
    if "$@" >/dev/null 2>&1; then printf '  ok    %s\n' "$what"; else printf '  FAIL  %s\n' "$what"; fails=$((fails + 1)); fi
}
not() { ! "$@"; }

mkdir -p "$T/bin" "$T/modules"
cat >"$T/bin/sudo" <<EOF
#!/bin/bash
while [ "\${1#-}" != "\$1" ]; do shift; done
[ "\$1" = env ] && shift && while [[ \$1 == *=* ]]; do shift; done
exec "\$@"
EOF
cat >"$T/bin/apt-get" <<EOF
#!/bin/bash
echo "apt-get \$*" >>"$T/calls"
case \$1 in
    update) [ ! -e "$T/update-fails" ] ;;
    *upgrade*|-y) [ ! -e "$T/upgrade-fails" ] ;;
esac
EOF
cat >"$T/bin/ip" <<EOF
#!/bin/bash
[ -e "$T/offline" ] || echo "default via 10.0.0.1 dev eth0"
EOF
cat >"$T/bin/uname" <<EOF
#!/bin/bash
[ "\$1" = -r ] && echo 6.12.1-amd64 || /usr/bin/uname "\$@"
EOF
chmod +x "$T/bin/"*

run() { # the function, with the pretend commands first
    : >"$T/calls"
    env PATH="$T/bin:$PATH" WREN_MODULES="$T/modules" bash -c '. "$1/lib.sh"; PATH="$2:$PATH"; apt_early_upgrade; echo "kernel=${WREN_NEW_KERNEL:-no}"' _ "$HERE" "$T/bin" 2>&1
}
mkdir -p "$T/modules/6.12.1-amd64"

out=$(run)
check "online: the package lists are updated" grep -q '^apt-get .*update' "$T/calls"
check "...and what is installed is upgraded, asking nothing" grep -qE '^apt-get .*-y.* upgrade|^apt-get .*upgrade.* -y' "$T/calls"
check "...old settings files are kept when they were changed (the question is not asked)" grep -q 'force-confold' "$T/calls"
check "...no new kernel: no reboot due" grep -qx 'kernel=no' <<<"$out"
touch "$T/offline"
out=$(run)
check "offline: nothing is run" test ! -s "$T/calls"
check "...and it says so, once the install goes on" grep -qi 'no network' <<<"$out"
rm -f "$T/offline"
touch "$T/update-fails"
out=$(run)
check "the lists can't be fetched: a warning, no upgrade, the install goes on" bash -c '! grep -q upgrade "$1" && grep -qi "warn\|couldn.t" <<<"$2"' _ "$T/calls" "$out"
rm -f "$T/update-fails"
touch "$T/upgrade-fails"
out=$(run)
check "the upgrade fails: a warning, and the install goes on" grep -qi "warn\|didn.t finish\|couldn.t" <<<"$out"
rm -f "$T/upgrade-fails"
mkdir -p "$T/modules/6.12.9-amd64"
out=$(run)
check "a kernel newer than the running one: a reboot is due" grep -qx 'kernel=yes' <<<"$out"
check "...and it says so" grep -qi 'reboot' <<<"$out"
check "install-base.sh runs it before the packages, and says when to reboot" bash -c 'a=$(grep -n "apt_early_upgrade" "$1" | head -1 | cut -d: -f1); b=$(grep -n "^apt_install" "$1" | head -1 | cut -d: -f1); [ -n "$a" ] && [ "$a" -lt "$b" ] && grep -q "WREN_NEW_KERNEL" "$1"' _ "$HERE/install-base.sh"
check "it is passed by shellcheck" bash -c 'command -v shellcheck >/dev/null || exit 0; shellcheck -x "$1"' _ "$HERE/lib/apt.sh"

[ "$fails" -eq 0 ]