mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-04 16:37:46 +08:00
194 lines
6.8 KiB
Bash
194 lines
6.8 KiB
Bash
#!/usr/bin/env bash
|
|||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
REPO_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd -P)"
|
||
|
|
# shellcheck source=../install.sh
|
||
|
|
source "${REPO_ROOT}/install.sh"
|
||
|
|
|
||
|
|
TEST_ROOT="$(mktemp -d)/aether installer fixtures"
|
||
|
|
mkdir -p "${TEST_ROOT}"
|
||
|
|
|
||
|
|
cleanup_test_root() {
|
||
|
|
rm -rf -- "$(dirname -- "${TEST_ROOT}")"
|
||
|
|
}
|
||
|
|
trap cleanup_test_root EXIT
|
||
|
|
|
||
|
|
fail_test() {
|
||
|
|
echo "FAIL: $*" >&2
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
assert_link_target() {
|
||
|
|
local link="$1"
|
||
|
|
local expected="$2"
|
||
|
|
[[ -L "${link}" ]] || fail_test "${link} is not a symbolic link"
|
||
|
|
[[ "$(readlink "${link}")" == "${expected}" ]] \
|
||
|
|
|| fail_test "${link} does not point to ${expected}"
|
||
|
|
}
|
||
|
|
|
||
|
|
assert_switch_rejected() {
|
||
|
|
local release_dir="$1"
|
||
|
|
local current_link="$2"
|
||
|
|
if (switch_current_release_link "${release_dir}" "${current_link}"); then
|
||
|
|
fail_test "unsafe current-link fixture was accepted: ${current_link}"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
test_initial_switch() {
|
||
|
|
local fixture="${TEST_ROOT}/initial"
|
||
|
|
local release_dir="${fixture}/release new"
|
||
|
|
local current_link="${fixture}/current"
|
||
|
|
mkdir -p "${release_dir}"
|
||
|
|
|
||
|
|
switch_current_release_link "${release_dir}" "${current_link}"
|
||
|
|
|
||
|
|
assert_link_target "${current_link}" "${release_dir}"
|
||
|
|
[[ ! -e "${current_link}.new" && ! -L "${current_link}.new" ]] \
|
||
|
|
|| fail_test "temporary link remained after initial switch"
|
||
|
|
}
|
||
|
|
|
||
|
|
test_existing_link_switch() {
|
||
|
|
local fixture="${TEST_ROOT}/existing link"
|
||
|
|
local old_release="${fixture}/release old"
|
||
|
|
local new_release="${fixture}/release new"
|
||
|
|
local current_link="${fixture}/current"
|
||
|
|
mkdir -p "${old_release}" "${new_release}"
|
||
|
|
ln -s -- "${old_release}" "${current_link}"
|
||
|
|
|
||
|
|
switch_current_release_link "${new_release}" "${current_link}"
|
||
|
|
|
||
|
|
assert_link_target "${current_link}" "${new_release}"
|
||
|
|
[[ ! -e "${old_release}/current.new" && ! -L "${old_release}/current.new" ]] \
|
||
|
|
|| fail_test "temporary link was moved into the previous release directory"
|
||
|
|
}
|
||
|
|
|
||
|
|
test_dangling_links_are_replaced() {
|
||
|
|
local fixture="${TEST_ROOT}/dangling links"
|
||
|
|
local release_dir="${fixture}/release new"
|
||
|
|
local current_link="${fixture}/current"
|
||
|
|
mkdir -p "${release_dir}"
|
||
|
|
ln -s -- "${fixture}/missing current target" "${current_link}"
|
||
|
|
ln -s -- "${fixture}/missing temporary target" "${current_link}.new"
|
||
|
|
|
||
|
|
switch_current_release_link "${release_dir}" "${current_link}"
|
||
|
|
|
||
|
|
assert_link_target "${current_link}" "${release_dir}"
|
||
|
|
[[ ! -e "${current_link}.new" && ! -L "${current_link}.new" ]] \
|
||
|
|
|| fail_test "temporary dangling link remained after switch"
|
||
|
|
}
|
||
|
|
|
||
|
|
test_current_file_is_rejected() {
|
||
|
|
local fixture="${TEST_ROOT}/current file"
|
||
|
|
local release_dir="${fixture}/release new"
|
||
|
|
local current_link="${fixture}/current"
|
||
|
|
mkdir -p "${release_dir}"
|
||
|
|
printf '%s\n' "keep-current-file" >"${current_link}"
|
||
|
|
|
||
|
|
assert_switch_rejected "${release_dir}" "${current_link}"
|
||
|
|
|
||
|
|
[[ "$(cat "${current_link}")" == "keep-current-file" ]] \
|
||
|
|
|| fail_test "current file was modified"
|
||
|
|
[[ ! -e "${current_link}.new" && ! -L "${current_link}.new" ]] \
|
||
|
|
|| fail_test "temporary link was created for an unsafe current file"
|
||
|
|
}
|
||
|
|
|
||
|
|
test_current_directory_is_rejected() {
|
||
|
|
local fixture="${TEST_ROOT}/current directory"
|
||
|
|
local release_dir="${fixture}/release new"
|
||
|
|
local current_link="${fixture}/current"
|
||
|
|
mkdir -p "${release_dir}" "${current_link}"
|
||
|
|
|
||
|
|
assert_switch_rejected "${release_dir}" "${current_link}"
|
||
|
|
|
||
|
|
[[ -d "${current_link}" && ! -L "${current_link}" ]] \
|
||
|
|
|| fail_test "current directory was modified"
|
||
|
|
[[ ! -e "${current_link}/current.new" && ! -L "${current_link}/current.new" ]] \
|
||
|
|
|| fail_test "temporary link was moved into an unsafe current directory"
|
||
|
|
}
|
||
|
|
|
||
|
|
test_temporary_file_is_rejected() {
|
||
|
|
local fixture="${TEST_ROOT}/temporary file"
|
||
|
|
local old_release="${fixture}/release old"
|
||
|
|
local new_release="${fixture}/release new"
|
||
|
|
local current_link="${fixture}/current"
|
||
|
|
mkdir -p "${old_release}" "${new_release}"
|
||
|
|
ln -s -- "${old_release}" "${current_link}"
|
||
|
|
printf '%s\n' "keep-temporary-file" >"${current_link}.new"
|
||
|
|
|
||
|
|
assert_switch_rejected "${new_release}" "${current_link}"
|
||
|
|
|
||
|
|
assert_link_target "${current_link}" "${old_release}"
|
||
|
|
[[ "$(cat "${current_link}.new")" == "keep-temporary-file" ]] \
|
||
|
|
|| fail_test "temporary file was modified"
|
||
|
|
}
|
||
|
|
|
||
|
|
test_temporary_directory_is_rejected() {
|
||
|
|
local fixture="${TEST_ROOT}/temporary directory"
|
||
|
|
local old_release="${fixture}/release old"
|
||
|
|
local new_release="${fixture}/release new"
|
||
|
|
local current_link="${fixture}/current"
|
||
|
|
mkdir -p "${old_release}" "${new_release}" "${current_link}.new"
|
||
|
|
ln -s -- "${old_release}" "${current_link}"
|
||
|
|
|
||
|
|
assert_switch_rejected "${new_release}" "${current_link}"
|
||
|
|
|
||
|
|
assert_link_target "${current_link}" "${old_release}"
|
||
|
|
[[ -d "${current_link}.new" && ! -L "${current_link}.new" ]] \
|
||
|
|
|| fail_test "temporary directory was modified"
|
||
|
|
}
|
||
|
|
|
||
|
|
test_managed_directory_link_is_rejected() {
|
||
|
|
local fixture="${TEST_ROOT}/managed directory link"
|
||
|
|
local target="${fixture}/target"
|
||
|
|
local link="${fixture}/managed"
|
||
|
|
mkdir -p "${target}"
|
||
|
|
ln -s -- "${target}" "${link}"
|
||
|
|
|
||
|
|
if (ensure_directory "${link}"); then
|
||
|
|
fail_test "managed directory symbolic link was accepted"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
test_existing_release_is_never_rewritten_in_place() {
|
||
|
|
local fixture="${TEST_ROOT}/immutable release"
|
||
|
|
local requested="${fixture}/releases/v1.2.3"
|
||
|
|
local selected
|
||
|
|
mkdir -p "${requested}"
|
||
|
|
printf '%s\n' "old-release" >"${requested}/marker"
|
||
|
|
|
||
|
|
selected="$(select_release_install_directory "${requested}")"
|
||
|
|
|
||
|
|
[[ "${selected}" != "${requested}" ]] \
|
||
|
|
|| fail_test "an existing release directory was selected for in-place rewriting"
|
||
|
|
[[ -d "${selected}" && ! -L "${selected}" ]] \
|
||
|
|
|| fail_test "replacement release directory was not allocated safely"
|
||
|
|
[[ "$(cat "${requested}/marker")" == "old-release" ]] \
|
||
|
|
|| fail_test "the existing release was modified while allocating its replacement"
|
||
|
|
}
|
||
|
|
|
||
|
|
test_new_release_keeps_the_requested_version_path() {
|
||
|
|
local fixture="${TEST_ROOT}/new release"
|
||
|
|
local requested="${fixture}/releases/v1.2.3"
|
||
|
|
local selected
|
||
|
|
mkdir -p "$(dirname -- "${requested}")"
|
||
|
|
|
||
|
|
selected="$(select_release_install_directory "${requested}")"
|
||
|
|
[[ "${selected}" == "${requested}" ]] \
|
||
|
|
|| fail_test "a new release unexpectedly received a suffixed directory"
|
||
|
|
[[ ! -e "${requested}" && ! -L "${requested}" ]] \
|
||
|
|
|| fail_test "release selection created the requested path before installation"
|
||
|
|
}
|
||
|
|
|
||
|
|
test_initial_switch
|
||
|
|
test_existing_link_switch
|
||
|
|
test_dangling_links_are_replaced
|
||
|
|
test_current_file_is_rejected
|
||
|
|
test_current_directory_is_rejected
|
||
|
|
test_temporary_file_is_rejected
|
||
|
|
test_temporary_directory_is_rejected
|
||
|
|
test_managed_directory_link_is_rejected
|
||
|
|
test_existing_release_is_never_rewritten_in_place
|
||
|
|
test_new_release_keeps_the_requested_version_path
|
||
|
|
|
||
|
|
echo "PASS: current release link safety fixtures"
|