- Antithesis applique au logiciel en général les tests autonomes déterministes qui ont fait leurs preuves chez FoundationDB, afin de transformer des bugs de systèmes distribués difficiles à reproduire en problèmes répétables
- FoundationDB a d’abord construit une simulation mono-thread et mono-processus avant d’implémenter la base de données, ce qui permettait de rejouer de rares scénarios d’échec avec la même graine aléatoire
- Cette approche a fait des défaillances non déterministes — concurrence, latence et réordonnancement réseau, problèmes disque, pannes machine — un objet testable, et chez FoundationDB on estime qu’il n’y a eu que 1 à 2 bugs signalés par des clients sur toute la période
- Pour éviter d’obliger les équipes à réécrire leur logiciel depuis zéro, Antithesis a créé un hyperviseur qui émule un ordinateur déterministe, et se concentre aujourd’hui sur les tests de fiabilité et de tolérance aux pannes des systèmes distribués
- L’entreprise a travaillé avec MongoDB, l’Ethereum Foundation et Palantir, et a évolué d’un outil de chasse aux bugs rares vers un service de test continu qui valide en permanence les derniers builds
Antithesis, né de l’expérience FoundationDB
- Antithesis a dévoilé une plateforme développée pendant plus de 5 ans en mode furtif, fondée sur l’expérience des tests déterministes acquise chez FoundationDB
- Avant cette annonce, l’entreprise avait déjà travaillé sur le recrutement, ses premiers clients et ses investisseurs, tandis que son premier message public portait sur une méthode pour tester de manière répétable des systèmes complexes
Le problème de validation le plus difficile dans les bases de données distribuées
- FoundationDB a commencé en 2010 à construire une base de données distribuée extensible, tolérante aux pannes et compatible avec les transactions ACID
- À l’époque, Spanner n’avait pas encore été publié, et beaucoup interprétaient à tort le théorème CAP comme l’impossibilité de concilier forte cohérence et haute disponibilité
- La plus grande difficulté n’était pas la base de données elle-même, mais la manière de tester un tel système et d’obtenir un niveau de confiance dans sa correction
Les « inconnues inconnues » que les tests classiques laissent passer
- Un logiciel doit aussi gérer des situations que ses développeurs n’ont pas anticipées, alors que les tests classiques excellent surtout à vérifier des cas déjà imaginés
- Si un scénario a été suffisamment prévu pour devenir un test, il est probable que le code ait aussi été écrit pour le gérer
- Les tests traditionnels sont donc utiles pour éviter les régressions, mais faibles pour capturer les pannes imprévues produites par de vrais utilisateurs et des environnements d’exploitation réels
- Dans les systèmes de stockage distribués, le problème est encore plus marqué
- la concurrence existe à la fois à l’intérieur des machines et entre elles
- le réseau peut introduire de la latence et un réordonnancement des paquets
- les causes d’échec incluent les disques, les pannes machine, les coupures de courant, les incendies de datacenter et les erreurs humaines
- si un bug critique dépend d’une séquence d’événements répartie sur plusieurs machines, il peut être très difficile à reproduire même après l’avoir observé une première fois
La simulation déterministe de FoundationDB
- L’équipe FoundationDB a d’abord créé une simulation réseau entièrement déterministe et pilotée par événements avant même d’écrire la base de données
- Elle simulait tout le cluster dans une application mono-thread et mono-processus, en faisant tourner l’exécution avec le même générateur de nombres aléatoires
- Dans ce cluster virtuel, il était possible d’injecter des pannes réseau, d’éteindre des machines et de reproduire diverses situations anormales de façon répétée
- Si une exécution particulière révélait un bug dans la logique applicative, la même graine aléatoire permettait de rejouer la même séquence d’événements
- Cela rendait traçables même des bugs très rares, en ajoutant des logs ou en répétant les procédures de débogage
- Une présentation associée a eu lieu à Strangeloop en 2014, et la vidéo est disponible ici
Comment les tests ont changé la vitesse de développement
- Chez FoundationDB, on estime qu’il n’y a eu au total que 1 à 2 bugs signalés par des clients sur toute l’histoire de l’entreprise
- Kyle Kingsbury, alias « aphyr », n’a pas testé FoundationDB avec Jepsen car il estimait qu’il n’y avait rien à y trouver
- Une fois les tests capables de révéler immédiatement de nouveaux bugs, la manière de programmer de l’équipe a elle aussi changé
- Un compilateur et un système de types fort apportent de la confiance contre certaines catégories de bugs, mais cela n’équivaut pas à exécuter le logiciel réel dans des milliers de situations imprévues
- Fort de cette confiance, l’équipe FoundationDB a entrepris de grands changements
- elle a supprimé toutes ses dépendances, y compris Zookeeper, et écrit en peu de temps sa propre implémentation de Paxos, incluse dans le paper FoundationDB
- elle a réécrit l’ensemble du sous-système de traitement des transactions pour le rendre plus rapide et plus extensible
- L’effet le plus important n’a pas seulement été l’amélioration de la stabilité de la base de données, mais le fait d’avoir donné à une petite équipe d’ingénierie une productivité comparable à celle d’une équipe 50 fois plus grande
Le manque apparu après le rachat par Apple
- Apple a acquis FoundationDB en 2015 et l’a utilisé comme base de sa « cloud infrastructure »
- Quelques années plus tard, FoundationDB a été publié en open source
- Même après la dispersion des membres de l’équipe FoundationDB dans d’autres grands groupes technologiques, ces organisations ne disposaient pas de tests par simulation déterministe à la FoundationDB
- Les changements dans les systèmes backend avançaient lentement, car il était difficile de prévoir les effets involontaires sur le système, et diagnostiquer puis corriger des bugs en production mobilisait pendant des mois le temps d’ingénieurs très expérimentés
- En 2018, Antithesis a été lancé avec Dave Scherer, avec pour objectif d’apporter à d’autres équipes les tests autonomes déterministes de type FoundationDB
Comment rendre un logiciel existant déterministe
- FoundationDB était un projet greenfield conçu dès le départ pour être testé de cette façon, avec la possibilité d’éliminer les dépendances
- Un logiciel classique crée des threads, consulte l’heure, demande des valeurs aléatoires au kernel et communique avec d’autres logiciels sur le réseau
- Comme une méthodologie de développement imposant de tout réécrire depuis zéro serait difficile à adopter à grande échelle, Antithesis a développé un hyperviseur qui émule un ordinateur déterministe
- Il devient ainsi possible de placer les logiciels exécutés dans cet hyperviseur dans un environnement d’exécution déterministe
- Cela implique notamment de travailler sur des comportements bas niveau comme les extended page tables des CPU Intel
- Le problème qui consiste à trouver des violations de propriétés dans l’espace d’états d’un programme arbitraire est plus difficile encore que le problème de l’arrêt, et il peut exister des propriétés de test non calculables même avec un oracle de l’arrêt pour tous les programmes
La plateforme actuelle et les cas clients
- La plateforme Antithesis vise à prendre le logiciel de l’utilisateur, trouver des bugs et faire en sorte que les bugs découverts soient toujours reproductibles
- Elle cherche à préserver cette reproductibilité même dans les cas complexes où plusieurs services communiquent via le réseau
- Une fois le bug trouvé, de puissantes capacités de débogage peuvent être appliquées
- À long terme, la plateforme a été conçue pour détecter de nombreux types de bugs dans différents logiciels, mais pour l’instant elle se concentre sur les tests de fiabilité et de tolérance aux pannes des systèmes distribués, un domaine où l’équipe possède déjà une forte expérience
- Ces dernières années, l’entreprise a travaillé avec des équipes d’ingénierie exploitant de grands systèmes complexes pour lesquels la fiabilité est critique
- collaboration pluriannuelle avec MongoDB pour aider à tester le core server software et le moteur de stockage WiredTiger
- collaboration avec l’Ethereum Foundation à partir d’environ un an avant le Merge pour aider aux tests du Merge, collaboration toujours en cours
- collaboration également en cours avec Palantir
D’un outil pour bugs rares à un service de test continu
- Les premiers clients utilisaient Antithesis comme un outil commando pour découvrir et reproduire les bugs les plus difficiles à trouver et les plus risqués
- À mesure que la plateforme gagnait en maturité et devenait plus interactive, elle s’est transformée en service continu testant en permanence les derniers builds
- L’objectif est de réduire le délai entre l’introduction d’un bug et le moment où il est découvert
- Lors du développement de FoundationDB, cette approche rendait le diagnostic et la correction des bugs beaucoup plus simples, tout en améliorant l’efficacité et la qualité logicielle
- Antithesis souhaite échanger avec les organisations qui exploitent des systèmes distribués et accordent de l’importance à la fiabilité et à la productivité de l’ingénierie
- Pour les personnes qui veulent travailler sur des problèmes difficiles, l’entreprise renvoie vers ses offres d’emploi
1 commentaires
Avis sur Hacker News
J’ai l’impression que l’expression « développeur 10x légendaire » a été déformée pour désigner quelqu’un qui travaille 15 heures par jour, 6,5 jours par semaine, jusqu’au burn-out.
La vraie productivité 10x, voire 50x, vient de personnes qui implémentent des choses que presque personne ne pensait possibles ou ne comprenait, et qui permettent de produire un logiciel fonctionnel en beaucoup moins de temps.
Les managers remarquent trop souvent davantage la personne qui fait 8 heures de travail en 12 heures que celle qui termine le même travail en 8 heures.
Et les tentatives qui s’écartent de la « norme » sont mal vues, tandis que le planning ne prévoit pas de temps pour améliorer les processus ; dans un contexte où l’on pense qu’il suffit de porter les seaux plus vite, construire une brouette est découragé.
C’est pour cela que les ingénieurs 10x existent. À 30 ans, ils n’ont pas 10 ans d’expérience en programmation, mais plutôt 20.
Ils ont aussi beaucoup plus d’expérience professionnelle. Même si, à 15 ans, cela commence par de petits boulots bizarres pour aider un proche de temps en temps, vers 18 ans ils entrent dans une entreprise professionnelle tout en poursuivant des études d’informatique.
Du moins, c’était comme ça avant. C’était une réalité d’environ 2004 à 2018, mais je ne sais pas si c’est encore possible dans le contexte actuel du recrutement.
Pour que les ingénieurs 10x existent, il suffit de quelques exemples. Tout le monde semble globalement d’accord pour dire qu’ils sont rares, et voici un exemple publiquement observable d’ingénieur 10x. Il ne le dirait certainement jamais lui-même, mais à mon avis c’en est un : https://bellard.org/
Si vous n’êtes pas d’accord, je serais curieux de savoir sur quoi. Je ne suis qu’une personne qui ne touche qu’une partie de l’éléphant, comme dans les aveugles et l’éléphant, et je ne prétends pas voir l’ensemble du tableau.
Le développeur armée à lui tout seul, capable de tout faire, s’intègre mal dans des équipes où le travail est standardisé, découpé en petites tâches et réparti.
Ces personnes donnent le meilleur d’elles-mêmes quand elles travaillent sur leur propre projet, sans collègues ni managers qui les interrompent, mais la plupart des postes ne ressemblent pas à ça.
Une fois intégrées à une équipe, aussi brillantes soient-elles, elles ne peuvent pas faire énormément de choses seules, et finissent par être ralenties parce qu’elles doivent gérer les problèmes créés par des coéquipiers plus lents ou moins solides, ou par le management. Au final, même avec une rockstar, l’équipe avance au rythme du plus petit dénominateur commun.
Le fait que nous construisions des outils internes et que nous soyons très proches des processus et des parties prenantes aide aussi.
« Tiens, il y a une autre façon d’atteindre cet objectif » relève du 10x ; faire les choses plus vite n’est pas l’essentiel.
C’est peut-être le meilleur texte d’introduction que j’aie lu jusqu’ici.
Il pose bien les bases : qui sont les personnes, ce qu’elles ont construit, et le fait que ce qu’elles construisent maintenant découle de ce qu’elles ont construit auparavant.
On sent qu’elles veulent résoudre ce problème pour tout le monde, sans doute parce qu’elles ont déjà expérimenté à quel point leur solution est bonne.
Ensuite, le texte montre aussi les équipes qui l’ont déjà utilisée, avec des noms assez importants ayant des systèmes complexes.
Tout cela est emballé dans un bon texte qui parle bien aux développeurs et aux fondateurs, et la landing page est excellente.
J’aurais aimé voir de vrais cas d’usage et des exemples.
À la place, on a une liste de quelques grandes entreprises, l’affirmation que c’est un produit révolutionnaire qui fonctionne comme par magie, puis des buzzwords typiques comme « programmeur 10x » et « stealth mode ». Parler de stealth mode tout en publiant les noms des clients, ce n’est pas cohérent.
Il donne envie de cette solution parce qu’il propose une manière de vivre, de penser et d’exécuter que je n’ai encore jamais connue.
L’article lié est composé aux trois quarts d’histoire et de justification avant de dire ce qui a réellement été construit.
C’est comme ces blogs de recettes pénibles où l’on veut préparer des pancakes véganes, mais où l’auteur commence par raconter son enfance.
C’est un excellent pitch et je ne veux pas paraître négatif, mais j’ai l’impression qu’une phrase comme « on a trouvé tous les bugs » ne peut être vraie qu’en adoptant une définition du bug très étroite
Les bugs les plus vicieux et les plus difficiles à trouver que j’aie rencontrés jusqu’ici se situaient davantage autour de la logique métier de l’application que dans le fait de tomber dans un état d’erreur
Par exemple, que faut-il afficher sur la page des transactions récentes d’un client lorsque la base de données indique qu’une transaction a été finalisée, mais qu’il n’existe aucun article acheté finalisé ?
Dans ce genre de cas, il y a une grande différence entre implémenter « quelque chose s’affiche et ça ne crashe pas » et garantir que le choix a réellement du sens dans le contexte des autres choix faits sur toute la stack
Pour une base de données, il y a aussi des problèmes du type « le planificateur de requêtes produit un plan très inefficace dans ce cas limite »
Ce genre de choses est impossible à détecter automatiquement. Ce n’est pas un problème où le programme atteint un état d’erreur, mais un problème qui consiste à comprendre ce que signifie au départ la “correction” dans l’application
Peut-être que je place la barre trop haut pour ce qui compte comme bug, mais imaginer zéro bug et construire du logiciel dans le monde réel, ce n’est pas la même chose. En revanche, zéro erreur à l’exécution, ça, je pourrais l’accepter
Cela dit, il est vrai que FoundationDB est vraiment célèbre pour avoir repoussé l’état de l’art en matière de pratiques de test : https://apple.github.io/foundationdb/testing.html
D’ordinaire, cela sentirait l’arrogance ou l’excès de confiance, mais ici ils sont effectivement arrivés très près de zéro bug
Bien sûr, on ne peut pas prouver une négation, mais le fait d’être arrivé à cet état où « tout est vert » donnait une forte confiance dans le fait qu’on construisait sur des bases solides, et avec le temps cela s’est vérifié
Les problèmes autour de la logique métier ne sont pas une défaillance du système : le système a fonctionné conformément à la spécification, mais celle-ci n’était pas assez exhaustive, donc il faut maintenant itérer et l’améliorer
Bien sûr, beaucoup de logiciels manquent de documentation, et ça, c’est un bug de documentation
Mais cette définition est bonne parce que, même quand la documentation est incomplète, elle pousse à demander : « veut-on vraiment documenter ce comportement, ou bien changer le comportement et documenter cela ? »
Au moins pour moi, cela rend plus difficile de balayer sous le tapis un comportement étrange
Je me suis énormément intéressé à ce domaine depuis que je l’ai découvert avec le guide de simulation de
sledhttps://sled.rs/simulation.html, qui donne un aperçu de la façon dont FoundationDB procèdeEn ce moment, j’essaie d’introduire une approche de test similaire dans mon entreprise, en écrivant notre service pour qu’il s’exécute sur
madsimhttps://github.com/madsim-rs/madsim?tab=readme-ov-file#madsimCela permet de continuer à écrire des services en style async/await avec tokio, tout en remplaçant, dans les tests, toutes les sources de non-déterminisme — y compris les dépendances qui appellent le système d’exploitation — par un exécuteur déterministe. Ça fonctionne de manière assez fluide
L’auteur de cet article n’exagère pas quand il dit que le coût initial est énorme. Traiter toutes les sources possibles de non-déterminisme et réécrire les services sous une forme testable et sans-IO https://sans-io.readthedocs.io/ demande beaucoup d’efforts d’ingénierie
Mais une fois le système en place, il est difficile d’exprimer à quel point on a confiance dans le code. Combiné à des outils comme quickcheck https://github.com/BurntSushi/quickcheck?tab=readme-ov-file#quickcheck, on peut tester des centaines de milliers de cas de défaillance subtils : entrées/sorties, ordre des événements, timeouts, pertes de paquets, pannes du système de fichiers, etc.
Ce type de test est un outil extrêmement puissant à avoir dans sa boîte à outils, si l’on a la patience et la persévérance d’y investir
Antithesis lui-même a l’air vraiment impressionnant. Faire descendre les tests déterministes sous la couche du système d’exploitation est remarquable, et cela semble pouvoir permettre de tester des systèmes entiers sans devoir assembler manuellement un harnais à chaque fois. J’ai hâte de l’essayer
Une grande partie de la complexité que j’ai vue dans ce type de systèmes vient du fait que les appels de « fonctions » sont asynchrones, dépendent du système d’exploitation, peuvent s’exécuter un jour ou ne jamais s’exécuter, renvoient des paquets de chaînes de caractères qu’il faut parser pour revenir dans un système de types statique, et possèdent leurs propres modes de défaillance
La tâche apparemment simple consistant à abstraire la logique dans des composants nommés, c’est-à-dire des fonctions, devient extrêmement complexe
Si l’on garde la logique dans le même processus et qu’on se contente d’appeler des fonctions, il n’est pas nécessaire de tester tous les cas de défaillance subtils mentionnés
Un monolithe n’est pas toujours le bon choix ni toujours adapté, mais je suis très sceptique quant à savoir si la mode actuelle des architectures logicielles basées sur des services est justifiée et si elle en vaut vraiment la peine
Je me demande aussi si des entreprises utilisant Rust développent de cette manière
À noter que TigerBeetle est aussi un produit écrit de cette façon
madsimou des tests de simulation déterministe pour les applications JavaL’article est vraiment passionnant
Pouvoir écrire une phrase comme « programmer dans cet état, c’est comme vivre entouré d’un champ de force qui protège de tous les maux… comme nous avions des bugs, nous avons supprimé toutes nos dépendances, y compris Zookeeper, et en très peu de temps nous avons écrit notre propre implémentation de Paxos, qui n’avait pas de bug », puis l’étayer par des preuves, ce serait franchement classe.
Dans ce livre, l’auteur explique qu’il était tellement frustrant, en résolvant son propre problème, de devoir déboguer le logiciel de quelqu’un d’autre à cause de bugs dans des packages de calcul numérique, qu’il écrit généralement ses propres outils, à l’exception des packages d’algèbre linéaire.
Le point encore plus problématique, selon lui, est que les packages masquent les défauts de formulation du problème. Si l’on donne un système d’équations à un solveur, même s’il est mal conditionné ou comporte une singularité inattendue qui fait diverger la réponse de la réalité physique, il fournit généralement une solution sans se plaindre ; et lorsque tout cela est enfoui dans un gros programme, cela peut pousser à ignorer cette possibilité.
Même lorsqu’on repère un comportement suspect, il est difficile d’entrer dans le package pour creuser le problème ; au final, il faut donc le reprogrammer soi-même. Et si l’on avait fait cela dès le départ, on se serait probablement plongé plus profondément dans la réalité du problème et on aurait éliminé plus tôt les confusions logiques.
En fin de compte, le choix dépend du degré de rigueur de chacun, de celui de la dépendance concernée, et du temps disponible. Je n’écrirais pas ma propre base de données, car c’est trop complexe et il existe beaucoup d’options bien testées. En revanche, si l’on n’utilise qu’une partie des fonctionnalités d’un petit package peu testé, le faire soi-même peut avoir du sens.
Cela dit, je ne prétends pas que ma spécification soit sans bug.
Trois réflexions me viennent.
D’abord, c’est une excellente idée qui arrive au bon moment. Vu l’état d’esprit des développeurs vis-à-vis des fuzzers, du typage statique, de la sûreté mémoire, des protocoles standardisés, des conteneurs, etc., on a l’impression que les gens finissent enfin par perdre patience face aux logiciels instables.
Ensuite, cela semble viser un marché de niche. 2 dollars par CPU et par heure, 7 000 dollars par CPU et par an en réservation, pas de palier gratuit pour les usages hobby ou libres/open source, et il faut prendre contact même pour essayer ou acheter. C’est douloureux, mais c’est un modèle économique valable. Dommage toutefois que cela ne vise pas l’impact positif maximal.
Enfin, la qualité de l’article et de la documentation est élevée, et j’aime beaucoup le fait que la documentation contienne des formulations comme « si un bug est découvert en production ou chez un client, vous devez nous demander des explications ».
C’est exactement comme ça qu’on gagne la sympathie des développeurs. Cela me fait penser à Mullvad, que je continue de recommander aux gens même après qu’ils m’ont déçu par le passé.
Ils l’ont mentionné à ce sujet sur https://news.ycombinator.com/item?id=39358526. À noter que je suis cofondateur d’Antithesis.
Le matériel pourrait commencer lui aussi à ajouter des fonctionnalités pour le prendre en charge, et dans 30 ans, ce sera peut-être simplement la manière dont l’informatique fonctionne.
Mais avant que les pionniers ne le diffusent réellement, ils doivent d’abord récupérer le coût des flèches qu’ils ont reçues en premier. Il faut voir cela non comme un événement isolé, mais comme le début d’un processus.
D’après la documentation, les bugs que cette plateforme est conçue pour trouver sont du genre « non reproductibles », difficiles, qui n’apparaissent que rarement en production.
La plupart des équipes ont des problèmes bien plus gros et des bugs évidents à corriger. En réalité, aujourd’hui, la plupart des logiciels en production ont à peine des tests unitaires.
Je me demande comment les coûts se multiplient dans des cas d’usage réels.
J’ai rencontré Antithesis à Strangeloop cette année et j’ai discuté avec leurs employés ; même comparé à l’état de l’art de l’injection automatique de pannes que je suivais quand je travaillais chez Amazon, ce produit me semble être un énorme bond en avant par rapport à beaucoup de systèmes de vérification formelle utilisés aujourd’hui.
J’ai notamment pu suivre le processus de suivi d’un bug qu’ils avaient trouvé dans Apache Spark Streaming. D’après la documentation, ils avaient découvert une erreur de correction subtile et vicieuse dans une opération courante, un cas limite peu visible qui aurait posé problème pendant des années.
Au final, c’est la documentation qui s’est révélée erronée, mais après avoir vu ce processus, j’ai du mal à imaginer à quel point des outils comme Antithesis deviendront importants dans les entreprises qui construisent des systèmes distribués.
J’espère qu’un billet de blog plus technique et approfondi sortira bientôt. J’aimerais entendre comment ils en sont arrivés à leur approche actuelle.
Je ne veux pas me jeter tout de suite dans un cycle d’attentes surchauffées, mais cela ressemble au Saint Graal. On prend une application existante telle quelle et, en supposant qu’elle soit conteneurisée, il suffit de vérifier des propriétés par-dessus, non ?
Le point qui bloquait toujours, c’était la base de la machine : le CPU et le système d’exploitation non déterministes.
Recréer toute la pile informatique verticale étant pratiquement impossible, ils ont donc contourné le problème en créant un simulateur déterministe de haute fidélité.
Je me demande toutefois comment ils vérifient l’équivalence entre le simulateur et le système d’exploitation existant. Cela n’a pas l’air trivial. Malgré tout, je suis assez convaincu par l’idée.
Ensuite, ils exécutent les tests en injectant toutes sortes de défaillances : pannes du système d’exploitation, problèmes réseau, conditions de concurrence et de timing, problèmes de générateur de nombres aléatoires, etc.
C’est probablement aujourd’hui la seule méthode réellement pratique pour tester ces choses de manière fiable, mais il faut tout de même écrire tous les tests et définir l’état de l’application.
On parle d’une « plateforme qui prend un logiciel et chasse les bugs qu’il contient », mais concrètement, c’est quoi ?
Ça ressemble à un service cloud qui exécute des tests d’intégration. Il faut apparemment trouver comment déployer dans cet environnement particulier, et utiliser des bibliothèques spécifiques pour écrire quand même des tests d’intégration.
Mais même en faisant tout ce refactoring d’intégration, je ne vois pas comment cela permettrait de trouver de vrais bugs que mes propres tests d’intégration, dans mon environnement, n’auraient pas déjà trouvés.
Cela dit, Antithesis ne demande pas de tests manuels ni d’écrire des tests d’intégration.
Il faut empaqueter votre système logiciel dans des conteneurs, ce qui est relativement simple, puis écrire une workload qui imite le fonctionnement normal du système. Par exemple, pour un site d’e-commerce, cela pourrait être consulter des produits, ajouter au panier, payer, etc.
À partir de là, Antithesis exécute la workload, modifie les entrées, injecte des pannes et commence à tester le logiciel pour trouver des violations de propriétés de test.
Plus de 60 propriétés de test sont fournies par défaut, comme les crashes, le manque de mémoire, etc. Pour faire ressortir davantage les problèmes propres à votre système, vous pouvez — et devriez en pratique — définir des propriétés personnalisées.
Pendant l’exécution des tests, les violations de propriétés sont signalées, avec beaucoup d’informations de débogage utiles. Les exécutions de test particulièrement intéressantes peuvent être rembobinées, leurs entrées modifiées, leurs artefacts récupérés, des logs ajoutés, etc., ce qui permet de pousser l’analyse assez loin.
C’est à peu près tout ce que je sais pour l’instant. Je suppose qu’il y a une forme de fuzzing et d’analyse statique, ou une définition des actions que le logiciel peut effectuer.
Honnêtement, cela semble beaucoup recouper ce que le langage Vale cherche à résoudre : https://vale.dev/
Mais au lieu de créer un nouveau langage pour que les nouveaux logiciels aient cet état par défaut, ils semblent plutôt se concentrer sur le fait de rapprocher les logiciels existants de cet état.
À l’aide de l’hyperviseur, ils changent la graine aléatoire, font échouer ou ralentissent des requêtes HTTP, coupent les connexions entre serveurs, modifient l’ordre des réponses des serveurs, etc. — toutes sortes de choses qui arrivent dans la réalité mais qu’on ne contrôle généralement pas.
Ensuite, ils comparent avec la réponse attendue de la workload pour déterminer quelles conditions cassent le système.
C’est pour cela qu’ils vendent ça sous forme de contrat annuel : vous payez pour que vos workloads tournent en continu toute l’année et essaient toutes sortes de combinaisons de pannes.
J’étais très enthousiaste et j’ai parcouru un peu la documentation, mais je ne vois pas bien en quoi cela diffère de tests unitaires randomisés.
Si on a déjà une suite de tests unitaires, j’ai l’impression que cela représente 99 % du travail. Est-ce que je comprends mal ?
C’est la conclusion à laquelle j’arrive après avoir lu la série de démarrage de la documentation, en particulier la section Workloads : https://antithesis.com/docs/getting_started/workload.html
La page How Antithesis Works peut aider à expliquer en quoi ce n’est pas juste un regroupement de tests unitaires : https://antithesis.com/docs/introduction/how_antithesis_works.html
En résumé, les tests unitaires peuvent aider à construire une workload, mais ils ne sont pas indispensables.
Nous explorons de manière autonome les chemins d’exécution d’un système logiciel en introduisant différentes entrées, pannes, etc., et nous découvrons des comportements que l’auteur des tests unitaires n’avait peut-être pas anticipés.
Si vous avez écrit un test pour une fonction qui fait un appel réseau et écrit le résultat sur disque, le test échouera si votre code ne gère pas le cas où l’appel réseau échoue ou se bloque indéfiniment, où l’espace disque vient à manquer, où le courant est coupé juste avant la fermeture du fichier, etc.
Donc oui, c’est bien ça, mais cela étend l’espace testable aussi facilement qu’un test unitaire à un niveau de complexité bien plus intéressant.