name: Comprehensive Testing Suite
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
schedule:
- cron: '0 2 * * *'
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
unit-tests:
name: Unit Tests
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
rust: [stable, beta, 1.70.0] exclude:
- os: windows-latest
rust: beta
- os: macos-latest
rust: beta
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
profile: minimal
override: true
components: rustfmt, clippy
- name: Cache cargo registry
uses: actions/cache@v3
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-${{ matrix.rust }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.rust }}-cargo-registry-
- name: Cache cargo index
uses: actions/cache@v3
with:
path: ~/.cargo/git
key: ${{ runner.os }}-${{ matrix.rust }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.rust }}-cargo-index-
- name: Cache target directory
uses: actions/cache@v3
with:
path: target
key: ${{ runner.os }}-${{ matrix.rust }}-target-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.rust }}-target-
- name: Check formatting
run: cargo fmt -- --check
- name: Run clippy
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Build
run: cargo build --verbose --all-features
- name: Run unit tests
run: cargo test --lib --bins --all-features --verbose
- name: Run doc tests
run: cargo test --doc --all-features
integration-tests:
name: Integration Tests
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true
- name: Cache dependencies
uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-integration-${{ hashFiles('**/Cargo.lock') }}
- name: Install system dependencies (Ubuntu)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y libnuma-dev
- name: Install system dependencies (macOS)
if: matrix.os == 'macos-latest'
run: |
# Install any macOS-specific dependencies
echo "macOS dependencies installed"
- name: Install system dependencies (Windows)
if: matrix.os == 'windows-latest'
run: |
# Install any Windows-specific dependencies
echo "Windows dependencies installed"
- name: Build with all features
run: cargo build --release --all-features
- name: Run integration tests
run: cargo test --test '*' --release --all-features
- name: Run cross-platform tests
run: cargo test cross_platform_tests --release --all-features
- name: Run memory safety tests
run: cargo test memory_safety_tests --release --all-features
- name: Run runtime tests
run: cargo test runtime_tests --release --all-features
property-tests:
name: Property-based Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true
- name: Cache dependencies
uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-property-${{ hashFiles('**/Cargo.lock') }}
- name: Run property tests (extended)
env:
PROPTEST_CASES: 10000
PROPTEST_MAX_SHRINK_ITERS: 1000
run: cargo test property_tests --release -- --test-threads=1
browser-tests:
name: Browser Compatibility
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true
target: wasm32-unknown-unknown
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Cache dependencies
uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-wasm-${{ hashFiles('**/Cargo.lock') }}
- name: Build for WASM
run: wasm-pack build --target web --dev
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install browser test dependencies
run: |
npm install -g wasm-bindgen-test-runner
# Install Chrome for testing
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee /etc/apt/sources.list.d/google-chrome.list
sudo apt-get update
sudo apt-get install -y google-chrome-stable
- name: Run browser tests
env:
CHROMEDRIVER: /usr/bin/google-chrome
run: wasm-pack test --chrome --headless
- name: Test WASM module size
run: |
wasm-pack build --target web --release
WASM_SIZE=$(stat -c%s pkg/cuda_rust_wasm_bg.wasm)
echo "WASM module size: $WASM_SIZE bytes"
# Fail if module is too large (>10MB)
if [ $WASM_SIZE -gt 10485760 ]; then
echo "WASM module too large: $WASM_SIZE bytes"
exit 1
fi
benchmarks:
name: Performance Benchmarks
runs-on: ubuntu-latest
if: github.event_name == 'schedule' || contains(github.event.head_commit.message, '[benchmark]')
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true
- name: Cache dependencies
uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-bench-${{ hashFiles('**/Cargo.lock') }}
- name: Install criterion dependencies
run: |
sudo apt-get update
sudo apt-get install -y gnuplot
- name: Download previous benchmark results
uses: actions/cache@v3
with:
path: target/performance_baselines.json
key: performance-baselines-${{ github.ref }}
restore-keys: |
performance-baselines-refs/heads/main
performance-baselines-
- name: Run benchmarks
run: |
cargo bench --bench memory_benchmarks
cargo bench --bench kernel_benchmarks
cargo bench --bench transpiler_benchmarks
cargo bench --bench wasm_vs_native_benchmarks
cargo bench --bench regression_benchmarks
- name: Upload benchmark results
uses: actions/upload-artifact@v3
with:
name: benchmark-results
path: |
target/criterion/
target/performance_baselines.json
- name: Check for performance regressions
run: |
if [ -f target/performance_baselines.json ]; then
echo "Checking for performance regressions..."
# This would be handled by the regression benchmark itself
fi
coverage:
name: Code Coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true
components: llvm-tools-preview
- name: Install grcov
run: |
curl -L https://github.com/mozilla/grcov/releases/latest/download/grcov-x86_64-unknown-linux-gnu.tar.bz2 | tar jxf -
chmod +x grcov
sudo mv grcov /usr/local/bin/
- name: Cache dependencies
uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-coverage-${{ hashFiles('**/Cargo.lock') }}
- name: Run tests with coverage
env:
RUSTFLAGS: -Cinstrument-coverage
LLVM_PROFILE_FILE: coverage-%p-%m.profraw
run: |
cargo test --all-features
- name: Generate coverage report
run: |
grcov . \
--binary-path ./target/debug/ \
-s . \
-t lcov \
--branch \
--ignore-not-existing \
--ignore "/*" \
--ignore "tests/*" \
--ignore "benches/*" \
--ignore "examples/*" \
-o coverage.lcov
- name: Upload to codecov.io
uses: codecov/codecov-action@v3
with:
file: coverage.lcov
flags: unittests
name: cuda-rust-wasm
fail_ci_if_error: false
- name: Check coverage threshold
run: |
COVERAGE=$(grcov . --binary-path ./target/debug/ -s . -t json --branch --ignore-not-existing --ignore "/*" --ignore "tests/*" --ignore "benches/*" --ignore "examples/*" | jq '.message' | grep -o '[0-9]\+\.[0-9]\+' | head -1)
echo "Coverage: $COVERAGE%"
if (( $(echo "$COVERAGE < 80.0" | bc -l) )); then
echo "Coverage below 80% threshold: $COVERAGE%"
exit 1
fi
security:
name: Security Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true
- name: Install cargo-audit
run: cargo install cargo-audit
- name: Run security audit
run: cargo audit
- name: Install cargo-deny
run: cargo install cargo-deny
- name: Check licenses and dependencies
run: cargo deny check
sanitizers:
name: Memory Sanitizers
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust nightly
uses: actions-rs/toolchain@v1
with:
toolchain: nightly
profile: minimal
override: true
components: rust-src
- name: Cache dependencies
uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-sanitizer-${{ hashFiles('**/Cargo.lock') }}
- name: Run with AddressSanitizer
env:
RUSTFLAGS: -Zsanitizer=address
run: |
cargo +nightly test --target x86_64-unknown-linux-gnu --lib --bins
- name: Run with LeakSanitizer
env:
RUSTFLAGS: -Zsanitizer=leak
run: |
cargo +nightly test --target x86_64-unknown-linux-gnu memory_safety_tests
docs:
name: Documentation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true
- name: Check documentation
env:
RUSTDOCFLAGS: -D warnings
run: cargo doc --all-features --no-deps
- name: Deploy documentation (main branch only)
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
run: |
cargo doc --all-features --no-deps
echo '<meta http-equiv="refresh" content="0; url=cuda_rust_wasm">' > target/doc/index.html
- name: Upload documentation
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./target/doc
ci-success:
name: CI Success
runs-on: ubuntu-latest
needs: [unit-tests, integration-tests, property-tests, browser-tests, coverage, security, docs]
if: always()
steps:
- name: Check all jobs
run: |
if [[ "${{ needs.unit-tests.result }}" != "success" ]]; then
echo "Unit tests failed"
exit 1
fi
if [[ "${{ needs.integration-tests.result }}" != "success" ]]; then
echo "Integration tests failed"
exit 1
fi
if [[ "${{ needs.property-tests.result }}" != "success" ]]; then
echo "Property tests failed"
exit 1
fi
if [[ "${{ needs.browser-tests.result }}" != "success" ]]; then
echo "Browser tests failed"
exit 1
fi
if [[ "${{ needs.coverage.result }}" != "success" ]]; then
echo "Coverage check failed"
exit 1
fi
if [[ "${{ needs.security.result }}" != "success" ]]; then
echo "Security audit failed"
exit 1
fi
if [[ "${{ needs.docs.result }}" != "success" ]]; then
echo "Documentation check failed"
exit 1
fi
echo "All checks passed!"
- name: Report success
run: echo "🎉 All tests passed! Ready for deployment."