Навантажувальне тестування як CI-сервіс для розробників

Навантажувальне тестування як CI-сервіс для розробників

Однією з проблем, з якими часто стикаються мультипродуктові вендори ПЗ, є дублювання компетенцій інженерів — розробників, тестувальників та адміністраторів інфраструктури — майже в кожній команді. Це стосується й дорогих інженерів-спеціалістів у галузі навантажувального тестування.

Замість того, щоб займатися своїми прямими обов'язками та використовувати свій унікальний досвід для вибудовування процесу навантажувального тестування, вибирати методологію, оптимальні значення метрик та писати автотести відповідно до профілів навантаження, інженерам часто доводиться з нуля розгортати тестову інфраструктуру, налаштовувати інструменти навантаження, самим вбудовувати їх в CI-системи, налаштовувати моніторинг та публікацію звітів.

Вирішення деяких організаційних проблем у тестуванні, які ми застосовуємо у Positive Technologies, ви можете знайти у іншій статті. А в цій розповім про можливість інтеграції навантажувальних тестів в загальний CI-конвеєр за допомогою концепції «навантажувальне тестування як сервіс» (load testing as a service). Ви дізнаєтесь, як і які докер-образи джерел навантаження можна використовувати у CI-конвеєрі; як підключити джерела навантаження до свого CI-проекту за допомогою складального шаблону; як виглядає демопайплайн для запуску тестів навантаження і публікації результатів. Стаття може бути корисною інженерам з тестування ПЗ та інженерам-автоматизаторам в CI, хто задумався про архітектуру своєї системи навантаження.

Суть концепції

Концепція load testing as a service передбачає можливість інтегрувати інструменти навантаження Apache JMeter, Yandex.Tank та власні фреймворки у довільну систему continuous integration. Демоприклад буде GitLab CI, але принципи викладені загальні всім CI-систем.

Load testing as a service - це централізований сервіс для проведення тестування навантаження. Навантажувальні тести запускаються у виділених пулах агентів, публікація результатів відбувається автоматично в GitLab Pages, Influx DB та Grafana або у системи тест-репортингу (TestRail, ReportPortal тощо). Автоматизація та масштабування реалізуються максимально просто – через додавання та параметризацію у проекті GitLab CI звичайного шаблону gitlab-ci.yml.

Перевага підходу полягає в тому, що вся CI-інфраструктура, навантажувальні агенти, докер-образи джерел навантаження, пайплайни тестування та публікація звітів - підтримуються силами централізованого відділу автоматизації (DevOps-інженерами), а інженери з тестування навантаження можуть зосередити свої зусилля на розробці та аналіз їх результатів, не займаючись інфраструктурними питаннями.

Для простоти опису будемо вважати, що цільовий додаток, що тестується, або сервер вже розгорнуті і налаштовані заздалегідь (для цього можуть бути використані автоматизовані сценарії на Python, SaltStack, Ansible та ін). Тоді вся концепція тестування навантаження як сервісу укладається в три етапи: підготовка, тестування, публікація звітів. Детальніше на схемі (всі картинки клікабельні):

Навантажувальне тестування як CI-сервіс для розробників

Основні поняття та визначення у навантажувальному тестуванні

Під час проведення навантажувальних випробувань ми намагаємося дотримуватися стандартів та методології ISTQB, використовуємо відповідну термінологію та рекомендовані метрики. Наведу короткий перелік основних понять та визначень у тестуванні навантаження.

Навантажувальний агент (load agent) - Віртуальна машина, на якій буде запущено додаток - джерело навантаження (Apache JMeter, Yandex.Tank або самописний модуль навантаження).

Мета тестування (target) — сервер або програму, встановлену на сервері, який зазнаватиме навантаження.

Тестовий сценарій (test case) — набір параметризованих кроків: дії користувачів та очікувані реакції на ці дії із зафіксованими мережевими запитами та відповідями залежно від заданих параметрів.

