Skip to content

Commit 1032dbc

Browse files
sbryngelsonclaude
andcommitted
Fix review findings: dir failure re-raise, FYPP_GCOV_OPTS init, dep_changed safety, SYSCHECK cleanup
- Re-raise OSError in _prepare_test after directory creation failure instead of silently continuing with a broken test directory - Initialize FYPP_GCOV_OPTS to empty before the MFC_GCov block so non-gcov builds don't pass an undefined variable to Fypp - Push dep_changed now defaults to true on git diff failure, matching the safe PR-path behavior - Remove dead SYSCHECK references from test stubs and fix exec fallback replace string to match actual coverage.py imports - Improve docstrings, comments, and cleanup error handling Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 6d6f57e commit 1032dbc

File tree

5 files changed

+22
-9
lines changed

5 files changed

+22
-9
lines changed

.github/workflows/test.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,11 @@ jobs:
8888
exit 0
8989
}
9090
elif [ "${{ github.event_name }}" = "push" ]; then
91-
DIFF=$(git diff "$BEFORE".."$AFTER" 2>/dev/null || echo "")
91+
DIFF=$(git diff "$BEFORE".."$AFTER" 2>/dev/null) || {
92+
echo "git diff failed for push event — defaulting to dep_changed=true for safety."
93+
echo "dep_changed=true" >> "$GITHUB_OUTPUT"
94+
exit 0
95+
}
9296
else
9397
DIFF=""
9498
fi

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ endif()
113113
# debug builds. These include optimization and debug flags, as well as some that
114114
# are required for a successful build of MFC.
115115

116+
set(FYPP_GCOV_OPTS "")
117+
116118
if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
117119
add_compile_options(
118120
$<$<COMPILE_LANGUAGE:Fortran>:-ffree-line-length-none>

toolchain/mfc/cli/commands.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@
460460
),
461461
Argument(
462462
name="build-coverage-cache",
463-
help="Run all tests with gcov instrumentation to build the file-level coverage cache. Requires a prior --gcov build: ./mfc.sh build --gcov -j 8",
463+
help="Run all tests with gcov instrumentation to build the file-level coverage cache. Pass --gcov to enable coverage instrumentation in the internal build step.",
464464
action=ArgAction.STORE_TRUE,
465465
default=False,
466466
dest="build_coverage_cache",

toolchain/mfc/test/coverage.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88
covered file set. Only tests that touch at least one changed file run.
99
1010
Workflow:
11-
./mfc.sh build --gcov -j 8 # one-time: build with coverage
12-
./mfc.sh test --build-coverage-cache # one-time: populate the cache
13-
./mfc.sh test --only-changes -j 8 # fast: run only affected tests
11+
./mfc.sh test --build-coverage-cache --gcov -j 8 # one-time: populate the cache
12+
./mfc.sh test --only-changes -j 8 # fast: run only affected tests
1413
"""
1514

1615
import io
@@ -234,6 +233,9 @@ def _collect_single_test_coverage( # pylint: disable=too-many-locals
234233
"""
235234
build_subdir = os.path.join(test_gcda, "build")
236235
if not os.path.isdir(build_subdir):
236+
# No .gcda files produced — test may not have run or GCOV_PREFIX
237+
# was misconfigured. Return empty list; the sanity check at the end
238+
# of build_coverage_cache will catch systemic failures.
237239
return uuid, []
238240

239241
gcno_copies = []
@@ -374,6 +376,7 @@ def _prepare_test(case, root_dir: str) -> dict: # pylint: disable=unused-argume
374376
except OSError as exc:
375377
cons.print(f"[yellow]Warning: Failed to prepare test directory for "
376378
f"{case.get_uuid()}: {exc}[/yellow]")
379+
raise
377380

378381
# Lagrange bubble tests need input files generated before running.
379382
if case.params.get("bubbles_lagrange", 'F') == 'T':
@@ -466,6 +469,8 @@ def build_coverage_cache( # pylint: disable=too-many-locals,too-many-statements
466469
strip = _compute_gcov_prefix_strip(root_dir)
467470

468471
if n_jobs is None:
472+
# Caller should pass n_jobs explicitly on SLURM systems;
473+
# os.cpu_count() may exceed the SLURM allocation.
469474
n_jobs = max(os.cpu_count() or 1, 1)
470475
# Cap Phase 2 test parallelism: each test spawns gcov-instrumented MPI
471476
# processes (~2-5 GB each under gcov). Too many concurrent tests cause OOM.
@@ -568,7 +573,11 @@ def build_coverage_cache( # pylint: disable=too-many-locals,too-many-statements
568573
if completed % 50 == 0 or completed == len(test_results):
569574
cons.print(f" [{completed:3d}/{len(test_results):3d}] tests processed")
570575
finally:
571-
shutil.rmtree(gcda_dir, ignore_errors=True)
576+
try:
577+
shutil.rmtree(gcda_dir)
578+
except OSError as exc:
579+
cons.print(f"[yellow]Warning: Failed to clean up temp directory "
580+
f"{gcda_dir}: {exc}[/yellow]")
572581

573582
# Sanity check: at least some tests should have non-empty coverage.
574583
tests_with_coverage = sum(1 for v in cache.values() if v)

toolchain/mfc/test/test_coverage_unit.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ class _FakeMFCException(Exception):
6868
_build_stub.PRE_PROCESS = "pre_process"
6969
_build_stub.SIMULATION = "simulation"
7070
_build_stub.POST_PROCESS = "post_process"
71-
_build_stub.SYSCHECK = "syscheck"
7271

7372
_case_stub = sys.modules.get("toolchain.mfc.test.case", _make_stub("toolchain.mfc.test.case"))
7473
_case_stub.input_bubbles_lagrange = lambda case: None
@@ -123,7 +122,6 @@ class _FakeMFCException(Exception):
123122
"PRE_PROCESS": "pre_process",
124123
"SIMULATION": "simulation",
125124
"POST_PROCESS": "post_process",
126-
"SYSCHECK": "syscheck",
127125
}
128126
with open(_COVERAGE_PATH, encoding="utf-8") as _f:
129127
_src = _f.read()
@@ -133,7 +131,7 @@ class _FakeMFCException(Exception):
133131
.replace("from ..printer import cons", "cons = _globals['cons']")
134132
.replace("from .. import common", "")
135133
.replace("from ..common import MFCException", "MFCException = _globals['MFCException']")
136-
.replace("from ..build import PRE_PROCESS, SIMULATION, POST_PROCESS, SYSCHECK", "")
134+
.replace("from ..build import PRE_PROCESS, SIMULATION, POST_PROCESS", "")
137135
.replace("from .case import (input_bubbles_lagrange, get_post_process_mods,\n"
138136
" POST_PROCESS_3D_PARAMS)",
139137
"input_bubbles_lagrange = lambda case: None\n"

0 commit comments

Comments
 (0)