Tests de performances (partie 1/2) : préparation et analyse

Test de performances Certains acteurs dans le développement se demandent quelle approche employer avec les tests de performances. Pourtant, dans un cadre de gestion de projet en cycle en V ou en mode Agile, une campagne de tests de performances peut être considérée comme un projet classique, un projet qui dépend du projet d’implémentation. Nous comprenons alors que la première contrainte d’un projet de tests de performances est le calendrier prévisionnel. D’un côté, il faut prévoir à l’avance une plage afin de préparer les scénarios de tests et les machines associées, s’assurer qu’une équipe sera disponible pour effectuer le test et, de l’autre, il faudra attendre que le projet d’implémentation soit assez avancé afin d’avoir un ensemble cohérent à tester.
Nous verrons durant cet article la démarche à entreprendre pour déterminer le besoin des tests de performances ainsi que l’architecture et les scénarios appropriés, les types de performance, l’automatisation des lancements de tirs et enfin l’analyse des résultats.

Pourquoi un test de performance?

Toujours se poser d’abord la question « pourquoi ? » en premier lieu.

Rédiger la réponse à cette question et partager les finalités du test avec tous les acteurs sont des étapes nécessaires.

Un exemple de finalité est son usage ultérieur :

  • Contrôle qualité, Marketing
    • Quels sont nos temps de réponses ?
    • Sommes-nous conformes au SLA « Service Level Agreement » ?
    • Sommes-nous comparables ou mieux que nos concurrents ?
  • Conception
    • Les dernières évolutions livrées ont-elles impacté les performances ?

Quel type de test de performance?

Quel type de performance répondrait mieux à la question précédente (à savoir « pourquoi ») ?

  • Test de charge : « test au cours duquel on va simuler un nombre d’utilisateurs virtuels prédéfinis, afin de valider l’application pour une charge attendue d’utilisateurs »
  • Test de performance : « la différence avec le type précédent réside dans le fait qu’on ne cherche pas ici à valider les performances pour la charge attendue en production, mais plutôt vérifier les performances intrinsèques à différents niveaux de charge d’utilisateurs. »
  • Test de dégradations des transactions : « test technique primordial au cours duquel on ne va simuler que l’activité transactionnelle d’un seul scénario fonctionnel parmi tous les scénarios du périmètre des tests, de manière à déterminer quelle charge le système est capable de supporter pour chaque scénario fonctionnel et d’isoler éventuellement les transactions qui dégradent le plus l’ensemble du système. »
  • Test de stress : « test au cours duquel on va simuler l’activité maximale attendue tous scénarios fonctionnels confondus en heures de pointe de l’application, pour voir comment le système réagit au maximum de l’activité attendue des utilisateurs »
  • Test de robustesse, d’endurance, de fiabilité : « tests au cours duquel on va simuler une charge importante d’utilisateurs sur une durée relativement longue, pour voir si le système testé est capable de supporter une activité intense sur une longue période sans dégradations des performances et des ressources applicatives ou système »
  • Test de capacité, test de montée en charge : « test au cours duquel on va simuler un nombre d’utilisateurs sans cesse croissant de manière à déterminer quelle charge limite le système est capable de supporter »
  • Test aux limites : « test au cours duquel on va simuler en général une activité bien supérieure à l’activité normale, pour voir comment le système réagit aux limites du modèle d’usage de l’application »

La définition du type est structurante pour la suite et est souvent négligé. Par exemple, tel test de stress exigerait une certitude sur le nombre d’appels simultanés (multi-threadés) tandis que tel autre test de charge impliquerait plutôt de simuler une vraie population (appels désynchronisés).

Quelles sont les contraintes spécifiques de l’architecture testée ?

Y a-t-il des contraintes d’architecture qui influent sur le comportement de l’application à tester ? Si tel est le cas, il faut reporter ce point dans l’environnement de test. Par exemple, si l’architecture cible contient un Load-Balancer avec N conteneurs web, s’il existe un cache distribué, … ces facteurs sont certainement impactants sur les tests. Il est souvent d’usage d’avoir un environnement de benchmark proche de celui de la pré-production, ce qui se traduit dans la plupart des cas à avoir un même environnement pour des usages différents !

Définition des scénarios

Rédaction du scénario pas à pas
En parallèle de la mise en place de l’infrastructure, des scénarios de tests doivent être rédigés. Ces derniers doivent être communiqués et partagés par tous les acteurs du projet.

Le pas à pas doit tout le temps répondre au « pourquoi ? » de départ. Le risque étant de basculer, par exemple, d’un test aux limites à du test de non régression !

Dans un premier temps il est conseillé de démarrer avec un scénario simplifié afin de valider globalement la cohérence du test, puis ensuite de détailler de plus en plus les étapes.

Optimisation des tirs

Rendre le tir le plus réaliste possible
Souvent la finalité implique que le test simule un pic de charge, une population utilisant de manière asynchrone l’application. Rendre un test réaliste n’est pas simple. Parfois, ajouter des temps d’attente aléatoires suffit mais si les requêtes à tester ont des temps de réponses très rapides, on sera vite confronté à des questions métaphysiques. Par exemple : est-on vraiment en train de tester l’application ou bien juste la robustesse du hardware ? Ce type de questions est légitime dans un test de charge et le seul moyen concret de répondre sereinement à cette question est un monitoring du hardware et de l’application. Pour de plus amples informations sur les outils de monitoring, vous pouvez consulter cet article.

Planification des montées en charge et les paliers de montées de charge
La montée en charge (simulation d’un nombre d’utilisateurs croissant) doit être adaptée au scénario et aux données à sonder. Les facteurs impactants étant :

  • La durée d’initialisation des données (initialisation d’un contexte ou tout autre paramétrage avant de lancer le test de performance lui-même) dépendante de la capacité de l’infrastructure : cette durée sera différente suivant les capacités des machines (RAM, Processeur, etc.)
  • Le nombre d’utilisateurs (Threads) par seconde attendu : suivant le type de test implémenté, ce nombre sera approximatif (simulation d’une population réaliste) ou bien il sera rigoureusement déterminé (un tir robuste permettant de garantir N Threads par seconde).

Mise en place de la plateforme de tests

Comme on l’a vu, la plateforme doit comporter les contraintes de l’environnement de production (cache distribué, Load-Balancer, …). Le choix de la plateforme dépend aussi des contraintes de la DSI. Les tests de performances doivent être effectués régulièrement afin d’avoir le plus de prises de mesures possible.

Automatisation d’une campagne de tests

Le modèle de Cloud Computing est bien adapté aux tests de performances avec la possibilité d’automatiser la mise en place de la plateforme, du lancement des tests. Nous verrons dans un prochain article un exemple de tests de performances avec des tests de charge distribués.

Les étapes d’automatisation sont celles-ci :

  • Lancement des machines:
    • Serveur(s) contenant l’application testée : capacité et contenu réalistes
    • Contrôleur : orchestrateur des scénarios de tirs
    • Injecteurs : N instances (le nombre dépend du scénario et du type de tests), pilotées par le contrôleur, lançant le scénario de test et accédant au(x) serveur(s) de l’application
    • Monitoring : sondes de supervision et de monitoring paramétrées et activées pour tous les types de machines, à savoir contrôleur, injecteurs, serveur(s) de l’application
  • Récupération des derniers livrables à partir d’un gestionnaire de sources et mise à jour du ou des serveurs de l’application
  • Lancement des scénarios de tests
  • Récupération des résultats de tests
  • Arrêt des machines

L’automatisation devra comprendre la possibilité de modifier aisément les paramètres d’environnement, la taille et le nombre des instances, le nombre de threads, … et autres variables du scénario. Il est important de dynamiser le lancement suivant le besoin des tests.

Analyse des résultats et Reporting

Vérification de cohérence du tir
Une fois une campagne terminée, le résultat doit être consolidé afin de répondre aux finalités attendues (le fameux « pourquoi ? » initial). Les outils de monitoring permettront de valider la cohérence des résultats. Par exemple, si les indicateurs réseau paraissent saturés, il se peut qu’ils aient impacté les temps de réponse; auquel cas, nous ne serions pas réellement en train de tester la performance de notre application mais plutôt la capacité réseau de l’environnement. Il faudrait donc revoir le scénario et les paramétrages système.

Optimisation et ré essai
Un premier tir nécessite souvent des réajustements (nombre de threads à modifier, temps de montée en charge insuffisant, paliers trop courts, etc.). Il est intéressant de démarrer une courte campagne afin de voir si le résultat répond aux attentes avant de lancer une campagne plus longue.

