Skip to content

Advanced Testing Suite #193

Advanced Testing Suite

Advanced Testing Suite #193

name: Advanced Testing Suite
on:
push:
branches: [ main, 0.4.1 ]
pull_request:
branches: [ main, 0.4.1 ]
schedule:
# Run tests daily at 6:00 AM UTC
- cron: '0 6 * * *'
workflow_dispatch:
permissions:
contents: read
pull-requests: write
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
test-suite:
name: Full Test Suite
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
rust: [stable, beta]
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.rust }}
override: true
components: rustfmt, clippy, rust-src
- name: Cache cargo registry
uses: actions/cache@v3
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo index
uses: actions/cache@v3
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo build
uses: actions/cache@v3
with:
path: target
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
- name: Install testing tools
run: |
cargo install cargo-tarpaulin --version 0.27.1 || cargo install cargo-tarpaulin || true
cargo install cargo-nextest || true
cargo install cargo-fuzz || true
- name: Run formatting check
run: cargo fmt -- --check
- name: Run clippy
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Run unit tests
run: cargo test --lib --verbose
- name: Run integration tests
run: cargo test --test '*' --verbose || true
continue-on-error: true
- name: Run property-based tests
run: |
if [ -f "Cargo.toml" ] && grep -q "proptest" Cargo.toml; then
cargo test --features proptest --verbose
else
echo "No proptest dependency found, skipping property-based tests"
fi
- name: Generate code coverage
run: |
cargo tarpaulin --out Xml --out Html --output-dir target/tarpaulin \
--line-coverage --branch-coverage --timeout 300 \
--exclude-files "tests/**,examples/**,benches/**" \
--fail-under 70 || true
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./target/tarpaulin/cobertura.xml
flags: unittests
name: codecov-${{ matrix.rust }}
fail_ci_if_error: false
- name: Upload coverage artifacts
uses: actions/upload-artifact@v4
with:
name: coverage-report-${{ matrix.rust }}
path: target/tarpaulin/index.html
retention-days: 30
- name: Run benchmarks
run: |
if [ -d "benches" ]; then
cargo bench --no-run
else
echo "No benchmarks found, skipping"
fi
- name: Security audit
run: |
cargo install cargo-audit || true
if command -v cargo-audit &>/dev/null; then
cargo audit || true
fi
continue-on-error: true
fuzz-testing:
name: Fuzz Testing
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Install fuzzing tools
run: cargo install cargo-fuzz
- name: Run fuzz tests
run: |
if [ -d "fuzz" ]; then
cargo fuzz build || true
cargo fuzz list || echo "No fuzz targets found"
# Run fuzz for a short time (5 minutes)
timeout 300 cargo fuzz run -- -max_total_time=300 || true
else
echo "No fuzz directory found, skipping fuzz tests"
fi
- name: Upload fuzz artifacts
if: failure()
uses: actions/upload-artifact@v4
with:
name: fuzz-artifacts
path: fuzz/artifacts
retention-days: 7
code-quality:
name: Code Quality Checks
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- name: Run cargo deny
run: |
cargo install cargo-deny
cargo deny check || true
- name: Check documentation
run: |
cargo doc --no-deps --all-features
cargo doc --no-deps --all-features --document-private-items || true
- name: Check for TODO comments
run: |
grep -r "TODO\|FIXME\|XXX" --include="*.rs" . | wc -l
- name: Check code complexity
run: |
cargo install cargo-complexity 2>/dev/null || echo "cargo-complexity not available in registry, skipping"
if command -v cargo-complexity &>/dev/null; then
cargo complexity --threshold 20 || true
fi
continue-on-error: true
performance-regression:
name: Performance Regression Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Cache cargo build
uses: actions/cache@v3
with:
path: target
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
- name: Run benchmarks
run: |
if [ -d "benches" ]; then
cargo bench || true
else
echo "No benchmarks found, skipping"
fi
continue-on-error: true
- name: Store benchmark results
uses: benchmark-action/github-action-benchmark@v1
with:
tool: 'cargo'
output-file-path: target/criterion/report/index.html
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: false
alert-threshold: '110%'
comment-on-alert: true
fail-on-alert: false
continue-on-error: true
test-summary:
name: Test Summary
runs-on: ubuntu-latest
needs: [test-suite, fuzz-testing, code-quality, performance-regression]
if: always()
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
continue-on-error: true
- name: Generate summary
run: |
echo "# Test Suite Summary" > summary.md
echo "" >> summary.md
echo "## Job Results" >> summary.md
echo "- Test Suite: ${{ needs.test-suite.result }}" >> summary.md
echo "- Fuzz Testing: ${{ needs.fuzz-testing.result }}" >> summary.md
echo "- Code Quality: ${{ needs.code-quality.result }}" >> summary.md
echo "- Performance Regression: ${{ needs.performance-regression.result }}" >> summary.md
- name: Comment PR with summary
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
continue-on-error: true
with:
script: |
const fs = require('fs');
const summary = fs.readFileSync('summary.md', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: summary
});