test: fiabilise et raccourcit la suite pytest (fix crash eccodes)#22
Merged
Conversation
La CI "Run Pytest" échouait pour deux raisons indépendantes :
1. Durée (>40 min) — le job téléchargeait de vraies données GRIB pour
11 modèles MF × 2 jeux de définitions × TOUS leurs paquets (4 à 11) ×
2 échéances, plus les 2 modèles ECMWF. Les runs finissaient annulés
("runner received a shutdown signal"), remontés comme échec.
2. Assertion fragile `ds.mean() < 1` par champ — en mode test chaque champ
vaut son masque isnull(), donc mean() = fraction de valeurs manquantes.
Certains champs ECMWF sont légitimement masqués à ~100 % sur les 2 échéances
échantillonnées (humidité du sol, variables océaniques) : selon le run, un
champ peut être entièrement NaN → l'assertion échoue de façon non
déterministe (d'où les échecs intermittents de test_aifs/test_ifs).
Changements :
- un seul paquet représentatif testé par modèle MF (au lieu de tous) ;
- limitation des échéances via monkeypatch (plus de mutation permanente de
classe ; l'attribut reste sur la classe réelle, donc picklable par le Pool) ;
- assertion au niveau dataset : au moins un champ doit contenir des données
réelles, ce qui détecte un pipeline cassé sans être sensible aux champs
masqués individuels ;
- marker pytest `availability` enregistré (supprime le warning) ;
- timeout-minutes: 30 + fail-fast: false sur le job CI.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rpréteur
En CI, le changement de définitions GRIB provoquait un crash C non rattrapable :
Fatal Python error: Aborted / Segmentation fault
gribapi.grib_context_delete
meteofetch/_misc.py:118 set_grib_defs -> eccodes.codes_context_delete()
La lecture des GRIBs a lieu dans des processus enfants (multiprocessing.Pool)
qui lisent ECCODES_DEFINITION_PATH à leur initialisation ; réinitialiser le
contexte eccodes du parent est donc inutile et dangereux. Vérifié localement :
le décodage bascule correctement entre définitions eccodes (mwd, swh, …) et
meteofrance (MDPS, SHWW, …) sans cet appel. Import eccodes devenu inutile retiré.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ajoute un déclencheur pull_request (en plus de workflow_dispatch) pour que la suite pytest s'exécute automatiquement sur les PR ciblant main. Les tests ne requièrent aucun secret (téléchargement de données publiques), donc les PR issues de forks sont couvertes également. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Option pytest --full (tests/conftest.py) : bascule entre suite partielle (un paquet représentatif par modèle Météo-France) et suite exhaustive (tous les paquets). - Workflow : les PR déclenchent la suite partielle ; le lancement manuel (workflow_dispatch, input "full" par défaut à true) exécute --full. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ests Un push authentifié par le GITHUB_TOKEN ne relance pas les workflows : le commit d'auto-formatage laissait donc les checks `test` absents du commit final, bloquant le merge sous branch protection. Le workflow pousse désormais avec le secret CI_PAT (repli sur github.token si absent, ex. PR de fork). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CyrilJl
pushed a commit
to miki4iaml/MeteoFetch
that referenced
this pull request
Jul 9, 2026
La PR proposait plusieurs changements dans _misc.py. Après les correctifs récents sur eccodes, je garde seulement les deux points qui restent utiles : - geo_encode_cf() copie la DataArray sans dupliquer les données sous-jacentes, pour éviter de modifier l'objet passé en argument ; - set_test_mode() passe par le logger du package au lieu d'écrire directement sur stdout. Je laisse set_grib_defs() aligné avec main. Remettre codes_context_delete(), même derrière un lock, réintroduirait le crash eccodes corrigé dans CyrilJl#22.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Contexte
La GitHub Action Run Pytest échouait de façon récurrente. L'audit a révélé trois causes indépendantes :
Crash C non déterministe (cause principale, aussi présente sur
main).set_grib_defs()appelaiteccodes.codes_context_delete()à chaque changement de définitions GRIB, ce qui provoquait :Crash non rattrapable par
try/except, dépendant de la version d'eccodes/du timing.Durée excessive (>40 min) → annulation du runner. Téléchargement de vraies données pour 11 modèles MF × 2 jeux de définitions × tous leurs paquets (4–11) × 2 échéances → runs coupés (
runner received a shutdown signal), remontés en échec.Assertion
assert ds.mean() < 1fragile. En mode test, elle exigeait qu'aucun champ ne soit 100 % manquant ; or certains champs ECMWF sont légitimement très masqués (vsw,zos,sithick) et peuvent atteindre 1.0 selon le run → échecs intermittents detest_aifs/test_ifs.Changements
meteofetch/_misc.py: suppression deeccodes.codes_context_delete()(et de l'importeccodesdevenu inutile). La lecture GRIB a lieu dans des processus enfants (multiprocessing.Pool) qui lisentECCODES_DEFINITION_PATHà leur init ; réinitialiser le contexte du parent est inutile et fatal. Vérifié : la bascule eccodes↔meteofrance décode toujours correctement (mwd/swh↔MDPS/SHWW).tests/test_models.py: un seul paquet représentatif testé par modèle Météo-France ; échéances limitées viamonkeypatch(plus de mutation permanente de classe, attribut picklable) ; assertion au niveau dataset (« au moins un champ contient des données réelles ») ;test_aifs/test_ifsfusionnés entest_ecmwf_modelsparamétré.pyproject.toml: enregistrement du marker pytestavailability(supprime le warning)..github/workflows/pytest.yml:timeout-minutes: 30etfail-fast: false.Validation CI
workflow_dispatchsurci/shorten-tests: 61 passed, ubuntu 12m24s / macos 12m35s (contre >40 min sans jamais aboutir).🤖 Generated with Claude Code