Trois pistes pour distribuer vos builds
L'objectif du build continu est de fournir aux développeurs un retour sur la qualité du code qu'ils viennent de commiter. Plus ce retour sera fait rapidement, plus il sera efficace. Dans leur présentation à l’Université du Système d’Information intitulée Les nouveaux défis de l’intégration continue, Jérôme Van Der Linden et Philippe Guicheney présentent le build distribué comme une solution aux problématiques de temps de build continu. Le but de cet article est d'approfondir cette notion de build distribué, en:
- Présentant trois concepts de distribution du build
- Positionnant les principaux outils d’intégration continue actuels par rapport à leurs implémentations du build distribué
Dans tout ce qui suivra, on rencontrera à plusieurs reprises les termes suivants :
- Build : Une configuration sur l’outil d’intégration continue servant à construire un projet, à générer sa documentation, à générer des rapports de qualité, etc. Un build peut effectuer une ou plusieurs de ces étapes.
- Agent : Un serveur d’intégration continue secondaire ou esclave du principal. Il reçoit des ordres de build du serveur principal, et se synchronise avec ce dernier à la fin de l’exécution de ces ordres
On peut distinguer plusieurs concepts de distribution des builds d’intégration continue.
Distribuer les builds
Ici, le principe est simple : des agents installés sur d’autres serveurs prennent à leur charge certains builds et fournissent le résultat au serveur principal. Un build constitue ici un élément atomique, et se déroule sur un seul agent :
Les builds sont répartis sur les différents agents selon une politique de distribution prédéfinie, dépendant des outils d’intégration continue. Hudson , Teamcity et Bamboo proposent un mode de distribution manuel, où l’on associe explicitement un job à un agent.
Si aucune assignation manuelle n'est faite:
- Hudson fera en sorte que tous les builds les plus longs (en se basant sur les dernières durées) soit exécutés sur des agents et non sur le serveur principal. Il fera également en sorte que chacun de ces builds soit exécuté sur l'agent où il a été exécuté la dernière fois.
- Teamcity et Bamboo détermineront l' agent libre en premier en se basant sur les anciens temps de build. Ils ajouteront le build sur la file d' attente de ce dernier.
L’intérêt de ce type de distribution n’est pas simplement d'optimiser le temps de lancement d'un build. Il permet aussi de faire ce que l’on appelle du build profilé, où les agents ne sont pas tous configurés de la même façon afin de tester l’application sur différentes plateformes (Systèmes d'exploitations, serveurs d'application,etc.).
Distribuer les modules d'un même build
Il s’agit ici de répartir un même build sur plusieurs agents. Imaginons par exemple le projet maven suivant. Ce projet est composé de trois modules (au sens maven) : A, B et C. Les dépendances suivent le schéma suivant :
A doit être buildé avant B et C, en revanche B et C peuvent être buildés simultanément. On pourrait imaginer que B et C soient buildés sur des agents séparés. Ceci est manuellement faisable avec Maven. En effet, il est possible de déduire l’arbre des dépendances, de builder le projet parent séparément grâce à l’option non-recursive de maven (-N), puis de lancer des builds de chaque module d’une façon isolée des autres, et ce grâce à l’option projects de maven (-pl).
Une telle possibilité n’est pas encore exploitée par les solutions d’intégration continue actuelles. Mais, comme les outils d'intégration continue proposent des builds de type maven2, nous imaginons que ce genre de fonctionnalités va arriver prochainement.
D'ailleurs, Hudson par exemple, pour offrir sa fonctionnalité de build incrémental, effectue déjà lors d'un build la détection des modules maven, ainsi que l'ordre de build. Cette fonctionnalité permet de ne builder que les modules qui ont changé.
Distribuer les tests
Il s’agit ici de distribuer les tests d' un même module sur plusieurs agents différents. Dans son post intitulé Combien de temps doit prendre un build maven , Benoit Lafontaine explique qu'un build doit prendre au maximum 30 secondes + le temps d' exécution des tests. Distribuer les tests permet donc de réduire de manière considérable le temps de build. Quelques frameworks de tests unitaires comme TestNG proposent aujourd’hui de distribuer les tests sur plusieurs agents. TestNG est déjà supporté par Teamcity et Hudson.
Gridgain est un framework open source pour développer des applications java en grille ou sur le cloud. Depuis la version 1.6, gridgain permet également de distribuer des tests JUnit et grâce à une simple annotation (@GridifyTest), vous pouvez distribuer une suite de tests sur les noeuds de la grille Gridgain (un prochain article approfondira ce sujet).
La distribution des tests sur plusieurs agents n’est pas encore implémentée. Un premier pas de l'implémentation de ce type de distribution serait de déclarer les agents d'une façon explicite dans les fichiers de configuration de TestNG ou de Gridgain. Mais nous pouvons imaginer aussi qu'un jour nous aurons une détection automatique des agents disponibles et une configuration à la volée de ces derniers dans les fichiers de configuration Gridgain et TestNG.
Conclusion
Le build distribué doit être une fonctionnalité à prendre en compte dans le choix d'une solution d’intégration continue. Et si le premier concept de distribution est dès aujourd'hui aisé à mettre en oeuvre, car déjà implémenté par la plupart des outils, les deux autres restent encore inexploités, et constituent à n'en pas douter une évolution majeure de l’intégration continue.