#!/usr/bin/env bash set -euo pipefail ROOT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd) # shellcheck source=tests/lib/assert.sh source "${ROOT_DIR}/tests/lib/assert.sh" maybe_enter_namespace() { if (( EUID == 0 )); then return 0 fi if [[ ${IPF_IN_NAMESPACE:-0} == 1 ]]; then return 0 fi if command -v unshare >/dev/null 2>&1 && unshare -Ur true >/dev/null 2>&1; then exec unshare -Ur env IPF_IN_NAMESPACE=1 bash "$0" fi printf 'SKIP: 安装测试需要 root 或可用的 unshare。\n' exit 0 } status_of() { set +e "$@" >/dev/null 2>&1 local rc=$? set -e printf '%s\n' "${rc}" } maybe_enter_namespace TMP_DIR=$(mktemp -d) trap 'rm -rf "${TMP_DIR}"' EXIT TARGET_BIN="${TMP_DIR}/bin/iptables-forward" OTHER_TARGET="${TMP_DIR}/bin/not-ours" SOURCE_SCRIPT="${ROOT_DIR}/iptables-forward.sh" install_output=$(INSTALL_TARGET="${TARGET_BIN}" "${ROOT_DIR}/install.sh") assert_contains "${install_output}" '已创建链接:' 'install should create symlink on first run' [[ -L ${TARGET_BIN} ]] || fail 'install should create a symlink' assert_eq "${SOURCE_SCRIPT}" "$(readlink -- "${TARGET_BIN}")" 'install should link to project entry script' install_output=$(INSTALL_TARGET="${TARGET_BIN}" "${ROOT_DIR}/install.sh") assert_contains "${install_output}" '链接已存在:' 'install should be idempotent for existing project link' printf 'keep-me\n' >"${OTHER_TARGET}" assert_status '1' "$(status_of env INSTALL_TARGET="${OTHER_TARGET}" "${ROOT_DIR}/install.sh")" 'install should refuse to overwrite non-project target' assert_eq 'keep-me' "$(cat "${OTHER_TARGET}")" 'install refusal should keep existing target untouched' uninstall_output=$(INSTALL_TARGET="${TARGET_BIN}" "${ROOT_DIR}/install.sh" --uninstall) assert_contains "${uninstall_output}" '已删除链接:' 'uninstall should remove project symlink' [[ ! -e ${TARGET_BIN} && ! -L ${TARGET_BIN} ]] || fail 'uninstall should remove installed symlink' assert_status '1' "$(status_of env INSTALL_TARGET="${OTHER_TARGET}" "${ROOT_DIR}/install.sh" --uninstall)" 'uninstall should refuse to delete non-project target' assert_eq 'keep-me' "$(cat "${OTHER_TARGET}")" 'uninstall refusal should keep existing target untouched' pass 'test_install.sh'