fix(runtimes/services): un conteneur arrêté se dit, au lieu d'accuser la commande (0.1.66) - #158
Merged
Merged
Conversation
… la commande (0.1.66) L'issue #155 demandait de mesurer avant de corriger. La mesure a réfuté l'hypothèse la plus tentante : entre docker run -d et le premier docker exec il n'y a aucune fenêtre, 0,08 s au repos et 0,23 s à load 15,8, conteneur déjà running. Ni le tirage d'image, ni l'ordre des tests, ni une collision de nom ne tiennent non plus. Ce qu'elle a trouvé ne demande aucune charge. Quand post_start vise un conteneur qui n'est plus debout, Docker répond « container <64 caractères hexadécimaux> is not running », et cette phrase était reprise dans « l'initialisation du service a échoué sur telle commande ». Elle accuse une commande qui n'a jamais été jouée, et nomme le conteneur par un identifiant que personne n'a vu. Le message donne maintenant l'arrêt, le code de sortie et les dix dernières lignes des logs. Le contrôle n'a lieu qu'après l'échec d'un docker exec : le chemin nominal ne paie aucun appel de plus. Les deux tests instables déclarent enfin la sonde ready_exec que le contrat recommande, au lieu d'enchaîner un docker exec que rien n'autorisait. Aucun délai n'a été allongé, ce que l'issue déconseillait. Leurs messages portent l'état du conteneur, son code de sortie et ses logs : un échec intermittent en intégration continue ne laisse aucune autre trace. Au passage, deux tests de documentation étaient rouges chez le contributeur et verts en intégration continue : le contrôle lisait tous les Markdown de la racine, y compris ceux que git ne suit pas. Il ne retient plus que les fichiers versionnés, et retombe sur tout hors dépôt git pour ne pas se vider. Les deux corrections sont éprouvées par leur échec, chacune neutralisée tour à tour pour voir le test rougir. L'issue reste ouverte : son occurrence exacte n'a pas été reproduite, seules plusieurs semaines de pre-push le diront. Refs #155 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Le merge de #157 a posé 0.1.65 sur main. Les seuls conflits sont la ligne de version et l'ordre des deux sections du CHANGELOG, résolus en gardant 0.1.66 au-dessus de 0.1.65. Le contenu obtenu est identique à celui d'un rebase joué séparément et validé sur 650 tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
L'issue #155 demandait de mesurer avant de corriger, et de ne pas allonger un
délai, qui est « la correction la plus tentante et la moins informative ». Cette
PR suit cet ordre, et le résultat de la mesure n'est pas celui qu'on attendait.
Ce que la mesure a réfuté
docker run -detdocker execrunning, premierexecréussi en 0,08 s au repos et 0,23 s à load 15,8, sur 12 tours chacunnginx:alpineethello-worlden cache localpytest-randomlynixdistdsoxlab-test/dsoxlab-test-net), aucun parallélismeL'occurrence exacte de l'issue n'a pas été reproduite : trois exécutions de la
suite complète à load 46 sont restées vertes. D'où
Refs #155et nonCloses:seules plusieurs semaines de
pre-pushdiront si l'intermittence a disparu.Ce qu'elle a trouvé, et qui ne demande aucune charge
Quand
post_startvise un conteneur qui n'est plus debout, Docker répondcontainer <64 caractères hexadécimaux> is not running. Cette phrase étaitreprise telle quelle :
Deux erreurs dans une seule ligne : elle accuse une commande qui n'a jamais été
jouée, et elle désigne le conteneur par un identifiant que l'utilisateur n'a
jamais vu. Désormais :
Le contrôle n'a lieu qu'après l'échec d'un
docker exec: le chemin nominalne paie aucun appel supplémentaire, et un service sain n'est jamais interrogé
pour rien. Une première version vérifiait avant, en réutilisant
_is_running:elle était fausse, parce que cette fonction répond à une autre question (« y
a-t-il un conteneur à réutiliser ? », avant le
run), et elle a cassé un testmocké. La mesure l'a attrapée.
Les deux tests de l'issue
Ils déclarent enfin la sonde
ready_execque le contrat recommande, au lieud'enchaîner un
docker execque rien n'autorisait : l'attente implicite tenait àla charge de la machine. Aucun délai n'a été allongé. Leurs messages portent
maintenant l'état du conteneur, son code de sortie et ses logs, parce qu'un échec
intermittent en intégration continue ne laisse aucune autre trace, et qu'un
assert x.oknu ne laissait rien à diagnostiquer.Un défaut trouvé en chemin, qui empêchait la mesure
Deux tests de
test_documentation_synchrone.pyétaient rouges chez lecontributeur et verts en intégration continue : le contrôle lisait tous les
Markdown de la racine, y compris ceux que git ne suit pas. Un
CLAUDE.mdcitant~/.config/dsoxlab/config.yamlpour dire que ce chemin n'existe pas encoresuffisait à le faire échouer. Il ne retient plus que les fichiers versionnés, et
retombe sur tout ce qu'il trouve hors dépôt git, pour qu'une archive extraite ne
le rende pas vert en le vidant.
Contrôles joués
Always
uv run ruff check src/dsoxlab tests tests_e2e fuzz scripts: All checks passeduv run mypy src/dsoxlab: no issues found in 60 source filesuv run pytest: 633 passed (629 avant, +4)uv run pytest tests_e2e: 16 passed sur la roue construite et installéepre-commitpassent, y compris le contrôle de documentationproduit ni aucune catégorie de labs
-
ansible-training, labvault-integration-hashicorp(ready_exec: vault statusetpost_start) : service démarré, et le secret déposépar
post_startrelu dans le conteneur pour prouver l'effet, pas la forme-
terraform-training(aucun blocinfra:), labaws-provider-aws-first-ec2(ready_execsanspost_start) :service démarré, chemin sans initialisation inchangé
tour à tour pour vérifier que le test nouveau rougit, puis restaurée
50,7, 32 processus de calcul et 6 boucles d'appels Docker) sans un seul
échec
When behavior changes
uv.lockalignéWhen a command or option is added, removed or changed — N/A
Aucune commande ni option n'est touchée. La clé i18n nouvelle
(
err_service_container_stopped) est posée dans en.py et fr.py, et lemessage a été lu sous
DSOXLAB_LANG=encomme sousDSOXLAB_LANG=fr.When
.github/workflows/is touched — N/AWhen the declarative contract changes — N/A
Ni
meta.ymlnilab.yamlne gagnent de champ.ready_execexistait déjà, etla documentation le décrivait déjà comme « le seul signal de disponibilité
fiable » : ce sont les tests du dépôt qui ne suivaient pas leur propre contrat.
Note de version
0.1.66 et non 0.1.65, ce numéro appartenant à la PR #157, ouverte et
mergeable. Si #157 part la première, l'enchaînement est cohérent.
Related issues
Refs #155
🤖 Generated with Claude Code