Тестируем мобильное приложение в
суровых реалиях интернета
Усов Андрей
a.usov@2gis.ru    usovand@gmail.com    techno.2gis.ru
•  2 года в тестировании
О себе
•  2 года в тестировании
•  Автоматизирую тестирование бекендов
О себе
•  2 года в тестировании
•  Автоматизирую тестирование бекендов
•  Разрабатываю инстументы для
тестирования
О себе
Мобильное приложение 2ГИС v4
•  iOS, Widows Phone, Android (beta)
Мобильное приложение 2ГИС v4
•  iOS, Widows Phone, Android (beta)
•  3 млн. пользователей
Мобильное приложение 2ГИС v4
•  iOS, Widows Phone, Android (beta)
•  3 млн. пользователей
•  9 стран
•  288 городов
Мобильное приложение 2ГИС v4
•  iOS, Widows Phone, Android (beta)
•  3 млн. пользователей
•  9 стран
•  288 городов
•  Работает офлайн
Ищи 2ГИС в любом магазине приложений
Доставка
данных
Нагрузка
•  Пиковый трафик 4 Gbps
Нагрузка
•  Пиковый трафик 4 Gbps
•  Максимум 400 rps
Нагрузка
•  Пиковый трафик 4 Gbps
•  Максимум 400 rps
•  Объем данных 512 Tb в месяц
Нагрузка
•  Пиковый трафик 4 Gbps
•  Максимум 400 rps
•  Объем данных 512 Tb в месяц
Но ещё не вышло обновление для Android (65% пользователей)
Критичность
•  Всегда актуальные данные
Критичность
•  Всегда актуальные данные
•  Обязательства перед партнерами
Критичность
•  Всегда актуальные данные
•  Обязательства перед партнерами
•  Доставка фич
Технология
доставки
Устройство
Приложение
Сеть
Серверы
Nginx
Хранилище
Связь
Выбирает клиент
Требования
•  Выбор стабильных серверов для загрузки
Требования
•  Выбор стабильных серверов для загрузки
•  Устойчивость к отказам даже в процессе закачки
Требования
•  Выбор стабильных серверов для загрузки
•  Устойчивость к отказам даже в процессе закачки
•  Нативные методы фоновой загрузки (iOS, Windows Phone)
Требования
•  Выбор стабильных серверов для загрузки
•  Устойчивость к отказам даже в процессе закачки
•  Нативные методы фоновой загрузки (iOS, Windows Phone)
Оказалось, что эти пункты плохо уживаются
Точки отказа
Нет доступа к сети
Нет связи с сервером
Встроенная реклама
Кончился Интернет
Сервер упал
Нет связи с хранилищем
Хранилище упало
Плохая связь
Обрывы
Сломалось все
И еще
•  Перегрузки на сервере
И еще
•  Перегрузки на сервере
•  Редиректы от провайдера
И еще
•  Перегрузки на сервере
•  Редиректы от провайдера
•  Ошибки DNS
И еще
•  Перегрузки на сервере
•  Редиректы от провайдера
•  Ошибки DNS
•  Баги в самом web-сервере
И еще
•  Перегрузки на сервере
•  Редиректы от провайдера
•  Ошибки DNS
•  Баги в самом web-сервере
Все эти сценарии необходимо проверить
Проблемы
Сложная настройка окружения
•  Изменение конфигурации web-сервера (Nginx, Apache)
Сложная настройка окружения
•  Изменение конфигурации web-сервера (Nginx, Apache)
•  Выполнение команд в хост-системе
Сложная настройка окружения
•  Изменение конфигурации web-сервера (Nginx, Apache)
•  Выполнение команд в хост-системе
•  Запуск произвольного скрипта на сервере
Большое количество работы
•  Серверов несколько
Большое количество работы
•  Серверов несколько
•  Платформы три
Большое количество работы
•  Серверов несколько
•  Платформы три
•  Релизов много
Ограничение по ресурсам
•  Времени мало
Ограничение по ресурсам
•  Времени мало
•  Людей мало
Ограничение по ресурсам
•  Времени мало
•  Людей мало
•  Людей с экспертизой очень мало
Ограничение по ресурсам
•  Времени мало
•  Людей мало
•  Людей с экспертизой очень мало
Но тестировать все равно надо
Решение
Требования к инструменту
•  Минимум операций
Требования к инструменту
•  Минимум операций
•  Простота использования
Требования к инструменту
•  Минимум операций
•  Простота использования
•  Простота реализации
Требования к инструменту
•  Минимум операций
•  Простота использования
•  Простота реализации
•  Надежность
Декомпозиция задачи
•  Копирование файлов на сервер
Декомпозиция задачи
•  Копирование файлов на сервер
•  Конфигурационный файл
Декомпозиция задачи
•  Копирование файлов на сервер
•  Конфигурационный файл
•  Скрипт
Декомпозиция задачи
•  Копирование файлов на сервер
•  Конфигурационный файл
•  Скрипт
•  Выполнение команд на сервере
Декомпозиция задачи
•  Копирование файлов на сервер
•  Конфигурационный файл
•  Скрипт
•  Выполнение команд на сервере
•  Перезапуск сервера
Декомпозиция задачи
•  Копирование файлов на сервер
•  Конфигурационный файл
•  Скрипт
•  Выполнение команд на сервере
•  Перезапуск сервера
•  Запуск скрипта
Ansible
Аналоги
Ansible
Почему Ansible?
Почему Ansible?
Почему Ansible?
Про Ansible
Про Ansible
Про Ansible
Про Ansible
Про Ansible
Про Ansible
Примеры
Inventory. Список серверов
[hosts]
host1 ansible_ssh_host=127.0.0.1
ansible_ssh_user=user ansible_ssh_pass=123
host2 ansible_ssh_host=127.0.0.2
ansible_ssh_user=user ansible_ssh_pass=456
Inventory. Задаем переменные
[hosts:vars]
return_for_files=502
limit_rate=256K
upstream=root.domain.name
nginx_apply_method=restarted
Playbook. Запускаем команду
- name: run-script | Run script
command: tc --help
async: 2678400
poll: 0
Playbook. Копируем файлы
- name: configure-nginx | Configure nginx
template: src=../resources/config.j2
dest=./your-server.conf
owner=root group=root mode=0644
Шаблоны
#содержимое config.j2
...
return {{return_for_files}};
...
Эта переменная в inventory
[hosts:vars]
return_for_files=502
limit_rate=256K
upstream=root.domain.name
nginx_apply_method=restarted
Вернемся в playbook
- name: configure-nginx | Configure nginx
template: src=../resources/config.j2
dest=./your-server.conf
owner=root group=root mode=0644
Полученный файл
#содержимое your-server.conf
...
return 502;
...
Playbook. Перезапускаем сервер
- name: restart-nginx | Restart nginx
service: name=nginx state=restarted
when: nginx_apply_method == "restarted"
Та самая переменная в inventory
[hosts:vars]
return_for_files=502
limit_rate=256K
upstream=root.domain.name
nginx_apply_method=restarted
Реализация
•  Разбиваем на классы конфигураций
Реализация
•  Разбиваем на классы конфигураций
•  Коды состояния HTTP
Реализация
•  Разбиваем на классы конфигураций
•  Коды состояния HTTP
•  Лимиты скорости
Реализация
•  Разбиваем на классы конфигураций
•  Коды состояния HTTP
•  Лимиты скорости
•  Определяем набор параметров для каждого класса
Реализация
•  Разбиваем на классы конфигураций
•  Коды состояния HTTP
•  Лимиты скорости
•  Определяем набор параметров для каждого класса
•  Пишем playbook'и
Важные моменты
•  Каждая операция должна быть обратима
Важные моменты
•  Каждая операция должна быть обратима
•  Нужно уметь приводить серверы в исходное состояние
Важные моменты
•  Каждая операция должна быть обратима
•  Нужно уметь приводить серверы в исходное состояние
•  Пишем мониторинг состояния
Профит
Ранее
•  Подлючаемся к каждому серверу
Ранее
•  Подлючаемся к каждому серверу
•  Копируем файлы
Ранее
•  Подлючаемся к каждому серверу
•  Копируем файлы
•  Редактируем конфигурацию
Ранее
•  Подлючаемся к каждому серверу
•  Копируем файлы
•  Редактируем конфигурацию
•  Запускаем команды
Ранее
•  Подлючаемся к каждому серверу
•  Копируем файлы
•  Редактируем конфигурацию
•  Запускаем команды
И так каждый раз
Сейчас
•  Меняем пару параметров в inventory
Сейчас
•  Меняем пару параметров в inventory
•  Запускаем нужный playbook
Сейчас
•  Меняем пару параметров в inventory
•  Запускаем нужный playbook
И всё
Интерфейс
Делаем web интерфейс
•  Интегрируем в Jenkins
Делаем web интерфейс
•  Интегрируем в Jenkins
•  Используем стандартные средства SCM
Делаем web интерфейс
•  Интегрируем в Jenkins
•  Используем стандартные средства SCM
•  Пишем что-то своё
Результаты
Результаты
•  Тестирование обновления данных стало простым
Результаты
•  Тестирование обновления данных стало простым
•  Найдено большое количество дефектов
Результаты
•  Тестирование обновления данных стало простым
•  Найдено большое количество дефектов
•  Изучено поведение мобильных платформ
Ссылки
•  http://www.ansible.com/ - Ansible
•  http://habrahabr.ru/post/211306/ - "Обзор: Puppet, Chef, Ansible, Salt"
•  https://jenkins-ci.org/ - Jenkins
Вопросы?
Усов Андрей
a.usov@2gis.ru
usovand@gmail.com

«Тестируем мобильное приложение в суровых реалиях Интернета» – Андрей Усов, 2ГИС