Files
NeoTachyon/tests/docker_e2e_test.sh
T
Dushnilin 7da51a62d7 fix(singbox): AWG-джанк в тегах и MTProto-секрет
- i1–i5/j1–j3: классический hex конвертируется в теги <b 0x…>;
  userspace WireGuard extended/lx молча игнорирует голый hex,
  handshake не завершался (#39 #41 #42)
- j1/j2/j3/itime эмитятся только для extended ≤2.6.0: в 2.6.1+
  поля удалены из схемы, sing-box падает на unknown fields
- j1–j3 больше не ломаются uci_bin_to_hex
- h1–h4: диапазоны «min-max» на обеих ветках
- MTProto: секрет канонизируется в ee-hex из любой формы
  (hex/base64), валидатор даёт понятную ошибку вместо
  FATAL decode psk (#23)
- XHTTP v2: парсинг и экспорт ключей подписок
- валидатор: warp/masque/openvpn/snell/mieru/sudoku — только extended
- тесты: stat→ucode (busybox), раннеры исключены из E2E,
  новые server_mtproto.sh и awg_variant_schema.sh
2026-08-24 10:13:33 +03:00

212 lines
7.7 KiB
Bash

#!/usr/bin/env bash
set -eo pipefail
export MSYS_NO_PATHCONV=1
# Check if docker or docker.exe command is available
if command -v docker.exe >/dev/null 2>&1; then
DOCKER_BIN="docker.exe"
elif command -v docker >/dev/null 2>&1; then
DOCKER_BIN="docker"
else
echo "Docker is not available. Skipping E2E test."
exit 0
fi
# Determine script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR/.."
if command -v cygpath >/dev/null 2>&1; then
ROOT_DIR="$(cygpath -w "$PWD")"
elif pwd -W >/dev/null 2>&1; then
ROOT_DIR="$(pwd -W)"
else
ROOT_DIR="$(pwd)"
fi
# Convert WSL or Sandbox mount paths to Windows-friendly drive paths for docker.exe
if [ "$DOCKER_BIN" = "docker.exe" ]; then
if [[ "$ROOT_DIR" =~ /mnt/host/([a-zA-Z])/(.*) ]]; then
ROOT_DIR="${BASH_REMATCH[1]}:/${BASH_REMATCH[2]}"
elif [[ "$ROOT_DIR" =~ ^/mnt/([a-zA-Z])/(.*) ]]; then
ROOT_DIR="${BASH_REMATCH[1]}:/${BASH_REMATCH[2]}"
elif [[ "$ROOT_DIR" =~ ^/([a-zA-Z])/(.*) ]]; then
ROOT_DIR="${BASH_REMATCH[1]}:/${BASH_REMATCH[2]}"
fi
fi
BUILDER_IMAGE="tachyon-builder"
if ! "$DOCKER_BIN" image inspect "$BUILDER_IMAGE:latest" >/dev/null 2>&1; then
echo "=== Creating cached builder image '$BUILDER_IMAGE:latest' ==="
cat <<EOF > Dockerfile.builder
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
sudo \
build-essential \
curl \
fakeroot \
file \
gawk \
git \
patch \
python3 \
rsync \
tar \
unzip \
util-linux \
wget \
xz-utils \
zstd \
&& rm -rf /var/lib/apt/lists/*
EOF
"$DOCKER_BIN" build -t "$BUILDER_IMAGE:latest" -f Dockerfile.builder .
rm -f Dockerfile.builder
fi
echo "=== Building Tachyon Package inside Ubuntu Container ==="
VERSION="1.0.0"
BUILD_OUT="$ROOT_DIR/build-out"
mkdir -p "$BUILD_OUT"
"$DOCKER_BIN" run --rm \
-v "$ROOT_DIR:/work" \
-w /work \
-e SDK_CACHE_DIR="/work/.wsl-build/sdk-cache" \
"$BUILDER_IMAGE:latest" \
bash -c "sed -i 's/\r$//' ./build.sh && bash ./build.sh $VERSION /work/build-out"
CONTAINER_NAME="tachyon-e2e-test"
TEST_IMAGE="tachyon-test-image"
if ! "$DOCKER_BIN" image inspect "$TEST_IMAGE:latest" >/dev/null 2>&1; then
echo "=== Creating custom cached test image '$TEST_IMAGE:latest' ==="
TEMP_CONTAINER="tachyon-test-temp"
"$DOCKER_BIN" rm -f "$TEMP_CONTAINER" >/dev/null 2>&1 || true
"$DOCKER_BIN" run -d \
--name "$TEMP_CONTAINER" \
--privileged \
openwrt/rootfs:x86-64-23.05.5 \
/bin/sh -c "sleep 3600"
echo "Installing dependencies inside temp container..."
"$DOCKER_BIN" exec "$TEMP_CONTAINER" mkdir -p /var/lock
for i in 1 2 3; do
"$DOCKER_BIN" exec "$TEMP_CONTAINER" opkg update && break || sleep 5
done
for i in 1 2 3 4 5; do
"$DOCKER_BIN" exec "$TEMP_CONTAINER" opkg install ucode ucode-mod-fs ucode-mod-uci curl ca-bundle bind-dig nftables ip-full coreutils-base64 sing-box bash node git git-http && break || sleep 5
done
"$DOCKER_BIN" exec "$TEMP_CONTAINER" git config --global --add safe.directory '*' || true
echo "=== Installing official sing-box 1.12.0 binary ==="
for i in 1 2 3; do
"$DOCKER_BIN" exec "$TEMP_CONTAINER" curl -sSL -o /tmp/sing-box.tar.gz https://github.com/SagerNet/sing-box/releases/download/v1.12.0/sing-box-1.12.0-linux-amd64.tar.gz && break || sleep 5
done
"$DOCKER_BIN" exec "$TEMP_CONTAINER" tar -zxf /tmp/sing-box.tar.gz -C /tmp
"$DOCKER_BIN" exec "$TEMP_CONTAINER" cp /tmp/sing-box-1.12.0-linux-amd64/sing-box /usr/sbin/sing-box
"$DOCKER_BIN" exec "$TEMP_CONTAINER" cp /tmp/sing-box-1.12.0-linux-amd64/sing-box /usr/bin/sing-box
"$DOCKER_BIN" exec "$TEMP_CONTAINER" chmod +x /usr/sbin/sing-box /usr/bin/sing-box
"$DOCKER_BIN" exec "$TEMP_CONTAINER" rm -rf /tmp/sing-box.tar.gz /tmp/sing-box-1.12.0-linux-amd64
"$DOCKER_BIN" commit "$TEMP_CONTAINER" "$TEST_IMAGE:latest"
"$DOCKER_BIN" rm -f "$TEMP_CONTAINER"
fi
cleanup() {
echo "=== Container logs (stdout/stderr) ==="
"$DOCKER_BIN" logs "$CONTAINER_NAME" || true
echo "=== OpenWrt system logs ==="
"$DOCKER_BIN" exec "$CONTAINER_NAME" logread || true
echo "=== Stopping Container ==="
"$DOCKER_BIN" rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
}
trap cleanup EXIT
echo "=== Starting OpenWrt Container from Cached Image ==="
"$DOCKER_BIN" rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
"$DOCKER_BIN" run -d \
--name "$CONTAINER_NAME" \
--privileged \
-e SB_REQUIRED_VERSION="1.11.0" \
-e ENABLE_DEPRECATED_SPECIAL_OUTBOUNDS="true" \
-v "$ROOT_DIR:/work" \
"$TEST_IMAGE:latest" \
/bin/sh /work/tests/container_entrypoint.sh
echo "Waiting for OpenWrt to initialize..."
sleep 5
echo "=== Installing Tachyon IPK ==="
"$DOCKER_BIN" exec "$CONTAINER_NAME" opkg install --force-reinstall /work/build-out/tachyon_1.0.0.ipk
echo "=== Configuring Tachyon ==="
"$DOCKER_BIN" exec "$CONTAINER_NAME" uci set tachyon.settings.enabled='1'
"$DOCKER_BIN" exec "$CONTAINER_NAME" uci set tachyon.settings.log_level='debug'
# Create a test bypass section
"$DOCKER_BIN" exec "$CONTAINER_NAME" uci set tachyon.test_sec='section'
"$DOCKER_BIN" exec "$CONTAINER_NAME" uci set tachyon.test_sec.label='TestSection'
"$DOCKER_BIN" exec "$CONTAINER_NAME" uci set tachyon.test_sec.enabled='1'
"$DOCKER_BIN" exec "$CONTAINER_NAME" uci set tachyon.test_sec.action='bypass'
"$DOCKER_BIN" exec "$CONTAINER_NAME" uci add_list tachyon.test_sec.domain='ip.podkop.fyi'
"$DOCKER_BIN" exec "$CONTAINER_NAME" uci commit tachyon
echo "=== Starting services ==="
"$DOCKER_BIN" exec "$CONTAINER_NAME" /etc/init.d/sing-box enable
"$DOCKER_BIN" exec "$CONTAINER_NAME" /etc/init.d/sing-box start
"$DOCKER_BIN" exec "$CONTAINER_NAME" /etc/init.d/tachyon enable
"$DOCKER_BIN" exec "$CONTAINER_NAME" /etc/init.d/tachyon start
echo "Waiting for services to stabilize..."
sleep 5
echo "=== Checking running services ==="
"$DOCKER_BIN" exec "$CONTAINER_NAME" /etc/init.d/tachyon status || echo "Tachyon status non-zero, continuing..."
"$DOCKER_BIN" exec "$CONTAINER_NAME" pgrep -l sing-box || echo "sing-box process not found"
echo "=== Running connection test via mixed port ==="
# Test routing of the proxy port
PROXY_TEST_HTTP_CODE=$("$DOCKER_BIN" exec "$CONTAINER_NAME" curl -s -o /dev/null -w "%{http_code}" -x http://127.0.0.1:4534 --connect-timeout 10 http://ip.podkop.fyi || echo "failed")
echo "HTTP proxy status: $PROXY_TEST_HTTP_CODE"
echo "=== Running transparent interception test ==="
# Running direct curl to test transparent proxying via nftables
"$DOCKER_BIN" exec "$CONTAINER_NAME" curl -s -I --connect-timeout 10 http://ip.podkop.fyi || echo "curl failed"
echo "=== Checking system logs ==="
LOGS=$("$DOCKER_BIN" exec "$CONTAINER_NAME" logread)
echo "$LOGS" | tail -n 100
echo "=== Checking nftables rules ==="
"$DOCKER_BIN" exec "$CONTAINER_NAME" nft list ruleset || echo "nft failed"
# Verification: check if logs contain trace of bypass or redirect
if echo "$LOGS" | grep -Fiq "ip.podkop.fyi"; then
echo "SUCCESS: Traffic to ip.podkop.fyi was intercepted/processed!"
else
echo "WARNING: Domain ip.podkop.fyi not found in system logs. Checking sing-box status."
if "$DOCKER_BIN" exec "$CONTAINER_NAME" pgrep -f sing-box >/dev/null; then
echo "sing-box is running, routing table was loaded."
else
echo "FAIL: sing-box is not running."
exit 1
fi
fi
echo "=== Normalizing line endings for test scripts ==="
"$DOCKER_BIN" exec "$CONTAINER_NAME" sh -c "sed -i 's/\r$//' /work/tests/*.sh"
echo "=== Running unit and integration tests inside OpenWrt container ==="
for f in tests/*.sh; do
if [ "$f" != "tests/docker_e2e_test.sh" ] && [ "$f" != "tests/container_entrypoint.sh" ] &&
[ "$f" != "tests/run_all.sh" ] && [ "$f" != "tests/ucode_syntax_lint.sh" ]; then
echo "Running $f inside container..."
"$DOCKER_BIN" exec -w /work -e SB_REQUIRED_VERSION="1.11.0" "$CONTAINER_NAME" bash "$f"
fi
done
echo "=== E2E and Unit Tests Passed Successfully ==="