Regression Tests #1
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: Regression Tests | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| regression_test_cores: | |
| description: 'Number of cores to run regression tests with' | |
| required: false | |
| default: '4' | |
| regression_test_options: | |
| description: 'Additional regression_test.py command-line options' | |
| required: false | |
| default: '--all-outputs --scons --use-dlls' | |
| copy_binaries: | |
| description: 'Copy built Eradication, reporter_plugins, schema' | |
| required: false | |
| type: boolean | |
| default: false | |
| use_existing_build: | |
| description: 'Skip build and download most recently built artifact' | |
| required: false | |
| type: boolean | |
| default: false | |
| run_generic: | |
| description: 'Run Generic suite' | |
| required: false | |
| type: boolean | |
| default: true | |
| run_hiv: | |
| description: 'Run HIV suite' | |
| required: false | |
| type: boolean | |
| default: true | |
| run_malaria: | |
| description: 'Run Malaria suite' | |
| required: false | |
| type: boolean | |
| default: true | |
| run_sti: | |
| description: 'Run STI suite' | |
| required: false | |
| type: boolean | |
| default: true | |
| run_vector: | |
| description: 'Run Vector suite' | |
| required: false | |
| type: boolean | |
| default: true | |
| jobs: | |
| build: | |
| name: Build | |
| if: ${{ !inputs.use_existing_build }} | |
| uses: ./.github/workflows/build_reusable.yml | |
| with: | |
| disease_type: 'All' | |
| build_jobs: '4' | |
| setup: | |
| name: Configure Matrix | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.set-matrix.outputs.matrix }} | |
| steps: | |
| - name: Build suite matrix | |
| id: set-matrix | |
| run: | | |
| includes='[]' | |
| if [ "${{ inputs.run_generic }}" = "true" ]; then | |
| includes=$(echo "$includes" | jq '. += [{"name":"Generic","suite":"generic"}]') | |
| fi | |
| if [ "${{ inputs.run_hiv }}" = "true" ]; then | |
| includes=$(echo "$includes" | jq '. += [{"name":"HIV","suite":"hiv"}]') | |
| fi | |
| if [ "${{ inputs.run_malaria }}" = "true" ]; then | |
| includes=$(echo "$includes" | jq '. += [{"name":"Malaria","suite":"malaria"}]') | |
| fi | |
| if [ "${{ inputs.run_sti }}" = "true" ]; then | |
| includes=$(echo "$includes" | jq '. += [{"name":"STI","suite":"sti"}]') | |
| fi | |
| if [ "${{ inputs.run_vector }}" = "true" ]; then | |
| includes=$(echo "$includes" | jq '. += [{"name":"Vector","suite":"vector"}]') | |
| fi | |
| echo "matrix=$(echo "$includes" | jq -c '{include: .}')" >> $GITHUB_OUTPUT | |
| test: | |
| name: Test - ${{ matrix.name }} | |
| needs: [build, setup] | |
| if: ${{ always() && (needs.build.result == 'success' || needs.build.result == 'skipped') && needs.setup.result == 'success' }} | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJson(needs.setup.outputs.matrix) }} | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Find Latest Build Artifact | |
| if: ${{ inputs.use_existing_build }} | |
| id: find-artifact | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const artifactName = 'emod-all-build'; | |
| const artifacts = await github.rest.actions.listArtifactsForRepo({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| name: artifactName, | |
| per_page: 10 | |
| }); | |
| const valid = artifacts.data.artifacts.filter(a => !a.expired); | |
| if (valid.length === 0) { | |
| core.setFailed(`No valid artifact '${artifactName}' found`); | |
| return; | |
| } | |
| valid.sort((a, b) => new Date(b.created_at) - new Date(a.created_at)); | |
| const latest = valid[0]; | |
| core.setOutput('run-id', latest.workflow_run.id.toString()); | |
| core.setOutput('name', artifactName); | |
| console.log(`Found '${artifactName}' from run ${latest.workflow_run.id} (${latest.created_at})`); | |
| - name: Download Build Artifacts | |
| if: ${{ !inputs.use_existing_build }} | |
| uses: actions/download-artifact@v5 | |
| with: | |
| name: ${{ needs.build.outputs.artifact_name }} | |
| path: . | |
| - name: Download Existing Build Artifacts | |
| if: ${{ inputs.use_existing_build }} | |
| uses: actions/download-artifact@v5 | |
| with: | |
| name: ${{ steps.find-artifact.outputs.name }} | |
| run-id: ${{ steps.find-artifact.outputs.run-id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| path: . | |
| - name: Restore executable permissions | |
| run: | | |
| echo "Checking downloaded artifact structure..." | |
| ls -la build/x64/Release/Eradication/ | |
| chmod +x build/x64/Release/Eradication/Eradication | |
| echo "✓ Permissions restored" | |
| - name: Run Regression Tests | |
| id: regression_tests | |
| continue-on-error: true | |
| run: | | |
| docker run --rm \ | |
| -v "${{ github.workspace }}:/EMOD" \ | |
| docker-production.packages.idmod.org/idm/dtk-centos-sfts:3.0 \ | |
| bash -c "\ | |
| cd /EMOD && \ | |
| mkdir -p /EMOD/regression_test_output && \ | |
| echo 'Running ${{ matrix.name }} regression tests' && \ | |
| cd Regression && \ | |
| python3 regression_test.py \ | |
| ${{ matrix.suite }} \ | |
| ../build/x64/Release/Eradication/Eradication \ | |
| --hidegraphs --config-constraints Num_Cores:${{ inputs.regression_test_cores }} \ | |
| ${{ inputs.regression_test_options }} \ | |
| --local \ | |
| --linux\ | |
| " | |
| - name: Check Test Results | |
| if: always() | |
| run: | | |
| echo "=== Looking for regression test reports ===" | |
| # Find the XML report file(s) | |
| REPORT_FILE=$(find Regression/reports -name "report_*.xml" 2>/dev/null | head -1) | |
| if [ -n "$REPORT_FILE" ] && [ -f "$REPORT_FILE" ]; then | |
| # Parse XML for failures and errors | |
| FAILURES=$(grep -oP 'failures="\K[0-9]+' "$REPORT_FILE" || echo "0") | |
| ERRORS=$(grep -oP 'errors="\K[0-9]+' "$REPORT_FILE" || echo "0") | |
| TESTS=$(grep -oP 'tests="\K[0-9]+' "$REPORT_FILE" || echo "0") | |
| echo "Test Summary (${{ matrix.name }}):" | |
| echo " Total tests: $TESTS" | |
| echo " Failures: $FAILURES" | |
| echo " Errors: $ERRORS" | |
| echo "" | |
| # Fail if there are any failures or errors | |
| if [ "$FAILURES" != "0" ] || [ "$ERRORS" != "0" ]; then | |
| echo "❌ ${{ matrix.name }} REGRESSION TESTS FAILED" | |
| echo " $FAILURES test(s) failed, $ERRORS error(s)" | |
| echo " Check the test results artifact for details" | |
| exit 1 | |
| else | |
| echo "✅ All $TESTS ${{ matrix.name }} regression tests passed!" | |
| fi | |
| else | |
| echo "⚠️ No regression report found at Regression/reports/report_*.xml" | |
| echo "Test step outcome: ${{ steps.regression_tests.outcome }}" | |
| if [ "${{ steps.regression_tests.outcome }}" != "success" ]; then | |
| echo "❌ ${{ matrix.name }} regression tests failed to complete" | |
| exit 1 | |
| else | |
| echo "⚠️ Tests completed but no report was generated" | |
| echo "This may indicate the test suite was empty or had configuration issues" | |
| fi | |
| fi | |
| - name: Copy Binaries to artifacts directory | |
| if: ${{ github.event.inputs.copy_binaries == 'true' }} | |
| run: | | |
| mkdir -p artifacts | |
| cp build/x64/Release/Eradication/Eradication artifacts/ | |
| cp build/x64/Release/schema.json artifacts/ 2>/dev/null || cp schema.json artifacts/ | |
| cp build/x64/Release/version artifacts/ 2>/dev/null || cp version artifacts/ | |
| if [ -d "build/x64/Release/reporter_plugins" ]; then | |
| cp -r build/x64/Release/reporter_plugins artifacts/ | |
| fi | |
| - name: Upload Build Artifacts | |
| if: ${{ github.event.inputs.copy_binaries == 'true' }} | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: emod-${{ matrix.name }}-binaries | |
| path: artifacts/ | |
| retention-days: 7 | |
| - name: Upload Test Results | |
| if: always() | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: emod-${{ matrix.name }}-regression-test-results | |
| path: | | |
| regression_test_output/ | |
| Regression/reports/ | |
| retention-days: 7 | |
| if-no-files-found: ignore |