name: tests on: push: branches: [master] pull_request: branches: [master] jobs: tests: strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v7 with: submodules: recursive - name: Install dependencies (Linux) if: runner.os == 'Linux' run: | sudo apt-get update sudo apt-get install -y libpcre2-dev libmbedtls-dev libsodium-dev libev-dev libc-ares-dev valgrind - name: Install dependencies (macOS) if: runner.os == 'macOS' run: brew install mbedtls@3 libsodium libev c-ares pcre2 - name: Build test binaries run: | mkdir -p build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release jobs="$(nproc 2>/dev/null || sysctl -n hw.ncpu)" make -j"$jobs" - name: CTest run: ctest --test-dir build -LE memcheck --output-on-failure --no-tests=error - name: Valgrind leak smoke tests if: runner.os == 'Linux' run: ctest --test-dir build -L memcheck --output-on-failure --no-tests=error - name: ss-setup TUI tests run: bash tests/test_ss_setup.sh - name: Stress test run: | python3 tests/stress_test.py --bin build/shared/bin/ --size 10 - name: ss-redir transparent proxy test (QEMU) if: runner.os == 'Linux' run: | sudo apt-get install -y qemu-system-x86 bash tests/test_redir_qemu.sh build/shared/bin/ timeout-minutes: 8 asan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 with: submodules: recursive - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y libpcre2-dev libmbedtls-dev libsodium-dev libev-dev libc-ares-dev - name: Build with ASan + UBSan run: | mkdir -p build && cd build cmake .. -DENABLE_SANITIZERS=ON make -j"$(nproc)" - name: CTest (ASan + UBSan) run: ctest --test-dir build -LE memcheck --output-on-failure --no-tests=error - name: Stress test (ASan + UBSan) run: python3 tests/stress_test.py --bin build/shared/bin/ --size 10 clang-tidy: runs-on: ubuntu-latest env: # Ratchet: number of known clang-tidy warnings (see .clang-tidy), # counted with clang-tidy-18 (pinned below so runner upgrades don't move # the number). All baseline findings have been fixed or triaged # (false positives carry NOLINT comments with rationale), so any new # warning fails CI. MAX_WARNINGS: 0 steps: - uses: actions/checkout@v7 with: submodules: recursive - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y clang-tidy-18 clang-tools-18 libpcre2-dev libmbedtls-dev libsodium-dev libev-dev libc-ares-dev - name: Configure (compile_commands.json) run: cmake -S . -B build - name: Run clang-tidy on project sources run: | run-clang-tidy-18 -quiet -p build '/src/[^/]+\.c$' 2>/dev/null | tee tidy.log || true grep 'warning:' tidy.log | sort -u > warnings.txt || true count="$(wc -l < warnings.txt)" echo "clang-tidy warnings: $count (max allowed: $MAX_WARNINGS)" { echo "### clang-tidy: $count warnings (budget: $MAX_WARNINGS)" echo '```' cat warnings.txt echo '```' } >> "$GITHUB_STEP_SUMMARY" if ! grep -q . warnings.txt && grep -qE 'error:' tidy.log; then echo "clang-tidy produced errors:"; grep -E 'error:' tidy.log | sort -u exit 1 fi if [ "$count" -gt "$MAX_WARNINGS" ]; then echo "FAIL: warning count $count exceeds budget $MAX_WARNINGS." echo "Fix the new warnings (or, if a check is misfiring, adjust .clang-tidy)." exit 1 fi coverage: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 with: submodules: recursive - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y lcov libpcre2-dev libmbedtls-dev libsodium-dev libev-dev libc-ares-dev - name: Build with coverage instrumentation run: | mkdir -p build && cd build cmake .. -DENABLE_COVERAGE=ON make -j"$(nproc)" - name: Run tests run: | ctest --test-dir build -LE memcheck --output-on-failure --no-tests=error python3 tests/stress_test.py --bin build/shared/bin/ --size 10 - name: Generate coverage report run: | cmake --build build --target coverage { echo '### Coverage (src/, unit + stress tests)' echo '```' lcov --list build/coverage.info --ignore-errors unused,empty echo '```' } >> "$GITHUB_STEP_SUMMARY" - name: Upload HTML report uses: actions/upload-artifact@v4 with: name: coverage-html path: build/coverage-html/