fix: DNS петля + watchdog автоисправление + централизация file_is_usable
Ключевые изменения:
1. core/helpers.uc: file_is_usable(path, min_bytes) + file_size_value(path)
для единообразной проверки файлов (минимальный размер порог).
2. singbox/dns.uc: WAN fallback DNS серверы (fallback_wan_main) теперь
используют прямой UDP без detour — исправлена петля когда
DNS шёл через мёртвую прокси-секцию.
Health probes для ВСЕХ DNS серверов (включая DoH) идут direct —
failover может определить доступность DNS серверов.
3. watchdog.uc: ai_heal_empty_sections() — автообнаружение пустых
proxy-секций с подписками → запуск subscription_update_async.
ai_heal_dns_loop() — при обнаружении DNS-петли (dead proxy +
dead DNS) → временно отключает DNS detour → загружает подписку →
восстанавливает настройки.
4. Единая file_is_usable: nft/apply.uc, generator_routes.uc,
components/{updates,action}.uc, config/validator.uc,
subscription/cache.uc — все используют helpers.file_is_usable.
5. Тест tests/file_usable.sh для проверки helpers CLI.
6. Исправлен components_updater_job.sh mock lib — добавлен core/helpers.uc
This commit is contained in:
@@ -191,6 +191,7 @@ package_runtime_bin="$WORK_DIR/package-runtime-bin"
|
||||
mkdir -p "$package_runtime_lib/components" "$package_runtime_lib/core" "$package_runtime_lib/singbox" "$package_runtime_bin"
|
||||
cp "$UPDATER" "$package_runtime_lib/components/updater.uc"
|
||||
cp "$TACHYON_LIB/core/common.uc" "$package_runtime_lib/core/common.uc"
|
||||
cp "$TACHYON_LIB/core/helpers.uc" "$package_runtime_lib/core/helpers.uc"
|
||||
cat >"$package_runtime_lib/core/constants.uc" <<'UCODE'
|
||||
function module_exports() {
|
||||
return {};
|
||||
@@ -380,6 +381,7 @@ cp "$UPDATES_UC" "$fake_lib/components/updates.uc"
|
||||
cp "$TACHYON_LIB/config/connections.uc" "$fake_lib/config/connections.uc"
|
||||
cp "$TACHYON_LIB/core/uci.uc" "$fake_lib/core/uci.uc"
|
||||
cp "$TACHYON_LIB/core/common.uc" "$fake_lib/core/common.uc"
|
||||
cp "$TACHYON_LIB/core/helpers.uc" "$fake_lib/core/helpers.uc"
|
||||
cat >"$fake_lib/components/action.uc" <<'UCODE'
|
||||
#!/usr/bin/env ucode
|
||||
if ((ARGV[0] || "") == "component-action") {
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
HELPERS_UC="$ROOT_DIR/tachyon/files/usr/lib/core/helpers.uc"
|
||||
TACHYON_LIB="$ROOT_DIR/tachyon/files/usr/lib"
|
||||
TMP_DIR="$ROOT_DIR/tmp_file_usable_test"
|
||||
|
||||
rm -rf "$TMP_DIR"
|
||||
mkdir -p "$TMP_DIR"
|
||||
|
||||
ucode() {
|
||||
command ucode -L "$TACHYON_LIB" "$@"
|
||||
}
|
||||
|
||||
fail() {
|
||||
printf 'FAIL: %s\n' "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
assert() {
|
||||
local expected="$1"
|
||||
local actual="$2"
|
||||
local label="$3"
|
||||
[ "$actual" = "$expected" ] || fail "$label: expected '$expected', got '$actual'"
|
||||
}
|
||||
|
||||
# --- file-is-usable CLI tests ---
|
||||
# Nonexistent file
|
||||
assert 1 "$(ucode "$HELPERS_UC" file-is-usable "$TMP_DIR/nonexistent.srs" 100 2>/dev/null; echo $?)" "nonexistent file not usable"
|
||||
|
||||
# Empty file
|
||||
touch "$TMP_DIR/empty.srs"
|
||||
assert 1 "$(ucode "$HELPERS_UC" file-is-usable "$TMP_DIR/empty.srs" 100 2>/dev/null; echo $?)" "empty file not usable"
|
||||
|
||||
# 1-byte file
|
||||
printf x > "$TMP_DIR/1byte.srs"
|
||||
assert 1 "$(ucode "$HELPERS_UC" file-is-usable "$TMP_DIR/1byte.srs" 100 2>/dev/null; echo $?)" "1-byte file not usable at min 100"
|
||||
|
||||
# 49-byte file
|
||||
dd if=/dev/urandom of="$TMP_DIR/49byte.srs" bs=1 count=49 2>/dev/null
|
||||
assert 1 "$(ucode "$HELPERS_UC" file-is-usable "$TMP_DIR/49byte.srs" 50 2>/dev/null; echo $?)" "49-byte file not usable at min 50"
|
||||
assert 0 "$(ucode "$HELPERS_UC" file-is-usable "$TMP_DIR/49byte.srs" 0 2>/dev/null; echo $?)" "49-byte file usable at min 0"
|
||||
|
||||
# 50-byte file
|
||||
dd if=/dev/urandom of="$TMP_DIR/50byte.srs" bs=1 count=50 2>/dev/null
|
||||
assert 0 "$(ucode "$HELPERS_UC" file-is-usable "$TMP_DIR/50byte.srs" 50 2>/dev/null; echo $?)" "50-byte file usable at min 50"
|
||||
|
||||
# 100-byte file
|
||||
dd if=/dev/urandom of="$TMP_DIR/100byte.srs" bs=1 count=100 2>/dev/null
|
||||
assert 0 "$(ucode "$HELPERS_UC" file-is-usable "$TMP_DIR/100byte.srs" 100 2>/dev/null; echo $?)" "100-byte file usable at min 100"
|
||||
assert 1 "$(ucode "$HELPERS_UC" file-is-usable "$TMP_DIR/100byte.srs" 200 2>/dev/null; echo $?)" "100-byte file not usable at min 200"
|
||||
|
||||
# No min_bytes = always usable if exists
|
||||
assert 0 "$(ucode "$HELPERS_UC" file-is-usable "$TMP_DIR/1byte.srs" 2>/dev/null; echo $?)" "1-byte file usable with no min"
|
||||
|
||||
# --- file-size CLI tests ---
|
||||
assert "-1" "$(ucode "$HELPERS_UC" file-size "$TMP_DIR/nonexistent.srs" 2>/dev/null)" "nonexistent file size is -1"
|
||||
assert "0" "$(ucode "$HELPERS_UC" file-size "$TMP_DIR/empty.srs" 2>/dev/null)" "empty file size is 0"
|
||||
assert "49" "$(ucode "$HELPERS_UC" file-size "$TMP_DIR/49byte.srs" 2>/dev/null)" "49-byte file size is 49"
|
||||
assert "100" "$(ucode "$HELPERS_UC" file-size "$TMP_DIR/100byte.srs" 2>/dev/null)" "100-byte file size is 100"
|
||||
|
||||
# Clean up
|
||||
rm -rf "$TMP_DIR"
|
||||
|
||||
printf 'file_usable checks passed\n'
|
||||
Reference in New Issue
Block a user