From a916d4bc9926bb15c3ff18071955cd9a1705694d Mon Sep 17 00:00:00 2001 From: Collins C Augustine Date: Tue, 30 Jun 2026 09:58:40 +0100 Subject: [PATCH] implementing --- .github/workflows/mutation.yml | 57 ++++++++++++++++++++++++++++++++++ .mutants.toml | 29 +++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 .github/workflows/mutation.yml create mode 100644 .mutants.toml diff --git a/.github/workflows/mutation.yml b/.github/workflows/mutation.yml new file mode 100644 index 0000000..dc59b93 --- /dev/null +++ b/.github/workflows/mutation.yml @@ -0,0 +1,57 @@ +name: Mutation Testing + +on: + schedule: + # Weekly on Monday at 06:00 UTC + - cron: '0 6 * * 1' + workflow_dispatch: + # Allow manual trigger from GitHub UI + +jobs: + mutants: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: wasm32-unknown-unknown + + - name: Install cargo-mutants + uses: taiki-e/install-action@v2 + with: + tool: cargo-mutants + + - name: Run mutation tests + run: cargo mutants --no-fail-fast 2>&1 | tee mutation-report.txt + + - name: Extract mutation score + id: score + run: | + SCORE=$(grep -oP '\d+\.?\d*% mutation score' mutation-report.txt || echo "0%") + echo "score=$SCORE" >> "$GITHUB_OUTPUT" + echo "Mutation score: $SCORE" + + - name: Upload mutation report + uses: actions/upload-artifact@v4 + if: always() + with: + name: mutation-report + path: mutation-report.txt + + - name: Upload mutants directory + uses: actions/upload-artifact@v4 + if: always() + with: + name: mutants-dir + path: mutants/ + + - name: Check minimum mutation score + run: | + SCORE=$(grep -oP '\d+\.?\d*(?=% mutation score)' mutation-report.txt || echo "0") + if [ "$(echo "$SCORE < 80" | bc -l)" -eq 1 ]; then + echo "❌ Mutation score ${SCORE}% is below target of 80%" + exit 1 + fi + echo "✅ Mutation score ${SCORE}% meets target of 80%" diff --git a/.mutants.toml b/.mutants.toml new file mode 100644 index 0000000..de41716 --- /dev/null +++ b/.mutants.toml @@ -0,0 +1,29 @@ +# Mutation testing configuration for cargo-mutants +# +# Reference: https://github.com/sourcefrog/cargo-mutants + +# Exclude test files from mutation — mutating test code is not useful +# and would produce false positives. +exclude_files = [ + "src/test.rs", + "src/security_test.rs", +] + +# Exclude generated code directories +exclude_dirs = [ + "target", +] + +# Only mutate source files in src/ (exclude build scripts, CI config, etc.) +include_paths = ["src/"] + +# Test timeout per mutant (seconds) +# Soroban contract tests can be slow; 120s prevents hangs from infinite loops +test_timeout = 120 + +# Run tests in a single thread to avoid flaky failures from shared state +test_flags = ["--test-threads=1"] + +# Do not fail fast — continue testing remaining mutants even if some fail +# This ensures we get a complete mutation report in a single CI run +no_fail_fast = true