L'artisan développeur

Blog de Sébastien Cormier
A la Une Les recettes de l'Artisan Performance

Les recettes de l’artisan : Test de charge Gatling buildé à la Maven

Aujourd’hui nous allons concocter une petite recette facile et rapide : le test de charge Gatling buildé à la Maven. Ce plat accompagnera vos fins de projets afin de pousser en production sereinement.

  • Temps de préparation : 20 minutes
  • Difficulté : Facile

Pré-requis

Pour réaliser cette recette, vous aurez besoin de :

Ne paniquez pas si vous ne connaissez pas Scala ! En effet, cela ne sera pas un gros problème pour mettre en place votre scénario de test. Maven est utilisé dans cette recette, il vous sera bien entendu possible de le remplacer par SBT ou Gradle.

Dans les ustensiles quasi-indispensables, vous aurez besoin d’un IDE pour importer votre projet, tel que IntelliJ ou Eclipse. Enfin, il est conseillé d’utiliser un ou plusieurs serveurs dédiés aux tests de charge pour déployer l’application à tester. Demandez à votre G.O. (Gentil Ops) s’il peut vous fournir une instance pour effectuer votre test de charge. Précisez bien qu’il s’agit d’un stress test pour ne pas le faire paniquer quand vous lancerez votre première charge et que son monitoring passera au rouge.

Pourquoi Gatling ?

Il existe une multitude d’outils pour effectuer des tests de charge. Les plus vieux connaissent probablement JMeter, complet mais compliqué à prendre en main. Je ne connais pas toutes les solutions existantes, mais Gatling est l’un des outils les plus populaires pour ses performances et sa stabilité. De plus, il permet d’enregistrer simplement ses scénarios sous forme de code Scala simplement en les reproduisant dans un navigateur. Il en résulte des scénarios faciles à éditer pour un dévelopeur, et surtout facile à intégrer dans un processus d’Intégration Continue.

Création du projet

Tout d’abord, nous allons créer notre projet à l’aide d’un Archtetype Maven (1). Dans votre répertoire de travail, tapez :

 > mvn archetype:generate

Maven va ensuite vous proposer la liste des Archetypes disponibles. Tapez « gatling » pour filtrer le résultat et sélectionnez l’Archetype correspondant à :

 Choose archetype: 
 1: remote -> io.gatling.highcharts:gatling-highcharts-maven-archetype (gatling-highcharts-maven-archetype)
 > 1

Pour la version, prenez la dernière disponible (la 2.3.0 au moment où j’écris ces lignes). Ensuite, saisissez un groupId et un artifactId. Le groupId correspondra au nom de votre package de base, l’artifactId au nom du projet. Par exemple :

  • groupId: fr.artisandev
  • artifactId : myStressTest

Enfin, pour la version, laissez la valeur par défaut, puis confirmez vos choix. Le projet est ensuite généré, il ne vous reste plus qu’à l’importer dans votre IDE préféré.

Structure du projet Gatling

Enregistrement du scénario

Configuration du Recorder

Le projet est généré avec des fichiers de configurations et 3 classes :

  • Les ressources dans /src/test/resources
  • Les 3 classes dans /src/test/scala

 

Pour créer votre premier scénario de test, exécutez la classe « Recorder ». Avec IntelliJ, un clic droit sur le nom de la classe « Recorder », puis sélectionnez « Run Recorder ».

Le Recorder va ensuite s’afficher. Il s’agit un serveur proxy qui se lancera par défaut sur le port 8000.

Le Recorder Gatling pour enregistrer vos scénarios depuis le navigateur.

Avant de lancer le Recorder, je vous conseille de cliquer sur « No static resources » afin de filtrer les resources statiques (JS, CSS, etc.). En effet, ce qui nous intéresse ici c’est la performance de notre application et non celle du serveur web.

Configuration du serveur Proxy avec Firefox

Ensuite, à partir du navigateur avec lequel vous voulez enregistrer le scénario, allez dans les préférences et configurer le server proxy sur le port 8000 (cf illustration sur la droite).

Enfin, vous pouvez lancer le Recorder en cliquant sur Start!

Exécution du scénario

A partir de là, il vous suffit de dérouler le scénario depuis votre navigateur en navigant sur les différentes pages, en postant des formulaires, etc. Bien évidemment, pensez à démarrer le scénario dans avoir de session active sur votre application (utilisez simplement la navigation privée en cas de doute).

Un mot sur le protocole HTTPS

