Lastentest als CI-Service für Entwickler

Lastentest als CI-Service für Entwickler

Eine der Herausforderungen, mit denen multinationale Softwareanbieter häufig konfrontiert sind, ist die Doppelung der Kompetenzen von Ingenieuren – Entwicklern, Testern und Infrastrukturadministratoren – in fast jedem Team. Dies betrifft auch kostspielige Ingenieure, die Spezialisten für Lasttests sind.

Anstatt sich auf ihre unmittelbaren Aufgaben zu konzentrieren und ihre einzigartigen Erfahrungen für den Aufbau des Lastentestprozesses zu nutzen, bei der Auswahl der Methodik, den optimalen Kennzahlen und dem Schreiben von automatisierten Tests gemäß den Lastprofilen, müssen Ingenieure oft die Testinfrastruktur von Grund auf neu aufbauen, die Lasttestwerkzeuge konfigurieren, diese selbst in CI-Systeme integrieren, das Monitoring einrichten und Berichte veröffentlichen.

Lösungen für einige organisatorische Probleme im Testprozess, die wir in Positive Technologies anwenden, finden Sie in einem anderen Artikel. In diesem Artikel erkläre ich die Möglichkeit, Lasttests in die gesamte CI-Pipeline zu integrieren, mithilfe des Konzepts „Lasttests als Dienst“ (load testing as a service). Sie erfahren, welche Docker-Images für Lastquellen in der CI-Pipeline verwendet werden können; wie Sie Lastquellen mit Hilfe einer Build-Vorlage in Ihr CI-Projekt integrieren; und wie eine Demopipeline für die Durchführung von Lasttests und die Veröffentlichung der Ergebnisse aussieht. Der Artikel könnte nützlich sein für Software-Testingenieure und Automatisierungsingenieure im CI, die über die Architektur ihres Lasttest-Systems nachdenken.

Kernkonzept

Das Konzept von Load Testing as a Service ermöglicht es, Lasttest-Tools wie Apache JMeter, Yandex.Tank und eigene Frameworks in beliebige Continuous Integration-Systeme zu integrieren. Das Demobeispiel wird für GitLab CI gezeigt, doch die Prinzipien sind allgemein für alle CI-Systeme gültig.

Load Testing als Dienst — ist ein zentralisierter Service für Lasttests. Die Lasttests werden in dedizierten Agenten-Pools ausgeführt, die Ergebnisse werden automatisch in GitLab Pages, Influx DB und Grafana oder in Testberichterstattungssysteme (TestRail, ReportPortal usw.) veröffentlicht. Automatisierung und Skalierung werden so einfach wie möglich umgesetzt — durch Hinzufügen und Parametrisieren einer normalen gitlab-ci.yml-Vorlage im GitLab CI-Projekt.

Der Vorteil dieses Ansatzes liegt darin, dass die gesamte CI-Infrastruktur, die Lastagenten, Docker-Images der Lastquellen, Test-Pipelines und die Veröffentlichung der Berichte — von der zentralen Automatisierungsabteilung (DevOps-Ingenieuren) unterstützt werden, während die Lasttestingenieure sich auf die Entwicklung von Tests und die Analyse ihrer Ergebnisse konzentrieren können, ohne sich mit infrastrukturellen Fragen beschäftigen zu müssen.

Um es einfach zu halten, gehen wir davon aus, dass die zu testende Anwendung oder der Server bereits bereitgestellt und konfiguriert sind (dazu können automatisierte Skripte in Python, SaltStack, Ansible usw. verwendet werden). Die gesamte Konzeptualisierung von Lasttests als Dienst lässt sich in drei Phasen unterteilen: Vorbereitung, Testen, Veröffentlichung von Berichten. Weitere Details finden Sie in der Grafik (alle Bilder sind klickbar):

Lastentest als CI-Service für Entwickler

Wichtige Begriffe und Definitionen im Lasttesting

Bei der Durchführung von Lasttests bemühen wir uns um die Einhaltung der Standards und Methodik des ISTQB, verwenden die entsprechenden Begriffe und empfohlenen Metriken. Hier ist eine kurze Liste der grundlegenden Begriffe und Definitionen im Lasttesting.

