mirror of
https://github.com/cfal/shoes.git
synced 2026-11-06 16:14:11 +00:00
Preserve payload bytes across fragmented VLESS response headers, nonempty WebSocket Ping frames, and ShadowTLS authentication fallback. Expand authentication, buffering, half-close, flow-control, and TUN reload coverage; harden isolated test selection, enable macOS process-watcher tests, and document suite boundaries and remaining gaps.
410 lines
15 KiB
YAML
410 lines
15 KiB
YAML
name: Test
|
|
|
|
on:
|
|
push:
|
|
branches: [ master ]
|
|
pull_request:
|
|
branches: [ master ]
|
|
|
|
env:
|
|
CARGO_TERM_COLOR: always
|
|
RUST_BACKTRACE: 1
|
|
SING_BOX_VERSION: 1.14.1
|
|
SING_BOX_SHA256: 12cb2816b52febb356f6a885b740cc8758c3f30b8ae0ca8edba80f0d2d35343f
|
|
MIHOMO_VERSION: 1.19.31
|
|
MIHOMO_SHA256: 04cf9f09671704f839ddbee2e93069dc831a4123a75281e725d1d96ab9ac1afc
|
|
XRAY_VERSION: 26.10.21
|
|
XRAY_SHA256: 0eec3ed4163c273d8c8bf821f7d219e257921cf584aa3fb970715e458e631978
|
|
XRAY_COMMIT: 1b1647cd9ddf0abc34b981d4611fc03bcac1ca74
|
|
MIHOMO_ALPHA_COMMIT: 94b13aed49b8dc41973e4bb3f721c5fa2c5c5c1f
|
|
NAIVE_CADDY_VERSION: 2.11.7-naive
|
|
NAIVE_CADDY_SHA256: ac97057c925bb098eb575e7b0cb8bd547d4c5f845b09a3dedfbe34444aa7ae88
|
|
|
|
jobs:
|
|
dependency-notices:
|
|
name: Dependency notices
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: dtolnay/rust-toolchain@stable
|
|
- uses: taiki-e/install-action@v2
|
|
with:
|
|
tool: cargo-about@0.9.2
|
|
- name: Verify generated dependency licenses and artifact checks
|
|
run: |
|
|
python3 scripts/generate-release-notices.py
|
|
git diff --exit-code -- licenses/dependencies.txt
|
|
cargo fetch --locked
|
|
python3 scripts/test-release-notices.py
|
|
|
|
wireguard-interop:
|
|
name: WireGuard interoperability
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 60
|
|
env:
|
|
GOMAXPROCS: 1
|
|
WG_SING_BOX_COMMIT: 7054cac5124465ffdb145870d7c01885566711b1
|
|
WG_XRAY_COMMIT: 1b1647cd9ddf0abc34b981d4611fc03bcac1ca74
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: dtolnay/rust-toolchain@stable
|
|
- name: Restore pinned WireGuard peers
|
|
id: wireguard-peers
|
|
uses: actions/cache/restore@v6
|
|
with:
|
|
path: ~/.cache/shoes-wireguard
|
|
key: ${{ runner.os }}-${{ runner.arch }}-wireguard-peers-go1.27.3-${{ env.WG_SING_BOX_COMMIT }}-${{ env.WG_XRAY_COMMIT }}
|
|
- uses: actions/setup-go@v7
|
|
if: steps.wireguard-peers.outputs.cache-hit != 'true'
|
|
with:
|
|
go-version: '1.27.3'
|
|
cache: false
|
|
- uses: actions/cache@v6
|
|
with:
|
|
path: |
|
|
~/.cargo/registry
|
|
~/.cargo/git
|
|
target
|
|
~/go/pkg/mod
|
|
~/.cache/go-build
|
|
key: ${{ runner.os }}-wireguard-${{ hashFiles('**/Cargo.lock') }}-${{ env.WG_SING_BOX_COMMIT }}-${{ env.WG_XRAY_COMMIT }}
|
|
- name: Build pinned independent WireGuard peers
|
|
if: steps.wireguard-peers.outputs.cache-hit != 'true'
|
|
run: |
|
|
mkdir -p "$HOME/.cache/shoes-wireguard"
|
|
git clone --filter=blob:none --no-checkout https://github.com/SagerNet/sing-box.git "$HOME/wg-sing-box"
|
|
git -C "$HOME/wg-sing-box" checkout --detach "$WG_SING_BOX_COMMIT"
|
|
test "$(git -C "$HOME/wg-sing-box" rev-parse HEAD)" = "$WG_SING_BOX_COMMIT"
|
|
git clone --filter=blob:none --no-checkout https://github.com/XTLS/Xray-core.git "$HOME/wg-xray"
|
|
git -C "$HOME/wg-xray" checkout --detach "$WG_XRAY_COMMIT"
|
|
test "$(git -C "$HOME/wg-xray" rev-parse HEAD)" = "$WG_XRAY_COMMIT"
|
|
cd "$HOME/wg-sing-box"
|
|
go build -mod=readonly -p 1 -tags with_gvisor,with_wireguard -o "$HOME/.cache/shoes-wireguard/sing-box" ./cmd/sing-box
|
|
cd "$HOME/wg-xray"
|
|
go build -mod=readonly -p 1 -o "$HOME/.cache/shoes-wireguard/xray" ./main
|
|
- name: Save pinned WireGuard peers
|
|
if: steps.wireguard-peers.outputs.cache-hit != 'true'
|
|
uses: actions/cache/save@v6
|
|
with:
|
|
path: ~/.cache/shoes-wireguard
|
|
key: ${{ steps.wireguard-peers.outputs.cache-primary-key }}
|
|
- name: Select WireGuard peers
|
|
run: |
|
|
echo "SHOES_TEST_SING_BOX_BIN=$HOME/.cache/shoes-wireguard/sing-box" >> "$GITHUB_ENV"
|
|
echo "SHOES_TEST_XRAY_BIN=$HOME/.cache/shoes-wireguard/xray" >> "$GITHUB_ENV"
|
|
"$HOME/.cache/shoes-wireguard/sing-box" version
|
|
"$HOME/.cache/shoes-wireguard/xray" version
|
|
- name: Test both roles, inner address families, and real rekey
|
|
env:
|
|
RUST_LOG: warn
|
|
run: >-
|
|
cargo test -p shoes --locked --features optional-peer-tests
|
|
--test optional_peer wireguard -- --ignored --test-threads=1
|
|
|
|
unit-tests:
|
|
name: Unit tests
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 25
|
|
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
|
|
- name: Install Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
|
|
- name: Cache cargo registry
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: ~/.cargo/registry
|
|
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
|
|
|
|
- name: Cache cargo index
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: ~/.cargo/git
|
|
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
|
|
|
|
- name: Cache cargo build
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: target
|
|
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
|
|
|
|
- name: Build
|
|
run: cargo build --workspace --locked --verbose
|
|
|
|
- name: Run local tests
|
|
run: cargo test --workspace --locked --lib --bins --verbose
|
|
|
|
- name: Run process contract tests
|
|
run: cargo test -p shoes --locked --test process_contract --verbose -- --test-threads=1
|
|
|
|
- name: Run rule compilation allocation regression
|
|
run: cargo test -p shoes --locked --test rule_allocation --verbose
|
|
|
|
- name: Run host FFI tests
|
|
run: cargo test -p shoes --locked --lib --features ffi -- --test-threads=1
|
|
|
|
benchmark-tooling:
|
|
name: Benchmark tooling
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/setup-node@v7
|
|
with:
|
|
node-version: '24'
|
|
package-manager-cache: false
|
|
- name: Test benchmark harness and manifests
|
|
run: node --test benches/*.test.mjs
|
|
|
|
tun-macos:
|
|
name: Rootless TUN (macOS)
|
|
runs-on: macos-latest
|
|
timeout-minutes: 30
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
|
|
- name: Install Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
|
|
- name: Cache Rust build
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: |
|
|
~/.cargo/registry
|
|
~/.cargo/git
|
|
target
|
|
key: ${{ runner.os }}-tun-cargo-${{ hashFiles('**/Cargo.lock') }}
|
|
|
|
- name: Run raw-FD and packet tests without a TUN device
|
|
run: >-
|
|
cargo test -p shoes --locked --lib --features ffi tun:: -- --test-threads=1
|
|
|
|
- name: Run rootless WireGuard, FFI, and process lifecycle tests
|
|
run: >-
|
|
cargo test -p shoes --locked --lib --test process_contract --features ffi wireguard -- --test-threads=1
|
|
|
|
- name: Run FFI rule-source startup and packet tests
|
|
run: >-
|
|
cargo test -p shoes --locked --lib --features ffi ffi::common::rule_source_tests -- --test-threads=1
|
|
|
|
- name: Run rule-source routing and filesystem reload tests
|
|
run: >-
|
|
cargo test -p shoes --locked --test process_contract --features ffi rule_sets:: -- --test-threads=1
|
|
|
|
- name: Run process filesystem watcher unit tests
|
|
run: >-
|
|
cargo test -p shoes --locked --bin shoes process:: -- --test-threads=1
|
|
|
|
integration-tests:
|
|
name: Integration (${{ matrix.name }})
|
|
needs: unit-tests
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- name: local protocols
|
|
features: integration-tests
|
|
target: integration
|
|
filters: ""
|
|
peer: sing-box
|
|
- name: optional peer interoperability
|
|
features: optional-peer-tests
|
|
target: optional_peer
|
|
filters: ""
|
|
peer: mihomo
|
|
- name: XHTTP interoperability
|
|
features: integration-tests
|
|
target: xhttp_interop
|
|
filters: ""
|
|
peer: xhttp
|
|
- name: external DNS
|
|
features: external-network-tests
|
|
target: external_network
|
|
filters: dns resolver vless_doh vless_dot
|
|
peer: sing-box
|
|
- name: external proxies
|
|
features: external-network-tests
|
|
target: external_network
|
|
filters: portforward shadowtls
|
|
peer: sing-box
|
|
- name: external REALITY
|
|
features: external-network-tests
|
|
target: external_network
|
|
filters: reality
|
|
peer: sing-box
|
|
- name: kernel WireGuard
|
|
features: privileged-tests
|
|
target: privileged
|
|
filters: wireguard_kernel
|
|
peer: kernel-wireguard
|
|
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
|
|
- name: Install Rust
|
|
uses: dtolnay/rust-toolchain@stable
|
|
|
|
- name: Cache cargo registry
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: ~/.cargo/registry
|
|
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
|
|
|
|
- name: Cache cargo index
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: ~/.cargo/git
|
|
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
|
|
|
|
- name: Cache cargo build
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: target
|
|
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
|
|
|
|
- name: Install kernel WireGuard test tools
|
|
if: matrix.peer == 'kernel-wireguard'
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install --yes --no-install-recommends wireguard-tools iproute2
|
|
uname -r
|
|
wg --version
|
|
|
|
- name: Install sing-box test peer
|
|
if: matrix.peer == 'sing-box' || matrix.target == 'optional_peer'
|
|
run: |
|
|
archive="$RUNNER_TEMP/sing-box.tar.gz"
|
|
curl --fail --location --retry 3 \
|
|
--output "$archive" \
|
|
"https://github.com/SagerNet/sing-box/releases/download/v${SING_BOX_VERSION}/sing-box-${SING_BOX_VERSION}-linux-amd64.tar.gz"
|
|
echo "${SING_BOX_SHA256} ${archive}" | sha256sum --check --strict
|
|
tar --extract --gzip --file "$archive" --directory "$RUNNER_TEMP"
|
|
binary="$RUNNER_TEMP/sing-box-${SING_BOX_VERSION}-linux-amd64/sing-box"
|
|
chmod +x "$binary"
|
|
echo "SHOES_TEST_SING_BOX_BIN=$binary" >> "$GITHUB_ENV"
|
|
|
|
- name: Install Mihomo test peer
|
|
if: matrix.peer == 'mihomo'
|
|
run: |
|
|
archive="$RUNNER_TEMP/mihomo.gz"
|
|
binary="$RUNNER_TEMP/mihomo"
|
|
curl --fail --location --retry 3 \
|
|
--output "$archive" \
|
|
"https://github.com/MetaCubeX/mihomo/releases/download/v${MIHOMO_VERSION}/mihomo-linux-amd64-compatible-v${MIHOMO_VERSION}.gz"
|
|
echo "${MIHOMO_SHA256} ${archive}" | sha256sum --check --strict
|
|
gzip --decompress --stdout "$archive" > "$binary"
|
|
chmod +x "$binary"
|
|
echo "SHOES_TEST_MIHOMO_BIN=$binary" >> "$GITHUB_ENV"
|
|
|
|
- name: Install Xray test peer
|
|
if: matrix.target == 'optional_peer'
|
|
run: |
|
|
archive="$RUNNER_TEMP/xray.zip"
|
|
curl --fail --location --retry 3 \
|
|
--output "$archive" \
|
|
"https://github.com/XTLS/Xray-core/releases/download/v${XRAY_VERSION}/Xray-linux-64.zip"
|
|
echo "${XRAY_SHA256} ${archive}" | sha256sum --check --strict
|
|
unzip "$archive" xray -d "$RUNNER_TEMP/xray-peer"
|
|
binary="$RUNNER_TEMP/xray-peer/xray"
|
|
chmod +x "$binary"
|
|
echo "SHOES_TEST_XRAY_BIN=$binary" >> "$GITHUB_ENV"
|
|
|
|
- name: Install native Naive Caddy test peer
|
|
if: matrix.target == 'optional_peer'
|
|
run: |
|
|
archive="$RUNNER_TEMP/caddy-forwardproxy-naive.tar.xz"
|
|
curl --fail --location --retry 3 \
|
|
--output "$archive" \
|
|
"https://github.com/klzgrad/forwardproxy/releases/download/v${NAIVE_CADDY_VERSION}/caddy-forwardproxy-naive.tar.xz"
|
|
echo "${NAIVE_CADDY_SHA256} ${archive}" | sha256sum --check --strict
|
|
tar --extract --xz --file "$archive" --directory "$RUNNER_TEMP"
|
|
binary="$RUNNER_TEMP/caddy-forwardproxy-naive/caddy"
|
|
chmod +x "$binary"
|
|
echo "SHOES_TEST_NAIVE_CADDY_BIN=$binary" >> "$GITHUB_ENV"
|
|
|
|
- name: Run sing-box mux lifecycle tests
|
|
if: matrix.name == 'local protocols'
|
|
run: >-
|
|
cargo test -p shoes --locked --lib --features integration-tests
|
|
h2mux::h2mux_server_session::singbox_interop_tests:: -- --test-threads=1
|
|
|
|
- name: Restore pinned XHTTP peers
|
|
if: matrix.target == 'xhttp_interop'
|
|
id: xhttp-peers
|
|
uses: actions/cache/restore@v6
|
|
with:
|
|
path: |
|
|
~/.cache/shoes-xray/xray
|
|
~/.cache/shoes-mihomo/mihomo
|
|
key: ${{ runner.os }}-xhttp-peers-go1.27.3-${{ env.XRAY_COMMIT }}-${{ env.MIHOMO_ALPHA_COMMIT }}
|
|
|
|
- name: Install Go for XHTTP peers
|
|
if: matrix.target == 'xhttp_interop' && steps.xhttp-peers.outputs.cache-hit != 'true'
|
|
uses: actions/setup-go@v7
|
|
with:
|
|
go-version: '1.27.3'
|
|
cache: false
|
|
|
|
- name: Build pinned Xray test peer
|
|
if: matrix.target == 'xhttp_interop' && steps.xhttp-peers.outputs.cache-hit != 'true'
|
|
run: |
|
|
source="$HOME/.cache/shoes-xray"
|
|
git clone --filter=blob:none --no-checkout https://github.com/XTLS/Xray-core.git "$source"
|
|
git -C "$source" checkout --detach "$XRAY_COMMIT"
|
|
test "$(git -C "$source" rev-parse HEAD)" = "$XRAY_COMMIT"
|
|
cd "$source"
|
|
GOMAXPROCS=1 go build -p 1 -o "$source/xray" ./main
|
|
|
|
- name: Build pinned Mihomo Alpha test peer
|
|
if: matrix.target == 'xhttp_interop' && steps.xhttp-peers.outputs.cache-hit != 'true'
|
|
run: |
|
|
source="$HOME/.cache/shoes-mihomo"
|
|
git clone --filter=blob:none --no-checkout https://github.com/MetaCubeX/mihomo.git "$source"
|
|
git -C "$source" checkout --detach "$MIHOMO_ALPHA_COMMIT"
|
|
test "$(git -C "$source" rev-parse HEAD)" = "$MIHOMO_ALPHA_COMMIT"
|
|
cd "$source"
|
|
GOMAXPROCS=1 CGO_ENABLED=0 go build -p 1 \
|
|
-ldflags "-X github.com/metacubex/mihomo/constant.Version=alpha-${MIHOMO_ALPHA_COMMIT:0:8}" \
|
|
-o "$source/mihomo" .
|
|
|
|
- name: Save pinned XHTTP peers
|
|
if: matrix.target == 'xhttp_interop' && steps.xhttp-peers.outputs.cache-hit != 'true'
|
|
uses: actions/cache/save@v6
|
|
with:
|
|
path: |
|
|
~/.cache/shoes-xray/xray
|
|
~/.cache/shoes-mihomo/mihomo
|
|
key: ${{ steps.xhttp-peers.outputs.cache-primary-key }}
|
|
|
|
- name: Select XHTTP peers
|
|
if: matrix.target == 'xhttp_interop'
|
|
run: |
|
|
echo "SHOES_TEST_XRAY_BIN=$HOME/.cache/shoes-xray/xray" >> "$GITHUB_ENV"
|
|
echo "SHOES_TEST_MIHOMO_BIN=$HOME/.cache/shoes-mihomo/mihomo" >> "$GITHUB_ENV"
|
|
"$HOME/.cache/shoes-xray/xray" version
|
|
"$HOME/.cache/shoes-mihomo/mihomo" -v
|
|
|
|
- name: Run integration tests
|
|
env:
|
|
TEST_FILTERS: ${{ matrix.filters }}
|
|
RUST_LOG: warn
|
|
run: |
|
|
if [ -z "$TEST_FILTERS" ]; then
|
|
cargo test -p shoes --locked \
|
|
--features "${{ matrix.features }}" \
|
|
--test "${{ matrix.target }}" \
|
|
--verbose -- --test-threads=1
|
|
else
|
|
for filter in $TEST_FILTERS; do
|
|
cargo test -p shoes --locked \
|
|
--features "${{ matrix.features }}" \
|
|
--test "${{ matrix.target }}" \
|
|
--verbose "$filter::" -- --test-threads=1
|
|
done
|
|
fi
|