Профіль або план навантаження (profile) - У методології ISTQB (п. 4.2.4, стор. 43) профілі навантаження визначають критично важливі для конкретного тесту метрики та варіанти зміни параметрів навантаження протягом тесту. Приклади профілів можна побачити на малюнку.

Навантажувальне тестування як CI-сервіс для розробників

Тест (test) — сценарій із заздалегідь визначеним набором параметрів.

Тест-план (test-plan) - Набір тестів і профіль навантаження.

Тестран (testrun) - одна ітерація запуску одного тесту з повністю виконаним сценарієм навантаження та отриманим звітом.

Мережевий запит (request) - HTTP-запит, що відправляється від агента до мети.

Мережева відповідь (response) - HTTP-відповідь, що відправляється від мети до агента.
HTTP-код відповіді (HTTP responses status) – стандартний код відповіді від сервера додатків.
Транзакція (transaction) – повний цикл «запит – відповідь». Транзакція вважається від початку надсилання запиту (request) до завершення прийому відповіді (response).

Статус транзакції (transactions status) - Чи вдалося успішно завершити цикл "запит - відповідь". Якщо цьому циклі була будь-яка помилка, то вся транзакція вважається неуспішною.

Час відгуку (latency) - Час від закінчення відправки запиту (request) до початку прийому відповіді (response).

Метрики навантаження (metrics) - Визначаються в процесі навантажувального тестування характеристики сервісу, що навантажується, і навантажувального агента.

Основні метрики для вимірювання параметрів навантаження

Деякі найбільш загальновживані та рекомендовані в методології ISTQB (Стор. 36, 52) метрики наведені в таблиці нижче. Подібні метрики для агента та цілі вказані в одному рядку.

Метрики для навантажувального агента
Метрики цільової системи або програми, що тестуються під навантаженням

Кількість  vCPU та пам'яті Оперативна пам'ять,
Диск - «залізні» характеристики навантажувального агента
центральний процесор, Пам'ять, використання диска — динаміка завантаження процесора, пам'яті та диска
у процесі тестування. Зазвичай вимірюється у відсотках від
максимально доступних значень

Пропускна здатність мережі (on load agent) - пропускна спроможність
мережного інтерфейсу на сервері,
де встановлений навантажувальний агент.
Зазвичай вимірюється в байтах за секунду (bps)
Пропускна здатність мережі(on target) - пропускна здатність мережного інтерфейсу
на цільовому сервері. Зазвичай вимірюється в байтах за секунду (bps)

Віртуальні користувачі- Кількість віртуальних користувачів,
реалізують сценарії навантаження та
що імітують реальні дії користувачів
Virtual users status, Passed / Failed / Total - кількість успішних і
неуспішних статусів роботи віртуальних користувачів
для сценаріїв навантаження, а також їхня загальна кількість.

Зазвичай очікується, що всі користувачі змогли виконати
усі свої завдання, вказані у профілі навантаження.
Будь-яка помилка означатиме, що реальний користувач не зможе
вирішити своє завдання під час роботи з системою

Requests per second (minute)— кількість запитів мережі за секунду (або хвилину).

Важлива характеристика агента навантаження: скільки він може генерувати запитів.
Фактично це імітація звернення до програми віртуальними користувачами
Responses per second (minute)
— кількість мережевих відповідей за секунду (або хвилину).

Важлива характеристика цільового сервісу: скільки вдалося
згенерувати та відправити відповідей на запити з
навантажувального агента

HTTP responses statusкількість різних кодів відповіді
від сервера програми, отриманих навантажувальним агентом.
Наприклад, 200 OK означає успішне звернення,
а 404 - що ресурс не виявлено

Затримка (час відгуку) - час від закінчення
надсилання запиту (request) до початку прийому відповіді (response).
Зазвичай вимірюється у мілісекундах (ms)

Час відповіді на транзакцію- час однієї повної транзакції,
завершення циклу "запит - відповідь".
Це час від початку надсилання запиту (request)
до завершення прийому відповіді.