Lastagent (load agent) — eine virtuelle Maschine, auf der die Anwendung — die Lastquelle (Apache JMeter, Yandex.Tank oder ein maßgeschneiderter Lastmodul) — ausgeführt wird.

Testziel (target) — der Server oder die Anwendung, die auf dem Server installiert ist und der Last ausgesetzt wird.

Testfall (test case) — eine Reihe von parametrisierten Schritten: Aktionen der Benutzer und erwartete Reaktionen auf diese Aktionen, mit festgelegten Netzwerkrequests und -antworten, abhängig von den definierten Parametern.

Profil oder Lastplan (profile) – dafür braucht man 10-mal weniger Hardware. ISTQB-Methodiken (Abschnitt 4.2.4, S. 43) Lastprofile definieren kritische Metriken für den jeweiligen Test und Optionen zur Anpassung der Lastparameter während des Tests. Beispiele für Profile finden Sie im Bild.

Lastentest als CI-Service für Entwickler

Test (test) — ein Szenario mit einem vordefinierten Satz von Parametern.

Testplan (test-plan) — eine Sammlung von Tests und einem Lastprofil.

Testlauf (testrun) — eine Iteration der Ausführung eines Tests mit vollständig ausgeführtem Lastszenario und erhaltenem Bericht.

Netzwerkanfrage (request) — HTTP-Anfrage, die vom Agenten an das Ziel gesendet wird.

Netzwerkantwort (response) — HTTP-Antwort, die vom Ziel an den Agenten gesendet wird.
HTTP-Antwort-Code (HTTP responses status) — Standardantwortcode vom Anwendungsserver.
Transaktion (transaction) — kompletter Zyklus 'Anfrage — Antwort'. Eine Transaktion wird vom Zeitpunkt des Sendens der Anfrage (request) bis zum Abschluss des Erhalts der Antwort (response) betrachtet.

Transaktionsstatus (transactions status) — wurde der Zyklus "Anfrage – Antwort" erfolgreich abgeschlossen? Wenn in diesem Zyklus ein Fehler aufgetreten ist, gilt die gesamte Transaktion als nicht erfolgreich.

Antwortzeit (Latenz) — die Zeit vom Ende der Anfrage (Request) bis zum Beginn des Empfangs der Antwort (Response).

Lastmetriken (Metriken) — definierte Eigenschaften des belasteten Dienstes und des Lastagents während des Lasttests.

Wichtige Metriken zur Messung von Lastparametern

Einige der gebräuchlichsten und in der Methodik empfohlenen ISTQB (S. 36, 52) Metriken sind in der folgenden Tabelle aufgeführt. Ähnliche Metriken für Agent und Ziel sind in einer Zeile angegeben.

Metriken für den Lastagenten
Metriken des Zielsystems oder der Anwendung, die unter Last getestet werden

Anzahl  vCPU und Arbeitsspeicher RAM,
Festplatte — die "Hardware"-Merkmale des Lastagenten
CPU, Speicher, Festplattennutzung — Dynamik der CPU-, Speicher- und Festplattennutzung
während des Tests. Normalerweise in Prozent von
den maximal verfügbaren Werten

Netzwerkdurchsatz (auf dem Lastagenten) — die Bandbreite
des Netzwerkinterfaces auf dem Server,
wo der Lastagent installiert ist.
Normalerweise in Bytes pro Sekunde (bps) gemessen.
Netzwerkdurchsatz(auf Ziel) — Bandbreite des Netzwerkschnittstellens
auf dem Zielserver. Üblicherweise gemessen in Bytes pro Sekunde (bps)

Virtuelle Benutzer— Anzahl der virtuellen Benutzer,
die Lastszenarien ausführen und
reale Benutzeraktionen simulieren
Status der virtuellen Benutzer, Bestanden/Nicht bestanden/Gesamt — Anzahl der erfolgreichen und
nicht erfolgreichen Status der virtuellen Benutzer
für die Lastszenarien sowie deren Gesamtanzahl.