Consolidation des résultats
Les résultats peuvent être présentés sous forme d’un ensemble de données rapprochées (tableaux croisés dynamiques) ou bien certains outils de benchmarks proposent des consolidations. Afin de ne pas courir de risque de dégrader les performances à cause de calculs qui ne sont pas en rapport avec les fonctionnalités à tester, il est préférable d’éviter d’effectuer ce type de traitement à la volée durant le test et de récupérer des résultats bruts que vous pourrez exploiter ultérieurement. Evidemment, le format du rapport consolidé devrait être défini avant l’implémentation du test (découle du « pourquoi ? ») :

  • pour les courbes : les abscisses et les ordonnées attendues
  • pour les tableaux : les lignes et les colonnes attendues

Rédaction d’un rapport de résultats
Un rapport devrait illustrer le résultat. Celui-ci contiendrait

  • une consolidation des métriques (courbes et tableaux)
  • des alertes et des diagnostics
  • une comparaison avec la campagne N-1

Conclusion

Le test de performances suit moins des règles établies que des bonnes pratiques. La première étant de ne pas démarrer le chantier avant d’avoir un but clair : sur toutes les étapes du projet de test, se reposer la question initiale « pourquoi ? », « Quelle était notre finalité initiale ? ».

« Learn to live with unpredictable behavior »: l’infrastructure d’aujourd’hui est devenue trop complexe pour que nous puissions préjuger d’un résultat en termes de qualité de service sans tester concrètement. Voir la présentation de Joshua Bloch (« Performance Anxiety »).

« In Java, run VM 30 times to get meaningful data » (George Buytaert and Eackhout). « The problem doesn’t go away if you use C or C++ » (Mytkowicz and Diwan). Il n’est pas exclu de trouver d’une campagne à une autre des chiffres différents sans que l’application ou la configuration (système, réseau, …) du test soit en cause. Les tests de performances doivent être réguliers et comparatifs.

Une campagne de tests de performances ne doit pas remplacer des tests de non régression.

Il faut minimiser les calculs durant le tir : la plupart des calculs pourront être effectués à posteriori. Privilégiez aussi les scénarios les plus simples.

Le code ne doit pas être optimisé trop tôt : les résultats des campagnes de tests de performances servent aussi à savoir quelles sont les optimisations les plus impactantes. De plus en plus de projets s’organisent aussi avec des tests de performances inclus dans les cycles de livraisons et d’intégration continue.

Dans un second article je vous présenterai un cas pratique avec la configuration associée.

Mahyar SEPEHR @Ysance

4 commentaires pour Tests de performances (partie 1/2) : préparation et analyse

  • [...] Post Interessant sur les tests de charges J'aime ceci:J'aimeSoyez le premier à aimer ceci. [...]

  • fidoteam

    Post intéressent, néanmoins vous avez, à mon avis,oublié l’aspect donnée (volumétrie mort et jeu de donnée utile) ainsi que l’aspect hypothèse de charge qui permettent de calibrer les tir afin d’être le plus réaliste que possible dans la simulation proposée.

    d’après mon retour d’expérience (six ans dans le domaine des perfs) , la source des goulots d’étranglement sont dans la majorité des cas applicatifs. étant donnée ce constat, les outils de supervision de la plateforme ne sont pas nécessaire à ce stade, ce qui doit être mis en place est un monitoring de la JVM (application) via des outils livrés par les serveurs d’applications ou outils livré avec les JVM.

  • Bonjour !

    Concernant la « supervision » et plus précisément la métrologie de la plateforme, même si il est vrai que dans la majorité des cas le problème est applicatif puisque c’est principalement le développement que l’on teste, il ne faut pas oublier qu’il n’y a pas que des développements JAVA : par exemple, pour tester une application PHP, outre les outils type XDebug qui permettent de faire du profiling (donc test de performance sur requête unitaire), il est nécessaire pour des tests de charge de placer des sondes au niveau Apache (par exemple) et système.

  • Bonjour.
    Je partage le point de vue de @FredericFaure sur le monitoring. Pour avoir testé sans, on se retrouve souvent à vouloir connaître la part de lecture/écriture système, des statistiques sur l’évolution de load average etc. Cela dit, @fidoteam a raison de bien souligner l’importance du monitoring de la JVM.
    Enfin, l’hypothèse de charge devra être compris dans le document décrivant le but des tests (le « pourquoi »).

Répondre

 

 

 

Vous pouvez utiliser ces balises HTML

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>