Час транзакції може вимірюватись у секундах (або хвилинах)
декількома способами: вважають мінімальне,
максимальне, середнє та, наприклад, 90-й перцентиль.
Мінімальні та максимальні показання – це крайні
стану продуктивності системи
Дев'янистий перцентиль використовується найчастіше,
оскільки він показує більшість користувачів,
комфортно працюючих на порозі продуктивності системи

Transactions per second (minute) - Кількість повних
транзакцій за секунду (хвилину),
тобто скільки додаток зміг прийняти і
обробити запити та видати відповіді.
Фактично це пропускна спроможність системи

Transactions status , Passed / Failed / Total - кількість
успішних, неуспішних та загальна кількість транзакцій.

Для реальних користувачів неуспішна
транзакція фактично означатиме
неможливість працювати з системою під навантаженням

Принципова схема тесту навантаження

Принципова схема навантаження тестування дуже проста і складається з трьох основних етапів, про які я вже згадував: Prepare - Test - Report, тобто підготовка цілей тестування та завдання параметрів для джерел навантаження, потім виконання навантажувальних тестів і, наприкінці, формування та публікація звіту про тестування.

Навантажувальне тестування як CI-сервіс для розробників

Примітки до схеми:

  • QA.Tester - експерт з навантажувального тестування,
  • Target — цільова програма, для якої потрібно дізнатися її поведінку під навантаженням.

Класифікатор сутностей, етапів та кроків на схемі

Етапи та кроки
Що відбувається
Що на вході
Що на виході

Prepare: етап підготовки до тестування

LoadParameters
Завдання та ініціалізація
користувачем
параметрів навантаження,
вибір метрик та
підготовка тест-плану
(Профілю навантаження)
Настройки користувача для
ініціалізації агента навантаження
Тест-план
Ціль тестування

VM
Розгортання у хмарі
віртуальної машини з
необхідними характеристиками
Параметри ВМ для агента навантаження
Скрипти автоматизації для
створення ВМ
Налаштована ВМ в
хмарі

Окр
Налаштування ОС та підготовка
оточення для
роботи навантажувального агента
Параметри оточення для
агента навантаження
Скрипти автоматизації для
налаштування оточення
Підготовлене оточення:
ОС, послуги та додатки,
необхідні для роботи
агента навантаження

LoadAgents
Встановлення, налаштування та параметризація
навантажувального агента.
Або завантаження докер-образу з
передналаштованим джерелом навантаження
Докер-образ джерела навантаження
(ЯТ, JM або самописний фреймворк)
Параметри налаштування
агента навантаження
Налаштований та готовий
до роботи агент навантаження

Test: етап виконання тестів навантаження. Джерелами є агенти навантаження, розгорнуті у виділених пулах агентів для GitLab CI

Навантаження
Запуск агента навантаження
з вибраним тест-планом
та параметрами навантаження
Настройки користувача
для ініціалізації
агента навантаження
Тест-план
Ціль тестування
Логи виконання
навантажувальних тестів
Системні журнали
Динаміка зміни метрик мети та навантажувального агента

RunAgents
Виконання агентом
навантаження тестових сценаріїв
відповідно до
профілем навантаження
Взаємодія агента навантаження
з метою тестування
Тест-план
Ціль тестування

Logs
Збір «сирих» логів
у процесі навантажувального тестування:
записи про дії агента навантаження,
стан мети тестування
та ВМ, на якій запущений агент

Логи виконання
навантажувальних тестів
Системні журнали

Метрика
Збір «сирих» метрик у процесі тестування

Динаміка зміни метрик мети
та навантажувального агента

Report: етап підготовки звіту про тестування

Generator
Обробка зібраних
навантажувальною системою та
системою моніторингу «сирих»
метрик та логів
Формування звіту в
людиночитаному вигляді,
можливо з елементами
аналітики
Логи виконання
навантажувальних тестів
Системні журнали
Динаміка зміни метрик
цілі та навантажувального агента
Оброблені «сирі» логи
у форматі, придатному для
вивантаження у зовнішні сховища
Статичний звіт про навантаження,
придатний для аналізу людиною

