set -eu
repo_root=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
test_tmp=$(mktemp -d)
trap 'rm -rf "$test_tmp"' EXIT HUP INT TERM
install_dir="$test_tmp/install"
output="$test_tmp/output"
command_dir="$test_tmp/commands"
mkdir "$command_dir"
ln -s "$(command -v uname)" "$command_dir/uname"
PATH="$command_dir" \
/bin/sh "$repo_root/install.sh" \
--dry-run \
--version v0.4.2 \
--target x86_64-unknown-linux-musl \
--install-dir "$install_dir" \
>"$output" 2>&1
grep -F '[dry-run] No network requests or filesystem changes will be made.' "$output" >/dev/null
grep -F 'safe-migrate-x86_64-unknown-linux-musl.tar.gz' "$output" >/dev/null
grep -F "atomically install ${install_dir}/safe-migrate" "$output" >/dev/null
if [ -e "$install_dir" ]; then
printf '%s\n' 'dry run unexpectedly created the requested install directory' >&2
exit 1
fi
archive_root="$test_tmp/archive"
archive="$test_tmp/safe-migrate-x86_64-unknown-linux-musl.tar.gz"
zip_archive="$test_tmp/safe-migrate-x86_64-pc-windows-msvc.zip"
mkdir "$archive_root"
printf '%s\n' '#!/bin/sh' 'printf "mock safe-migrate\n"' > "$archive_root/safe-migrate"
chmod +x "$archive_root/safe-migrate"
tar -czf "$archive" -C "$archive_root" safe-migrate
cp "$archive_root/safe-migrate" "$archive_root/safe-migrate.exe"
(cd "$archive_root" && zip -q "$zip_archive" safe-migrate.exe)
mock_dir="$test_tmp/mock-commands"
mkdir "$mock_dir"
for command_name in \
uname tar gzip unzip sed head grep mktemp cp chmod mkdir mv rm cut tr cat find sha256sum
do
ln -s "$(command -v "$command_name")" "$mock_dir/$command_name"
done
mock_curl="$mock_dir/curl"
printf '%s\n' \
'#!/bin/sh' \
'set -eu' \
'output=""' \
'url=""' \
'while [ "$#" -gt 0 ]; do' \
' case "$1" in' \
' -o) output="$2"; shift 2 ;;' \
' -*) shift ;;' \
' *) url="$1"; shift ;;' \
' esac' \
'done' \
'case "$url" in' \
' *.tar.gz.sha256) exit 22 ;;' \
' *.sha256)' \
' case "$MOCK_CHECKSUM_MODE" in' \
' missing) exit 22 ;;' \
' network) exit 6 ;;' \
' malformed) printf "not-a-checksum archive.tar.gz\n" > "$output" ;;' \
' mismatch) printf "%064d archive.tar.gz\n" 0 > "$output" ;;' \
' valid)' \
' digest=$(sha256sum "$MOCK_ARCHIVE" | cut -d" " -f1)' \
' printf "%s archive.tar.gz\n" "$digest" > "$output"' \
' ;;' \
' *) exit 2 ;;' \
' esac' \
' ;;' \
' *.tar.gz) cp "$MOCK_ARCHIVE" "$output" ;;' \
' *.zip) cp "$MOCK_ARCHIVE" "$output" ;;' \
' *) exit 22 ;;' \
'esac' \
> "$mock_curl"
chmod +x "$mock_curl"
run_mock_install() {
checksum_mode="$1"
expected_status="$2"
case_dir="$test_tmp/$checksum_mode"
case_output="$case_dir/output"
case_install="$case_dir/install"
mkdir "$case_dir"
set +e
PATH="$mock_dir" \
MOCK_ARCHIVE="$archive" \
MOCK_CHECKSUM_MODE="$checksum_mode" \
/bin/sh "$repo_root/install.sh" \
--version v0.4.2 \
--target x86_64-unknown-linux-musl \
--install-dir "$case_install" \
>"$case_output" 2>&1
status=$?
set -e
if [ "$status" -ne "$expected_status" ]; then
printf 'installer case %s returned %s, expected %s\n' \
"$checksum_mode" "$status" "$expected_status" >&2
sed -n '1,80p' "$case_output" >&2
exit 1
fi
case "$checksum_mode" in
valid)
test -x "$case_install/safe-migrate"
;;
network)
grep -F 'network failure downloading' "$case_output" >/dev/null
test ! -e "$case_install/safe-migrate"
;;
*)
grep -F 'release integrity verification failed' "$case_output" >/dev/null
test ! -e "$case_install/safe-migrate"
;;
esac
}
run_mock_install missing 1
run_mock_install network 1
run_mock_install malformed 1
run_mock_install mismatch 1
run_mock_install valid 0
zip_case="$test_tmp/zip"
mkdir "$zip_case"
PATH="$mock_dir" \
MOCK_ARCHIVE="$zip_archive" \
MOCK_CHECKSUM_MODE=valid \
/bin/sh "$repo_root/install.sh" \
--version v0.4.2 \
--target x86_64-pc-windows-msvc \
--install-dir "$zip_case/install" \
>"$zip_case/output" 2>&1
test -x "$zip_case/install/safe-migrate.exe"
if /bin/sh "$repo_root/install.sh" --dry-run --version v1.2.beta \
--target x86_64-unknown-linux-musl >/dev/null 2>&1; then
printf '%s\n' 'installer accepted a non-semantic version' >&2
exit 1
fi
for invalid_version in v1.2.3. v.1.2.3 v1..3 v01.2.3; do
if /bin/sh "$repo_root/install.sh" --dry-run --version "$invalid_version" \
--target x86_64-unknown-linux-musl >/dev/null 2>&1; then
printf 'installer accepted invalid version: %s\n' "$invalid_version" >&2
exit 1
fi
done
if /bin/sh "$repo_root/install.sh" --dry-run --version v1.2.3 \
--target aarch64-pc-windows-msvc >/dev/null 2>&1; then
printf '%s\n' 'installer accepted an unpublished target' >&2
exit 1
fi
if find "$test_tmp" -name '.safe-migrate.tmp.*' -print -quit | grep -q .; then
printf '%s\n' 'installer left a temporary destination behind' >&2
exit 1
fi