Es wird normalerweise erwartet, dass alle Benutzer ihre
Aufgaben gemäß dem Lastprofil erfolgreich durchführen konnten.
Ein Fehler würde bedeuten, dass auch ein realer Benutzer
seine Aufgabe beim Arbeiten mit dem System nicht lösen kann.

Anfragen pro Sekunde (Minute)— Anzahl der Netzwerkanfragen pro Sekunde (oder Minute).

Ein wichtiges Merkmal des Lastgenerators: wie viele Anfragen er erzeugen kann.
Tatsächlich ist dies eine Simulation eines Zugriffs auf die Anwendung durch virtuelle Benutzer.
Antworten pro Sekunde (Minute)
— Anzahl der Netzwerkantworten pro Sekunde (oder Minute).

Ein wichtiges Merkmal des Zielservices: wie viele Antworten
erzeugt und auf die Anfragen des
Lastgenerators gesendet werden konnten.

HTTP-Antwortstatus— Anzahl der verschiedenen Antwortcodes
vom Anwendungserver, empfangen vom Lastagenten.
Zum Beispiel bedeutet 200 OK einen erfolgreichen Zugriff,
während 404 bedeutet, dass die Ressource nicht gefunden wurde.

Latenz (Reaktionszeit) — die Zeit vom Ende
der Anfrage (request) bis zum Beginn der Antwort (response).
Normalerweise wird sie in Millisekunden (ms) gemessen.

Transaktions-Reaktionszeitist die Zeit einer vollständigen Transaktion,
der Abschluss des Zyklus „Anfrage — Antwort“.
Dies ist die Zeit vom Beginn des Sendens der Anfrage (request)
bis zum Abschluss des Empfangs der Antwort (response).

Die Transaktionszeit kann in Sekunden (oder Minuten) gemessen werden
auf verschiedene Arten: man zählt das Minimum,
Maximum, Durchschnitt und beispielsweise das 90. Perzentil.
Minimale und maximale Messwerte sind die Extremwerte
der Systemleistung.
Das 90. Perzentil wird am häufigsten verwendet,
da es die Mehrheit der Benutzer zeigt,
die komfortabel an der Grenze der Systemleistung arbeiten.

Transaktionen pro Sekunde (Minute) sind die Anzahl der vollständigen
Transaktionen pro Sekunde (Minute),
das heißt, wie viele Anfragen das Programm annehmen konnte
und beantworten konnte.
Tatsächlich ist dies die Durchsatzrate des Systems.

Transaktionsstatus , Bestanden / Gescheitert / Gesamtzahl — Anzahl
erfolgreiche, fehlgeschlagene und insgesamt durchgeführte Transaktionen.

Für echte Nutzer bedeutet eine fehlgeschlagene
Transaktion in der Tat
die Unmöglichkeit, unter Last mit dem System zu arbeiten.

Das grundlegende Schema der Lasttestverfahren

Das grundlegende Schema des Lasttestverfahrens ist sehr einfach und besteht aus drei Hauptphasen, die ich bereits erwähnt habe: Vorbereitung — Test — Bericht, das heißt die Vorbereitung der Testziele und die Festlegung der Parameter für die Lastquellen, gefolgt von der Durchführung der Lasttests und schließlich der Erstellung und Veröffentlichung des Testberichts.

Lastentest als CI-Service für Entwickler

Hinweise zum Schema:

  • QA.Tester — Experte für Lasttests,
  • Ziel — die Zielanwendung, deren Verhalten unter Last untersucht werden soll.

Klassifikator der Entitäten, Phasen und Schritte im Schema

Phasen und Schritte
Was passiert
Was kommt hinein
Was kommt heraus

Vorbereitung: Phase der Vorbereitung auf den Test

LoadParameters
Festlegung und Initialisierung
durch den Benutzer von
Lastparametern,
Auswahl der Metriken und
Vorbereitung des Testplans
(Lastprofil)
Benutzerspezifische Parameter zur
Initialisierung des Lastagenten
Testplan
Testziel

