test(splitter-v3): 108 tests, fuzz targets, CI coverage pipeline #1186
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Splitter-V3 CI | |
| on: | |
| push: | |
| paths: | |
| - "contracts/splitter-v3/**" | |
| - ".github/workflows/rust-ci.yml" | |
| pull_request: | |
| paths: | |
| - "contracts/splitter-v3/**" | |
| - ".github/workflows/rust-ci.yml" | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| # ── 1. Build & unit tests ───────────────────────────────────────────────── | |
| test: | |
| name: Unit Tests (snapshot) | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: contracts/splitter-v3 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust stable | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| contracts/splitter-v3/target | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('contracts/splitter-v3/Cargo.lock') }} | |
| restore-keys: ${{ runner.os }}-cargo- | |
| - name: Run tests (snapshot mode) | |
| run: RUSTFLAGS="--cap-lints=warn" cargo test --all-features 2>&1 | |
| - name: Verify snapshots are up-to-date | |
| run: | | |
| # Snapshots are written on first run. If the working tree is clean | |
| # after running tests, all snapshots are committed and current. | |
| git diff --exit-code -- test_snapshots/ || (echo "::error::Snapshots out of date. Run 'cargo test' and commit the updated snapshots." && exit 1) | |
| # ── 2. Coverage with llvm-cov ───────────────────────────────────────────── | |
| coverage: | |
| name: Line Coverage ≥ 90% | |
| runs-on: ubuntu-latest | |
| needs: test | |
| defaults: | |
| run: | |
| working-directory: contracts/splitter-v3 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust stable + llvm-tools | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: llvm-tools-preview | |
| - name: Cache cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| contracts/splitter-v3/target | |
| key: ${{ runner.os }}-cargo-cov-${{ hashFiles('contracts/splitter-v3/Cargo.lock') }} | |
| restore-keys: ${{ runner.os }}-cargo-cov- | |
| - name: Install cargo-llvm-cov | |
| uses: taiki-e/install-action@cargo-llvm-cov | |
| - name: Generate coverage report | |
| run: | | |
| cargo llvm-cov \ | |
| --all-features \ | |
| --lcov \ | |
| --output-path coverage.lcov \ | |
| -- --test-threads=1 | |
| - name: Check line coverage threshold (90%) | |
| run: | | |
| cargo llvm-cov \ | |
| --all-features \ | |
| --summary-only \ | |
| -- --test-threads=1 2>&1 | tee coverage-summary.txt | |
| # Extract "Lines" percentage and assert >= 90 | |
| LINE_COV=$(grep -oP 'Lines\s*\|\s*\K[0-9]+\.[0-9]+' coverage-summary.txt | head -1) | |
| echo "Line coverage: ${LINE_COV}%" | |
| python3 -c " | |
| cov = float('${LINE_COV}') | |
| if cov < 90.0: | |
| raise SystemExit(f'Coverage {cov:.1f}% is below the 90% threshold') | |
| print(f'Coverage check passed: {cov:.1f}%') | |
| " | |
| - name: Upload coverage report | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-lcov | |
| path: contracts/splitter-v3/coverage.lcov | |
| - name: Upload to Coveralls (optional) | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: coverallsapp/github-action@v2 | |
| with: | |
| file: contracts/splitter-v3/coverage.lcov | |
| format: lcov | |
| # ── 3. Fuzz smoke-test (short run in CI) ────────────────────────────────── | |
| fuzz: | |
| name: Fuzz Smoke Test | |
| runs-on: ubuntu-latest | |
| needs: test | |
| defaults: | |
| run: | |
| working-directory: contracts/splitter-v3 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust nightly (required by cargo-fuzz) | |
| uses: dtolnay/rust-toolchain@nightly | |
| - name: Cache cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| contracts/splitter-v3/target | |
| key: ${{ runner.os }}-cargo-fuzz-${{ hashFiles('contracts/splitter-v3/Cargo.lock') }} | |
| restore-keys: ${{ runner.os }}-cargo-fuzz- | |
| - name: Install cargo-fuzz | |
| run: cargo install cargo-fuzz --locked | |
| - name: Fuzz split_funds (30 seconds) | |
| run: | | |
| cargo fuzz run fuzz_split_funds \ | |
| -- -max_total_time=30 -max_len=100 | |
| - name: Fuzz scheduled_split (30 seconds) | |
| run: | | |
| cargo fuzz run fuzz_scheduled_split \ | |
| -- -max_total_time=30 -max_len=16 | |
| # ── 4. WASM size guard ─────────────────────────────────────────────────── | |
| wasm-size: | |
| name: WASM Size Guard (≤ 64 KB) | |
| runs-on: ubuntu-latest | |
| needs: test | |
| defaults: | |
| run: | |
| working-directory: contracts/splitter-v3 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install Rust stable + wasm32 target | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| targets: wasm32-unknown-unknown | |
| - name: Cache cargo registry | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| contracts/splitter-v3/target | |
| key: ${{ runner.os }}-cargo-wasm-${{ hashFiles('contracts/splitter-v3/Cargo.lock') }} | |
| restore-keys: ${{ runner.os }}-cargo-wasm- | |
| - name: Build release WASM | |
| run: | | |
| cargo build \ | |
| --release \ | |
| --target wasm32-unknown-unknown \ | |
| --no-default-features | |
| - name: Report WASM size | |
| run: | | |
| WASM=target/wasm32-unknown-unknown/release/stellar_splitter_v3.wasm | |
| SIZE=$(wc -c < "$WASM") | |
| LIMIT=65536 | |
| echo "WASM size: ${SIZE} / ${LIMIT} bytes" | |
| if [ "$SIZE" -gt "$LIMIT" ]; then | |
| echo "::error::WASM size ${SIZE} exceeds 64 KB limit" | |
| exit 1 | |
| fi |