
Jedním z problémů, s nimiž se často setkávají multi-produktoví dodavatelé softwaru, je duplicita kompetencí inženýrů — vývojářů, testerů a administrátorů infrastruktury — téměř v každém týmu. To se týká také drahých inženýrů — specialistů na zátěžové testování.
Místo toho, aby se věnovali svým přímým povinnostem a využívali své jedinečné zkušenosti k budování procesu zátěžového testování, výběru metodiky, optimálním hodnotám metrik a psaní automatizovaných testů podle profilů zátěže, inženýři často musejí od nuly budovat testovací infrastrukturu, nastavovat zátěžové nástroje, integraci do CI systémů, nastavovat monitoring a publikaci zpráv.
Řešení některých organizačních problémů v testování, která používáme v Positive Technologies, najdete v . A v tomto článku vám povím o možnosti integrace zátěžových testů do celkového CI pipeline pomocí konceptu "zátěžové testování jako služba" (load testing as a service). Zjistíte, jaké dockerové obrazy zátěžových zdrojů lze použít v CI pipeline; jak připojit zátěžové zdroje k vašemu CI projektu pomocí stavební šablony; jak vypadá ukázkový pipeline pro spuštění zátěžových testů a publikaci výsledků. Článek může být užitečný testerům softwaru a automatizačním inženýrům v CI, kteří přemýšleli o architektuře svého zátěžového systému.
Podstata konceptu
Koncept zátěžového testování jako služby zahrnuje možnost integrovat zátěžové nástroje Apache JMeter, Yandex.Tank a vlastní rámce do libovolného systému continuous integration. Příkladem bude GitLab CI, ale principy jsou obecné pro všechny CI systémy.
Zátěžové testování jako služba je centralizovaná služba pro provádění zátěžového testování. Zátěžové testy se spouštějí ve vyhrazených poolech agentů, publikace výsledků probíhá automaticky v GitLab Pages, Influx DB a Grafana nebo v systémech test-reportingu (TestRail, ReportPortal atd.). Automatizace a škálování jsou realizovány maximálně jednoduše — prostřednictvím přidání a parametrizace v projektu GitLab CI běžné šablony gitlab-ci.yml.
Hlavní výhodou tohoto přístupu je, že celá CI infrastruktura, zátěžové agenty, dockerové obrazy zátěžových zdrojů, testovací pipeline a publikování zpráv jsou spravovány centrálním oddělením automatizace (inženýry DevOps), zatímco inženýři pro zátěžové testování se mohou soustředit na vývoj testů a analýzu jejich výsledků, aniž by se museli zabývat infrastrukturními otázkami.
Pro jednoduchost popisu budeme předpokládat, že cílová testovaná aplikace nebo server jsou již předem nasazeny a nakonfigurovány (k tomu mohou být použity automatizované skripty v Pythu, SaltStack, Ansible a další). Pak celá koncepce zátěžového testování jako služby spočívá ve třech fázi: příprava, testování, publikování zpráv. Více podrobností na schématu (všechny obrázky jsou klikatelné):
Základní pojmy a definice v zátěžovém testování
Při provádění zátěžových testů se snažíme dodržovat , používáme odpovídající terminologii a doporučené metriky. Předkládám krátký seznam základních pojmů a definic v zátěžovém testování.
Zátěžový agent (load agent) — virtuální stroj, na kterém bude spuštěna aplikace — zdroj zátěže (Apache JMeter, Yandex.Tank nebo vlastní zátěžový modul).
Cíl testování (target) — server nebo aplikace, nainstalovaná na serveru, která bude zatěžována.
Testovací scénář (test case) — soubor parametrově definovaných kroků: akce uživatelů a očekávané reakce na tyto akce, s pečlivě zaznamenanými síťovými požadavky a odpověďmi, v závislosti na zadaných parametrech.
Profil nebo plán zátěže (profile) — v (č. 4.2.4, s. 43) profily zátěže definují kriticky důležité metriky pro konkrétní test a variace změn parametrů zátěže během testu. Příklady profilů můžete vidět na obrázku.
Test (test) — scénář s předem definovaným souborem parametrů.
Testovací plán (test-plan) — soubor testů a profil zátěže.
Testovací běh (testrun) — jedna iterace spuštění jednoho testu s plně provedeným scénářem zátěže a získanou zprávou.
Síťový požadavek (request) — HTTP požadavek zasílaný od agenta k cíli.
Síťová odpověď (response) — HTTP odpověď zaslaná z cíle k agentovi.
HTTP kód odpovědi (HTTP response status) — standardní odpovědní kód od aplikačního serveru.
Transakce (transaction) — kompletní cyklus „požadavek — odpověď“. Transakce se považuje od začátku odeslání požadavku (request) až po dokončení příjmu odpovědi (response).
Stav transakce (transactions status) — zda se podařilo úspěšně dokončit cyklus „požadavek – odpověď“. Pokud došlo k jakékoli chybě, pak se celá transakce považuje za neúspěšnou.
Čas odezvy (latency) — čas od dokončení odeslání požadavku (request) až do začátku příjmu odpovědi (response).
Zátěžové metriky (metrics) — charakteristiky zatížené služby a zátěžového agenta určené během zátěžového testování.
Hlavní metriky pro měření parametrů zátěže
Některé z nejčastěji používaných a doporučovaných v metodice (str. 36, 52) metriky jsou uvedeny v tabulce níže. Podobné metriky pro agenta a cíl jsou uvedeny v jednom řádku.
Metriky pro zátěžového agenta
Metriky cílového systému nebo aplikace, testovaných pod zátěží
Počet vCPU a paměti RAM,
Disk — „hardwarové“ charakteristiky zátěžového agenta
CPU, Memory, Disk usage — dynamika zatížení CPU, paměti a disku
během testování. Obvykle se měří v procentech z
maximálně dostupných hodnot
Síťový propustnost (na zátěžovém agentu) — propustnost
síťového rozhraní na serveru,
kde je nainstalován zátěžový agent.
Obvykle se měří v bajtech za sekundu (bps)
Síťový propustnost(na cíli) — propustnost síťového rozhraní
na cílovém serveru. Obvykle se měří v bajtech za sekundu (bps)
Virtuální uživatelé— počet virtuálních uživatelů,
realizujících zátěžové scénáře a
imitujících reálné akce uživatelů
Stav virtuálních uživatelů, Passed/Failed/Total — počet úspěšných a
neúspěšných stavů práce virtuálních uživatelů
pro zátěžové scénáře, stejně jako jejich celkový počet.
Obvykle se očekává, že všichni uživatelé budou schopni splnit
všechny své úkoly, uvedené v profilu zátěže.
Jakákoli chyba by znamenala, že ani skutečný uživatel nebude schopen
splnit svůj úkol při práci se systémem.
Požadavky za sekundu (minutu)— počet síťových požadavků za sekundu (nebo minutu).
Důležitá charakteristika zátěžového agenta: kolik požadavků může generovat.
V podstatě se jedná o simulaci přístupu k aplikaci virtuálními uživateli
Odpovědi za sekundu (minutu)
— počet síťových odpovědí za sekundu (nebo minutu).
Důležitá charakteristika cílové služby: kolik se podařilo
vygenerovat a odeslat odpovědí na požadavky z
zátěžového agenta
Stav HTTP odpovědí— počet různých kódů odpovědí
ze serveru aplikace, které obdržel zátěžový agent.
Například 200 OK znamená úspěšné volání,
a 404 — že zdroj nebyl nalezen
Latence (doba odezvy) — doba od skončení
odeslání požadavku (request) do začátku příjmu odpovědi (response).
Obvykle se měří v milisekundách (ms)
Doba odezvy transakce— doba jedné kompletní transakce,
dokončení cyklu „požadavek — odpověď”.
Tato doba od začátku odeslání požadavku (request)
do ukončení příjmu odpovědi (response).
Doba transakce může být měřena v sekundách (nebo minutách)
několika způsoby: počítá se minimální,
maximální, průměrná a například 90. percentil.
Minimální a maximální hodnoty jsou krajní
stavy výkonnosti systému.
Devadesátý percentil se používá nejčastěji,
protože ukazuje většinu uživatelů,
kteří pracují pohodlně na hranici výkonu systému
Transakce za sekundu (minutu) — počet kompletních
transakcí za sekundu (minutu),
tj. kolik požadavků aplikace dokázala přijmout a
zpracovat a vydat odpovědí.
V podstatě se jedná o propustnost systému
Stav transakcí , Úspěšné / Neúspěšné / Celkem — počet
úspěšných, neúspěšných a celkový počet transakcí.
Pro skutečné uživatele bude neúspěšná
transakce v podstatě znamenat
nemožnost pracovat se systémem pod zátěží
Základní schéma zátěžového testování
Základní schéma zátěžového testování je velmi jednoduché a skládá se ze tří základních kroků, o kterých jsem již zmínil: Příprava — Test — Zpráva, tedy příprava cílů testování a nastavení parametrů pro zdroje zatížení, poté provedení zátěžových testů a nakonec vytvoření a publikování zprávy o testování.
Poznámky k šestě:
- QA.Tester — odborník na zátěžové testování,
- Cíl — cílová aplikace, pro kterou je potřeba zjistit její chování pod zátěží.
Klasifikátor entit, etap a kroků na schématu
Etapy a kroky
Co se děje
Co na vstupu
Co na výstupu
Příprava: krok přípravy k testování
LoadParameters
Úkol a inicializace
uživatelem
parametrů zatížení,
výběr metrik a
příprava testovacího plánu
(profil zatížení)
Uživatelské parametry pro
inicializaci zatěžovacího agenta
Testovací plán
Cíl testování
VM
Nasazení v cloudu
virtuálního stroje s
požadovanými charakteristikami
Parametry VM pro zatěžovacího agenta
Skripty pro automatizaci pro
vytváření VM
Nastavený VM v
cloudu
Env
Nastavení OS a příprava
prostředí pro
fungování zatěžovacího agenta
Parametry prostředí pro
zatěžovacího agenta
Skripty pro automatizaci pro
nastavení prostředí
Připravené prostředí:
OS, služby a aplikace,
potřebné pro práci
zatěžovacího agenta
LoadAgents
Instalace, konfigurace a parametrizace
zatěžovacího agenta.
Nebo stažení docker image s
přednastaveným zdrojem zatížení
Docker image zdroje zatížení
(JMeter, JM nebo vlastní rámec)
Parametry nastavení
zatěžovacího agenta
Nastavený a připravený
k práci zatěžovací agent
Test: fáze provádění zatěžovacích testů. Zdroje jsou zatěžovací agenti nasazení ve vyhrazených skupinách agentů pro GitLab CI
Načtení
Spuštění zatěžovacího agenta
s vybraným testovacím plánem
a parametry zatížení
Uživatelské parametry
pro inicializaci
zatěžovacího agenta
Testovací plán
Cíl testování
Logy provedení
zatěžovacích testů
Systémové záznamy
Dynamika změny metrik cíle a zatěžovacího agenta
RunAgents
Vykonání agentem
zatížení testovacích scénářů
v souladu s
profil zatížení
Interakce zatěžovacího agenta
s cílem testování
Testovací plán
Cíl testování
Protokoly
Sběr „syrových“ logů
během zatěžovacího testování:
záznamy o činnostech zatěžovacího agenta,
stavu cíle testování
a VM, na které je agent spuštěn
Logy provedení
zatěžovacích testů
Systémové záznamy
Metrics
Sběr „syrových“ metrik během testování
Dynamika změny metrik cíle
a zatěžovacího agenta
Report: fáze přípravy zprávy o testování
Generator
Zpracování shromážděných
zatěžovacím systémem a
systémem monitorování „syrových“
metrik a logů
Vytvoření zprávy v
čitelné podobě,
možná s prvky
analytiky
Logy provedení
zatěžovacích testů
Systémové záznamy
Dynamika změny metrik
cíle a zatěžovacího agenta
Zpracované „syrové“ logy
ve formátu vhodném pro
export do externích úložišť
Statická zpráva o zatížení,
vhodná pro analýzu člověkem
Publish
Publikace zprávy
o zatěžovacím
testování ve vnějším
servisu
Zpracované „surové“
logy ve formátu vhodném
pro export do externích
úložiště
Uložené ve vnějším
úložišti zprávy o
zátěži vhodné
pro analýzu člověkem
Připojení zdrojů zátěže v CI šabloně
Přejdeme k praktické části. Chci ukázat, jak na některých projektech ve společnosti jsme implementovali koncept zátěžového testování jako službu.
Nejdříve jsme silou našich DevOps inženýrů vytvořili v GitLab CI vyhrazený pool agentů pro spuštění zátěžových testů. Abychom je nezaměňovali v šablonách s jinými, například sestavovacími, pooly, přidali jsme na tyto agenty značky, : load. Můžete použít jakékoli jiné srozumitelné značky. Ty se definují GitLab CI Runners.
Jak zjistit požadovaný výkon pro „hardware“? Charakteristiky zátěžových agentů - dostatečný počet vCPU, RAM a Disk - mohou být vypočteny na základě toho, že na agentu by měly být spuštěny Docker, Python (pro Yandex.Tank), agent GitLab CI, Java (pro Apache JMeter). Pro Java pod JMeter se také doporučuje používat minimálně 512 MB RAM a jako maximální limit, .
Takže na základě naší zkušenosti doporučujeme používat pro zátěžové agenty alespoň: 4 vCPU, 4 GB RAM, 60 GB SSD. Propustnost síťové karty je určena na základě požadavků profilu zátěže.
Většinou používáme dva zdroje zátěže — Docker obrazů Apache JMeter a Yandex.Tank.
— je open-source nástroj společnosti Yandex pro provádění zátěžového testování. V jeho modulární architektuře se zakládá na vysoce výkonném asynchronním hit-based generátoru HTTP dotazů Phantom. Tank má vestavěný monitoring zdrojů testovaného serveru přes protokol SSH, může automaticky zastavit test podle zadaných podmínek, umí vypisovat výsledky jak na konzoli, tak ve formě grafů, lze k němu připojit vlastní moduly pro rozšíření funkcionality. Mimochodem, Tank jsme používali, když to ještě nebylo mainstreamem. V článku „“ si můžete přečíst příběh, jak jsme v roce 2013 prováděli s jeho pomocí zátěžové testování — jednoho z produktů naší společnosti.
— je to open-source nástroj pro zátěžové testování od společnosti Apache. Může být použit stejně dobře jak pro testování statických, tak dynamických webových aplikací. JMeter podporuje obrovské množství protokolů a způsobů interakce s aplikacemi: HTTP, HTTPS (Java, NodeJS, PHP, ASP.NET atd.), SOAP / REST webové služby, FTP, TCP, LDAP, SMTP(S), POP3(S) a IMAP(S), databáze přes JDBC, umí vykonávat shellové příkazy a pracovat s objekty Java. JMeter má IDE pro vytváření, ladění a spouštění testovacích plánů. Dále je k dispozici CLI pro práci v příkazovém řádku jakéhokoli operačního systému kompatibilního s Java (Linux, Windows, Mac OS X). Nástroj umí dynamicky generovat HTML zprávu o testování.
Pro pohodlné použití v naší společnosti, aby si sami testeři mohli měnit a přidávat prostředí, jsme vytvořili buildu dockerových obrazů zátěžových zdrojů na GitLab CI s publikováním do interní . Tak se dá rychleji a snadněji připojit do pipeline pro zátěžové testy. Jak udělat docker push do registru přes GitLab CI — podívejte se na .
Základní dockerfile pro Yandex.Tank jsme vzali tento:
Dockerfile
1 | FROM direvius/yandex-tank
2 | ENTRYPOINT [""]A pro Apache JMeter tento:
Dockerfile
1 | FROM vmarrazzo/jmeter
2 | ENTRYPOINT [""]Jak funguje náš systém kontinuální integrace, můžete si přečíst v článku „».
Šablona a pipeline
Příklad šablony pro provádění zátěžových testů je k dispozici v projektu . V můžete přečíst pokyny k použití šablony. V samotné šabloně (soubor ) jsou poznámky o tom, za co jednotlivé kroky odpovídají.
Šablona je velmi jednoduchá a ukazuje tři fáze zátěžového testování, které jsou popsány výše na schématu: příprava, testování a publikace zpráv. Za to odpovídají : Prepare, Test a Report.
- Fáze by měl být použit pro předběžné nastavení cíle testování nebo ověření jejich dostupnosti. Prostředí pro zátěžové zdroje není třeba nastavovat, jsou předem připraveny jako dockerové obrazy a umístěny v docker registru: stačí uvést požadovanou verzi ve fázi Test. Ale je možné je znovu sestavit a vytvořit si vlastní modifikované obrazy.
- Fáze používá se k určení zdroje zátěže, spuštění testů a uchování testovacích artefaktů. Lze vybrat jakýkoli zdroj zátěže: Yandex.Tank, Apache JMeter, vlastní nebo všechny dohromady. Pro vypnutí nepotřebných zdrojů stačí zakomentovat nebo smazat job. Vstupní body pro zdroje zátěže:
- parametry spuštění Yandex.Tank jsou uvedeny v souboru.,
- parametry spuštění Apache JMeter jsou uvedeny v souboru .
Poznámka: šablona konfiguračního souboru se používá pro nastavení interakce s CI systémem a nepředpokládá zahrnutí logiky testů. Pro testy je určena vstupní cesta, kde se nachází řídicí bash skript. Způsob spuštění testů, generování zpráv a samotné testovací scénáře musí být realizovány QA inženýry. V ukázkovém příkladu pro oba zdroje zátěže je jako nejjednodušší test použit požadavek na hlavní stránku Yandexu. Scénáře a parametry testů se nacházejí v adresáři .
- Na etapě je třeba popsat způsoby publikace výsledků testování získaných ve fázi Test do externích úložišť, například do GitLab Pages nebo speciálních systémů reportování. Pro GitLab Pages je nutné, aby po skončení testů byl adresář ./public neprázdný a obsahoval alespoň soubor index.html. O nuancích funkce služby GitLab Pages se můžete dočíst .
Příklady, jak exportovat data:
- z JMeter do ,
- z Yandex.Tank do .
Pokyny k nastavení publikace:
- HTML statiky do ,
- do InfluxDB a poté do .
V ukázkovém příkladu pipeline s zátěžovými testy a dvěma zdroji zátěže (některé by mohly být vypnuty) vypadá takto:
Apache JMeter umí sám generovat HTML zprávu, takže je výhodnější ji uchovávat v GitLab Pages standardními prostředky. Takto vypadá zpráva Apache JMeter:
V ukázkovém příkladu pro Yandex.Tank uvidíte pouze v sekci pro GitLab Pages. Během testování Tank umí ukládat výsledky do databáze InfluxDB, odkud je lze zobrazit například v Grafana (nastavení se provádí v souboru ). Takto vypadá zpráva Tanku v Grafana:
Shrnutí
V článku jsem popsal koncept „testování zatížení jako službu“ (load testing as a service). Hlavní myšlenka spočívá v používání infrastruktury přednastavených skupin zátěžových agentů, dockerových obrazů zátěžových zdrojů, systémů reportování a spojujícího pipeline v GitLab CI na základě jednoduché šablony .gitlab-ci.yml (příklad ). To všechno je podporováno malým týmem inženýrů-automatizátorů a je duplikováno na žádost produktových týmů. Doufám, že vám to pomůže při přípravě a realizaci podobného schématu ve vaší společnosti. Děkuji za pozornost!
P. S. Chci poděkovat mým kolegům, Sergeji Kurbanovovi a Nikolaji Jusevovi, za technickou pomoc s realizací konceptu load testing as a service v naší společnosti.
Autor: — zástupce vedoucího oddělení technologií a procesů vývoje (DevOps) společnosti Positive Technologies
Zdroj: habr.com