Публікувати
Публікація звіту
про навантажувальне
тестуванні у зовнішньому
сервісі
Оброблені «сирі»
логі у форматі, придатному
для вивантаження у зовнішні
сховища
Збережені у зовнішньому
сховище звіти про
навантаженні, придатні
для аналізу людиною

Підключення джерел навантаження в CI-шаблоні

Перейдемо до практичної частини. Я хочу показати, як на деяких проектах у компанії Позитивні технології ми реалізували концепцію тесту навантаження як сервісу.

Спочатку силами наших DevOps-інженерів ми створили в GitLab CI виділений пул агентів для запуску тестів навантаження. Щоб не плутати їх у шаблонах з іншими, наприклад, складальними, пулами, ми додали теги на ці агенти, теги: load. Можна використати будь-які інші зрозумілі теги. Вони задаються під час реєстрації GitLab CI Runners.

Як дізнатися потрібну потужність за «залізом»? Характеристики навантажувальних агентів - достатня кількість vCPU, RAM і Disk - можуть бути розраховані виходячи з того, що на агенті повинні бути запущені Docker, Python (Yandex.Tank), агент GitLab CI, Java (для Apache JMeter). Для Java під JMeter також рекомендують використовувати мінімум 512 МБ RAM і, як верхню межу, 80% доступної пам'яті.

Таким чином, виходячи з нашого досвіду, ми рекомендуємо використовувати для агентів навантаження як мінімум: 4 vCPU, 4 ГБ RAM, 60 ГБ SSD. Пропускна спроможність мережевої карти визначається з урахуванням вимог профілю навантаження.

У нас в основному використовуються два джерела навантаження – докер-образи Apache JMeter та Yandex.Tank.

Yandex.Tank — це опенсорсний інструмент компанії Yandex для проведення тестування навантаження. В основі його модульної архітектури є високопродуктивний асинхронний hit-based-генератор HTTP-запитів Phantom. Танк має вбудований моніторинг ресурсів сервера, що тестується, за протоколом SSH, може автоматично зупинити тест за заданими умовами, вміє виводити результати як у консоль, так і у вигляді графіків, до нього можна підключити свої модулі для розширення функціональності. До речі, ми використовували Танк, коли ще не було мейнстримом. У статті "Яндекс.Танк та автоматизація навантажувального тестування» можна прочитати історію, як у 2013-му ми проводили за його допомогою навантажувальне тестування PT Appllication Firewall - одного з продуктів нашої компанії.

Apache JMeter — це опенсорсний інструмент для проведення тестування навантаження компанії Apache. Він може однаково добре використовуватись як для тестування статичних, так і динамічних веб-додатків. JMeter підтримує величезну кількість протоколів і способів взаємодії з додатками: HTTP, HTTPS (Java, NodeJS, PHP, ASP.NET і т.д.), SOAP / REST Webservices, FTP, TCP, LDAP, SMTP (S), POP3 (S ) та IMAP(S), бази даних через JDBC, вміє виконувати shell-команди та працювати з Java-об'єктами. JMeter має IDE для створення, налагодження та виконання тест-планів. Також є CLI для роботи в командному рядку будь-якої сумісної з ОС Java (Linux, Windows, Mac OS X). Інструмент вміє динамічно генерувати HTML-звіт про тестування.

Для зручності використання всередині нашої компанії, для можливості самим тестувальникам змінювати та додавати оточення, ми зробили збірки докер-образів джерел навантаження на GitLab CI з публікацією у внутрішній. докер-реджистри на Artifactory. Так виходить швидше та простіше підключати їх у пайплайнах для навантажувальних тестів. Як зробити docker push в registry через GitLab CI. інструкції.

Базовий докер-файл для Yandex.Tank ми взяли це:

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

А для Apache JMeter цей:

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

Як влаштована наша система continuous integration, ви можете прочитати у статті «Автоматизація процесів розробки: як ми в Positive Technologies впроваджували ідеї DevOps».

Шаблон та пайплайн

