mirror of
https://github.com/wweir/sower.git
synced 2026-10-20 00:15:34 +00:00
test(install): cover install.sh end to end from make test
install.sh was only syntax-checked (sh -n), so the install and upgrade paths, the config-preservation contract and the failure modes for a malformed release tarball had no coverage. Add an offline, unprivileged E2E test that builds its own tarballs and installs into a temp prefix with --service none: fresh install, an in-place upgrade that keeps an operator-edited config, --with-server, a dry run that creates nothing, three malformed tarballs that must fail closed, and the CLI surface. Wire it into make test as test-install and syntax-check the new script.
This commit is contained in:
@@ -3,15 +3,20 @@ GO:=CGO_ENABLED=0 go
|
||||
|
||||
default: test build
|
||||
|
||||
test: web check-scripts
|
||||
test: web check-scripts test-install
|
||||
${GO} vet ./...
|
||||
${GO} test ./...
|
||||
|
||||
.PHONY: check-scripts
|
||||
check-scripts:
|
||||
sh -n install.sh
|
||||
sh -n install_e2e_test.sh
|
||||
sh -n .github/sower.init
|
||||
|
||||
.PHONY: test-install
|
||||
test-install:
|
||||
sh install_e2e_test.sh
|
||||
|
||||
build: sower sowerd
|
||||
.PHONY: web
|
||||
web:
|
||||
|
||||
Executable
+155
@@ -0,0 +1,155 @@
|
||||
#!/bin/sh
|
||||
# End-to-end test for install.sh.
|
||||
#
|
||||
# Everything runs offline against tarballs built here, with --service none into
|
||||
# a throwaway prefix and config dir, so the test never needs root, never touches
|
||||
# the system and never opens a network connection. It covers what `sh -n`
|
||||
# cannot: the install and upgrade paths, the config-preservation contract, the
|
||||
# dry-run contract, and the failure modes for a malformed release tarball.
|
||||
set -eu
|
||||
|
||||
HERE=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
INSTALL="$HERE/install.sh"
|
||||
|
||||
WORK=$(mktemp -d)
|
||||
trap 'rm -rf "$WORK"' EXIT INT TERM
|
||||
|
||||
fail() {
|
||||
printf 'install_e2e_test: %s\n' "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# stage_tarball <archive> <version> <member>...
|
||||
# Builds a minimal release tarball. The binaries are shell stubs that echo
|
||||
# their own name and version, so the test can tell a replaced binary from a
|
||||
# stale one.
|
||||
stage_tarball() {
|
||||
archive=$1
|
||||
version=$2
|
||||
shift 2
|
||||
stage="$WORK/stage-$version"
|
||||
rm -rf "$stage"
|
||||
mkdir -p "$stage"
|
||||
for member in "$@"; do
|
||||
case "$member" in
|
||||
sower | sowerd)
|
||||
printf '#!/bin/sh\necho "%s %s"\n' "$member" "$version" >"$stage/$member"
|
||||
chmod 0755 "$stage/$member"
|
||||
;;
|
||||
sower.toml)
|
||||
printf 'config %s\n' "$version" >"$stage/sower.toml"
|
||||
;;
|
||||
*)
|
||||
printf '%s\n' "$member" >"$stage/$member"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
tar -czf "$archive" -C "$stage" "$@"
|
||||
rm -rf "$stage"
|
||||
}
|
||||
|
||||
# run_install <archive> <prefix> <config-dir> [extra args...]
|
||||
run_install() {
|
||||
archive=$1
|
||||
prefix=$2
|
||||
config_dir=$3
|
||||
shift 3
|
||||
sh "$INSTALL" --tarball "$archive" --service none \
|
||||
--prefix "$prefix" --config-dir "$config_dir" "$@"
|
||||
}
|
||||
|
||||
# --- fresh install -----------------------------------------------------------
|
||||
|
||||
PREFIX="$WORK/prefix"
|
||||
CONFDIR="$WORK/config"
|
||||
stage_tarball "$WORK/release-v1.tar.gz" v1 sower sowerd sower.toml
|
||||
|
||||
if ! run_install "$WORK/release-v1.tar.gz" "$PREFIX" "$CONFDIR" >"$WORK/fresh.log" 2>&1; then
|
||||
fail "fresh install failed:
|
||||
$(cat "$WORK/fresh.log")"
|
||||
fi
|
||||
|
||||
[ -x "$PREFIX/sower" ] || fail "sower was not installed as an executable"
|
||||
[ "$("$PREFIX/sower")" = "sower v1" ] || fail "installed sower is not the tarball's binary"
|
||||
[ -f "$CONFDIR/sower.toml" ] || fail "starter config was not written"
|
||||
[ "$(cat "$CONFDIR/sower.toml")" = "config v1" ] || fail "starter config content mismatch"
|
||||
|
||||
config_mode=$(ls -l "$CONFDIR/sower.toml" | cut -c1-10)
|
||||
[ "$config_mode" = "-rw-------" ] || fail "starter config mode is $config_mode, want -rw-------"
|
||||
|
||||
# --- upgrade in place --------------------------------------------------------
|
||||
|
||||
printf 'edited by the operator\n' >"$CONFDIR/sower.toml"
|
||||
stage_tarball "$WORK/release-v2.tar.gz" v2 sower sowerd sower.toml
|
||||
|
||||
if ! run_install "$WORK/release-v2.tar.gz" "$PREFIX" "$CONFDIR" >"$WORK/upgrade.log" 2>&1; then
|
||||
fail "upgrade failed:
|
||||
$(cat "$WORK/upgrade.log")"
|
||||
fi
|
||||
|
||||
[ "$("$PREFIX/sower")" = "sower v2" ] || fail "upgrade did not replace the binary"
|
||||
[ "$(cat "$CONFDIR/sower.toml")" = "edited by the operator" ] ||
|
||||
fail "upgrade overwrote the existing config"
|
||||
grep -q 'keeping existing config' "$WORK/upgrade.log" || fail "upgrade did not report keeping the config"
|
||||
|
||||
# --- --with-server installs sowerd -------------------------------------------
|
||||
|
||||
if ! run_install "$WORK/release-v2.tar.gz" "$PREFIX" "$CONFDIR" --with-server >"$WORK/server.log" 2>&1; then
|
||||
fail "--with-server install failed:
|
||||
$(cat "$WORK/server.log")"
|
||||
fi
|
||||
[ -x "$PREFIX/sowerd" ] || fail "--with-server did not install sowerd"
|
||||
|
||||
# --- dry run must not touch the system --------------------------------------
|
||||
|
||||
DRY_PREFIX="$WORK/dry/prefix"
|
||||
DRY_CONFDIR="$WORK/dry/config"
|
||||
if ! run_install "$WORK/release-v1.tar.gz" "$DRY_PREFIX" "$DRY_CONFDIR" --dry-run >"$WORK/dry.log" 2>&1; then
|
||||
fail "dry run failed:
|
||||
$(cat "$WORK/dry.log")"
|
||||
fi
|
||||
[ ! -e "$DRY_PREFIX" ] || fail "dry run created the prefix directory"
|
||||
[ ! -e "$DRY_CONFDIR" ] || fail "dry run created the config directory"
|
||||
grep -q '^\[dry-run\]' "$WORK/dry.log" || fail "dry run printed no action preview"
|
||||
|
||||
# --- malformed tarballs ------------------------------------------------------
|
||||
|
||||
stage_tarball "$WORK/no-config.tar.gz" v1 sower sowerd
|
||||
if run_install "$WORK/no-config.tar.gz" "$WORK/bad-a/prefix" "$WORK/bad-a/config" >"$WORK/no-config.log" 2>&1; then
|
||||
fail "installer accepted a tarball without sower.toml"
|
||||
fi
|
||||
grep -q 'no sower.toml' "$WORK/no-config.log" ||
|
||||
fail "unexpected failure for a tarball without sower.toml:
|
||||
$(cat "$WORK/no-config.log")"
|
||||
[ ! -e "$WORK/bad-a/config/sower.toml" ] || fail "half-written config left behind"
|
||||
|
||||
stage_tarball "$WORK/no-binary.tar.gz" v1 sower.toml
|
||||
if run_install "$WORK/no-binary.tar.gz" "$WORK/bad-b/prefix" "$WORK/bad-b/config" >"$WORK/no-binary.log" 2>&1; then
|
||||
fail "installer accepted a tarball without the sower binary"
|
||||
fi
|
||||
grep -q 'no sower binary' "$WORK/no-binary.log" ||
|
||||
fail "unexpected failure for a tarball without the sower binary:
|
||||
$(cat "$WORK/no-binary.log")"
|
||||
[ ! -e "$WORK/bad-b/prefix/sower" ] || fail "installed a binary from a tarball without one"
|
||||
|
||||
stage_tarball "$WORK/no-server.tar.gz" v1 sower sower.toml
|
||||
if run_install "$WORK/no-server.tar.gz" "$WORK/bad-c/prefix" "$WORK/bad-c/config" --with-server >"$WORK/no-server.log" 2>&1; then
|
||||
fail "installer accepted --with-server from a tarball without sowerd"
|
||||
fi
|
||||
grep -q 'no sowerd binary' "$WORK/no-server.log" ||
|
||||
fail "unexpected failure for a tarball without sowerd:
|
||||
$(cat "$WORK/no-server.log")"
|
||||
|
||||
# --- CLI surface -------------------------------------------------------------
|
||||
|
||||
if ! sh "$INSTALL" --help >"$WORK/help.log" 2>&1; then
|
||||
fail "--help exited non-zero"
|
||||
fi
|
||||
grep -q 'Install or upgrade the sower client' "$WORK/help.log" || fail "--help printed no usage"
|
||||
|
||||
if sh "$INSTALL" --not-a-flag >"$WORK/unknown.log" 2>&1; then
|
||||
fail "installer accepted an unknown option"
|
||||
fi
|
||||
grep -q 'unknown option' "$WORK/unknown.log" || fail "unknown option reported nothing useful"
|
||||
|
||||
printf 'install_e2e_test: PASS\n'
|
||||
Reference in New Issue
Block a user