Стратегии тестирования
Интеграция тестирования с Ansible Playbook
Часто задают вопрос: «Как лучше всего интегрировать тестирование с Ansible playbook?» Существует много вариантов. Ansible фактически разработан как «быстро ломающаяся» и упорядоченная система, поэтому легко встроить тестирование непосредственно в Ansible playbook. В этой главе мы рассмотрим некоторые шаблоны для интеграции тестов инфраструктуры и обсудим подходящий уровень тестирования.
Примечание
Эта глава посвящена тестированию приложения, которое вы развертываете, а не тестированию Ansible модулей во время разработки. Для этой информации перейдите в раздел «Разработка».
Внедрение тестирования в ваш рабочий процесс развертывания позволит избежать неожиданностей, когда код попадает в производство, и в многих случаях тесты можно использовать в производстве, чтобы предотвратить распространение неисправных обновлений по всей установке. Поскольку это основанная на отправке система, легко выполнять шаги на локальном сервере или тестовых серверах. Ansible позволяет вставлять в ваш рабочий процесс обновления столько проверок и балансировок, сколько вам нужно.
Правильный уровень тестирования
Ansible ресурсы являются моделями желаемого состояния. Следовательно, не нужно тестировать, запущены ли службы, установлены ли пакеты или другие подобные вещи. Ansible — это система, которая гарантирует, что эти вещи будут декларативно истинными. Вместо этого, утверждайте эти вещи в своих playbook.
tasks: - service: name=foo state=started enabled=yes
Если вы считаете, что служба может не запуститься, лучше всего попросить её запуститься. Если служба не запустится, Ansible соответствующим образом сообщит об этом. (Это не следует путать с тем, выполняет ли служба какие-то функциональные действия, о чём мы расскажем подробнее позже).
Режим проверки как тест на отклонение
В настройках выше, режим проверки в Ansible также может быть использован как уровень тестирования. Если вы выполняете playbook развертывания на существующей системе, использование флага –check для команды ansible покажет, считает ли Ansible, что ему нужно внести какие-либо изменения, чтобы привести систему к желаемому состоянию.
Это позволит вам узнать заранее, требуется ли развертывание на данной системе. Обычно скрипты и команды не выполняются в режиме проверки, поэтому, если вы хотите, чтобы определённые шаги всегда выполнялись в режиме проверки, например, вызовы модуля скрипта, отключите режим проверки для этих задач:
roles:
- webserver
tasks:
- script: verify.sh
check_mode: no
Модули, полезные для тестирования
Определённые модули playbook особенно подходят для тестирования. Ниже приведен пример, гарантирующий открытость порта:
tasks:
- wait_for: host={{ inventory_hostname }} port=22
delegate_to: localhost
Вот пример использования модуля URI для проверки того, что веб-служба возвращает:
tasks:
- action: uri url=http://www.example.com return_content=yes
register: webpage
- fail: msg='service is not happy'
when: "'AWESOME' not in webpage.content"
Легко отправить произвольный скрипт (на любом языке) на удалённый хост, и скрипт автоматически завершится неудачно, если его код возврата не равен нулю:
tasks: - script: test_script1 - script: test_script2 --parameter value --parameter2 value
Если вы используете роли (а вы должны, роли отличные!), скрипты, отправленные модулем скрипта, могут храниться в каталоге «files/» роли.
А модуль assert очень упрощает проверку различных истин:
tasks:
- shell: /usr/bin/some-command --parameter value
register: cmd_result
- assert:
that:
- "'not ready' not in cmd_result.stderr"
- "'gizmo enabled' in cmd_result.stdout"
Если вам нужно проверить существование файлов, которые не декларативно заданы вашей конфигурацией Ansible, модуль «stat» — отличный выбор:
tasks:
- stat: path=/path/to/something
register: p
- assert:
that:
- p.stat.exists and p.stat.isdir
Как упоминалось выше, нет необходимости проверять коды возврата команд. Ansible проверяет их автоматически. Вместо проверки существования пользователя, используйте модуль «user» для его создания.
Ansible — это система с быстрым обнаружением ошибок, поэтому при возникновении ошибки при создании пользователя playbook завершится. Вам не нужно проверять ситуацию за ним.
Жизненный цикл тестирования
Если вы внедрите некоторую базу проверки вашего приложения в свои playbook, они будут выполняться каждый раз при развертывании.
Таким образом, развертывание в локальной VM разработки и среде Staging позволит валидировать, что всё соответствует плану до развертывания в Production.
Ваш рабочий процесс может быть таким:
- Use the same playbook all the time with embedded tests in development - Use the playbook to deploy to a staging environment (with the same playbooks) that simulates production - Run an integration test battery written by your QA team against staging - Deploy to production, with the same integrated tests.
Если вы являетесь разработчиком веб-службы Production, ваша команда QA должна написать набор интеграционных тестов. Это может включать Selenium тесты или автоматизированные API тесты, и обычно это не должно встраиваться в ваши Ansible playbook.
Однако, имеет смысл включить некоторые базовые проверки состояния в свои playbook, и в некоторых случаях возможно запустить подмножество батареи QA на удалённых узлах. Это описывается в следующей секции.
Интеграция тестирования с поэтапными обновлениями
Если вы ознакомились с Делегирование, Поэтапные обновления и Локальные действия, вам может стать очевидным, что шаблон поэтапных обновлений можно расширить, и вы можете использовать результат выполнения playbook для принятия решения о добавлении машины в балансировщик нагрузки или нет.
Это кульминация встроенных тестов:
---
- hosts: webservers
serial: 5
pre_tasks:
- name: take out of load balancer pool
command: /usr/bin/take_out_of_pool {{ inventory_hostname }}
delegate_to: 127.0.0.1
roles:
- common
- webserver
- apply_testing_checks
post_tasks:
- name: add back to load balancer pool
command: /usr/bin/add_back_to_pool {{ inventory_hostname }}
delegate_to: 127.0.0.1
Конечно, в примере выше шаги «извлечь из пула» и «добавить обратно» заменяются вызовом модуля Ansible для балансировщика нагрузки или соответствующей оболочке команды. У вас также могут быть шаги, использующие модуль мониторинга для запуска и завершения периода простоя машины.
Однако, из примера видно, что тесты используются как контрольная точка — если шаг «apply_testing_checks» не выполнен, машина не вернётся в пул.
Прочитайте главу о делегировании о «max_fail_percentage», и вы также сможете контролировать, сколько тестов с ошибками остановят поэтапное обновление.
Этот подход также можно изменить, чтобы запустить шаг с тестовой машины удалённо на другой машине:
---
- hosts: webservers
serial: 5
pre_tasks:
- name: take out of load balancer pool
command: /usr/bin/take_out_of_pool {{ inventory_hostname }}
delegate_to: 127.0.0.1
roles:
- common
- webserver
tasks:
- script: /srv/qa_team/app_testing_script.sh --server {{ inventory_hostname }}
delegate_to: testing_server
post_tasks:
- name: add back to load balancer pool
command: /usr/bin/add_back_to_pool {{ inventory_hostname }}
delegate_to: 127.0.0.1
В примере выше скрипт запускается с тестового сервера на удалённом узле до возвращения его в пул.
В случае проблемы, исправить несколько серверов, которые завершились неудачно, используя автоматически сгенерированный Ansible файл retry, чтобы повторить развертывание только на этих серверах.
Достижение непрерывного развертывания
При необходимости вышеуказанные техники можно расширить для поддержки практик непрерывного развертывания.
Рабочий процесс может выглядеть так:
- Write and use automation to deploy local development VMs - Have a CI system like Jenkins deploy to a staging environment on every code change - The deploy job calls testing scripts to pass/fail a build on every deploy - If the deploy job succeeds, it runs the same deploy playbook against production inventory
Некоторые пользователи Ansible используют этот подход для развертывания раз в полчаса или час, не выводя всю инфраструктуру из строя. Культура автоматизированного QA имеет жизненно важное значение, если вы хотите достичь такого уровня.
Если вы всё ещё используете большое количество ручного QA, вы всё равно должны принимать решение о ручном развертывании, но это может помочь работать по шаблонам поэтапных обновлений из предыдущего раздела и включать некоторые базовые проверки состояния с использованием модулей «script», «stat», «uri» и «assert».
Заключение
Ansible считает, что вам не нужен другой фреймворк для проверки основных свойств вашей инфраструктуры. Это потому, что Ansible — это система на основе порядка, которая немедленно завершит выполнение на узле при возникновении необработанных ошибок и предотвратит дальнейшую конфигурацию этого узла. Это позволяет обнаружить ошибки и отобразить их в сводке по завершении выполнения Ansible.
Однако, поскольку Ansible разработан как система многоуровневой оркестрации, он очень легко интегрирует тесты в конец выполнения playbook, используя отдельные задачи или роли. При использовании с поэтапными обновлениями шаги тестирования могут принимать решения о возвращении машины в пул балансировщика нагрузки или нет.
Наконец, поскольку ошибки Ansible передаются до кода возврата самой программы Ansible, и Ansible по умолчанию работает в простом режиме отправки, Ansible отлично подходит для включения в среду сборки, если вы хотите использовать его для развертывания систем как части конвейера непрерывной интеграции/непрерывной доставки, как описано в разделах выше.
Фокус должен быть не на тестировании инфраструктуры, а на тестировании приложения, поэтому мы настоятельно рекомендуем обсудить с вашей командой QA, какие тесты будут уместны при каждом развертывании виртуальных машин разработки и какие тесты они хотели бы запускать в среде Staging при каждом развертывании. Очевидно, что на этапе разработки отличным вариантом являются модульные тесты. Но не тестируйте свой playbook модульно. Ansible описывает состояния ресурсов декларативно, поэтому это не требуется. Однако, если есть случаи, когда вам нужно убедиться в чём-то, это замечательно, и такие модули как stat/assert отлично подходят для этой цели.
В общем, тестирование — это очень организационный и зависящий от сайта аспект. Каждый должен это делать, но то, что больше всего подходит для вашей среды, будет меняться в зависимости от того, что вы развертываете и кто это использует — но все выигрывают от более надёжной и стабильной системы развертывания.
См. также
- О Модулях
- Вся документация по модулям Ansible
- Playbooks
- Вступление к playbook
- Делегирование, Поэтапные обновления и Локальные действия
- Делегирование, полезно для работы с балансировщиками нагрузки, облаками и локально выполняемыми шагами.
- Список рассылки пользователей
- Есть вопрос? Загляните в группу Google!
- irc.freenode.net
- #ansible IRC чат-канал
© 2012–2018 Michael DeHaan
© 2018–2019 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.4/test_strategies.html