Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Переход на PHP 5.5 и юнит-тесты

Anna | 29.05.2014 | нет комментариев

С момента перехода с PHP 4.4 на PHP 5.3 в Badoo прошло теснее 4 года, пришла пора обновлять PHP, на данный раз сразу на версию PHP 5.5. Помимо новых фич, новая версия PHP в следующий раз принесла нам значительное увеличение продуктивности, следственно у нас было много причин для апгрейда. В этой статье мы расскажем о том, как мы переходили на PHP 5.5, какие «грабли» собрали, и для чего в следующий раз переписывали нашу систему для запуска юнит-тестов на основе PHPUnit.

Рис 1. Всеобщая зодчество

«Грабли» при переходе с PHP 5.3 на PHP 5.5

В прошлый раз мы переходили с четвертой версии PHP на пятую, причём наша версия PHP 5.3 содержала патчи, Дабы работал «ветхий» синтаксис PHP, скажем, $a = &new ClassName();, и Дабы наша кодовая база могла трудиться на PHP4 и PHP5 единовременно. На данный раз у нас таких ограничений не было, следственно при переходе мы легко обнаружили и заменили все устаревшие конструкции на больше актуальные, и на этом переписывание кода было завершено.

Основные задачи, которые у нас появились:

  • часть deprecated-фич языка была убрана;
  • растяжение mysql стало deprecated;
  • низкая продуктивность растяжения runkit, которое мы используем при написании юнит-тестов.

Позже перехода на PHP 5.5 наши юнит-тесты начали проходить гораздо дольше (в несколько раз), следственно мы решили в следующий раз доработать нашу «пускалку», Дабы решить эту задачу.

Runkit и PHP 5.4

С поддержкой растяжения xhprof мы стремительно узнали, что наши тесты «тормозят» из-за того, что продуктивность растяжения runkit значительно упала, следственно мы стали искать причину. В результате оказалось, что задача, по каждой видимости, в добавлении «необъяснимого» runtime cache для PHP 5.4, тот, что нужно сбрасывать всякий раз позже вызова функции “runkit_*_redefine”.

Растяжение runkit при всяком вызове проходится по каждому зарегистрированным классам, способам и функциям и сбрасывает данный кэш. Мы наивно испробовали это отключить, но позже этого PHP начал падать, следственно нам пришлось искать другое решение.

Доктрина «микросьютов» (microsuite)

До перехода на PHP 5.5 у нас теснее была пускалка юнит-тестов в виде надстройки над phpunit, которая разделяла один огромный suite юнит-тестов на несколько больше мелких: на тот момент мы применяли запуск тестов в 11 потоков (Илья Кудинов теснее рассказывал об этом на конференциях, в том числе на конференции Badoo LoveQA: www.youtube.com/watch?v=gAisPsfbLkg).

Мы провели несколько примитивных бенчмарков и узнали, что тесты проходят в несколько раз стремительней, если поделить наш suite не на 11 частей, как это было прежде, а на 128 либо огромнее (при фиксированном числе процессорных ядер). В всяком сьюте получалось каждого около 10­15 файлов, следственно мы назвали эту доктрину «микросьютами». Таких микросьютов у нас получилось около 150 штук, и всякий из них сомнительно отлично подходил, Дабы быть «заданием» для какого­нибудь скрипта (при этом задание состоит из списка файлов для соответствующего сьюта, а он теснее, в свою очередь, запускает phpunit с соответствующими параметрами).

Тесты «в облаке»

Так уж получилось, что автор этой статьи не имеет никакого отношения к QA, но но был одним из основных разработчиков «нового скриптового фреймворка», тот, что, по сути, является «облаком» для скриптов и поддерживает доктрину заданий (о нашем облаке мы тоже многократно рассказывали на конференциях и непременно расскажем о нём подробнее на Прогре). А раз у нас есть задания в виде списков файлов для всякого сьюта phpunit, значит, их тоже дозволено «запихнуть в облако», что мы и решили сделать. Идея дюже простая: раз у нас есть много мелких заданий, то они могут быть запущены на нескольких серверах самостоятельно друг от друга, что должно ещё огромнее ускорить прохождение тестов.

Всеобщая зодчество

Мы запускаем тесты из нескольких различных источников:

  1. механические прогоны тестов с поддержкой AIDA (http://habrahabr.ru/company/badoo/blog/169417/):
    — по ветке (git branch) задачи;
    — по «билду» — коду, тот, что уедет на production;
    — по ветке master;
  2. «ручные» прогоны тестов, инициированные разработчиками либо тестировщиками с dev­-сервера.

Все эти виды прогонов тестов объединяет то, что необходимо вначале «стянуть» (fetch) ветку из какого­то источника, а потом запустить прогон тестов на этой ветке.
Данный факт и определил архитектуру нашей новой «облачной» пускалки тестов (Рис. 1, в начале статьи):

Вначале создается одно задание для master-процесса, тот, что:

  • выбирает доступную директорию в базе данных (Рис. 2);
  • скачивает ветку git из надобного места (всеобщий репозиторий либо dev-сервер);
  • (опционально) исполняет git merge master;
  • (опционально) создает новейший коммит со всеми локальными изменениями.

Рис 2. Доступные директории в MySQL

Позже этого master­процесс анализирует подлинный phpunit suite для прогона тестов и делит его на надобное число частей (не больше 10 файлов на один microsuite). Получившиеся задания (thread-процессы) добавляются в виде заданий в облако и начинают исполнение на доступных для выполнения серверах.

Первое задание, которое попадает на новейший сервер, подготавливает выбранную директорию для прогона тестов, забирая необходимый коммит с сервера, на котором работает master­процесс. Для того Дабы все остальные задания, которые пришлись на соответствующий сервер, не занимались тем же самым единовременно с первым заданием, применяются файловые блокировки (Рис. 3).

Единовременно могут идти несколько прогонов тестов для больше полной утилизации источников нашего кластера: тесты проходят стремительно, и существенную часть времени занимает подготовка начальных текстов, нежели непринужденно исполнение кода.

Рис. 3. Блокировки при подготовке директории

Некоторые тесты могут идти гораздо дольше остальных, и у нас есть статистика времени прохождения по всякому тесту, следственно мы используем эту информацию, Дабы запускать «длинные» тесты в первую очередь. Такая тактика разрешает добиться больше равномерной загрузки серверов в процессе выполнения тестов, а также сократить всеобщее время их выполнения (Рис. 4).

Рис 4. Контроль времени исполнения тестов

«При отличной погоде» каждый наш suite из 28 000 юнит­тестов проходит за 1 минуту, следственно тесты, которые длятся дольше, становятся «бутылочным горлышком», и наша система вывешивает авторов соответствующих тестов на «доску позора», которая показывается при всяком прогоне тестов. Помимо этого, если осталось немного тестов, показывается список тех, кто остался (Рис. 5).

Рис 5. Доска позора: список тестов, которые исполняются огромнее минуты

Сама по себе пускалка юнит-тестов была первым скриптом, тот, что был переведен в облако. Она помогла устранить много багов и недоработок в самом облаке, заодно гораздо ускорив прохождение юнит-тестов.

Итоги

Позже перехода на PHP 5.5 мы сумели применять новые фичи языка, гораздо снизили потребление CPU на наших серверах (в среднем на 25%), а также перевели в облако нашу пускалку юнит­тестов. Последнее дозволило нам снизить всеобщее время прохождения тестов с 5­6 минут (на PHP 5.5 — десятков минут) до одной минуты, заодно переместив нагрузку с всеобщего dev­-сервера в облако.

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB