197 lines
4.9 KiB
Bash
Executable file
197 lines
4.9 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
MH_BIN="${ROOT_DIR}/mh"
|
|
PROFILE="${1:-tnt}"
|
|
TIMEOUT="${TIMEOUT:-10}"
|
|
API_PORT="${API_PORT:-9090}"
|
|
MIXED_PORT="${MIXED_PORT:-7897}"
|
|
SOCKS_PORT="${SOCKS_PORT:-7898}"
|
|
OLD_PROXY_PORT="${OLD_PROXY_PORT:-}"
|
|
RUN_PID_FILE="${ROOT_DIR}/run.pid"
|
|
LOG_FILE="${ROOT_DIR}/${PROFILE}/mihomo.log"
|
|
|
|
PASS_COUNT=0
|
|
FAIL_COUNT=0
|
|
|
|
log() {
|
|
printf '[%s] %s\n' "$(date +%H:%M:%S)" "$*"
|
|
}
|
|
|
|
pass() {
|
|
PASS_COUNT=$((PASS_COUNT + 1))
|
|
log "PASS $*"
|
|
}
|
|
|
|
fail() {
|
|
FAIL_COUNT=$((FAIL_COUNT + 1))
|
|
log "FAIL $*"
|
|
}
|
|
|
|
run_check() {
|
|
local label="$1"
|
|
shift
|
|
if "$@"; then
|
|
pass "$label"
|
|
else
|
|
fail "$label"
|
|
fi
|
|
}
|
|
|
|
print_section() {
|
|
printf '\n== %s ==\n' "$1"
|
|
}
|
|
|
|
cleanup_env() {
|
|
unset http_proxy https_proxy all_proxy HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY no_proxy || true
|
|
}
|
|
|
|
port_listen_check() {
|
|
local port="$1"
|
|
ss -lnt 2>/dev/null | awk '{print $4}' | grep -qE "(:|\\.)${port}\$"
|
|
}
|
|
|
|
curl_proxy_head() {
|
|
local url="$1"
|
|
curl -I -m "$TIMEOUT" -x "http://127.0.0.1:${MIXED_PORT}" "$url" >/dev/null 2>&1
|
|
}
|
|
|
|
curl_env_head() {
|
|
local url="$1"
|
|
curl -I -m "$TIMEOUT" "$url" >/dev/null 2>&1
|
|
}
|
|
|
|
print_recent_log() {
|
|
if [[ -f "$LOG_FILE" ]]; then
|
|
print_section "Recent mihomo.log"
|
|
tail -n 40 "$LOG_FILE" || true
|
|
else
|
|
print_section "Recent mihomo.log"
|
|
echo "missing log file: $LOG_FILE"
|
|
fi
|
|
}
|
|
|
|
print_context() {
|
|
print_section "Context"
|
|
echo "root_dir=${ROOT_DIR}"
|
|
echo "profile=${PROFILE}"
|
|
echo "api_port=${API_PORT}"
|
|
echo "mixed_port=${MIXED_PORT}"
|
|
echo "socks_port=${SOCKS_PORT}"
|
|
echo "old_proxy_port=${OLD_PROXY_PORT}"
|
|
echo "timeout=${TIMEOUT}"
|
|
}
|
|
|
|
print_env_snapshot() {
|
|
print_section "Proxy Env Before Test"
|
|
env | grep -iE 'http_proxy|https_proxy|all_proxy|no_proxy' || true
|
|
}
|
|
|
|
print_port_snapshot() {
|
|
print_section "Port Snapshot"
|
|
ss -lnt | grep -E ":(7897|7898|9090)\\b" || true
|
|
}
|
|
|
|
print_pid_snapshot() {
|
|
print_section "PID Snapshot"
|
|
if [[ -f "$RUN_PID_FILE" ]]; then
|
|
local pid
|
|
pid="$(cat "$RUN_PID_FILE" 2>/dev/null || true)"
|
|
echo "run.pid=${pid:-<empty>}"
|
|
if [[ -n "${pid:-}" ]]; then
|
|
ps -fp "$pid" -o pid,ppid,cmd || true
|
|
fi
|
|
else
|
|
echo "run.pid missing"
|
|
fi
|
|
}
|
|
|
|
api_json() {
|
|
local path="$1"
|
|
curl -fsS --noproxy '*' "http://127.0.0.1:${API_PORT}${path}"
|
|
}
|
|
|
|
api_selector_now() {
|
|
local selector="$1"
|
|
api_json "/proxies" | jq -r --arg selector "$selector" '.proxies[$selector].now // empty'
|
|
}
|
|
|
|
selector_equals() {
|
|
local selector="$1"
|
|
local expected="$2"
|
|
[[ "$(api_selector_now "$selector")" == "$expected" ]]
|
|
}
|
|
|
|
selector_non_empty() {
|
|
local selector="$1"
|
|
[[ -n "$(api_selector_now "$selector")" ]]
|
|
}
|
|
|
|
main() {
|
|
[[ -x "$MH_BIN" ]] || { echo "missing executable: $MH_BIN"; exit 1; }
|
|
|
|
print_context
|
|
print_env_snapshot
|
|
print_port_snapshot
|
|
|
|
if [[ -n "$OLD_PROXY_PORT" ]] && port_listen_check "$OLD_PROXY_PORT"; then
|
|
echo
|
|
echo "旧代理端口 ${OLD_PROXY_PORT} 仍在监听。先手动关闭它,再重新运行此脚本。"
|
|
exit 2
|
|
fi
|
|
|
|
cleanup_env
|
|
|
|
print_section "Start Profile"
|
|
"$MH_BIN" end >/dev/null 2>&1 || true
|
|
"$MH_BIN" start "$PROFILE"
|
|
|
|
run_check "API port ${API_PORT} is listening" port_listen_check "$API_PORT"
|
|
run_check "mixed port ${MIXED_PORT} is listening" port_listen_check "$MIXED_PORT"
|
|
run_check "socks port ${SOCKS_PORT} is listening" port_listen_check "$SOCKS_PORT"
|
|
run_check "run.pid exists" test -f "$RUN_PID_FILE"
|
|
|
|
if [[ -f "$RUN_PID_FILE" ]]; then
|
|
pid="$(cat "$RUN_PID_FILE" 2>/dev/null || true)"
|
|
run_check "run.pid process is alive" test -n "${pid:-}"
|
|
if [[ -n "${pid:-}" ]]; then
|
|
run_check "PID ${pid} exists" kill -0 "$pid"
|
|
fi
|
|
fi
|
|
|
|
print_pid_snapshot
|
|
|
|
print_section "API Checks"
|
|
run_check "GET /configs" api_json "/configs"
|
|
run_check "GET /proxies" api_json "/proxies"
|
|
run_check "GLOBAL selector points to Proxy" selector_equals "GLOBAL" "Proxy"
|
|
run_check "Proxy selector has current node" selector_non_empty "Proxy"
|
|
|
|
print_section "Shell Proxy Checks"
|
|
eval "$("$MH_BIN" env)"
|
|
run_check "HTTP_PROXY points to ${MIXED_PORT}" bash -lc '[[ "${HTTP_PROXY:-}" == "http://127.0.0.1:'"${MIXED_PORT}"'" ]]'
|
|
run_check "HTTPS_PROXY points to ${MIXED_PORT}" bash -lc '[[ "${HTTPS_PROXY:-}" == "http://127.0.0.1:'"${MIXED_PORT}"'" ]]'
|
|
|
|
print_section "Network Through Proxy"
|
|
run_check "proxy -> baidu" curl_proxy_head "https://www.baidu.com"
|
|
run_check "proxy -> github" curl_proxy_head "https://www.github.com"
|
|
run_check "proxy -> google" curl_proxy_head "https://www.google.com"
|
|
|
|
print_section "Network Through Current Shell"
|
|
run_check "env -> baidu" curl_env_head "https://www.baidu.com"
|
|
run_check "env -> github" curl_env_head "https://www.github.com"
|
|
run_check "env -> google" curl_env_head "https://www.google.com"
|
|
|
|
print_recent_log
|
|
|
|
print_section "Summary"
|
|
echo "PASS=${PASS_COUNT}"
|
|
echo "FAIL=${FAIL_COUNT}"
|
|
|
|
if (( FAIL_COUNT > 0 )); then
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
main "$@"
|