Привет! Меня зовут Денис Веренцов, я Android-инженер из команды Emcee. Это технопродукт Авито, универсальное решение для запуска iOS и Android-тестов, с его помощью можно быстрее выкатывать новые фичи пользователям и клиентам. В этой статье я расскажу, как можно развернуть облачную инфраструктуру для запуска нативных автотестов Android-приложений на основе разработанного нами решения.
Статья будет полезна тем, кто хочет организовать инфраструктуру для запуска тестов, но не обладает подходящим для этого «железом». Материал также будет интересен тем, у кого есть желание попробовать технологию Emcee в деле.
Emcee и его преимущества
Emcee — это инструмент для мобильных автотестов. С его помощью можно развернуть инфраструктуру для нативных автотестов Android/iOS и запускать тесты, эффективно утилизируя ресурсы и повышая time-to-market.
Основные преимущества Emcee:
- эффективность: тесты запускаются сразу на всех доступных ресурсах, не нужно выделять отдельные пулы ресурсов под определенные запуски тестов;
- автоматический менеджмент жизненного цикла эмуляторов;
- гибкая конфигурация запуска тестов: разные стратегии деления тестов, повторы упавших тестов, настройка таймаутов и так далее.
Облачная инфраструктура
На мой взгляд, у облачной инфраструктуры есть свои плюсы и минусы.
Плюсы:
- можно быстро получить «железо» в широком спектре конфигураций. Это бывает полезно при проведении быстрых экспериментов или тестировании новых технологий;
- можно обратиться в техподдержку, если есть проблемы или вопросы;
- некоторые провайдеры на первое время дают гранты или бонусные рубли — первые эксперименты можно проводить бесплатно.
Минусы:
- пожалуй, самый главный минус — стоимость: аренда мощного сервера или виртуальной машины может быть очень дорогой. Это десятки или даже сотни тысяч рублей в месяц;
- не у всех провайдеров есть возможность выделить машины с KVM. У каждого провайдера нужно уточнять этот момент через техподдержку или документацию, а также проверять доступность KVM вручную;
- нужно отдельно решать вопросы безопасности, так как без дополнительной подготовки такая инфраструктура открыта для интернета;
- если для тестов нужны дополнительные инструменты или данные из корпоративной сети, то нужно думать, как соединить облачную инфраструктуру и корпоративную сеть.
У Emcee есть ряд требований к железу, поэтому перед арендой облачных мощностей нужно убедиться, что железо соответствует требованиям.
Требования такие:
- OS на базе Linux, Docker, KVM (Kernel-based Virtual Machine)*;
- процессор с архитектурой x86-64;
- достаточное количество ресурсов для запуска нескольких docker-контейнеров. Минимум 4 CPU и 8ГБ RAM.
*На данный момент наличие KVM является обязательным, так как эта технология позволяет значительно улучшить перформанс Android-эмулятора. Подробнее можно прочесть в официальной документации эмулятора.
Аренда облачных ресурсов
Для примера был выбран провайдер VK Cloud, на котором в качестве демонстрации я арендую подходящую виртуальную машину (далее ВМ).
Создадим новый инстанс ВМ. Я выбрал Ubuntu 22.04, 8 CPU и 16ГБ RAM, а также диск SSD на 100ГБ.
Обратите внимание, что изначально конфигурация NESTED-X-X не была доступна. Для её получения я написал в техподдержку и спросил, как можно получить работающий KVM или рабочую вложенную виртуализацию внутри моей ВМ.
Далее настраиваем сеть:
- Для доступа к ВМ я указал свой SSH-ключ. Ключ можно создать или указать свой в меню выбора ключа.
- Дополнительно я добавил настройку Firewall: добавил новую группу безопасности emcee, в которой указал, какой входящий трафик разрешен для моей ВM.
3.⠀В группе безопасности emcee я указал порты, необходимые для работы Emcee: 8081, 8082 и 41000.
Следующим шагом предлагается настроить резервное копирование. Я отключил эту опцию и далее выбрал «Создать инстанс».
Немного ждем, пока ВМ подготовится и запустится.
После этого можно подключаться к ВМ по SSH с помощью ключа, который мы указывали при создании ВМ. Дополнительно в общей информации о ВМ описан способ подключения.
Как подготовить инфраструктуру
Подключаемся к ВМ по SSH:
ssh -i vktest ubuntu@<VM ip address>
Проверяем доступность KVM
После успешного подключения нужно проверить, что KVM доступен на данной ВМ. Для этого нужно установить утилиты cpu-checker и libvirt-clients . Можно установить что-то одно, но для примера я установлю обе.
Устанавливаем cpu-checker:
sudo apt-get install cpu-checker
И после установки вызываем в консоли команду sudo kvm-ok, которая должна показать наличие или отсутствие KVM. Вывод команды, если KVM доступен:
INFO: /dev/kvm existsKVM acceleration can be used
Если KVM недоступен, то вывод будет такой:
INFO: Your CPU does not support KVM extensionsKVM acceleration can NOT be used
Устанавливаем libvirt-clients:
sudo apt-get update && sudo apt-get install libvirt-daemon-system libvirt-clients
После установки вызываем в консоли команду virt-host-validate qemu. Вывод команды, если KVM доступен:
QEMU: Checking for hardware virtualization : PASSQEMU: Checking if device /dev/kvm exists : PASSQEMU: Checking if device /dev/kvm is accessible : FAIL (Check /dev/kvm is world writable or you are in a group that is allowed to access it)QEMU: Checking if device /dev/vhost-net exists : PASSQEMU: Checking if device /dev/net/tun exists : PASSQEMU: Checking for cgroup 'cpu' controller support : PASSQEMU: Checking for cgroup 'cpuacct' controller support : PASSQEMU: Checking for cgroup 'cpuset' controller support : PASSQEMU: Checking for cgroup 'memory' controller support : PASSQEMU: Checking for cgroup 'devices' controller support : WARN (Enable 'devices' in kernel Kconfig file or mount/enable cgroup controller in your system)QEMU: Checking for cgroup 'blkio' controller support : PASSQEMU: Checking for device assignment IOMMU support : WARN (No ACPI DMAR table found, IOMMU either disabled in BIOS or not supported by this hardware platform)QEMU: Checking for secure guest support : WARN (Unknown if this platform has Secure Guest support)
Если KVM недоступен, то вывод может быть примерно таким:
QEMU: Checking for hardware virtualization : FAIL (Host not compatible with KVM; HW virtualization CPU features not found. Only emulated CPUs are available; performance will be significantly limited)QEMU: Checking if device /dev/vhost-net exists : PASSQEMU: Checking if device /dev/net/tun exists : PASSQEMU: Checking for cgroup 'cpu' controller support : PASSQEMU: Checking for cgroup 'cpuacct' controller support : PASSQEMU: Checking for cgroup 'cpuset' controller support : PASSQEMU: Checking for cgroup 'memory' controller support : PASSQEMU: Checking for cgroup 'devices' controller support : PASSQEMU: Checking for cgroup 'blkio' controller support : PASSQEMU: Checking for device assignment IOMMU support : WARN (Unknown if this platform has IOMMU support)QEMU: Checking for secure guest support : WARN (Unknown if this platform has Secure Guest support)
В случае, если после проверок обнаружилось, что KVM недоступен, то нужно узнать у техподдержки, как его включить/получить. А если такой возможности нет, то следует сменить провайдера.
Запускаем инфраструктуру Emcee через Docker Compose
Система Emcee запускается на основе docker-контейнеров. Минимальный набор контейнеров включается в себя три контейнера с сущностями:
- очередь Emcee распределяет тесты по воркерам в завиcимости от стратегии распределения и повтора тестов;
- воркер Emcee запускает тесты и собирает их результаты, управляет жизненным циклом Android-эмуляторов, которые запускаются внутри контейнера;
- Artifactory — готовая система для менеджмента артефактов. Нужна для передачи файлов между воркерами и клиентами Emcee.
Так как используются docker-контейнеры, Emcee можно развернуть разными способами: через Docker или Docker Compose, а также через Kubernetes. Для простоты я выберу способ с Docker Compose, который можно установить по официальной документации.
Нам потребуется всего 2 файла, создадим docker-compose.yaml:
version: '3'services:emcee-queue-service:image: avitotech/emcee-queue:21.5.0container_name: emcee-queue-serviceports:- 41000:41000queue-worker:image: avitotech/emcee-worker:21.5.0env_file:- emcee-worker.envdepends_on:- emcee-queue-servicedeploy:replicas: 2devices:- "/dev/kvm:/dev/kvm"emcee-artifactory:image: docker.bintray.io/jfrog/artifactory-oss:7.63.11container_name: emcee-artifactoryports:- 8081:8081- 8082:8082volumes:- emcee_artifactory:/var/opt/jfrog/artifactoryvolumes:emcee_artifactory:
Создадим второй файл, где указываются переменные окружения для воркера emcee-worker.env:
EMCEE_WORKER_QUEUE_URL=http://emcee-queue-service:41000EMCEE_WORKER_LOG_LEVEL=info
Имя хоста emcee-queue-service резолвится в локальный адрес контейнера с таким же именем.
Далее поднимаем контейнеры командой:
docker compose up -d
И проверяем, что поднятие прошло успешно:
> docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESb631f9f32fa2 avitotech/emcee-worker:21.1.0 "./entrypoint.sh" 45 seconds ago Up 45 seconds 41001/tcp ubuntu-queue-worker-2600a8a769bff avitotech/emcee-worker:21.1.0 "./entrypoint.sh" 45 seconds ago Up 44 seconds 41001/tcp ubuntu-queue-worker-16f7f5aca1fc0 docker.bintray.io/jfrog/artifactory-oss:7.63.11 "/entrypoint-artifac…" 46 seconds ago Up 45 seconds 0.0.0.0:8081-8082->8081-8082/tcp, :::8081-8082->8081-8082/tcp emcee-artifactorycd2c4c1cb7b3 avitotech/emcee-queue:21.1.0 "/usr/local/bin/entr…" 46 seconds ago Up 45 seconds 0.0.0.0:41000->41000/tcp, :::41000->41000/tcp emcee-queue-service
Дополнительно можно проверить логи контейнера с воркером и увидеть, что воркер готов к работе:
> docker logs --tail 2 b631f9f32fa2[INFO] [HttpServer] 2024-08-23 08:00:33.610: REST server at 41001 port started[INFO] [StartWorkerCommand] 2024-08-23 08:00:33.611: Worker is ready for work
Кроме запуска контейнеров нужно настроить Artifactory. Для этого нужно:
- зайти по адресу <ваш ip>:8082 и пройти первоначальную настройку. Для первого входа использовать первичные данные admin и password;
- создать новый репозиторий с типом Generic и именем на ваш выбор;
- создать нового юзера, данные которого будут использоваться в клиентах Emcee и в воркерах, либо включить анонимный доступ. Здесь важно выдать новому юзеру, в том числе анонимному, права на чтение/запись/удаление. Если создан новый юзер, то в конфигурации воркера нужно задать его username/password в файле конфигурации emcee-worker.env . Подробнее про конфигурацию воркера описано здесь.
Подробнее про настройку Artifactory можно прочесть в документации Emcee.
Отмечу, что если у вас уже есть готовый и настроенный Artifactory, то можно использовать его. Главное, чтобы Artifactory был доступен и для клиентов, и для воркеров Emcee.
На этом запуск и настройка Emcee завершены, наша система готова принимать тесты.
Запускаем тесты через Emcee
Для запуска тестов в Emcee нам нужен клиент Emcee, который можно скачать на странице с релизами.
Android-клиенты бывают двух видов:
- cli-утилита;
- Gradle plugin.
Я выберу cli-утилиту, которую можно установить разными способами.
Для запуска тестов нам потребуется файл с конфигурацией, например, config.yaml:
queue:baseUrl: http://emcee-network-address:41000 # адрес очереди Emceetests:configurations:- platform: androidappApk: ./apks/regress-debug.apktestApk: ./apks/regress-debug-androidTest.apktestTimeout: 120screenRecordConfiguration:videoRecordStrategy: record_nonedevices:- sdkVersion: 31 # версия Android SDK, на которой будут запущены тесты на эмулятореdeviceType: "default"outputs:- junit # включаю создание отчета JUnit- allure # включаю загрузку файлов для Allure отчетаstorage:type: artifactorybaseUrl: http://emcee-network-address:8081/artifactory/ # адрес настроенной Artifactoryrepository: emcee-transportuser: "emcee_user"password: "emcee_password"
Здесь файлы apk с приложением и тестами я положил рядом с файлом конфига. Как показывает практика, разные команды по-разному создают apk в рамках своих конвейеров на CI. Поэтому можно указать свой путь до актуальных apk файлов.
Бинарный файл с cli-утилитой я скачал вручную и теперь мой запуск прогона тестов выглядит так:
./emcee run config.yaml --outdir=results
После прогона тестов я получаю финальный результат:
Emcee run finished.Sent tests count: 12Executed tests count: 12Run status: FailedSuccessful tests count: 10Skipped tests count: 1Skipped tests:com.avito.emcee.regress.ExampleInstrumentedTest#assumptionFalseFailed tests count: 1Failed tests:com.avito.emcee.regress.ExampleInstrumentedTest#failedTests results written to: /my/path/results/emcee_artifacts/c15f0e85-7f3a-4007-95cc-25101b3aa231com.avito.emcee.client.internal.result.JobResultHasFailedTestsException: These tests have failed:com.avito.emcee.regress.ExampleInstrumentedTest#failed
Таким образом, мы успешно запустили прогон тестов в Emcee.
Бонус: готовое облако
Для тех, кто не хочет заморачиваться с виртуальными машинами и провайдерами, можно попробовать сразу запустить тесты в нашем облаке Emcee Cloud. В Emcee Сloud не нужно платить за аренду мощностей, плата берется только за время выполнения тестов. А для всех новых клиентов мы даем бесплатную квоту в 300 минут на прогоны тестов.
Три главных факта про Emcee
В современном мире можно быстро арендовать мощности под любые задачи, в том числе под инфраструктуру для автотестов.
- Инструмент Emcee позволяет быстро развернуть масштабируемую инфраструктуру для автотестов Android (как попробовать Emcee для iOS можно почитать здесь).
- Для запуска Emcee нужен подходящий сервер с Docker Compose, на котором можно развернуть контейнеры с Emcee и Artifactory: Artifactory нужно настроить либо использовать готовый.
- Для тех, у кого нет своего железа и кто не готов платить за его аренду, мы создали сервис Emcee Cloud, где можно запускать свои тесты в облаке.
Спасибо за уделенное время для статьи!