Test de charge en tant que service CI pour les développeurs

Test de charge en tant que service CI pour les développeurs

L'un des problèmes auxquels les éditeurs de logiciels multiproduits sont souvent confrontés est la duplication des compétences des ingénieurs (développeurs, testeurs et administrateurs d'infrastructure) dans presque toutes les équipes. Cela s'applique également aux ingénieurs coûteux - spécialistes dans le domaine des tests de charge.

Au lieu de faire leurs tâches directes et d'utiliser leur expérience unique pour construire un processus de test de charge, choisir une méthodologie, des métriques optimales et écrire des autotests conformément aux profils de charge, les ingénieurs doivent souvent déployer une infrastructure de test à partir de zéro, configurer des outils de charge et les intégrer. s'inscrire dans les systèmes d'IC, mettre en place le suivi et la publication des rapports.

Vous pouvez trouver des solutions à certains problèmes d'organisation dans les tests que nous utilisons chez Positive Technologies en un autre article. Et dans celui-ci, je parlerai de la possibilité d'intégrer des tests de charge dans un pipeline commun de CI en utilisant le concept de « test de charge en tant que service » (load testing as a service). Vous apprendrez comment et quelles images Docker des sources de charge peuvent être utilisées dans le pipeline CI ; comment connecter des sources de charge à votre projet CI à l'aide d'un modèle de build ; à quoi ressemble le pipeline de démonstration pour exécuter des tests de charge et publier les résultats. L'article peut être utile aux ingénieurs de test de logiciels et aux ingénieurs en automatisation de CI qui réfléchissent à l'architecture de leur système de charge.

L'essence du concept

Le concept de test de charge en tant que service implique la possibilité d'intégrer les outils de charge Apache JMeter, Yandex.Tank et vos propres frameworks dans un système d'intégration continue arbitraire. La démo sera pour GitLab CI, mais les principes sont communs à tous les systèmes CI.

Le test de charge en tant que service est un service centralisé pour les tests de charge. Les tests de charge sont exécutés dans des pools d'agents dédiés, les résultats sont publiés automatiquement dans les pages GitLab, Influx DB et Grafana ou dans les systèmes de rapport de test (TestRail, ReportPortal, etc.). L'automatisation et la mise à l'échelle sont implémentées aussi simplement que possible - en ajoutant et en paramétrant le modèle gitlab-ci.yml habituel dans le projet GitLab CI.

L'avantage de cette approche est que l'ensemble de l'infrastructure CI, les agents de charge, les images Docker des sources de charge, les pipelines de test et les rapports de publication sont gérés par un service d'automatisation centralisé (ingénieurs DevOps), tandis que les ingénieurs de test de charge peuvent concentrer leurs efforts sur le développement de tests. et l'analyse de leurs résultats, sans traiter des questions d'infrastructure.

Pour simplifier la description, nous supposerons que l'application ou le serveur cible sous test a déjà été déployé et configuré à l'avance (des scripts automatisés en Python, SaltStack, Ansible, etc. peuvent être utilisés pour cela). Ensuite, tout le concept de test de charge en tant que service s'inscrit en trois étapes : préparation, test, publication de rapports. Plus de détails sur le schéma (toutes les images sont cliquables) :

Test de charge en tant que service CI pour les développeurs

Concepts de base et définitions des tests de charge

Lors de la réalisation des tests de charge, nous essayons de respecter Normes et méthodologie ISTQB, utilisez la terminologie appropriée et les mesures recommandées. Je vais donner une courte liste des principaux concepts et définitions des tests de charge.

Chargez l'agent - une machine virtuelle sur laquelle l'application sera lancée - la source de chargement (Apache JMeter, Yandex.Tank ou un module de chargement auto-écrit).

Objectif du test (cible) - serveur ou application installé sur le serveur qui sera soumis à la charge.

Scénario de test (cas de test) - un ensemble d'étapes paramétrées : actions de l'utilisateur et réactions attendues à ces actions, avec des requêtes et des réponses réseau fixes, en fonction des paramètres spécifiés.

Profil ou plan de charge (profil) - dans Méthodologie ISTQB (Section 4.2.4, p. 43) les profils de charge définissent les métriques qui sont critiques pour un test particulier et les options pour modifier les paramètres de charge pendant le test. Vous pouvez voir des exemples de profils dans la figure.

Test de charge en tant que service CI pour les développeurs

Test — un script avec un ensemble prédéterminé de paramètres.

Plan de test (test-plan) - un ensemble de tests et un profil de charge.

Testran (essai) - une itération d'exécution d'un test avec un scénario de charge entièrement exécuté et le rapport reçu.

Demande de réseau (demande) — Une requête HTTP envoyée d'un agent à une cible.

Réponse du réseau (réponse) — Une réponse HTTP envoyée de la cible à l'agent.
Code de réponse HTTP (état des réponses HTTP) - code de réponse standard du serveur d'application.
Une transaction est un cycle complet requête-réponse. Une transaction est comptée depuis le début de l'envoi d'une demande (demande) jusqu'à la fin de la réception d'une réponse (réponse).

État de la transaction - s'il a été possible de mener à bien le cycle demande-réponse. S'il y a eu une erreur dans ce cycle, la transaction entière est considérée comme ayant échoué.

Temps de réponse (latence) - le temps entre la fin de l'envoi d'une requête (request) et le début de la réception d'une réponse (response).

Métriques de chargement — les caractéristiques du service chargé et de l'agent de charge déterminés lors du processus d'essai de charge.

Métriques de base pour mesurer les paramètres de charge

Certains des plus couramment utilisés et recommandés dans la méthodologie ISTQB (p. 36, 52) les mesures sont présentées dans le tableau ci-dessous. Des mesures similaires pour l'agent et la cible sont répertoriées sur la même ligne.

Métriques pour l'agent de charge
Métriques du système cible ou de l'application testée sous charge

nombre  Processeur virtuel et mémoire RAM,
Disque - caractéristiques "fer" de l'agent de charge
Processeur, Mémoire, Utilisation du disque - dynamique du CPU, de la mémoire et du chargement du disque
en cours de test. Habituellement mesuré en pourcentage de
valeurs maximales disponibles

Débit réseau (agent en charge) - débit
interface réseau sur le serveur,
où l'agent de charge est installé.
Habituellement mesuré en octets par seconde (bps)
Débit réseau(sur la cible) - bande passante de l'interface réseau
sur le serveur cible. Habituellement mesuré en octets par seconde (bps)

Utilisateurs virtuels- le nombre d'utilisateurs virtuels,
mettre en œuvre des scénarios de charge et
imitant les actions réelles de l'utilisateur
Statut des utilisateurs virtuels, Succès/Échec/Total — nombre de réussites et
états d'échec des utilisateurs virtuels
pour les scénarios de charge, ainsi que leur nombre total.

On s'attend généralement à ce que tous les utilisateurs aient pu remplir
toutes vos tâches spécifiées dans le profil de charge.
Toute erreur signifiera qu'un utilisateur réel ne pourra pas
résoudre votre problème lorsque vous travaillez avec le système

Requêtes par seconde (minute)- le nombre de requêtes réseau par seconde (ou minute).

Une caractéristique importante d'un agent de charge est le nombre de requêtes qu'il peut générer.
En fait, il s'agit d'une imitation de l'accès à l'application par des utilisateurs virtuels
Réponses par seconde (minute)
- le nombre de réponses réseau par seconde (ou minute).

Une caractéristique importante du service cible : combien
générer et envoyer des réponses aux requêtes avec
agent de chargement

État de la réponse HTTP— nombre de codes de réponse différents
du serveur d'application reçu par l'agent de charge.
Par exemple, 200 OK signifie un appel réussi,
et 404 - que la ressource n'a pas été trouvée

Latence (temps de réponse) - temps depuis la fin
envoyer une requête (request) avant de commencer à recevoir une réponse (response).
Habituellement mesuré en millisecondes (ms)

Temps de réponse des transactions— le temps d'une transaction complète,
l'achèvement du cycle demande-réponse.
C'est le temps depuis le début de l'envoi de la demande (demande)
jusqu'à la fin de la réception d'une réponse (réponse).

Le temps de transaction peut être mesuré en secondes (ou minutes)
de plusieurs façons : considérer le minimum,
maximum, moyenne et, par exemple, le 90e centile.
Les lectures minimales et maximales sont extrêmes
l'état des performances du système.
Le quatre-vingt-dixième centile est le plus couramment utilisé,
comme il le montre la plupart des utilisateurs,
fonctionnant confortablement au seuil de performance du système

Transactions par seconde (minute) - le nombre de complet
transactions par seconde (minute),
c'est-à-dire combien l'application a pu accepter et
traiter les demandes et émettre des réponses.
En fait, c'est le débit du système

État de la transaction , Réussi / Échoué / Total - nombre
réussies, infructueuses et le nombre total de transactions.

Pour les vrais utilisateurs infructueux
la transaction signifiera en fait
incapacité à travailler avec le système sous charge

Diagramme schématique des tests de charge

Le concept de test de charge est très simple et se compose de trois étapes principales, que j'ai déjà mentionnées : Préparer-Test-Rapport, c'est-à-dire préparer les objectifs de test et définir les paramètres des sources de charge, puis exécuter les tests de charge et, à la fin, générer et publier un rapport de test.

Test de charge en tant que service CI pour les développeurs

Remarques schématiques :

  • QA.Tester est un expert des tests de charge,
  • Target est l'application cible dont vous souhaitez connaître le comportement en charge.

Classificateur d'entités, d'étapes et d'étapes dans le diagramme

Étapes et étapes
Ce qui se passe
Qu'y a-t-il à l'entrée
Quelle est la sortie

Préparer : étape de préparation aux tests

ChargerParamètres
Réglage et initialisation
par utilisateur
charger les paramètres,
choix de mesures et
préparation du plan de test
(profil de charge)
Options personnalisées pour
chargement de l'initialisation de l'agent
Plan de test
But du test

VM
Déploiement cloud
machine virtuelle avec
caractéristiques requises
Paramètres de machine virtuelle pour l'agent de chargement
Scripts d'automatisation pour
Création de machine virtuelle
VM configurée dans
nuage

Env
Configuration et préparation du système d'exploitation
environnement pour
charger le travail de l'agent
Paramètres d'environnement pour
agent de charge
Scripts d'automatisation pour
paramètres d'environnement
Environnement préparé :
OS, services et applications,
nécessaire au travail
agent de charge

Agents de chargement
Installation, configuration et paramétrage
agent de chargement.
Ou en téléchargeant une image docker à partir de
source de charge préconfigurée
Charger l'image du menu fixe de la source
(YAT, JM ou cadre auto-écrit)
Réglages
agent de charge
Installé et prêt
agent de charge de travail

Test : étape d'exécution des tests de charge. Les sources sont des agents de charge déployés dans des pools d'agents dédiés pour GitLab CI

Charge
Démarrage de l'agent de chargement
avec plan de test sélectionné
et charger les paramètres
Options utilisateur
pour l'initialisation
agent de charge
Plan de test
But du test
Journaux d'exécution
essais de charge
Journaux système
Dynamique des changements dans les métriques d'objectif et l'agent de charge

Exécuter des agents
Exécution de l'agent
des tas de scripts de test
selon
profil de charge
Charger l'interaction de l'agent
dans le but de tester
Plan de test
But du test

Journaux
Collection de journaux "bruts"
lors des tests de charge :
charger les enregistrements d'activité des agents,
état de la cible de test
et la machine virtuelle exécutant l'agent

Journaux d'exécution
essais de charge
Journaux système

Métrique
Collecte de métriques "brutes" pendant les tests

Dynamique des changements dans les métriques d'objectif
et charger l'agent

Rapport : étape de préparation du rapport de test

Générateur
Traitement collecté
système de chargement et
système de surveillance "brut"
métriques et journaux
Formation d'un rapport en
forme lisible par l'homme
possible avec des éléments
Analystes
Journaux d'exécution
essais de charge
Journaux système
Dynamique des changements de métriques
cibler et charger l'agent
Journaux "bruts" traités
dans un format adapté à
téléchargements vers le stockage externe
Rapport de charge statique,
lisible par l'homme

Publier
Publication du rapport
à propos de la charge
test en externe
service
Transformé "brut"
journaux dans un format approprié
pour le déchargement à l'extérieur
référentiels
Enregistré en externe
rapports de stockage sur
charge, adapté
pour l'analyse humaine

Connexion de sources de chargement dans un modèle de CI

Passons à la partie pratique. Je veux montrer comment sur certains projets dans l'entreprise Technologies positives nous avons implémenté le concept de test de charge en tant que service.

Tout d'abord, avec l'aide de nos ingénieurs DevOps, nous avons créé un pool d'agents dédiés dans GitLab CI pour exécuter des tests de charge. Afin de ne pas les confondre dans les templates avec d'autres, comme les pools d'assemblage, nous avons ajouté des balises à ces agents, étiquettes: charger. Vous pouvez utiliser toute autre balise compréhensible. Ils demandent lors de l'inscription Coureurs GitLab CI.

Comment connaître la puissance requise par le matériel? Les caractéristiques des agents de charge - un nombre suffisant de vCPU, de RAM et de disque - peuvent être calculées sur la base du fait que Docker, Python (pour Yandex.Tank), l'agent GitLab CI, Java (pour Apache JMeter) doivent être exécutés sur l'agent . Pour Java sous JMeter, il est également recommandé d'utiliser un minimum de 512 Mo de RAM et, comme limite supérieure, 80% de mémoire disponible.

Ainsi, sur la base de notre expérience, nous recommandons d'utiliser au moins 4 vCPU, 4 Go de RAM, 60 Go de SSD pour les agents de charge. Le débit de la carte réseau est déterminé en fonction des exigences du profil de charge.

Nous utilisons principalement deux sources de chargement - les images Docker Apache JMeter et Yandex.Tank.

Yandex. Réservoir est un outil open source de Yandex pour les tests de charge. Son architecture modulaire est basée sur le générateur de requêtes HTTP asynchrones hautes performances basé sur les hits de Phantom. Le réservoir a une surveillance intégrée des ressources du serveur sous test via le protocole SSH, peut arrêter automatiquement le test dans des conditions spécifiées, peut afficher les résultats à la fois dans la console et sous forme de graphiques, vous pouvez connecter vos modules pour étendre les fonctionnalités. Au fait, nous avons utilisé le Tank alors qu'il n'était pas encore grand public. Dans l'article "Yandex.Tank et automatisation des tests de charge» vous pouvez lire l'histoire de la façon dont nous avons effectué des tests de charge avec lui en 2013 Pare-feu applicatif PT est l'un des produits de notre société.

Apache JMeter est un outil de test de charge open source d'Apache. Il peut être utilisé aussi bien pour tester des applications Web statiques que dynamiques. JMeter prend en charge un grand nombre de protocoles et de façons d'interagir avec les applications : HTTP, HTTPS (Java, NodeJS, PHP, ASP.NET, etc.), Webservices SOAP / REST, FTP, TCP, LDAP, SMTP(S), POP3( S) ) et IMAP(S), bases de données via JDBC, peuvent exécuter des commandes shell et travailler avec des objets Java. JMeter dispose d'un IDE pour créer, déboguer et exécuter des plans de test. Il existe également une CLI pour le fonctionnement en ligne de commande sur tout système d'exploitation compatible Java (Linux, Windows, Mac OS X). L'outil peut générer dynamiquement un rapport de test HTML.

Pour une facilité d'utilisation au sein de notre entreprise, pour la capacité des testeurs eux-mêmes à changer et ajouter l'environnement, nous avons réalisé des builds d'images docker des load sources sur GitLab CI avec publication à l'interne registre docker chez Artifactory. Cela permet de les connecter plus rapidement et plus facilement dans des pipelines pour les tests de charge. Comment faire docker push vers le registre via GitLab CI - voir instructions.

Nous avons pris ce fichier docker de base pour Yandex.Tank :

Dockerfile 
1 | FROM direvius/yandex-tank
2 | ENTRYPOINT [""]

Et pour Apache JMeter celui-ci :

Dockerfile 
1 | FROM vmarrazzo/jmeter
2 | ENTRYPOINT [""]

Vous pouvez lire comment fonctionne notre système d'intégration continue dans l'article "Automatisation des processus de développement : comment nous avons mis en œuvre les idées DevOps chez Positive Technologies».

Modèle et pipeline

Un exemple de modèle pour effectuer des tests de charge est disponible dans le projet chargement de démonstration. la fichier Lisez-moi Vous pouvez lire les instructions d'utilisation du modèle. Dans le modèle lui-même (fichier .gitlab-ci.yml) il y a des notes sur ce dont chaque étape est responsable.

Le modèle est très simple et illustre les trois étapes du test de charge décrites dans le diagramme ci-dessus : préparation, test et publication des rapports. Responsable de cela étapes: Préparer, tester et rapporter.

  1. Stage Préparer doit être utilisé pour préconfigurer les cibles de test ou vérifier leur disponibilité. L'environnement des sources de charge n'a pas besoin d'être configuré, elles sont pré-construites sous forme d'images Docker et publiées dans le registre Docker : il suffit de spécifier la version souhaitée à l'étape Test. Mais vous pouvez les reconstruire et créer vos propres images modifiées.
  2. Stage Teste utilisé pour spécifier la source de chargement, exécuter des tests et stocker des artefacts de test. Vous pouvez choisir n'importe quelle source de charge : Yandex.Tank, Apache JMeter, la vôtre ou toutes ensemble. Pour désactiver les sources inutiles, il vous suffit de commenter ou de supprimer le travail. Points d'entrée pour les sources de charge :
    • Les paramètres de lancement pour Yandex.Tank sont spécifiés dans le fichier ./tests/yandextank.sh,
    • Les paramètres de démarrage d'Apache JMeter sont spécifiés dans le fichier ./tests/jmeter.sh.

    Remarque : Le modèle de configuration d'assembly est utilisé pour configurer l'interaction avec le système CI et n'implique pas le placement de la logique de test dans celui-ci. Pour les tests, le point d'entrée est spécifié, là où se trouve le script bash de contrôle. La méthode d'exécution des tests, la génération de rapports et les scripts de test eux-mêmes doivent être mis en œuvre par les ingénieurs QA. Dans la démo, pour les deux sources de chargement, la demande de page principale Yandex est utilisée comme test le plus simple. Les scripts et les paramètres de test sont dans le répertoire ./essais.

  3. À l'étape Rapport vous devez décrire comment publier les résultats des tests obtenus à l'étape Test sur des stockages externes, par exemple, sur des pages GitLab ou des systèmes de rapport spéciaux. GitLab Pages exige que le répertoire ./public soit non vide et contienne au moins un fichier index.html une fois les tests terminés. Vous pouvez en savoir plus sur les nuances du service GitLab Pages. lien.

    Exemples d'exportation de données :

    Instructions de configuration de la publication :

Dans l'exemple de démonstration, le pipeline avec des tests de charge et deux sources de charge (vous pouvez désactiver celle qui n'est pas nécessaire) ressemble à ceci :

Test de charge en tant que service CI pour les développeurs

Apache JMeter peut générer lui-même un rapport HTML, il est donc plus rentable de l'enregistrer dans les pages GitLab à l'aide d'outils standard. Voici à quoi ressemble le rapport Apache JMeter :

Test de charge en tant que service CI pour les développeurs

Dans l'exemple de démonstration pour Yandex.Tank, vous ne verrez que faux rapport de texte dans la section des pages GitLab. Pendant les tests, le Tank peut enregistrer les résultats dans la base de données InfluxDB, et à partir de là, ils peuvent être affichés, par exemple, dans Grafana (la configuration se fait dans le fichier ./tests/exemple-yandextank-test.yml). Voici à quoi ressemble le rapport de Tank dans Grafana :

Test de charge en tant que service CI pour les développeurs

Résumé

Dans l'article, j'ai parlé du concept de "load testing as a service" (test de charge en tant que service). L'idée principale est d'utiliser l'infrastructure de pools préconfigurés d'agents de charge, d'images docker de sources de charge, de systèmes de reporting et d'un pipeline qui les combine dans GitLab CI basé sur un simple modèle .gitlab-ci.yml (exemple lien). Tout cela est supporté par une petite équipe d'automaticiens et répliqué à la demande des équipes produits. J'espère que cela vous aidera à préparer et à mettre en œuvre un programme similaire dans votre entreprise. Merci de votre attention!

PS Je tiens à dire un grand merci à mes collègues, Sergey Kurbanov et Nikolai Yusev, pour l'assistance technique à la mise en œuvre du concept de test de charge en tant que service dans notre entreprise.

auteur: Timur Gilmullin - Adjoint Responsable Technologies et Processus de Développement (DevOps) chez Positive Technologies

Source: habr.com

Ajouter un commentaire