Files
IPTables-Management/tests/test_interactive.sh
ahdoawhfo 26fbcf3584 Mark runnable scripts executable in git
The repo was committed from WSL with core.filemode=false, so the exec
bit was never recorded. After actions/checkout the entry script comes
down as 100644 and tests/test_cli.sh fails with Permission denied.

Set mode 100755 on every script that is invoked directly (entry,
installer, test suite, mock binaries). Sourced helpers under lib/
keep 100644 per convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 13:58:42 +08:00

97 lines
4.0 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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 -Urn true >/dev/null 2>&1; then
exec unshare -Urn env IPF_IN_NAMESPACE=1 bash "$0"
fi
printf 'SKIP: 交互测试需要 root 或可用的 unshare。\n'
exit 0
}
maybe_enter_namespace
TMP_DIR=$(mktemp -d)
trap 'rm -rf "${TMP_DIR}"' EXIT
export IPF_STORAGE_DIR="${TMP_DIR}/storage"
export IPF_STORAGE_DB="${IPF_STORAGE_DIR}/rules.db"
export IPF_LOCK_FILE="${IPF_STORAGE_DIR}/.lock"
export IPTABLES_MOCK_DIR="${TMP_DIR}/iptables-mock"
export IPTABLES_MOCK_LOG="${TMP_DIR}/iptables.log"
export IPTABLES_BIN="${ROOT_DIR}/tests/mocks/iptables"
export IP6TABLES_BIN="${ROOT_DIR}/tests/mocks/ip6tables"
export IPTABLES_SAVE_BIN="${ROOT_DIR}/tests/mocks/iptables-save"
export IP6TABLES_SAVE_BIN="${ROOT_DIR}/tests/mocks/ip6tables-save"
export NETFILTER_PERSISTENT_BIN="${ROOT_DIR}/tests/mocks/persist-mock.sh"
export PERSIST_MOCK_LOG="${TMP_DIR}/persist.log"
export IPF_SKIP_ENV_CHECK=1
export IPF_FORCE_PLAIN_UI=1
# shellcheck source=lib/common.sh
source "${ROOT_DIR}/lib/common.sh"
# shellcheck source=lib/storage.sh
source "${ROOT_DIR}/lib/storage.sh"
# shellcheck source=lib/persist.sh
source "${ROOT_DIR}/lib/persist.sh"
# shellcheck source=lib/iptables_ops.sh
source "${ROOT_DIR}/lib/iptables_ops.sh"
# shellcheck source=lib/rules_mgr.sh
source "${ROOT_DIR}/lib/rules_mgr.sh"
reset_mock_state() {
rm -rf "${IPTABLES_MOCK_DIR}" "${IPF_STORAGE_DIR}"
mkdir -p "${IPTABLES_MOCK_DIR}" "${IPF_STORAGE_DIR}"
: >"${IPTABLES_MOCK_LOG}"
: >"${PERSIST_MOCK_LOG}"
storage_init
}
reset_mock_state
export IPF_TEST_INPUTS=$'4\n2\n1\n8080\n1\n127.0.0.1\n80\ninteractive web\ny\n5\n1\n3\n1\ny\n0\n'
output=$("${ROOT_DIR}/iptables-forward.sh" 2>&1)
assert_contains "${output}" '== 环境状态 ==' 'interactive flow should open environment status view'
assert_contains "${output}" '规则总数: 0' 'environment status should show empty rule count before adding'
assert_contains "${output}" '== 添加新的转发规则 ==' 'interactive flow should enter add screen'
assert_contains "${output}" '描述: interactive web' 'interactive add summary should echo description'
assert_contains "${output}" '规则已保存到磁盘。' 'interactive flow should exercise menu save action'
assert_contains "${output}" 'interactive web' 'interactive list/delete flow should display the created description'
assert_contains "${output}" '规则已添加UUID=' 'interactive flow should add one managed rule'
assert_contains "${output}" '已退出。' 'interactive flow should return cleanly from main menu'
assert_eq '0' "$(wc -l < "${IPF_STORAGE_DB}")" 'interactive add/delete flow should leave storage empty'
assert_eq '0' "$(wc -l < "${IPTABLES_MOCK_DIR}/state.v4")" 'interactive add/delete flow should leave runtime mock state empty'
assert_eq '4' "$(grep -Ec ' -A ' "${IPTABLES_MOCK_LOG}")" 'interactive add flow should emit four IPv4 add commands'
assert_eq '4' "$(grep -Ec ' -D ' "${IPTABLES_MOCK_LOG}")" 'interactive delete should emit four delete commands'
assert_eq '3' "$(grep -Ec 'persist-mock\.sh save' "${PERSIST_MOCK_LOG}")" 'interactive add/menu-save/delete flow should persist three times'
reset_mock_state
uuid=$(cmd_add_batch tcp 8081 127.0.0.1 81 4 'degraded menu' 2>/dev/null)
"${IPTABLES_BIN}" -D FORWARD \
-p tcp -s 127.0.0.1 --sport 81 \
-m conntrack --ctstate ESTABLISHED,RELATED \
-j ACCEPT \
-m comment --comment "MGMT:${uuid}"
export IPF_TEST_INPUTS=$'0\n'
degraded_output=$("${ROOT_DIR}/iptables-forward.sh" 2>&1)
assert_contains "${degraded_output}" '运行态: [!]' 'main menu should surface degraded runtime status'
assert_contains "${degraded_output}" '规则数: 1' 'main menu should still show current rule count'
pass 'test_interactive.sh'