Приклад шаблону для проведення тестів навантаження доступний у проекті demo-load. У readme-файлі Ви можете прочитати інструкцію з використання шаблону. У самому шаблоні (файл .gitlab-ci.yml) є примітки про те, за що відповідає той чи інший крок.

Шаблон дуже простий і демонструє три етапи тестування навантаження, описаних вище на схемі: підготовка, тестування і публікація звітів. За це відповідають етапи: Prepare, Test та Report.

  1. етап Готувати слід використовувати для попереднього налаштування цілей тестування або перевірки їх доступності. Оточення для джерел навантаження не потрібно налаштовувати, вони заздалегідь зібрані як докер-образи і викладені в docker registry: достатньо вказати потрібну версію на етапі Test. Але можна перезбирати їх і створити свої модифіковані образи.
  2. етап Тест використовується для вказівки джерела навантаження, запуску тестів та збереження артефактів тестування. Можна вибрати будь-яке джерело навантаження: Yandex.Tank, Apache JMeter, свій чи всі разом. Для відключення непотрібних джерел достатньо закоментувати або видалити job. Точки входу для джерел навантаження:
    • параметри запуску Yandex.Tank вказуються у файлі./tests/yandextank.sh,
    • параметри запуску Apache JMeter вказуються у файлі ./tests/jmeter.sh.

    Примітка: шаблон конфігурації конфігурації використовується для налаштування взаємодії з CI-системою і не передбачає розміщення в ньому логіки тестів. Для тестів вказується точка входу, де знаходиться керуючий bash-скрипт. Спосіб запуску тестів, формування звітів і самі тестові сценарії повинні бути реалізовані QA-інженерами. У демоприкладі для обох джерел навантаження як найпростіший тест використовується реквест основної сторінки Яндекса. Сценарії та параметри тестів лежать у каталозі ./tests.

  3. На етапі доповідь потрібно описати способи публікації результатів тестування, отриманих на етапі Test, у зовнішні сховища, наприклад GitLab Pages або спеціальні системи звітності. Для GitLab Pages потрібно, щоб після закінчення тестів каталог ./public був непустим і містив щонайменше файл index.html. Про нюанси роботи сервісу GitLab Pages ви можете прочитати за посиланням.

    Приклади, як експортувати дані:

    Інструкції з налаштування публікації:

У демоприкладі пайплайн із навантажувальними тестами та двома джерелами навантаження (можна відключити непотрібний) виглядає так:

Навантажувальне тестування як CI-сервіс для розробників

Apache JMeter вміє сам формувати HTML-звіт, тому його вигідніше зберігати в GitLab Pages штатними засобами. Ось так виглядає звіт Apache JMeter:

Навантажувальне тестування як CI-сервіс для розробників

У демоприкладі для Yandex.Tank ви побачите лише фейковий текстовий звіт у розділі для GitLab Pages. У процесі тестування Танк вміє зберігати результати до бази InfluxDB, а звідти їх можна відобразити, наприклад, у Grafana (налаштування виконується у файлі ./tests/example-yandextank-test.yml). Ось так звіт Танка виглядає у Grafana:

Навантажувальне тестування як CI-сервіс для розробників

Резюме

У статті я розповів про концепцію "навантажувальне тестування як сервіс" (load testing as a service). Основна ідея полягає у використанні інфраструктури преднастроенных пулів навантажувальних агентів, докер-образів джерел навантаження, систем звітності та пайплайну, що їх об'єднує, в GitLab CI на базі простого шаблону .gitlab-ci.yml (приклад за посиланням). Все це підтримується силами невеликої команди інженерів-автоматизаторів та тиражується на запит продуктових команд. Сподіваюся, це допоможе вам у підготовці та реалізації аналогічної схеми у вашій компанії. Дякую за увагу!

PS Хочу сказати велике спасибі моїм колегам, Сергію Курбанову та Миколі Юсєву, за технічну допомогу з реалізацією концепції load testing as a service у нашій компанії.

Автор: Тимур Гільмуллін - Заст. керівника відділу технологій та процесів розробки (DevOps) компанії Positive Technologies

Джерело: habr.com

Додати коментар або відгук