VM
Bereitstellung in der Cloud
virtuellen Maschine mit
den erforderlichen Eigenschaften
VM-Parameter für den Lastagenten
Automatisierungsskripte für
die Erstellung von VMs
Eingestellte VM in
der Cloud

Env
Betriebssystemeinrichtung und Vorbereitung
der Umgebung für
die Arbeit des Lastagenten
Umgebungsparameter für
den Lastagenten
Automatisierungsskripte für
Umgebungseinstellungen
Vorbereitetes Umfeld:
Betriebssystem, Dienste und Anwendungen,
die für den Betrieb erforderlich sind
den Lastagenten

LoadAgents
Installation, Einrichtung und Parametrierung
des Lastagenten.
Oder herunterladen eines Docker-Images mit
einer vorkonfigurierten Lastquelle
Docker-Image der Lastquelle
(JMeter, JM oder benutzerdefiniertes Framework)
Einstellungen zur Konfiguration
den Lastagenten
Eingestellter und betriebsbereiter
Lastagent

Test: Phase der Durchführung von Lasttests. Die Quellen sind Lastagenten, die in dedizierten Agenten-Pools für GitLab CI bereitgestellt werden.

Load
Start des Lastagenten
mit dem ausgewählten Testplan
und den Lastparametern
Benutzerdefinierte Parameter
zur Initialisierung
den Lastagenten
Testplan
Testziel
Ausführungsprotokolle
von Lasttests
Systemprotokolle
Dynamik der Veränderung der Zielmetriken und des Lastagenten

RunAgents
Ausführung des Lastagenten
von Testszenarien
entsprechend
dem Lastprofil
Lastenagent-Interaktion
zum Testen
Testplan
Testziel

Protokolle
Sammlung von «rohen» Protokollen
während des Lasttests:
Aufzeichnungen der Aktionen des Lastenagents,
Zustand des Testziels
und der VM, auf der der Agent läuft

Ausführungsprotokolle
von Lasttests
Systemprotokolle

Metriken
Erhebung von «rohen» Metriken während des Tests

Dynamik der Veränderung der Zielmetriken
und des Lastenagents

Bericht: Vorbereitungsphase des Testberichts

Generator
Verarbeitung der gesammelten
von der Lastsystem- und
Überwachungssoftware „rohe“
Metriken und Protokolle
Erstellung des Berichts in
menschlich lesbare Form,
möglicherweise mit Elementen
der Analyse
Ausführungsprotokolle
von Lasttests
Systemprotokolle
Dynamik der Veränderung der Metriken
des Ziels und des Lastenagents
Verarbeitete „rohe“ Protokolle
in einem Format, das für
den Export in externe Speicher geeignet ist
Statischer Lastbericht,
der für die menschliche Analyse geeignet ist

Veröffentlichen
Veröffentlichung des Berichts
über die Lasttest
in einem externen
Dienst
Verarbeitete „rohe“
Protokolle in einem Format, das für
den Export in externe
Speicher geeignet ist
Gespeicherte Berichte über
Lasten im externen
Speicher, geeignet
für die menschliche Analyse

Anbindung der Lastquellen im CI-Template

Kommen wir zum praktischen Teil. Ich möchte zeigen, wie wir in einigen Projekten bei der Firma Positive Technologies das Konzept des Lasttestings als Service umgesetzt haben.

Zunächst haben unsere DevOps-Ingenieure in GitLab CI einen dedizierten Pool von Agenten für die Durchführung von Lasttests erstellt. Um sie nicht mit anderen Pools, wie zum Beispiel den Build-Pools, zu verwechseln, haben wir diesen Agenten Tags hinzugefügt, tags: load. Es können auch andere verständliche Tags verwendet werden. Diese werden bei der Registrierung von GitLab CI Runners festgelegt.

Wie ermittelt man die erforderliche Hardwarekapazität? Die Spezifikationen der Lasttestagenten – genügend vCPU, RAM und Disk – können auf der Annahme basieren, dass Docker, Python (für Yandex.Tank), der GitLab CI-Agent und Java (für Apache JMeter) auf dem Agenten ausgeführt werden müssen. Für Java unter JMeter wird außerdem empfohlen, mindestens 512 MB RAM zu verwenden und als obere Grenze 80 % des verfügbaren Speichers.

