précédent article, Meriem Berkane introduisait le build distribué et notamment la distribution des tests sur des agents. TestNG propose cette fonctionnalité de base, JUnit par contre ne le fait pas. Mais Gridgain vient combler ce manque depuis sa version 1.6. Dans cet article, je vais donc mettre en oeuvre Gridgain dans un build Maven afin de pouvoir, par la suite, l'utiliser sur le serveur d'intégration continue.
Gridgain est un framework open source permettant de développer des applications java en cloud ou en grille. Basé sur des annotations, il permet depuis la version 1.6 de distribuer les tests :
public class GridTests extends TestSuite {
@GridifyTest
public static Test suite()
{
TestSuite suite = new TestSuite("Test for com.octo.gridgain");
suite.addTestSuite(ClientDaoTest.class);
// ...
}
}
L'annotation @GridifyTest
permet d'exécuter la suite de tests sur la grille. Si vous n'aimez pas les annotations, vous pouvez utiliser GridJunit3TestSuite
au lieu de la simple TestSuite
.
C'est censé fonctionner avec JUnit 4 également (GridJunit4Suite
) mais j'ai essuyé quelques exceptions m'empêchant d'aller au bout...
Le code et les tests sont envoyés sur chaque nœud automatiquement selon l'algorithme Round Robin. Vous pouvez également réécrire votre méthode de répartition.
Alors bien sûr, ce n’est pas magique et pour distribuer les tests, il faut bien un ou des nœuds sur lesquels les distribuer. Plusieurs possibilités :
Gridgain peut découvrir les nœuds faisant partie de la grille grâce au mécanisme d'IP multicast. Ça simplifie beaucoup le travail, gridgain se charge de soumettre les paquets et toute machine capable de les recevoir (gridgain installé) se verra remettre des tests à exécuter.
Une fois l'infrastructure prête, plusieurs choses restent à configurer pour exécuter les tests. Et plutôt que de le faire dans Eclipse comme la vidéo d'exemple le montre, je l'ai fait dans Maven (toujours dans l'optique de mon build continu)...
Avant de rentrer dans les détails techniques, quelques généralités. Tout d'abord, les dépendances de build :
<repositories>
<repository>
<id>gridgain</id>
<name>GridGain Repository</name>
<url>http://www.gridgainsystems.com/maven2/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<dependencies>
<dependency>
<groupid>junit</groupid>
<artifactid>junit</artifactid>
<version>4.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupid>org.gridgain</groupid>
<artifactid>gridgain</artifactid>
<version>2.1.1</version>
<scope>test</scope>
</dependency>
</dependencies>
Il faut ajouter le repo gridgain car les dépendances ne sont pour le moment pas dans le repo central.
Compilation en 1.5 pour le support des annotations :
<build>
<plugins>
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-compiler-plugin</artifactid>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<!-- ... -->
</plugins>
</build>
<properties>
<aspectjweaverversion>1.6.4</aspectjweaverversion>
</properties>
<build>
<plugins>
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-surefire-plugin</artifactid>
<version>2.4</version>
<configuration>
<!-- (1) -->
<includes>
<include>**/*GridTests.java</include>
</includes>
<!-- (2) -->
<argline>-javaagent:${project.build.directory}/libs/aspectjweaver-${aspectjweaverversion}.jar</argline>
<workingdirectory>${project.build.directory}/libs/</workingdirectory>
</configuration>
</plugin>
<!-- (3) -->
<plugin>
<groupid>org.apache.maven.plugins</groupid>
<artifactid>maven-dependency-plugin</artifactid>
<executions>
<execution>
<id>copy</id>
<phase>process-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactitems>
<artifactitem>
<groupid>org.aspectj</groupid>
<artifactid>aspectjweaver</artifactid>
<version>${aspectjweaver-version}</version>
<outputdirectory>${project.build.directory}/libs/</outputdirectory>
</artifactitem>
</artifactitems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Un point important qu'on ne voit pas dans le pom est la présence du META-INF/aop.xml (disponible dans gridgain-x.x.x/config/aop/aspectj/) dans les ressources du projet (src/test/resources). Effectivement ce répertoire doit être dans le classpath. Il permet de sélectionner les portions de code qui seront tissés et donc susceptibles d'être exécutées sur la grille gridgain.
Comme je le disais plus haut, il faut utiliser le .bat pour simuler des nœuds ou avoir une vraie grille. Ensuite, depuis votre projet maven, lancez simplement un mvn test -DGRID_ROUTER_PREFER_REMOTE=true
Running com.octo.gridgain.GridTests [00:56:01,906][INFO ][main][GridKernal%junit] _____ _ _ _____ _ / ____| (_) | |/ ____| (_) | | __ _ __ _ __| | | __ __ _ _ _ __ | | |_ | '__| |/ _` | | |_ |/ _` | | '_ \ | |__| | | | | (_| | |__| | (_| | | | | | \_____|_| |_|\__,_|\_____|\__,_|_|_| |_|
...
[INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------
Et voilà ! On a un build Maven qui exécute les tests en parallèle sur plusieurs nœuds (dans les logs jboss ou sur la console du bat, vous pouvez voir les tests exécutés par le nœud en question).
Écrire des tests, c'est bien... Les exécuter, c'est mieux ! Et donc si vous avez arrêté de les exécuter car vous êtes perpétuellement en train d'attendre qu'ils soient terminés, gridgain peut vous aider en répartissant l'exécution sur une grille.
Je ne l'ai pas précisé avant mais il va de soit que les tests doivent être le plus unitaires, optimisés et indépendants possibles. Donc dans un premier temps, envisagez d'optimiser vos tests, et si les problèmes persistent, songez à gridgain et gardez en tête que les tests ne doivent pas être dépendants.
Sur l'intégration continue, cela peut également être utile pour alléger la charge sur le serveur. L'idéal serait de pouvoir combiner cette fonctionnalité avec les possibilités de build distribué fournies par les principaux acteurs du marché (Teamcity, Hudson, ...) et ainsi lancer les tests sur les agents déjà configurés. Mais pour peu que le réseau soit capable de gérer l'IP Multicast (sur du LAN de préférence), vous devriez déjà pouvoir distribuer les tests sur différents nœuds en laissant Gridgain découvrir les noeuds participants à la grille...