fix(tests): exiger que le cleanup EFFACE le marqueur, pas qu'il le mentionne - #55
Closed
stephrobert wants to merge 4 commits into
Closed
fix(tests): exiger que le cleanup EFFACE le marqueur, pas qu'il le mentionne#55stephrobert wants to merge 4 commits into
stephrobert wants to merge 4 commits into
Conversation
Première campagne de validation complète du catalogue : les 84 labs rejoués sur KVM avec contrôle négatif (rouge sans la solution, vert avec). Dix défauts sont remontés, tous invisibles jusque-là. Les tests d'un lab ne tournent que si quelqu'un le joue, et personne ne les enchaînait. Trois labs étaient purement infaisables. l4-reverse-proxy-lb et l4-ldap-integration démarraient leur service sur le second nœud sans ouvrir le port dans son pare-feu : HAProxy rendait un 503, SSSD ne résolvait rien. l2-filesystem-create-xfs n'était rejouable qu'une fois, son cleanup laissant le marqueur qui garde son setup. Six cleanup.yaml ne pouvaient pas s'exécuter : « . fichier || exit 0 » ne protège rien, un sh POSIX non interactif meurt sur le source avant d'atteindre le ||. Leur dsoxlab reset échouait, donc l'apprenant restait bloqué. Le reste tient à l'état partagé entre labs, qui se joue toujours de la même façon : le lab fautif reste vert, et c'est le suivant qui échoue. Trois labs laissaient une partition sur le disque commun, trois autres laissaient leurs comptes (alice, appuser, smbuser…) et drill-firewall laissait firewalld désactivé, ce qui cassait le capstone RHCSA. Un cas inverse mérite d'être noté : sur l2-luks-encryption, c'était le TEST qui était faux, pas la solution. Il cherchait le « 2 » de Version: dans une tranche de 8 caractères, alors que l'alignement de cryptsetup le place en 9e position. Le volume était en LUKS2 depuis le début. Trois garde-fous accompagnent ces corrections, chacun vérifié en le faisant échouer : - test_playbooks_syntaxe.py joue ansible-playbook --syntax-check sur les 129 playbooks. Un YAML valide ne prouve pas qu'Ansible charge les tâches : une apostrophe française dans un bloc shell casse le découpage des arguments, et cela ne se voyait qu'à l'exécution, en rc=4 sans une seule tâche jouée. - test_marqueurs_setup_cleanup.py exige qu'un cleanup rende ce que son setup garde : marqueurs « creates: » et comptes créés. Il a trouvé deux défauts que la lecture manuelle avait manqués, dont smbuser. - verify-solutions.py compare l'état du disque partagé avant et après chaque lab vm, et nomme le lab qui salit au lieu de laisser échouer le suivant. Enfin, la séquence l1 exigeait d'éditer un fichier sans jamais l'avoir enseigné : l1-first-terminal passe en tête et gagne une section sur nano et la survie sous vi. Le challenge interdit la redirection, l'éditeur était donc obligatoire et introuvable dans le cours. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…jamais traduite Le job « Pre-commit parity » joue les hooks sur TOUS les fichiers, là où un commit ne les joue que sur les fichiers touchés. Il révélait donc 27 problèmes ruff préexistants, dans du code que personne n'avait relinté depuis que le hook utilise `uvx ruff` (donc la dernière version publiée, pas un pin). Dix-sept se corrigent d'eux-mêmes (imports, `re.M` en `re.MULTILINE`). Les dix autres demandaient une décision : - cinq subprocess.run sans `check` explicite, dans des tests de labs et le conftest racine. Tous JUGENT le code de retour, ils ne doivent surtout pas lever dessus : `check=False` est rendu explicite. - `datetime.date.today()` sans fuseau, dans le test l1 qui compare l'année courante. Remplacé par une heure locale assumée. - un `if` imbriqué inutile dans le conftest racine. - un shebang sans bit exécutable sur gen_catalog.py. Les deux dernières étaient le même défaut, et il avait une conséquence visible : deux conditions « if lang == en else » dont les deux branches disaient exactement la même chose. La variante anglaise n'avait jamais été écrite, si bien que le README ANGLAIS affichait sa légende de catalogue en français. Elle est traduite, et les deux catalogues sont régénérés. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ça échoue
Trois collections hors ansible.builtin sont employées et aucune n'était
déclarée. Deux se trouvaient installées par hasard sur la machine de
développement, la troisième non, et le capstone rhcsa-mock-exam échouait alors
sur « rc=4, Stats : {} » — le code « unreachable » d'Ansible, qui envoie
chercher un problème de réseau pendant que la cause est une dépendance absente.
Quatre pistes ont été instruites avant la bonne, dont l'état des VM,
l'inventaire et la clé SSH, alors que les trois hôtes répondaient au ping.
Le volet qui vaut le plus n'est donc pas requirements.yml, c'est le message :
la fixture remonte désormais la première ligne d'erreur d'Ansible, qu'elle
avait déjà sous la main dans PlaybookResult.stdout et n'utilisait pas.
Un test refuse qu'une collection employée manque à la déclaration. Il porte sur
ce que les fichiers emploient, pas sur ce que la machine a d'installé : une
suite verte parce que le poste est bien garni ne dit rien de celui du prochain
qui clone. Il déchiffre les solutions au passage, et un second test vérifie que
ce déchiffrement a bien eu lieu, sans quoi le premier passerait au vert sans
avoir rien regardé.
Un premier jet du motif cherchait mot.mot.mot n'importe où et remontait
auto.master, logs.tar, net.ipv4 et dl.flathub — des chemins, une archive et un
nom de domaine. Un garde-fou qui crie au loup se fait désactiver, donc il ne
regarde que la position de clé dans une tâche, et la raison est écrite dans le
fichier.
Éprouvé par mutation : retirer community.crypto de la déclaration fait échouer
le test en nommant le fichier fautif.
Au passage, runtime.hosts_required disparaît du capstone : le champ n'est lu ni
par dsoxlab ni par ce dépôt, et le compte d'hôtes est déjà porté par
runtime.targets[].
Validation : 84 labs verts sur 84, infra provisionnée, solutions rejouées.
Closes #50
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ntionne 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
4 tasks
Owner
Author
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.
Summary
Le test devait garantir qu'un lab reste rejouable : ce qu'un
creates:protège,le
cleanup.yamldoit le rendre. Sa vérification étaitassert marqueur in texte— le chemin apparaît quelque part dans le fichier. Un commentaire quile cite, ou la lecture
. /root/xxx.env, satisfaisaient la condition sans riensupprimer.
Le défaut, reproduit avant d'être corrigé
La mutation exacte que décrit l'issue, sur
l2-filesystem-create-xfs:45 passed, 1 skipped— le test ne voit rien2 failed, 43 passed, 1 skippedC'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 vieainsi, 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.
Cinq labs remontés, cinq corrigés, aucun exempté
La vérification stricte a fait remonter cinq labs — l'issue le prévoyait — et
tous pour la même raison : le cleanup lit le
.envpour connaître le disque,puis ne l'efface jamais.
l2-autofs-ondemandautofs-disk.envabsent durml2-disk-space-troubleshootdsk-disk.envabsent de la loopstate: absentl2-partition-gptl2-storage-performanceperf-disk.envabsent durm -rfl3-fs-readonly-recoverfsro-disk.envabsent durm -f— le lab de #48La 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, traitées une par une plutôt que par une substitution
générale qui aurait placé le
rmau mauvais endroit dans au moins l'une d'elles.Ce que
_est_efface()accepteDeux formes, et seulement elles :
rmsuivi du chemin, éventuellement parmi d'autres ;state: absent.Vérification
.envd'un cleanup corrigé le rend rouge aussi ;cleanup.yamlrestent du YAML valide et passentansible-playbook --syntax-check;dsoxlab validate-structure: les 84 labs valides.Critères de l'issue
l3-fs-readonly-recoverest signalé par le test, puis corrigé (l3-fs-readonly-recover : reset impossible en séquence (hôte injoignable), et son cleanup laisse un marqueur #48).rm -fà plusieurs chemins, etansible.builtin.fileavecstate: absent.Related issues
Closes #49
Refs #48 — le marqueur de
l3-fs-readonly-recoverest corrigé ici. Le point 1 decette issue (l'hôte qui devient injoignable en séquence) reste ouvert : il demande
une campagne de validation réelle.
🤖 Generated with Claude Code