Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 42 additions & 10 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ on: [push, pull_request, workflow_dispatch]
jobs:
file-changes:
name: Detect File Changes
runs-on: 'ubuntu-latest'
outputs:
runs-on: ubuntu-latest
outputs:
checkall: ${{ steps.changes.outputs.checkall }}
steps:
- name: Clone
Expand All @@ -15,36 +15,68 @@ jobs:
- name: Detect Changes
uses: dorny/paths-filter@v3
id: changes
with:
with:
filters: ".github/file-filter.yml"

run:
name: Coverage Test on CodeCov
if: needs.file-changes.outputs.checkall == 'true'
needs: file-changes
runs-on: "ubuntu-latest"
runs-on: ubuntu-latest
steps:
- name: Checkouts
uses: actions/checkout@v4

- name: Setup Ubuntu
run: |
sudo apt update -y
sudo apt install -y tar wget make cmake gcc g++ python3 \
python3-dev "openmpi-*" libopenmpi-dev hdf5-tools \
libfftw3-dev libhdf5-dev libblas-dev liblapack-dev
sudo apt update -y
sudo apt install -y tar wget make cmake gcc g++ python3 python3-pip \
"openmpi-*" libopenmpi-dev hdf5-tools libfftw3-dev libhdf5-dev \
libblas-dev liblapack-dev
python3 -m pip install --upgrade pip gcovr

- name: Build
- name: Build (with coverage)
run: /bin/bash mfc.sh build -j $(nproc) --gcov

- name: Test
run: /bin/bash mfc.sh test -a -j $(nproc)

- name: Upload coverage reports to Codecov
- name: Generate coverage (gcovr XML)
run: |
gcovr \
--root "${{ github.workspace }}" \
--object-directory "${{ github.workspace }}/build" \
--exclude '.*(tests|examples|toolchain|docs|benchmarks)/.*' \
--gcov-ignore-parse-errors \
--xml-pretty -o coverage.xml

- name: Rewrite paths from generated .fpp.f90 -> repo .fpp
run: |
python3 - <<'PY'
import os, xml.etree.ElementTree as ET
fn = "coverage.xml"
t = ET.parse(fn)
r = t.getroot()
for c in r.iter('class'):
p = c.get('filename') or ''
if p.endswith('.fpp.f90'):
base = os.path.basename(p).rsplit('.fpp.f90', 1)[0] + '.fpp'
for sub in ('pre_process','simulation','post_process','common'):
cand = os.path.join('src', sub, base)
if os.path.exists(cand):
c.set('filename', cand)
break
t.write(fn, encoding='utf-8', xml_declaration=True)
PY

- name: Upload coverage to Codecov (XML only)
uses: codecov/codecov-action@v4
with:
files: coverage.xml
fail_ci_if_error: false
verbose: true
disable_search: true
disable_file_fixes: true
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

110 changes: 110 additions & 0 deletions scripts/generate_coverage.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#!/bin/bash

# MFC Coverage Generation Script
# This script generates coverage reports locally using gcovr with the same
# configuration as the CI workflow.

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MFC_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"

echo "MFC Coverage Generation"
echo "======================"
echo "Root directory: $MFC_ROOT"
echo

# Check if gcovr is available
if ! command -v gcovr &> /dev/null; then
echo "Error: gcovr is not installed. Install it with:"
echo " pip install gcovr"
exit 1
fi

cd "$MFC_ROOT"

# Check if MFC was built with coverage
if [ ! -d "build" ]; then
echo "Error: No build directory found. Build MFC with coverage first:"
echo " ./mfc.sh build --gcov -j \$(nproc)"
exit 1
fi

# Look for gcov files
GCOV_FILES=$(find build -name "*.gcda" 2>/dev/null | wc -l)
if [ "$GCOV_FILES" -eq 0 ]; then
echo "Warning: No coverage data found. Run tests first:"
echo " ./mfc.sh test -j \$(nproc) -f EA8FA07E -t 9E2CA336"
echo
fi

echo "Generating coverage reports..."

# Generate XML coverage report (same as CI)
gcovr \
--root "$MFC_ROOT" \
--object-directory "$MFC_ROOT/build" \
--filter '.*/fypp/.+\.f90$' \
--exclude '.*(tests|examples|toolchain|docs|benchmarks)/.*' \
--gcov-ignore-parse-errors \
--xml-pretty -o coverage.xml

echo "Generated coverage.xml"

# Also generate a broader report for debugging
gcovr \
--root "$MFC_ROOT" \
--object-directory "$MFC_ROOT/build" \
--exclude '.*(tests|examples|toolchain|docs|benchmarks)/.*' \
--gcov-ignore-parse-errors \
--xml-pretty -o coverage_all.xml

echo "Generated coverage_all.xml (broader scope for debugging)"

# Generate HTML coverage report for local viewing
gcovr \
--root "$MFC_ROOT" \
--object-directory "$MFC_ROOT/build" \
--filter '.*/fypp/.+\.f90$' \
--exclude '.*(tests|examples|toolchain|docs|benchmarks)/.*' \
--gcov-ignore-parse-errors \
--html-details -o coverage.html

echo "Generated coverage.html"

# Rewrite paths from generated .fpp.f90 -> repo .fpp (same as CI)
python3 - <<'PY'
import os, xml.etree.ElementTree as ET

print("Rewriting XML paths from generated .fpp.f90 to source .fpp files...")

fn = "coverage.xml"
if not os.path.exists(fn):
print(f"Error: {fn} not found")
exit(1)

t = ET.parse(fn)
r = t.getroot()
remapped = 0

for c in r.iter('class'):
p = c.get('filename') or ''
if p.endswith('.fpp.f90'):
base = os.path.basename(p).rsplit('.fpp.f90', 1)[0] + '.fpp'
for sub in ('pre_process','simulation','post_process','common'):
cand = os.path.join('src', sub, base)
if os.path.exists(cand):
c.set('filename', cand)
remapped += 1
break

t.write(fn, encoding='utf-8', xml_declaration=True)
print(f"Remapped {remapped} file paths in coverage.xml")
PY

echo
echo "Coverage reports generated:"
echo " - coverage.xml (for Codecov upload)"
echo " - coverage.html (for local viewing)"
echo
echo "To view the HTML report, open coverage.html in your browser."
2 changes: 1 addition & 1 deletion src/simulation/m_acoustic_src.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module m_acoustic_src

use m_helper_basic !< Functions to compare floating point numbers

use m_constants !< Definitions of the constants
use m_constants !< Definitions of constants

implicit none
private; public :: s_initialize_acoustic_src, s_precalculate_acoustic_spatial_sources, s_acoustic_src_calculations
Expand Down
Loading