From 9c698ac4284c1daa2be4dd3ff5b5b5e925dfaed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20ROBERT?= Date: Mon, 24 Aug 2026 22:51:14 +0200 Subject: [PATCH] fix(tests): exiger que le cleanup EFFACE le marqueur, pas qu'il le mentionne MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le test devait garantir qu'un lab reste rejouable : ce qu'un « creates: » protège, le cleanup doit le rendre. Sa vérification était « assert marqueur in texte » — le chemin apparaît quelque part dans le fichier. Un commentaire qui le cite, ou la lecture « . /root/xxx.env », satisfaisaient la condition sans rien supprimer. Défaut reproduit avant d'être corrigé, avec la mutation exacte de l'issue : sur l2-filesystem-create-xfs, remplacer le « rm -f » par un « echo » qui cite les deux mêmes chemins laissait la suite à 45 passed. Plus aucun marqueur n'était effacé, et le test ne voyait rien. C'est le piège que la partie « comptes » du même module avait déjà corrigé avec _est_supprime(), dont la docstring note : « ce test a commencé sa vie ainsi, et il passait sur un cleanup dont on venait de retirer le userdel ». La leçon n'avait pas été reportée sur les marqueurs. _est_efface() n'accepte que deux formes, celles qui suppriment vraiment : un « rm » shell portant le chemin parmi d'autres, ou une tâche Ansible qui porte à la fois le chemin et « state: absent ». La vérification stricte a fait remonter CINQ labs, comme l'issue le prévoyait, et tous pour la même raison : le cleanup lit le fichier .env pour connaître le disque, puis ne l'efface jamais. Aucun n'est exempté, les cinq sont corrigés — l2-autofs-ondemand, l2-disk-space-troubleshoot, l2-partition-gpt, l2-storage-performance et l3-fs-readonly-recover. La suppression est placée APRÈS la lecture dans chaque cas : l'effacer avant priverait le cleanup de la variable dont il a besoin. Trois formes distinctes selon les labs, traitées une par une plutôt que par une substitution générale qui aurait placé le rm au mauvais endroit : ajout au rm existant, ajout à la loop d'un « file: state: absent », et création du rm là où il n'y en avait aucun (l2-partition-gpt n'effaçait rien du tout). Vérifié : la mutation de l'issue rend maintenant le test rouge, retirer le .env d'un cleanup corrigé aussi, les cinq cleanups restent du YAML valide et passent le --syntax-check d'ansible-playbook, 871 tests verts et les 84 labs valides. Closes #49 Refs #48 --- labs/linux/l2/l2-autofs-ondemand/cleanup.yaml | 2 +- .../l2-disk-space-troubleshoot/cleanup.yaml | 3 ++ labs/linux/l2/l2-partition-gpt/cleanup.yaml | 1 + .../l2/l2-storage-performance/cleanup.yaml | 2 +- .../l3/l3-fs-readonly-recover/cleanup.yaml | 2 +- tests/test_marqueurs_setup_cleanup.py | 32 +++++++++++++++++-- 6 files changed, 37 insertions(+), 5 deletions(-) diff --git a/labs/linux/l2/l2-autofs-ondemand/cleanup.yaml b/labs/linux/l2/l2-autofs-ondemand/cleanup.yaml index 5d4f810..bbc36e9 100644 --- a/labs/linux/l2/l2-autofs-ondemand/cleanup.yaml +++ b/labs/linux/l2/l2-autofs-ondemand/cleanup.yaml @@ -21,5 +21,5 @@ wipefs -a "$part" 2>/dev/null || true wipefs -a "$DISK" 2>/dev/null || true partprobe "$DISK" 2>/dev/null || true - rm -f /root/.autofs-lab-ready + rm -f /root/.autofs-lab-ready /root/autofs-disk.env changed_when: false diff --git a/labs/linux/l2/l2-disk-space-troubleshoot/cleanup.yaml b/labs/linux/l2/l2-disk-space-troubleshoot/cleanup.yaml index c155c0c..ec216b3 100644 --- a/labs/linux/l2/l2-disk-space-troubleshoot/cleanup.yaml +++ b/labs/linux/l2/l2-disk-space-troubleshoot/cleanup.yaml @@ -27,3 +27,6 @@ loop: - /srv/data - /root/.dsk-lab-ready + # Lu plus haut pour connaître le disque : il doit partir avec + # le reste, sinon le prochain setup saute la détection. + - /root/dsk-disk.env diff --git a/labs/linux/l2/l2-partition-gpt/cleanup.yaml b/labs/linux/l2/l2-partition-gpt/cleanup.yaml index 30b138a..7a6cf8c 100644 --- a/labs/linux/l2/l2-partition-gpt/cleanup.yaml +++ b/labs/linux/l2/l2-partition-gpt/cleanup.yaml @@ -20,4 +20,5 @@ wipefs -a "$DISK" 2>/dev/null || true sgdisk --zap-all "$DISK" 2>/dev/null || true partprobe "$DISK" 2>/dev/null || true + rm -f /root/part-disk.env changed_when: false diff --git a/labs/linux/l2/l2-storage-performance/cleanup.yaml b/labs/linux/l2/l2-storage-performance/cleanup.yaml index e1e7dc7..708ea40 100644 --- a/labs/linux/l2/l2-storage-performance/cleanup.yaml +++ b/labs/linux/l2/l2-storage-performance/cleanup.yaml @@ -25,5 +25,5 @@ wipefs -a "$part" 2>/dev/null || true wipefs -a "$DISK" 2>/dev/null || true partprobe "$DISK" 2>/dev/null || true - rm -rf /srv/data /root/.perf-lab-ready + rm -rf /srv/data /root/.perf-lab-ready /root/perf-disk.env changed_when: false diff --git a/labs/linux/l3/l3-fs-readonly-recover/cleanup.yaml b/labs/linux/l3/l3-fs-readonly-recover/cleanup.yaml index f75995d..c1e3274 100644 --- a/labs/linux/l3/l3-fs-readonly-recover/cleanup.yaml +++ b/labs/linux/l3/l3-fs-readonly-recover/cleanup.yaml @@ -15,6 +15,6 @@ . /root/fsro-disk.env part="${DISK}1"; [ -b "$part" ] || part="${DISK}p1" wipefs -a "$part" 2>/dev/null || true - rm -f /root/.fsro-ready + rm -f /root/.fsro-ready /root/fsro-disk.env chdir: / changed_when: false diff --git a/tests/test_marqueurs_setup_cleanup.py b/tests/test_marqueurs_setup_cleanup.py index 7d3d0f5..bed94d2 100644 --- a/tests/test_marqueurs_setup_cleanup.py +++ b/tests/test_marqueurs_setup_cleanup.py @@ -55,6 +55,32 @@ def _marqueurs(setup: Path) -> list[str]: ] +def _est_efface(cleanup: str, marqueur: str) -> bool: + """Le cleanup EFFACE-t-il réellement ce marqueur ? + + Le mentionner ne suffit pas : « . /root/xxx.env » le lit sans le rendre, et + un commentaire qui le cite satisfaisait la vérification. C'est exactement le + piège que la partie « comptes » de ce module avait déjà corrigé avec + `_est_supprime()`, dont la docstring note : « ce test a commencé sa vie + ainsi, et il passait sur un cleanup dont on venait de retirer le userdel ». + La leçon n'avait pas été reportée ici. + + Deux formes légitimes, et seulement elles : + + - shell : ``rm`` suivi du chemin, éventuellement parmi d'autres ; + - Ansible : une tâche qui porte à la fois le chemin et ``state: absent``. + """ + echappe = re.escape(marqueur) + # `rm -f a b c` : le marqueur peut être n'importe lequel des chemins. + if re.search(rf"^\s*rm\b[^\n#]*\s{echappe}(\s|$)", cleanup, re.MULTILINE): + return True + # Une tâche Ansible se délimite au « - name: » suivant. + for tache in re.split(r"\n\s*- name:", cleanup): + if "state: absent" in tache and re.search(rf"{echappe}(\s|$|\")", tache): + return True + return False + + @pytest.mark.parametrize( ("lab", "marqueur"), CAS, @@ -70,9 +96,11 @@ def test_le_cleanup_efface_le_marqueur(lab: Path, marqueur: str) -> None: assert cleanup.is_file(), f"{lab.name} a un setup.yaml mais pas de cleanup.yaml" texte = cleanup.read_text(encoding="utf-8") - assert marqueur in texte, ( + assert _est_efface(texte, marqueur), ( f"{lab.name} : le setup se garde avec « creates: {marqueur} », mais le " - f"cleanup ne mentionne jamais ce chemin.\n" + f"cleanup ne l'EFFACE jamais.\n" + f"Le mentionner ne suffit pas — « . {marqueur} » le lit, un commentaire " + f"le cite — et cette vérification a d'ailleurs commencé sa vie ainsi.\n" f"Le nettoyage laissera donc le marqueur en place : au prochain setup, " f"la tâche sera sautée et l'état de départ ne sera jamais reconstruit.\n" f"Ajouter par exemple : rm -f {marqueur}"