Le Recorder Gatling est un proxy qui fonctionne aussi en HTTPS. Sachant que Gatling utilise des certificats auto-signés, la première fois que vous vous connecterez via le proxy, un message d’avertissement apparaîtra. Il vous sera possible dans les options avancées de faire une exception pour l’URL en question. Si vous utilisez uniquement le protocole HTTP, vous n’aurez aucun problème.

Edition du scénario

Une fois terminé, revenez au Recorder et stoppez le. Dans le répertoire /src/scala/<votre package>, une classe est apparue . Il s’agit du code source de votre test qui devrait ressembler à cela :


class RecordedPetSore extends Simulation {

val httpProtocol = http
.baseURL("http://computer-database.gatling.io")
.inferHtmlResources(BlackList(""".*\.js""", """.*\.css""", """.*\.gif""", """.*\.jpeg""", """.*\.jpg""", """.*\.ico""", """.*\.woff""", """.*\.(t|o)tf""", """.*\.png"""), WhiteList())
.acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
.acceptEncodingHeader("gzip, deflate")
.acceptLanguageHeader("fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3")
.userAgentHeader("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:57.0) Gecko/20100101 Firefox/57.0")

val headers_0 = Map("Upgrade-Insecure-Requests" -&amp;amp;gt; "1")

val scn = scenario("RecordedPetSore")
.exec(http("request_0")
.get("/computers")
.headers(headers_0))
.pause(5)
.exec(http("request_1")
.get("/computers?f=amstrad")
.headers(headers_0))
.pause(1)
.exec(http("request_2")
.get("/computers/412")
.headers(headers_0))
.pause(8)
.exec(http("request_3")
.post("/computers/412")
.headers(headers_0)
.formParam("name", "Amstrad CPC 6128")
.formParam("introduced", "1984")
.formParam("discontinued", "")
.formParam("company", "38")
.check(status.is(400)))
.pause(9)
.exec(http("request_4")
.post("/computers/412")
.headers(headers_0)
.formParam("name", "Amstrad CPC 6128")
.formParam("introduced", "1984-01-10")
.formParam("discontinued", "")
.formParam("company", "38"))

setUp(scn.inject(atOnceUsers(1))).protocols(httpProtocol)
}

Même si vous n’êtes pas familié avec Scala, vous devriez comprendre la signification des différentes lignes de code.

  1. La variable httpProtocol définit l’URL de base ainsi que les en-têtes utilisés pour toutes les requêtes.
  2. La variable scn est la description du scénario avec les différentes requêtes GET ou POST, les paramètres de formulaires ainsi que les temps de pause en secondes.
  3. Le setUp qui injecte un utilisateur au scénario « scn« 

Chaque requête étant nommée de façon incrémentale (request_0, request_1, etc.), il est préférable de leur donner un nom explicite pour générer un rapport d’exécution plus lisible.

Enfin, il faut modifiez le nombre d’utilisateurs pour simuler la charge désirée (atOnceUsers(1)). Pour éviter d’écrouler votre serveur en lançant toutes les connexions au même moment (ce qui ne serait pas réaliste), vous pouvez les étaler dans le temps. Par exemple, pour 100 utilisateurs se connectant sur une période de 10 secondes :

setUp(scn.inject(rampUsers (100) over (10 seconds))).protocols(httpProtocol)

Lancement du test

Nous arrivons au bout des 20 minutes, il est maintenant grand temps de lancer notre test. Ce dernier peut-être exécuter directement depuis l’IDE en exécutant la classe « Engine » (à coté du Recorder).

Dans la console de votre IDE, vous serez invité à choisir votre scénario et à saisir une description (optionnel). Une fois validé, vous n’avez plus qu’à attendre que le test se déroule.

A la fin du test, un rapport HTML complet sera généré. Il vous sera possible de visualiser le détail par requête (d’où l’intérêt de les renommer).

Exemple de rapport Gatling

Conclusion

Ceci est bien évidemment un petit aperçu de ce qu’il est possible de faire avec Gatling. Il s’inspire de l’exemple « Quickstart » du site officiel. Je vous invite donc à aller un peu plus loin avec le tutoriel avancé :

Vous y apprendrez à combiner différents profils d’utilisateurs déroulant un scénario différents, paramétrer vos requêtes, gérer les cas d’erreurs, etc.

Je vous souhaite une bonne mise en production, et à bientôt pour de nouvelles recettes !


(1) Un Maven Archetype est un système de template proposé par Maven permettant de simplifier le démarrage d’un projet

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.