Skip to content

Commit d6d0f1a

Browse files
authored
Merge pull request #321 from nipreps/codex/debug-flaky-test-on-github-actions
MNT: Address flaky test by adding checksum guard and relative baseline test oracle.
2 parents 70e27cf + bf35646 commit d6d0f1a

File tree

1 file changed

+47
-5
lines changed

1 file changed

+47
-5
lines changed

test/test_integration.py

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#
2323
"""Integration tests."""
2424

25+
import hashlib
2526
from os import cpu_count
2627

2728
import nibabel as nb
@@ -33,11 +34,38 @@
3334
from nifreeze.model.base import TrivialModel
3435
from nifreeze.registration.utils import displacements_within_mask
3536

37+
EXPECTED_DWI_MOTION_SHA256 = "3ba55cc3acfd584a7738f9701724e284f54bdf72261bf535b5dae062d7c0c30e"
3638

37-
def test_proximity_estimator_trivial_model(datadir, tmp_path, atol_mm=0.15):
38-
"""Check the proximity of transforms estimated by the estimator with a trivial B0 model."""
3939

40-
dwi_motion = DWI.from_filename(datadir / "dmri_data" / "motion_test_data" / "dwi_motion.h5")
40+
def _sha256sum(path):
41+
hasher = hashlib.sha256()
42+
with path.open("rb") as fileobj:
43+
for chunk in iter(lambda: fileobj.read(1024 * 1024), b""):
44+
hasher.update(chunk)
45+
return hasher.hexdigest()
46+
47+
48+
def test_proximity_estimator_trivial_model(datadir, tmp_path, p_error=20.0):
49+
"""
50+
Check the proximity of transforms estimated by the estimator with a trivial B0 model.
51+
52+
Parameters
53+
----------
54+
datadir : pathlib.Path
55+
Path to the test data directory.
56+
tmp_path : pathlib.Path
57+
Path to a temporary directory for test outputs.
58+
p_error : float, optional
59+
Acceptable percentage error in the estimated transforms, by default 20.0.
60+
61+
"""
62+
63+
dwi_motion_path = datadir / "dmri_data" / "motion_test_data" / "dwi_motion.h5"
64+
assert _sha256sum(dwi_motion_path) == EXPECTED_DWI_MOTION_SHA256, (
65+
"Unexpected checksum for dwi_motion.h5"
66+
)
67+
68+
dwi_motion = DWI.from_filename(dwi_motion_path)
4169
dwi_motion._filepath = tmp_path / "dwi_motion.h5" # Prevent accidental overwriting
4270

4371
ground_truth_affines = (
@@ -81,9 +109,23 @@ def test_proximity_estimator_trivial_model(datadir, tmp_path, atol_mm=0.15):
81109
]
82110
)
83111

112+
gt_inverse_errors = np.array(
113+
[
114+
displacements_within_mask(
115+
masknii, # type: ignore
116+
~nt.linear.Affine(truth),
117+
nt.linear.Affine(np.eye(4)),
118+
).max()
119+
for truth in ground_truth_affines # type: ignore
120+
]
121+
)
122+
123+
error_levels = gt_inverse_errors * p_error * 0.01
84124
masksize = (np.asanyarray(masknii.dataobj) > 0).astype(int).sum()
85-
assert np.all(max_error_mask < atol_mm), (
86-
f"Some max error exceeds {atol_mm}mm, N={masksize}vox."
125+
assert np.all(max_error_mask < error_levels), (
126+
"Errors per volume [estimated(ground truth) mm]: "
127+
+ ", ".join(f"{e:.2f}({g:.2f})" for e, g in zip(max_error_mask, gt_inverse_errors))
128+
+ f" (N={masksize} voxels)."
87129
)
88130

89131

0 commit comments

Comments
 (0)