Présentation de the grinder et test de charge d'une application play!
Introduction
The grinder est un framework java Open source (BSD) de test de charge.
Il permet de tester tout ce qui possède une API java :
- Serveur HTTP : SOAP, REST,
- Serveur FTP, POP3, SMTP, LDAP,
- Serveur d’application : RMI, EJB, JMS, JDBC,
Il permet de réaliser les types de tests suivants :
- Test de charge : permet de vérifier que l’application peut supporter une charge donnée,
- Test de capacité : permet de connaître la charge maximale supportée par l’application avant l’apparition d’erreurs,
- Test fonctionnel : vérifie le comportement fonctionnel de l’application, dans ce cas, on fait des assertions sur le résultat attendu,
- Test de stress : application d’une charge donnée pendant un longue durée, cela permet de vérifier la stabilité et fiabilité de l’application
Dans cet article nous allons présenter the grinder, ses concepts, son installation et sa mise en place sur une application play!
Composants de grinder

La console controle les worker process par l’intermédiaire d’agents et affiche les statistiques à l’utilisateur.
Les agents sont en charge de piloter un ou plusieurs worker processes via des scripts écrits en jython. Les agents peuvent être repartis sur plusieurs machines physiques lors de fortes montée en charge.
Les workers process injectent la charge au système évalué et remontent des informations statistiques à la console. La console agrège alors ces données et les présente à l’utilisateur par l’intermédiaire de son interface.
Quelques projets intéressants autour de the grinder
- Grinder plugin pour hudson : Ce plugin va exécuter le test de charge pendant le build et va présenter dans le rapport hudson les métriques obtenus.
- Grinder stone : plugin eclipse permettant d'écrire le script the grinder, il permet entre autre de lancer des sessions de debugging sur les scripts et de faire du pas à pas lors de son exécution.
the grinder VS JMeter
Je mets en place de temps en temps des tests de charge avec Jmeter. A chaque fois, ce n’est pas avec un grand enthousiasme car je ne suis pas un gran fan de son interface et des nombreux étapes de configuration, entre les échantillons, récepteurs et les nombreuses options de configuration, un temps d’adaptation est nécessaire. Une sorte de gros XML est alors généré, contenant l’ensemble de la configuration effectuée, mais on ne le modifie jamais directement.
Avec the grinder, le script est la base du travail. Un développeur s’y sent tout de suite à son aise, même si le fait de passer par python est un petit inconvénient. La console est assez simple à utiliser une fois que l’on connait la différence entre la console, les agents et les process. On obtient donc au final, un script python qui peut facilement être associé et versionné avec le code source de l’application. Grinder stone associé à PyDev permet d'éditer son script avec Eclipse. Et last but not least, de debugger son script et même d’y faire du pas à pas.
Installation
Pour installer the grinder, je vous invite à lire le Getting started de the grinder.
J’ai du cepepdant modifier légèrement les scripts de lancement pour ne plus avoir d’outOfMemory error :
#startConsole.sh java -Xmx1024m -cp $CLASSPATH net.grinder.Console
#startAgent.sh java -Xmx1024m -cp $CLASSPATH net.grinder.Grinder $GRINDERPROPERTIES
Configuration
Voici le fichier grinder.properties que j’ai utilisé
#Indique l'emplacement du script jython de test de charge grinder.script = http.py # The number of worker processes each agent should start grinder.processes = 5 # The number of worker threads each worker process should start. grinder.threads = 3 # The number of runs each worker process will perform. When using the # console this is usually set to 0, meaning "run until the console # sneds a stop or reset signal". The default is 1. grinder.runs = 100 grinder.logDirectory = log grinder.numberOfOldLogs = 1
Anatomie d’un script
Le script doit définir une classe TestRunner
class TestRunner:
Un test est ensuite identifié par un numéro unique et une description, exemple :
#Crée un test avec un numéro (1) et une description test1 = Test(1, "Un test")
Il faut ensuite créer une requête sur une url
requestHome=HTTPRequest(url="http://localhost:9000/")
Il faut ensuite associer le test à la requête en le wrappant
requestHome = test1.wrap(requestHome)
On peut également faire le tout en une seule ligne de commande :
requestHome = Test(1, 'Un test').wrap(HTTPRequest(url="http://localhost:9000/"))
Il faut ensuite faire l’appel HTTP
requestHome.GET()
Ci dessous, le script complet de test de l’application play! yabe
#import
from net.grinder.script import Test
from net.grinder.plugin.http import HTTPPluginControl,HTTPRequest
from HTTPClient import NVPair
# Parse global parameters.
control = HTTPPluginControl.getConnectionDefaults()
control.setFollowRedirects(1)
#Définition des URL et requete
SERVER = "http://localhost:9000/"
homeUrl=SERVER
requestHome=HTTPRequest(url=homeUrl)
requestHome = Test(101, 'Page d accueuil').wrap(requestHome)
articleUnUrl=SERVER+'posts/1'
requestArticleUn = HTTPRequest(url=articleUnUrl)
requestArticleUn = Test(102, 'Article').wrap(requestArticleUn)
authentificationUrl=SERVER+'login'
requestAuthentification = HTTPRequest(url=authentificationUrl)
requestAuthentification = Test(103, 'Authentification').wrap(requestAuthentification)
#Création de la classe
class TestRunner:
def __call__(self):
self.home()
self.articleUn()
self.authentification()
#Test de home
def home(self):
requestHome.GET()
#Test d'un article
def articleUn(self):
requestArticleUn.GET()
#Test de l'authent
def authentification(self):
authenticationFormData = ( NVPair("username", "bob@gmail.com"), NVPair("password", "secret"))
requestAuthentification.POST(authenticationFormData)
Métrique obtenus sur l’application yabe de playframework

Conclusion
Une fois la barrière du langage python passée, on se rend compte que l'écriture d’un script pour the grinder est très simple, surtout si l’on s’aide eclipse (PyDev), et de grinderStone.
Lorsque l’on développe un script on bénéficie de la puissance du language pour faire des assertions sur les résultats. Dans le cas d’une application JSF, il sera d’autant plus simple d’extraire le viewState.
Pour ceux qui veulent enregistrer un scénario directement avece leur navigateur, cette option est aussi disponible avec le proxy de the grinder.
Désormais si j’ai le choix entre mettre en place un test de charge avec soit jmeter ou the grinder, mon choix se portera sur cet outil.
Je vous encourage à lui donner une chance, et trouver ainsi une alternative à jmeter.