Ce post montre avec un exemple concret comment utiliser Docker pour faire un test e2e qui déroule le scénario :

  • Etant donnée une base de données Mysql
  • Un batch alimente la base de données avec un fichier csv
  • Une application REST est déployée telle que son stockage s’appuie la base de données
  • On vérifie que l’api REST permet de consulter les données persistées et d’en ajouter

Pré – requis pour exécuter l’exemple

  • JDK 8 et Maven
  • Sur un hôte non Linux, un moyen rapide pour lancer des container docker en partant de rien est d’installer docker machine et le client docker (l’exemple a été testé sous Mac OS).
  • Démarrer la VM host des container docker et configurer les variables d’environnement pour le client docker (voir doc d’installation docker machine)

Cloner les repos Github du test e2e, sources et configuration

Pour exécuter le test e2e complet, lancer la commande : cd e2etest && source env.sh && ./run.sh


Explication de l’exécution du test phase par phase (build, pré-intégration, test, post-intégration)

Build Maven du batch springbatch-sample et de la restapp spring-boot-sample à partir des sources

  •  mvn clean package

Pré-intégration (voir script docker-run.sh)

  • lancement container docker mysql « mysqldb »
  • exécution dans container « mysqldb » d’un ping mysqladmin à intervalle d’une seconde pour attendre que mysql soit prêt à recevoir des connexions
  • exécution création schémas base de données technique Spring batch et fonctionnelle dans le container « mysqldb »
  • lancement du batch java Spring batch dans le container java8 « java »
  • lancement container java8 « webapp » et démarrage du jar restapp exécutable
  • exécution dans container « webapp » d’une vérification à intervalle d’une seconde que tomcat est disponible sur port 8080

docker-run.sh et explications commandes docker :

docker run --name mysqldb -d -v $work/configuration/:/configuration -v $e2e/pre-integration/:/pre-integration \
 -e MYSQL_USER=mysql -e MYSQL_PASSWORD=mysql -e MYSQL_ROOT_PASSWORD=dba -p 3306:3306 mysql:5.7.7
docker exec mysqldb bash /pre-integration/wait/mysql.sh

docker exec mysqldb bash -c "mysql -u root -pdba < configuration/sql/functional-schema.sql"
docker exec mysqldb bash -c "mysql -u root -pdba < configuration/sql/technical-schema.sql"

batch_name=springbatch-sample
job_name=alimentationJob
job_param=input.file.path=/pre-integration/input/alimentation.csv
docker run --rm -v $work/configuration/:/configuration -v $work/dist/:/dist -v $e2e/pre-integration/:/pre-integration \
 java:8 java -Dbatch.properties.path=file:/configuration/properties/batch.properties -Djob.name=$job_name \
 -jar /dist/$batch_name.jar $job_param \
 > $work/log/batch.log

restapp_name=spring-boot-sample
redirect_log="2>&1 | tee /var/log/restapp.log"
run_restapp="java -jar /dist/$restapp_name.jar --spring.config.location=file:/configuration/properties/application.properties $redirect_log"
docker run --name webapp -d -v $work/configuration/:/configuration -v $work/dist/:/dist -v $work/log/:/var/log \
 -v $e2e/pre-integration/:/pre-integration --expose 8080 -p 8080:8080 \
 java:8 bash -c "$run_restapp"
docker exec webapp bash /pre-integration/wait/tomcat.sh
  • docker run : commande pour lancer les containers « mysqldb », « java » et « webapp »
  • les containers « mysqldb » et « webapp » s’exécutent en fond (mode detached -d)
  • suppression du container « java » après après la fin de l’exécution du batch avec la clause –rm
  • les ressource présentes sur l’hôte sont partagées avec la clause -v (jar, fichiers de conf,..)
  • container « webapp » expose et publie le port 8080 vers le host –expose et -p
  • docker exec lance des scripts bash à l’intérieur du container pour attendre que mysql et tomcat soient up (voir scripts complémentaires d’attente ci-après)

Scripts d’attente

  • démarrage mysql
while [ $(mysqladmin -u root -pdba ping | grep 'mysqld is alive' | wc -l) -ne 1 ] 
do
 sleep 1
 echo -n "."
done
  • démarrage tomcat
while [ $(cat /var/log/restapp.log | grep 'Tomcat started on port' | wc -l) -ne 1 ] 
do
 sleep 1
 echo -n "."
done

Test des ressources REST avec CURL

curl -s http://$host:8080/personnes/search?nom=nom1 2>&1 | tee $work/log/test.log
echo -e "\nSHOULD FOUND 1 personne"
curl -H "Content-Type: application/json" -X POST -d '{"nom":"nom3","prenom":"prenom3"}' http://$host:8080/personnes
curl -H "Content-Type: application/json" -X POST -d '{"nom":"nom3","prenom":"prenom4"}' http://$host:8080/personnes
curl -s http://$host:8080/personnes/search?nom=nom3 2>&1 | tee -a $work/log/test.log
echo -e "\nSHOULD FOUND 2 personnes"
  • une ressource personne telle que nom=nom1 existe déjà suite au lancement du batch
  • 2 ressources personne telles que nom=nom3 sont ajoutées avec succès
  • les 2 ressources personne telles nom=nom3 sont bien récupérées

Post-intégration

  • arrêt et suppression des containers docker
docker stop webbap
docker rm webapp
docker stop mysqldb
docker rm mysqldb

Pour aller plus loin dans l’industrialisation

  • utiliser un repository d’artefacts pour récupérer les jars
  • mapper les phases du test e2e dans les phases standard d’un build Maven
  • le test curl peut être remplacé par un client de test REST basé sur JUnit dans la phase Maven intégration-test
Publicité