Stratégie de tests — CVN-N014-ED-S01 (object-storage XCom backend flip)¶
Réfs : plan dossier · architecture · runbook. Taxonomie : ADR-83 (tiers
fast/medium/nightly/operator-driven+ marqueurstory). Principe directeur : les livrables S01 sont des outils read-only in-pod + un standard. La logique pure (classification, verdicts, invariants read-only) est testable unitairement et déterministe, hors cluster. Le comportement in-pod réel (round-trip, config effective) relève de la validation système (dogfood contre le scheduler réel), déjà exécutée.
1. Objectifs & périmètre¶
Tester : (a) la correction du classifieur d'audit (json_literal / numpy_suspect / unknown) ; (b) la sémantique de verdict du round-trip (régression contrôle-flow bloque ; numpy EXPECTED-FAIL ne bloque pas) ; (c) les invariants read-only des sondes embarquées (aucune écriture XCom/DB ; le write S3 du pre-flight est gated par --functional-s3) ; (d) le footgun config (le pre-flight lit la section pointée common.io).
Ne PAS tester (relève d'autre chose) : la valeur réelle du round-trip in-pod et de la config effective (= validation système, dogfood cluster, déjà fait) ; le flip prod lui-même (= staged, gated rehearsal) ; la stratégie numpy (= S02).
2. Pyramide de tests + tiers ADR-83¶
| Niveau | Marqueur | Tier | Ce qui est testé | Fichier |
|---|---|---|---|---|
| Classifieur audit (pur) | unit |
fast (PR-blocking) | json_literal / numpy_suspect / unknown ; @task vs fonction nue ; push value kwarg/positional ; pull/output = consommation ; parse-error surfacé ; path absent | tests/unit/test_xcom_serialization_audit.py |
| Verdict round-trip (pur) | unit |
fast | all-green → 0 ; régression contrôle-flow → 1 ; numpy EXPECTED-FAIL → 0 ; jeux de cas disjoints + couvrant le corpus ; invariant read-only de la sonde | tests/unit/test_xcom_roundtrip_probe.py |
| Pre-flight (pur) | unit |
fast | lit la section pointée common.io ; vérifie provider + connexion ; write S3 gated par --functional-s3 ; functional off par défaut ; check FAIL → exit non-zéro |
tests/unit/test_xcom_flip_preflight.py |
Tous portent @pytest.mark.story("CVN-N014-ED-S01") (ADR-87, filtre pytest --story). 19 tests, tier fast, verts.
3. Cas de tests — couche AUDIT (le cœur du classifieur)¶
| # | Entrée | Classification attendue | Pourquoi |
|---|---|---|---|
| A1 | @task → return {'auc':0.5,'ok':True} |
json_literal |
dict de constantes = flip-safe |
| A2 | @task → return {'P': np.vstack(rows)} |
numpy_suspect |
np/vstack ⇒ non-JSON |
| A3 | @task → return df.to_numpy() |
numpy_suspect |
pandas → numpy |
| A4 | ti.xcom_push(key=..., value={'a':1}) |
json_literal |
value kwarg constant |
| A5 | ti.xcom_push('k', some_ndarray) |
unknown |
Name non résoluble → à probe-r, pas un faux json_literal |
| A6 | xcom_pull(...) / .output |
n/a (consommation) |
sites de lecture, pas de producteur |
| A7 | fonction nue (sans @task) renvoyant numpy |
aucun finding | ce n'est pas un XCom |
| A8 | source non-parsable | parse_error surfacé (pas de crash) |
ADR-25 |
| A9 | path inexistant | FileNotFoundError |
fail-fast |
4. Cas de tests — couche VERDICT (round-trip) & READ-ONLY¶
- V1 all-green → exit 0 ; V2 régression contrôle-flow → exit 1 ; V3 numpy EXPECTED-FAIL (tous) + contrôle-flow OK → exit 0 ; V4 jeux
CONTROL_FLOW_CASES/EXPECTED_FAIL_CASESdisjoints et couvrant le corpus de la sonde. - R1 (read-only) : la sonde round-trip ne contient ni
xcom_push, nisession, niexecute(, ni SQL d'écriture, nicreate_engine; elle faitjson.dumps(val, cls=XComEncoder). - P1 (pre-flight footgun) : la sonde lit
conf.get("common.io", "xcom_objectstorage_{path,threshold}")+core.xcom_backend; P2 le write S3 est sousif req.get("functional"); P3--functional-s3absent ⇒functional=False; P4 un check FAIL ⇒ exit non-zéro.
5. Validation système (dogfood — déjà exécutée)¶
Hors test unitaire, contre le scheduler réel (airflow-scheduler-…-jsmhp) :
| Outil | Run réel | Résultat |
|---|---|---|
xcom_serialization_audit.py --path dags |
129 sites | 0 numpy_suspect, 116 unknown, 1 json_literal |
xcom_roundtrip_probe.py |
corpus + forme s43 | contrôle-flow GREEN (3/3), numpy EXPECTED-FAIL (3/3), exit 0 |
xcom_flip_preflight.py (read-only) |
provider + config | provider OK, backend=BaseXCom, threshold=-1 (prouvés in-pod) |
airflow config get-value core enable_xcom_pickling |
— | False effectif (clé de voûte H1) |
6. Hors-scope test (par conception)¶
- Le flip prod et son round-trip d'offload réel : exigent un payload > seuil (post-S02) + un rehearsal kill-switch — validation système gated, pas test.
- La serde numpy : c'est S02 (X′/X″/Y).
- Recommandation comité (suivi) : automatiser le round-trip d'offload (gros JSON) en CI ; audit récurrent (trimestriel) sur le jeu de DAGs le plus large.