Daher empfehlen wir basierend auf unseren Erfahrungen für Lasttestagenten mindestens: 4 vCPU, 4 GB RAM, 60 GB SSD. Die Bandbreite der Netzwerkkarte wird entsprechend den Anforderungen des Lastprofils festgelegt.

Wir verwenden hauptsächlich zwei Lastquellen – Docker-Images von Apache JMeter und Yandex.Tank.

Yandex.Tank ist ein Open-Source-Tool von Yandex für Lasttests. Seine modulare Architektur basiert auf dem leistungsstarken asynchronen hit-basierten HTTP-Anfrage-Generator Phantom. Der Tank verfügt über integrierte Ressourcenüberwachung des getesteten Servers über das SSH-Protokoll, kann Tests unter bestimmten Bedingungen automatisch stoppen, und die Ergebnisse können sowohl im Konsolenformat als auch grafisch angezeigt werden. Zudem lässt er sich durch eigene Module erweitern. Übrigens, wir haben Yandex.Tank genutzt, als es noch nicht mainstream war. In dem Artikel „Yandex.Tank und die Automatisierung von Lasttestskann man die Geschichte nachlesen, wie wir 2013 mithilfe davon Lasttests durchgeführt haben PT Application Firewall eines unserer Produkte.

Apache JMeter — ist ein Open-Source-Tool für Lasttests der Apache-Software. Es kann sowohl für das Testen von statischen als auch von dynamischen Webanwendungen verwendet werden. JMeter unterstützt eine Vielzahl von Protokollen und Interaktionsmethoden mit Anwendungen: HTTP, HTTPS (Java, NodeJS, PHP, ASP.NET usw.), SOAP / REST Webservices, FTP, TCP, LDAP, SMTP(S), POP3(S) und IMAP(S), Datenbanken über JDBC, es kann Shell-Befehle ausführen und mit Java-Objekten arbeiten. JMeter bietet eine IDE zur Erstellung, Debugging und Ausführung von Testplänen. Es gibt auch eine CLI für die Arbeit in der Kommandozeile jeder mit Java kompatiblen OS (Linux, Windows, Mac OS X). Das Tool kann dynamisch einen HTML-Testbericht generieren.

Zur Erleichterung der Nutzung innerhalb unserer Firma und um den Testern die Möglichkeit zu geben, ihre Umgebung selbst zu ändern und zu erweitern, haben wir Docker-Image-Bauten für Lasttests auf GitLab CI erstellt und in unser internes Docker-Registry auf Artifactory. So wird es schneller und einfacher, sie in Pipelines für Lasttests zu integrieren. Wie man docker push in ein Registry über GitLab CI macht, sehen Sie in der Anleitung.

Die Basis-Docker-Datei für Yandex.Tank haben wir aus diesem:

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

Für Apache JMeter ist dieser:

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

Wie unser kontinuierlicher Integrationsprozess funktioniert, können Sie in dem Artikel „Automatisierung von Entwicklungsprozessen: So haben wir bei Positive Technologies DevOps-Ideen implementiert».

Vorlage und Pipeline

Ein Beispiel für eine Vorlage zum Durchführen von Lasttests ist im Projekt demo-loadIn Im readme-File kann die Anleitung zur Verwendung der Vorlage gelesen werden. In der Vorlage selbst (Datei .gitlab-ci.yml) gibt es Hinweise dazu, wofür jeder Schritt verantwortlich ist.

