Автоматизация нагрузочного тестирования банковского ПО для терминалов |
23.08.2017 00:00 |
Автор: Команда нагрузочного тестирования компании "Инфосистемы Джет" Оригинальная публикация: habrahabr.ru/company/jetinfosystems/blog/329014/?utm_source=software-testing В этом посте речь пойдет о тестировании серверного ПО, которое обслуживает огромную сеть банковских терминалов в России и за рубежом. Название банка мы раскрыть не можем, некоторые строчки конфигов скрыты. Автоматизация Начнем издалека. Мы постоянно слышим одно и то же: “Автоматизировать нагрузочное тестирование банковского и финансового ПО невозможно! У нас слишком много взаимосвязей! Мы очень сложные!”. Этот вызов только усиливал азарт решения задачи. Нам всегда хотелось проверить сложность на конкретном примере. Вместо того, чтобы заниматься нагрузочным тестированием ПО на уровне взаимодействий систем, в секторе банковского ПО традиционно все тестируют через UI, как повелось со времен неразъемных систем и приложений. На это уходит много времени и сил, что делает разработку банковского ПО медленной, некачественной и нетехнологичной. Мы в компании “Инфосистемы Джет” были избавлены от этих стереотипов — разработчики сами писали юнит-тесты на свой код, функциональные тестировщики прекрасно программировали UI-тесты через Selenium+Cucumber. Осталось только встроить в процесс дополнительную стадию нагрузочного тестирования. Проектирование инфраструктуры В самом начале мы решили отказаться от взаимосвязей, которые усложняют и размывают ответ на вопрос, насколько производительный и надежный код мы разрабатываем. Например, авторизация и выдача токенов на проведение операций — это функциональность сторонней системы, исследовать производительность которой в рамках задачи было бы избыточно. Помимо этого мы сразу отказались от интеграции с несколькими back-office системами, сделав заглушку, отвечающую нашей системе с определенной задержкой (все мы знаем, как опасно тестировать систему на сверхбыстрых моках). После проектирования и осмотра оставшейся инфраструктуры стало примерно понятно, как будет выстроен процесс, какие бенефиты будут получены, и нужно было приступать к созданию самого процесса НТ. CI/CD процесс и программное обеспечение Код ПО выкладывается во внутреннем git-репозитории (GitLab). После коммита по специальному триггеру Jenkins вытаскивает код на сборочную машину и пытается собрать релиз с прогоном всех заведенных Unit-тестов. После успешной сборки с помощью скриптов собранный билд инсталлируется в два тестовых окружения ‒ НТ и ФТ ‒ и делает рестарт тестинга. После подъема бэкенда Jenkins прогоняет друг за другом ФТ, UI и ИФТ-тесты. Нагрузочное тестирование запускается отдельной задачей, но про это стоит рассказать отдельно. Самое интересное После того как билд попадает на нагрузочный стенд, посредством скриптов в Jenkins запускается специальная задача для нагрузочного тестирования. Задача настроена классическим способом, через shell-скриптинг и параметризацию. Кликните на картинку, чтобы увеличить изображение Так выглядит конфиг Yandex.Tank: Кликните на картинку, чтобы увеличить изображение А так выглядит пример shell-script запуска всего процесса НТ: Кликните на картинку, чтобы увеличить изображение Как видите, все настройки достаточно примитивны. При автоматическом запуске джоба дефолтные параметры применяются автоматически, при ручном же запуске вы можете конфигурировать стрелялку параметрами Jenkins, не разбираясь в документации и не копаясь на Linux-машинке и перебирая необходимые конфиги. Кликните на картинку, чтобы увеличить изображение После запуска теста вы получаете ссылку в Console View Jenkins и Telegram, перейдя по которой можно наблюдать нагрузочный тест в реальном времени: Кликните на картинку, чтобы увеличить изображение Кликните на картинку, чтобы увеличить изображение Если результаты теста вышли за пределы SLA, то тест автоматически останавливается и вы получаете репорт в Telegram, почту и JIRA о проблемах с релизом. Если же результат хороший, то после репорта релиз получает статус SUCCESS и готов для деплоя на нагруженную среду, в продакшн. А так бот репортит результаты в JIRA: Кликните на картинку, чтобы увеличить изображение В качестве корпоративной “плюшки” от Яндекса мы получили доступ к сравнению тестов: Кликните на картинку, чтобы увеличить изображение и доступ к построению регрессионных отчетов по KPI-метрикам: Кликните на картинку, чтобы увеличить изображение Проблемы и решения
В данном случае, все метрики с серверов и load-генераторов пишутся в InfluxDB локальными агентами telegraf, а мониторинг Яндекс.Танка уже извлекает данные из InfluxDB простейшим скриптом и пушит данные в Overload. Такой подход позволяет отказаться от поддержки всего зоопарка операционных систем со стороны Яндекс.Танка и избежать необходимости коннекта “от одного ко всем”. from inflow import Client import sys try: connect = Client(sys.argv[1]) try: query_string = "SELECT LAST(" + sys.argv[4] + ") FROM " + sys.argv[3] + " WHERE host='" + sys.argv[2] + "';" result = connect.query(query_string) print (result[0]["values"][0]["last"]) except: print ("Bad request or something wrong with DB. See logs on " + sys.argv[1] + " for details.") except ValueError: print("Something wrong with parameters. " "Usage: python ./influx_picker <http://db_host:port/dbname> <target_host> <group> <metric>") except IndexError: print("Usage: python ./influx_picker <http://db_host:port/dbname> <target_host> <group> <metric>")
<Monitoring> <Host address="localhost" interval="5"> <Custom diff="0" measure="call" label="cpu_sys">python influx_picker.py http://<INFLUXDB_IP>:8086/target_host target_host cpu usage_system</Custom> <Custom diff="0" measure="call" label="cpu_usr">python influx_picker.py http://<INFLUXDB_IP>:8086/target_host target_host cpu usage_user</Custom> <Custom diff="0" measure="call" label="cpu_iowait">python influx_picker.py http://<INFLUXDB_IP>:8086/target_host target_host cpu usage_iowait</Custom> <Custom diff="0" measure="call" label="mem_free_perc">python influx_picker.py http://<INFLUXDB_IP>:8086/target_host target_host mem available_percent</Custom> <Custom diff="0" measure="call" label="mem_used_perc">python influx_picker.py http://<INFLUXDB_IP>:8086/target_host target_host mem used_percent</Custom> <Custom diff="0" measure="call" label="diskio_read">python influx_picker.py http://<INFLUXDB_IP>:8086/target_host target_host diskio read_bytes</Custom> <Custom diff="0" measure="call" label="diskio_write">python influx_picker.py http://<INFLUXDB_IP>:8086/target_host target_host diskio write_bytes</Custom> </Host> </Monitoring>
Кликните на картинку, чтобы увеличить изображение Репортинг. Мы использовали два вида репортинга результатов. Заключение Как можно заметить, данная задача не из разряда Rocket Science, и вы могли читать подобные статьи здесь, здесь и даже смотреть видео здесь. Под капотом лежат обычные скрипты и сервисы ‒ мы всего лишь хотели продемонстрировать, что на самом деле к эре “Devops” и повальной автоматизации финансовый сектор готов уже давно, просто нужно иметь смелость и политическую волю внедрять современные и быстрые процессы.
|