Die Vorlage ist sehr einfach und zeigt drei Phasen des Lasttests, die oben im Diagramm beschrieben sind: Vorbereitung, Test und Veröffentlichung der Berichte. Dafür sind verantwortlich stages: Prepare, Test und Report.

  1. Phase Prepare sollte zur Vorabkonfiguration der Testziele oder zur Überprüfung ihrer Zugänglichkeit verwendet werden. Die Umgebung für die Lastquellen muss nicht eingerichtet werden, sie sind bereits als Docker-Images erstellt und im Docker-Registry bereitgestellt: es reicht aus, die benötigte Version in der Testphase anzugeben. Es kann jedoch auch möglich sein, diese neu zu erstellen und eigene modifizierte Images zu erstellen.
  2. Phase Test wird verwendet, um die Quelle der Last anzugeben, Tests auszuführen und Testartefakte zu speichern. Jede Lastquelle kann ausgewählt werden: Yandex.Tank, Apache JMeter, eine eigene oder alle zusammen. Um unerwünschte Quellen zu deaktivieren, reicht es aus, die Job-Definition zu kommentieren oder zu entfernen. Einstiegsstellen für Lastquellen:

    Hinweis: Die Vorlage für die Build-Konfiguration wird zur Einrichtung der Interaktion mit dem CI-System verwendet und soll keine Testlogik enthalten. Für Tests wird der Einstiegspunkt angegeben, an dem sich das Steuer-Bash-Skript befindet. Die Art und Weise, wie Tests gestartet werden, die Erstellung von Berichten und die Testskripte selbst müssen von QA-Ingenieuren implementiert werden. Im Demobeispiel wird für beide Lastquellen ein einfacher Test mit einer Anfrage an die Hauptseite von Yandex verwendet. Die Szenarien und Testparameter befinden sich im Verzeichnis ./tests.

  3. In der Phase Bericht Es ist notwendig, die Methoden zur Veröffentlichung der Testergebnisse, die in der Testphase erhalten wurden, in externe Speicherorte zu beschreiben, wie beispielsweise in GitLab Pages oder spezielle Berichtssysteme. Für GitLab Pages ist es erforderlich, dass das Verzeichnis ./public nach Abschluss der Tests nicht leer ist und mindestens die Datei index.html enthält. Über die spezifischen Funktionen von GitLab Pages können Sie hier lesen. über den Link.

    Beispiele, wie man Daten exportiert:

    Anleitungen zur Veröffentlichungseinrichtung:

Im Demobeispiel sieht die Pipeline für Lasttests mit zwei Lastquellen (eine kann deaktiviert werden) folgendermaßen aus:

Lastentest als CI-Service für Entwickler

Apache JMeter kann selbstständig HTML-Berichte erstellen, weshalb es vorteilhaft ist, diese mit integrierten Mitteln in GitLab Pages zu speichern. So sieht der Bericht von Apache JMeter aus:

Lastentest als CI-Service für Entwickler

Im Demobeispiel für Yandex.Tank sehen Sie lediglich einen fiktiven Textbericht im Abschnitt für GitLab Pages. Während des Tests kann Tank die Ergebnisse in eine InfluxDB-Datenbank speichern, und von dort können sie beispielsweise in Grafana angezeigt werden (die Konfiguration erfolgt in der Datei ./tests/example-yandextank-test.yml). So sieht der Bericht von Tank in Grafana aus:

Lastentest als CI-Service für Entwickler

Zusammenfassung

In diesem Artikel habe ich das Konzept des "Lasttests als Service" (load testing as a service) erläutert. Die Hauptidee besteht darin, die Infrastruktur von vorkonfigurierten Pools von Lastagenten, Docker-Images für die Lastquellen, Berichtssysteme und deren zusammenführende Pipeline in GitLab CI anhand einer einfachen .gitlab-ci.yml-Vorlage zu nutzen. über den LinkDas Ganze wird von einem kleinen Team von Automatisierungsingenieuren unterstützt und auf Anfrage der Produktteams bereitgestellt. Ich hoffe, dies hilft Ihnen bei der Vorbereitung und Umsetzung eines ähnlichen Modells in Ihrem Unternehmen. Vielen Dank für Ihre Aufmerksamkeit!

P. S. Ich möchte meinen Kollegen, Sergey Kurbanov und Nikolay Yusev, für die technische Unterstützung bei der Umsetzung des Konzepts "Load Testing as a Service" in unserem Unternehmen herzlich danken.

Autor: Timur Gilmyullin — stellvertretender Leiter der Abteilung Technologie und Entwicklungsprozesse (DevOps) bei Positive Technologies

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster