Компания
294,03
рейтинг
20 августа 2013 в 15:00

Разработка → Процесс разработки и выкатка релизов в Badoo. Автоматическое тестирование. Девелоперское окружение


В июле мы вместе с ведущими IT-Kompot и релиз-инженерами Badoo Владиславом Черновым и Олегом Оямяэ записали выпуск подкаста «Процесс разработки и выкатка релизов в Badoo. Автоматическое тестирование. Девелоперское окружение».
Так как прошлый подкаст вызвал интерес у слушателей и читателей, то этот подкаст мы тоже превратили в статью.

О чем говорили:
Процесс разработки и выкатки релизов в компании Badoo. Используемые инструменты.
  • GIT Workflow. Каждая задача в отдельной ветке;
  • Использование JIRA, TeamCity и AIDA;
  • Формирование релиза и выкатка двух релизов в день. Проблемы и их решения (откат, патчи и т.д.).
Автоматическое тестирование. Рецепт быстрого прогона большого количества тестов.
  • Что мы используем;
  • Как гоняем тесты;
  • Code Coverage;
  • Пускалка. 18000 тестов за 3,5 минуты.
Девелоперское окружение в команде, разрабатывающей сложную распределенную систему
И рекомендации от ребят: полезные книги, статьи и т.д.


Антон Сергеев: Всем привет, вы слушаете 48 выпуск подкаста «IT-компот», и с вами его ведущие Антон Копылов.

Антон Копылов: И Антон Сергеев, привет.

Антон Сергеев: Сегодня у нас в гостях бравые ребята ― релиз-инженеры компании Badoo Олег Оямяэ и Владислав Чернов. Ребята, привет!

Владислав Чернов: Привет.

Олег Оямяэ: Привет.

Антон Сергеев: У нас получается цикл подкастов с компанией Badoo. Сегодня мы решили более подробно поговорить про область, которая является если не гордостью компании Badoo, то уж точно очень важным достижением и явным успехом. Это то, что компания делает успешно выкатку новых релизов, используя при этом полностью автоматизированные средства. Плюс в компании очень интересно сделан и настроен процесс тестирования. Он позволяет эффективно проводить большое количество тестов. Все, кто слушал прошлый выпуск подкаста, уже знают про 2 релиза в день ― про это говорил Алексей Рыбак.
Ну что, давайте начнём. Влад и Олег, я вам предлагаю рассказать коротко о себе и о том, чем вы занимаетесь в Badoo.


Владислав Чернов: Здравствуйте ещё раз. Мы с Олегом занимаемся в Badoo конфигурационным управлением и релиз-инжинирингом. Если говорить про себя, то я почти всю свою трудовую карьеру занимаюсь именно релиз-инжинирингом: начинал как обычный релиз-инженер, делал очень много руками, мы выкатывали простые релизы, а потом я ушёл в автоматизацию и всё больше и больше автоматизировал, накручивая этот процесс. Сейчас занимаюсь автоматизацией всего бизнес-процесса разработки и тестирования в Badoo.

Антон Сергеев: Понятно, круто. А Олег ― твой коллега и тебе в этом помогает, правильно?

Олег Оямяэ: На самом деле у меня немного другая история. Я был разработчиком и тимлидом в других компаниях, а в Badoo решил попробовать себя в новой для меня сфере ― в релиз-инжиниринге. Но я занимаюсь больше программированием, а не автоматизацией. Давайте я расскажу немного о том, как всё было устроено в Badoo с начала и до наших дней.

Антон Сергеев: Да, давайте поговорим про историю вашего процесса разработки, как вы всё это начали делать, ведь до такого состояния, как сейчас, удалось дойти явно не сразу. Наверное, было много всяческих преград и задач, которые приходилось решать. Расскажите, как это всё начиналось, почему получилось так, как сейчас, и как вы к этому пришли.

Олег Оямяэ: Довольно длительное время в Badoo в качестве системы контроля версий использовался SVN. То есть большую часть существования Badoo использовался SVN, и он даже до сих пор в некоторых частях используется. (Примечание: в далеких-далеких годах, конечно, был CVS).

Антон Сергеев: Сейчас некоторые слушатели, наверное, начинают «писать кипятком»: как же так, subversion! Но, насколько я знаю, SVN, он больше свойственен проектам типа enterprise всякого. У вас был с ним большой опыт работы ещё начиная с Mamba, то есть это исторически так сложилось, правильно?

Олег Оямяэ: Переход на Git начался года два с половиной назад: в это время как раз пошёл какой-то бум и все начали переходить на него. Но в Badoo это был запланированный процесс, как часть внедрения тестирования в компании.

Антон Копылов: А вы не рассматривали Mercurial как альтернативу Git?

Владислав Чернов: Насколько я знаю, мы не рассматривали альтернативу Mercurial, потому что на тот период количество плагинов, ПО для управления репозиториями и так далее больше было на Git. Плюс сообщество уже тогда сформировалось, а на Mercurial только начинало. Для меня, например, особый плюс ― это то, что Git использует любые языки, а с Mercurial все сложней.(Примечание от руководителя тестирования Ильи Агеева: Mercurial мы пробовали вводить много лет назад, но он у нас не прижился и мы вернулись обратно на SVN).

Антон Копылов: Угу, хорошо.

Олег Оямяэ: Вот так вот. Соответственно, два с половиной года назад начался процесс по внедрению контроля качества. Был создан отдел, который растёт и развивается до сих пор. Как раз в тот период было разработано новое workflow, в котором каждая задача делалась в отдельной ветке, но по-прежнему собиралось всё руками, не было ни автоматизации, ни, по большому счёту, ничего. Выкладка происходила, можно сказать, совсем руками. Была утилита, которую написали очень-очень давно, посредством неё всё выкладывалось, и никакого мониторинга не было. Со временем было много написано вокруг этой утилиты ― dashboards и прочие вещи, она стала своего рода ядром. Это если вкратце.

Антон Копылов: А процесс выкладывания и тестирования, он у вас был вместе собран или это были разные процессы?

Олег Оямяэ: Раньше это были не совсем связанные между собой процессы. Сейчас же это полноценная непрерывная интеграция, когда после каждого коммита прогоняются тесты, и это непосредственно влияет на выкладку и на staging. Эти два процесса сейчас связаны между собой и влияют друг на друга.

Антон Сергеев: Кстати, ребят, хотел спросить ваше мнение. Понятно, что многие проекты при старте чаще всего используют только систему контроля версий и, допустим, какие-то хуки, чтобы это контролировать. Обычно никто сразу не ставит мощные средства для continuous integration, для деплоя. Как считаете, что может являться переходной точкой, насколько проект должен разрастись, чтобы стало понятно, что невозможно дальше обходиться без нормального continuous integration и без тестов?

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

Антон Сергеев: То есть если бы вы сейчас делали Badoo заново, то вы сразу взяли бы такую систему и самый первый коммит попал бы уже через continuous integration и прошел бы все тесты?

Олег Оямяэ: Ну я бы ― да.

Владислав Чернов: Я бы сказал немножко по-другому. Если мы говорим о «попсовом» слове start-up, то понятно, что никто не будет делать такую сложную систему, потому что неизвестно, взлетит ли start-up, а ресурсы на тесты тратятся немаленькие, плюс у нас всегда есть ограниченные сроки, за которые мы должны выдать продукт на рынок. Соответственно, говорить об автоматическом тестировании с начала проекта, наверное, не нужно. Но говорить и думать про автоматические сборки и, возможно, какое-то «версионирование» и автоматическое развертывание надо с самого начала, потому что это не займёт очень много времени у команды проекта и это небольшие ресурсы по сравнению с теми же автоматическими тестами.

Антон Сергеев: Понятно. А давайте вы ещё вкратце нам расскажите по поводу того, как у вас проходят 2 релиза в день, про несколько этапов тестирования, n-ое количество тестов и как это работает. Про откаты, патчи, хотфиксы.

Владислав Чернов: Давайте я сначала немножко вернусь к истории: 2 релиза в день ― это действительно так, у нас уезжает порядка 50-60 задач в день. Всем, наверно, будет интересно узнать, почему именно 2 релиза. Всё очень просто. Понятно, что сначала был один релиз в неделю или один релиз в несколько дней, потом был релиз каждый день, а потом стало два релиза в день. Почему два?
Мы перешли в какой-то момент на flow, где каждая задача делается в отдельной ветке, и, соответственно, когда мы формируем релиз, мы сливаем эти задачи в релизную ветку, проверяем повторно каждую из задач и плюс мы проверяем смерженность кода (интеграционное тестирование). Когда это от 10 до 30-40 задач максимум ― это сделать достаточно легко. Когда вам нужно разгребать 100 задач в этом релизе, то это уже сделать сильно сложнее. И поэтому мы деплоим два раза в день, мы можем деплоить и чаще, но в этом нет большого смысла. Почему каждая задача в отдельной ветке, наверно, тоже ясно. У нас есть несколько этапов тестирования, их где-то около 5. Каждая задача в отдельной ветке, потому что мы её можем откатить и проверить. Получается, что у нас есть код с production плюс эта задачка. И мы её проверяем на нескольких этапах тестирования. Первый этап стандартный ― это code review, и смотрится только эта задача. Сделанная задача проверяется на девелоперском окружении. Девелоперское окружение ― это наша мини-серверная с виртуальными машинами, с базами и так далее. На ней можно проверять такие вещи, которые нельзя проверить в production. Задачи там тестируются, потом мы создаём мини-стейджинг для каждой задачи, он называется shot, база используется из production, и мы проверяем задачу ещё раз. Потом задача уезжает в релиз и проверяется на смерженность кода уже в релизной ветке, не ломает ли она другие задачи. И так далее и так далее. Там задача проверяется в четвёртый раз. И есть опциональные тестирования на post-production, когда мы тестируем эту задачу по какому-то запросу от product-менеджера, либо это очень важная задача и тестировщики повторно её проверяют на production, но это опциональные вещи.

Антон Сергеев: А как у вас происходит code review? Его делают какие-то специальные люди, либо разработчики случайным образом делают review кода других разработчиков?

Владислав Чернов: В каждом отделе всё проходит по-разному. Когда задача попадает на review, выбирается разработчик или группа разработчиков. В одних группах review делают руководители команд по компонентам. В других ― задачи просто ротируются внутри группы. Это зависит и от численности отдела, и от опыта людей, и от традиций.

Антон Сергеев: Ребята, давайте я задам вопросы, которые прислали слушатели. Например, Станислав прислал нам много вопросов всяких-разных. Я их разбил на несколько групп. Например, он спрашивает, кто принимает конечное решение о выкате релиза ― бездушная машина или какой-то аналог Сергея Дидыка.

Олег Оямяэ: Нет, у нас нету Сергея Дидыка, он есть в другой компании (примечание: речь идет о компании Бегун). У нас релиз идёт два раза в день в определённое время утром и вечером и, соответственно, мы собираем из задач релиз до этого времени, потом автомерж останавливается и мы начинаем тестировать эти задачи. Когда задачи протестированы и приходит момент выкатки релиза, релиз-инженер принимает решение и мы уезжаем на production.

Антон Сергеев: Чем выкатываете? И как закатываете назад, если не выкатилось? На какой промежуток времени можете откатиться назад, если что?

Владислав Чернов: Для выкатки у нас есть своя утилита для деплоя, она написана нашим разработчиком Юрием Насретдиновым. Если есть желание узнать про это подробнее, то у Юрия есть несколько докладов и статья об этом. Утилита очень быстро выкатывает тысячу серверов, буквально за 2-3 минуты. Это наша система деплоя, и мы её постоянно улучшаем.
(Примечание: откат ― это такая же выкатка, только номер версии другой. Таким образом и выкатиться, и откатиться мы можем за несколько минут. Откатиться даже быстрее, т.к. предыдущая версия на серверах остается. Нужно просто перекинуть линк, а это несколько ssh-команд для переключения и сброса кэша).

Антон Сергеев: А она есть где-нибудь на GitHub, её можно обычным людям пощупать?

Владислав Чернов: Нет, её нет, а почему ― это, наверное, вопрос к Юрию Насретдинову.

Антон Сергеев: Понятно, будем надеяться, что выложите. Было бы интересно пощупать, конечно.

Владислав Чернов: Да.

Антон Копылов: А у меня такой ещё вопрос, вы говорите, что у вас есть стадия тестирования, когда на стейджинге с production-базой проверяется код. А каким образом вы данные переносите с production в стейджинг? Если обнаруживается проблема, то что вы с этим делаете?

Олег Оямяэ: А что вы имеете в виду под этой проблемой?

Антон Копылов: Могу ли я проверить на стейджинге, например, не на ста миллионах пользователях, а на одном миллионе? Или вы переносите целиком всю базу и на полном объёме проверяете этот код?

Олег Оямяэ: Нет, там используется не копия, а полноценный настоящий production.

Антон Копылов: Ааа.

Олег Оямяэ: И только код с некоторыми новыми изменениями, а база используется именно от production.

Антон Копылов: Угу. А не страшно на стейджинге коннектиться к production-базе?

Олег Оямяэ: Нет, потому что тестирование происходит на тестовых пользователях, то есть даже если там что-то случится, это никак не «зааффектит» и не потревожит настоящих пользователей (плюс до этого задача тестируется дважды).

Антон Сергеев: Кстати, у нас похожий подход используется в компании и мы пытаемся от него уйти, но при этом думаем, нужно ли от него уходить. Тут главное здравый смысл: если действительно ничего страшного не делать, коллекции, например, не дропать, то, наверно, всё будет хорошо.
А ещё Стас спрашивает, используете ли вы выкатывание на часть кластера. Пользователи туда прибиты или это может быть любая часть кластера? Я так понимаю, что речь идет о том, можно ли выкатить на часть кластера, потестить и потом выкатить для всех.


Владислав Чернов: Я могу так ответить на этот вопрос: мы можем выкатить на любую машину и на любой кластер. Мы используем порядка 10 кластеров. И можем выкатить этот код с помощью утилиты на любую из частей кластера. По поводу интереса того, что куда-то выкатить и потестить, то мы в основном выкатываем для тестирования новой фичи и нам хочется посмотреть на результаты. Мы выкатываем отдельную страну, а не какой-то набор машин, потому что это гораздо удобнее.

Антон Сергеев: Понятно. А как у вас происходит откат? Допустим, у вас какая-то фича попала в релизную ветку и что-то пошло не так в процессе тестирования на стейджинге. Например, вы обнаруживаете, что есть какая-то серьёзная проблема и желательно её пока что откатить. То есть расскажите, как вы работаете с системой контроля версий (Git), используете ли вы git rebase или git revert. И если да, то расскажите, как.

Владислав Чернов: Мы используем git rebase, мы именно его используем, потому что git revert нас не устраивает, так как мы разрабатываем каждую задачу в отдельной ветке. Если мы откатываем с помощью revert после сливания ветки релиза и ветки мастера, то разработчику придётся делать revert на revert, поэтому мы используем git rebase. Мы моментально откатываемся, соответственно, собираем новую сборку и выкладываемся на стейджинг.

Антон Сергеев: А у вас не было проблем с git rebase? Насколько я знаю, штука эта довольно капризная, её нужно уметь правильно использовать. Какой у вас тут рецепт?

Владислав Чернов: На самом деле она не такая уж и капризная и рецепт очень прост: мы вмерживаем в релизную ветку другие ветки, и у нас дерево релизной ветки очень простое, и откатить задачу очень просто, так как это смерженный коммит. И мы понимаем, что git rebase ― это полностью ручная операция. Но у нас есть алгоритм и небольшой скрипт, который выполняет это в автоматическом, ну почти в автоматическом режиме.

Антон Сергеев: Мы уже знаем, что вы используете Git, но помимо этого вы ещё используете такой замечательный инструмент от компании JetBrains, как TeamCity ― это continuous integration server, а ещё у вас это всё заинтегрировано с баг-трекером JIRA, я так понимаю ― и постановка задач, и автоматические смены статусов. Как у вас всё это появлялось и интегрировалось, и как вы с этим работаете?

Олег Оямяэ: Да, как уже было сказано, мы используем Git, а также JIRA и TeamCity. TeamCity мы используем для прогона тестов и выкладки кода на стейджинг при успешном прогоне. На самом деле, flow в JIRA у нас сильно проработан и структурирован, и заинтегрированы все компоненты системы JIRA, Git и TeamCity. У нас очень большой workflow который мы регулярно оптимизируем, чтоб было удобно и разработчикам, и тестировщикам, и менеджерам продукта.

Антон Сергеев: Кстати, на последней конференции DevConf был доклад про проблемы в архитектуре, и спикер говорил, что JIRA ни в коем случае не нужно использовать, потому что там нельзя раздавать права разным пользователям на уровне просмотра задач, чтобы, допустим, разработчики не видели какую-то там дополнительную метаинфу, которая нужна проект-менеджеру, а проект-менеджер не видел каких-то деталей, которые могут быть полезны только разработчикам. Насколько это вообще, по-вашему, критично и с какими вы сталкивались проблемами с JIRA? Были какие-то действительно серьёзные вещи, которые вы как раз допилили?

Владислав Чернов: Эта проблема с проект-менеджером и с разработчиком, она какого-то очень закрытого плана, мы на самом деле все дружим и у нас нет скрытой информации, и нет такой проблемы по филдам, например, ― скрывать их или нет. По поводу того, использовать JIRA как баг-трекер или нет ― это каждый выбирает сам, но это как минимум самая распространённая система в мире, именно как баг-трекер. В чём-то она нас устраивает, в чём-то ― нет. Там, где она нас не устраивает, мы автоматизируем работу с ней. На самом деле, у нас сложный workflow, но в JIRA два уровня вложенности таска и сабтаска, и из-за этого мы получаем больше плюсов, чем минусов, т.к. не можем усложнить процесс.

Антон Сергеев: Угу. А Вы используете confluence? Если слушатели наши не знают, я просто сейчас скажу, что confluence ― это wiki, где можно хранить документацию и не только.

Владислав Чернов: Да, конечно, мы используем его. И я вот боюсь ошибиться, но насколько я знаю, мы даже пользуемся GreenHopper. Но мы не используем FishEye для просмотра кода, потому что это очень громоздкий инструмент, и мы для review кода используем GitPHP, который, опять же, сами допиливали, и он достаточно быстр по сравнению с тем же FishEye, который индексирует огромное количество наших веток несколько суток.

Антон Сергеев: А какое у вас впечатление от работы с TeamCity? Пользовались ли чем-то ещё, пробовали ли Jenkins, например?

Владислав Чернов: Да, я работал со многими серверами непрерывной интеграции: и с Jenkins, и с TeamCity, и с Bamboo. Но TeamCity нас устраивает в большей степени, чем остальные сервера непрерывной интеграции, в данный момент представленные на рынке.

Антон Сергеев: А можете поподробнее рассказать, с чем это связано? С вашим текущим процессом, с выкаткой релизов или там есть какие-то особенности, которые другие разработчики тоже могли бы учесть. Допустим, сейчас нас слушает разработчик и думает, что ему выбрать. Есть ли какие-то важные факторы, по которым стоит выбрать TeamCity?

Владислав Чернов: Одно из преимуществ TeamCity в том, что его бесплатного функционала достаточно для того, чтобы его могли использовать маленькие компании. С другой стороны, у него есть платные функции, он поддерживает платный support и сделан качественно. Все говорят, что Jenkins хорош тем, что для него очень много плагинов. Это действительно так, но получается, что если вы рассчитываете на какой-то плагин, а потом выходит новая версия Jenkins, бывает, что плагин не переписывается, и вы сталкиваетесь с проблемами, и вам нужно опять всё перестраивать.
TeamCity нас подкупил как минимум тем, что он достаточно прост в использовании и удобен не только релиз-инженерам, но и тестировщикам, и девелоперам. Плюс на тот момент у них выходили определённые фичи, которые нам отлично подходили. Это, например, ловля ветки по маске, а у нас огромное количество веток, и мы не перестраиваем билды. Потом эти фичи были добавлены в другие серверы непрерывной интеграции, но это уже было потом. Ну и, конечно, support нас отлично поддерживает и помогает, они дорабатывают продукт и некоторые вещи доделывают под нас.

Антон Копылов: Я ещё хотел добавить, что в TeamCity одна из фич, которая мне кажется killer-фичей, ― это наследование конфигурации. Можно сделать шаблон конфигурации и потом от него уже создавать какие-то клоны. Это сильно упрощает процесс добавления подпроектов в систему.

Владислав Чернов: Да. Это как если вы, допустим, используете один репозиторий и у вас нет кастомных конфигураций, и какие-то вещи вы можете настроить как шаблон и либо передать параметры, либо ещё что-то. Это тоже интересная особенность.

Антон Копылов: Это как раз то, чего нет у конкурентов ― наследование конфигурации, такая вот фишка TeamCity.

Антон Сергеев: А у меня ещё вопрос по поводу Git. Все знают или по крайней мере слышали про так называемый git-flow. Это такой стандартный подход к использованию Git. Данный подход был разработан достаточно давно, и это удачная модель бранчинга. Ваше flow основано на этом стандартном подходе, где используются feature branch, release branch, hot-fix branch, master, developer branch, или у вас есть свои фишечки, какие-то хорошие рецепты ― как лучше создавать ветки, как лучше сливать ветки ― что про это можете рассказать?

Владислав Чернов: Да, конечно. На самом деле мы далеки от git-flow. У нас всё просто: есть мастер, в котором содержится копия кода на production, туда никто не имеет право пушить, туда могут применять патчи, у нас есть специальный для этого инструмент, он называется Deploy Dashboard. Релиз-инженер смотрит этот патч: если всё хорошо, он его применяет в полуавтоматическом режиме в веб-интерфейсе, и, соответственно, код разложится на production и что-то там пофиксится. Это бывает достаточно редко, но бывает, конечно. И у нас есть релизная ветка, которая создаётся два раза в день полностью в автоматическом режиме, плюс есть ветки задач. В ветке задачи нумеруются по тикетам JIRA: номер тикета и какое-то описание ветки. И вот тикет создается, эта ветка вместе с тикетом идёт по flow, она разрабатывается, идёт на review, проверяется в несколько этапов тестирования, потом автоматически мержится в релизную ветку, и здесь включается сервер непрерывной интеграции, который собирает этот билд. И хотя у нас PHP-код, он у нас действительно собирается. Например, гоняются переводы, которые автоматически генерятся более чем на 40 языков и, соответственно, выкатываются на стейджинг и к окружению, и всё это делается в автоматическом режиме. Релиз заканчивается, он мержится в мастер и создаётся автоматически новый релиз.

Антон Копылов: У меня вопрос возник: а нумерацию вы какую-нибудь ведёте? Если у вас 2 релиза в день, то у вас, наверное, очень много релизов уже набралось, или не так быстро растёт этот номер?

Олег Оямяэ: Не совсем так. Да, в TeamCity есть внутренний инкремент, но он больше используется для работы непосредственно с TeamCity, а так сами имена релизов носят более «человекопонятный» формат, то есть там присутствует дата, время и проект, потому что мы выкладываем не только для web ― с недавних пор и для iOS, и для других проектов. Так что у нас нет такой проблемы, как, например, «релиз 365», и никто не понимает, что это вообще такое и откуда.

Антон Сергеев: Да, бывает такая проблема. Я сталкивался с ситуацией, когда есть у тебя задача, допустим, в Redmine, и ты пишешь, что фича такая-то, таск такой-то. Потом смотришь в релиз, а там куча фич. Ты говоришь: «Да что ж такое-то, какая из них моя?» И приходится в браузер лезть, чтобы там смотреть.
Я считаю, что несмотря на то, что каждый из инструментов, который вы используете, будь то JIRA, TeamCity или Git, сам по себе хорош, но лучше всего и эффективней всего они себя показывают, как мы видим, на вашем примере ― в интеграции. И вот для этого вы используете такой инструмент, как AIDA, правильно? Расскажите, как вы это делаете, как к этому пришли и какие профиты получаете?


Олег Оямяэ: Да, мы используем AIDA. Это такой виртуальный пользователь, от лица которого происходят все автоматические действия, какие-то скрипты запускаются, рассылаются нотификации в Jabber, в почту, обновляется информация в dashboard, то есть весь процесс автоматизирован, вся информация доступна как в TeamCity, так и в JIRA. Также у нас есть определенный формат commit message, когда мы просматриваем Git log, тоже всё видно и понятно. Также в JIRA присутствуют ссылки на GitPHP в конкретной задаче: всегда можно посмотреть как полный diff, так и все коммиты по отдельности. Так что да, наверно, использование этих трёх инструментов вместе действительно удобно и оправдано.

Антон Сергеев: А насколько сложно начать работать с AIDA, или это очень простой инструмент, не какой-то там rocket science?

Олег Оямяэ: Скажем так: там есть простые части, но есть и достаточно витиеватые.

Антон Сергеев: Какие у вас были самые серьёзные проблемы, с которыми вы столкнулись, используя AIDA и при интеграции с TeamCity, JIRA, Git?

Олег Оямяэ: Ну смотрите, на самом деле AIDA во многих случаях использует API к JIRA, TeamCity, с Git она работает как обычный пользователь. Первая часть, с которой мы столкнулись, это, конечно же, API. Оно меняется от версии к версии, и нельзя сказать, что оно всегда стабильно. И это была первая ситуация, когда мы столкнулись с трудностями. По поводу реализации AIDA, вопрос в том, как грамотно настроить бизнес-процесс: например, в какой момент создать ветку релиза, в какой момент запустить automerge и так далее. Правильно выстроить нотификации, потому что люди должны понимать как идёт этот процесс, и если мы что-то упустим, то AIDA будет работать без нас, и это будет неконтролируемый процесс. Выстраивание этого процесса ― это и есть самая большая сложность.

Антон Сергеев: Получается, это всё отлаживается, пишется, прогоняется, смотрится и так далее до тех пор, пока более-менее не войдёт в нормальный рабочий ритм, правильно?

Олег Оямяэ: Да. У нас есть специальное окружение, в котором мы пишем и тестируем AIDA, так что в большинстве случаев какие-то доработки и изменения проходят гладко и ничего не ломается. В этом плане всё хорошо.

Антон Сергеев: Ясно. А есть планы на будущее, может быть, какие-то интересные технологии в плане выкатки, деплоя, автоматизации, на которые вы смотрите, либо которые вы видите сейчас на рынке? Или вы пока более чем довольны вашими инструментами и не хотели бы что-либо менять?

Олег Оямяэ: Да, пока нас всё устраивает, мы дорабатываем AIDA и всё хорошо.

Антон Сергеев: Супер. Предлагаю тогда перейти к следующей большой теме. Давайте поговорим про тестирование и про то, как вы делаете автоматическое тестирование, что для этого используете, как это всё происходит и каких показателей вам удалось добиться?

Владислав Чернов: Да, мы используем автоматическое тестирование. Если начинать с самого начала, то стоит сказать, что unit-тесты у нас пишут разработчики. На данном этапе времени задача не принимается в релиз, если она не покрыта unit-тестами. Соответственно, мы используем Selenium для PHP-кода, считаем code coverage, это достаточно стандартно. У нас в какой-то момент возникла достаточно большая проблема из-за двух релизов в день: это ограниченное время, это буквально несколько часов на тестирование и сейчас, соответственно, у нас нет последовательного процесса, у нас всё идёт параллельно. Например, идёт push в релизную ветку, автоматически запускается сборка, автоматически запускаются unit-тесты и selenium-тесты ― параллельно, и, может быть, опционально отдельные какие-то тесты, которые очень важны. И мы столкнулись с такой проблемой, что у нас было порядка 18 000 тестов (примечание: сейчас 20000), и они проходили очень большое количество времени.

Наш замечательный коллега Илья Кудинов написал утилиту, которую мы называем «Пускалка», которая делит эти тесты на 11 потоков, при том она их полностью формирует по времени, так чтобы каждый поток проходил за равные промежутки времени, и сейчас у нас тесты гоняются где-то порядка 3,5 минут ― это 18 тысяч юнитов. И тесты гоняются не только на релизной ветке ― они гоняются также после того, как разработчик завершил свою задачу в ветке. Также в автоматическом режиме. Там существует отчёт, который пишется в JIRA, и разработчик либо тестировщик сразу же может посмотреть результат прогона этих тестов: что упало, что не упало и так далее.

Антон Сергеев: Ага. А по поводу Selenium, есть опять же от Станислава вопрос, большая ли ферма под Selenium?

Владислав Чернов: Я могу ошибаться, но насколько я знаю, ферма достаточно большая. Это связано с тем, что мы поддерживаем довольно большое количество браузеров и мы только недавно отказались от Explorer 6, то есть мы тестируем почти на всём: это и Chrome, и Firefox, и Explorer. И сама ферма достаточно большая. Мы также «распараллеливаем» тесты, пускаем их по параллели по причине того, что они проходят довольно продолжительное количество времени. Мы пробуем использовать браузеры и движки без GUI, но я не могу похвастаться и сказать, что это очень успешно проходит.

Антон Сергеев: Ага. Кстати, мне вспоминается знаете что: я был на Форуме Технологий Mail.ru, и там был доклад или от Яндекса, или от Mail.ru (честное слово, забыл) о том как они используют Selenium. И там был смысл примерно в том, что они сначала запускали для каждого браузера отдельную ноду ― я так понимаю, что это какая-то виртуальная машина типа Xen'а, и это всё получается довольно «ресурсозатратно» и не очень хорошо, и Selenium бил по рукам, что нельзя на одной это ноде запускать тесты одновременно для разных браузеров, потому что будет ломаться, будут глюки, в общем, будут проблемы. И они полезли в сорцы, что-то там подпилили, поняли какие-то особенности того же Explorer’а, когда ему, не знаю, фокус принудительно вернуть, что-нибудь ещё сделать, чтобы все тесты параллельно не падали. И они об этом рассказывали и говорили, что это вообще мегакруто, что мы смогли так и заставили так работать всю эту систему, что всё стало быстро проходить. Вы подобными вещами вообще баловались, сталкивались с этим? И как вы смотрите на подробного рода «костыли»?

Владислав Чернов: Я не знаю, что на самом деле происходит в браузерах, мы все-таки не пишем selenium-тесты и не знаем таких подробностей. Но на мой взгляд, есть браузеры, которые обновляются довольно часто, и тогда эти костыли надо переносить от одного браузера к другому как минимум. По поводу упавших тестов: selenium-тесты ― это такие тесты, которые всё равно падают, и самый распространённый способ это устранить ― это прогнать эти тесты повторно и посмотреть, упадут они или нет. По поводу того, кто что делает, например, по поводу отдельных виртуальных машин, мы это не используем, и для каждого отдельного браузера принимать свою машину слишком ресурсозатратно. Но, что интересно, Google, например, гоняет selenium-тесты на своем дата-центре.

Антон Сергеев: Ничего себе.

Владислав Чернов: Да, при этом машины ― это production-площадки, комовская площадка. Он берёт те же машины, которые используют пользователи, и гоняет там selenium-тесты, так что ресурсы у всех разные. Мы стараемся всё-таки менее ресурснозатратно всё делать.

Антон Сергеев: У нас еще остались вопросы от слушателей. Какие типы тестов вами пишутся?

Владислав Чернов: Смотрите, у нас как минимум есть unit-тесты и, понятное дело, функциональные тесты. То есть мы лезем в базы, мы смотрим там базы на devel. У нас есть Selenium, который работает на devel, на обоих площадках. У нас два дата-центра, и инфраструктура devel полностью повторяет инфраструктуру площадки. У нас здесь две площадки, и репликация баз на devel такая же, как на площадках. То есть всё, что есть на production, есть сейчас и в девелоперском окружении. Но мы гоняем selenium-тесты и на девелоперской площадке, и на стейджинг, и на какие-то критические моменты на production. Для PHP это, наверное, и всё.

Антон Сергеев: Ещё тогда такой вопрос: unit-тесты совсем unit? Без БД? Если да, то как тестируется связка хитрых SQL-запросов с парой джоинов и тем, что это обрабатывает?

Олег Оямяэ: Мы стараемся писать unit-тесты как unit-тесты, а хитрые запросы ― для этого есть функциональные тесты, которые как раз для этого и нужны. Unit должен быть Unit’ом и проверять только одну конкретную часть.

Антон Сергеев: Есть ещё вопрос от Стаса (он задал очень много вопросов, и я не могу удержаться ― надо же ответить человеку, раз ему интересно). Используете ли вы A/B-тестирование и как тестируете производительность?

Олег Оямяэ: Да, мы используем A/B-тесты. Правда это делается средствами другого отдела, но в Badoo используется A/B-тестирование, чтобы понять, какой вариант дизайна текста или, например, кнопки, лучше и приятней пользователю, чтобы сервис становился ещё более удобным и понятным. Для этого тоже есть специальные инструменты автоматизации.

Антон Сергеев: А производительность как тестируете? Я так понимаю, что здесь имеется в виду производительность не самих тестов, потому что вы сказали, что у вас 18 тысяч тестов проходят за 3,5 минуты, да?

Олег Оямяэ: Да. Всё верно.

Антон Сергеев: А производительность, не знаю, допустим, response на production, на какой-то конкретный запрос.

Олег Оямяэ: Не уверен, правильно ли я понял вопрос. Но у нас есть отдел мониторинга, который непрерывно ―24 часа в сутки 7 дней в неделю и так далее ― мониторит состояние всей системы, всех, абсолютно всех частей, а также время ответа страниц, насколько быстро отдаётся статика. Если что-то пошло не так, тут же эскалируется проблема ответственному лицу и проблема в кратчайший срок локализуется и исправляется.

Антон Сергеев: Давайте ещё поговорим по поводу code coverage: какие у вас требования есть к покрытию кода, как вы с этим работаете, насколько покрываете. Как я понял, самое главное это то, что код без покрытия не попадает в релиз. Но а дальше как вы это мониторите, насколько много стараетесь писать тестов?

Олег Оямяэ: Тестами должен покрываться весь новый функционал, то есть когда разработчик отдаёт какую-то задачу в тестирование, все методы, новые или изменённые, он обязан покрыть unit-тестами. Соответственно, потом задача уходит в QA, QA пишет selenium-тесты, функциональные тесты и затем считается coverage раз в сутки, и дальше руководители отделов, тестировщики и все заинтересованные лица в специальном веб-интерфейсе могут посмотреть, у какой группы насколько хорошее покрытие, и сделать соответствующие выводы, поставить какие-то задачи на дописывание unit-тестов, или отдел тестирования поставит задачу на дописывание Selenium’а. Всё это непрерывный процесс улучшения кода и покрытия.

Антон Сергеев: А давайте ещё тогда поговорим про вашу «пускалку», о которой вы только вскользь упомянули. Мне интересно подробнее узнать, насколько всё-таки у вас улучшилась производительность, сколько было, сколько стало, и поподробней расскажите про архитектурно-философские подходы, которые использовались при разработке «пускалки»?

Владислав Чернов: Мы там рассматривали несколько схем, даже самые простые, например, разделение какими-то suites на n-ое количество тестов и запуск их, и разные другие варианты. Они тоже все описаны, и про них можно почитать. По поводу профита и того, как это было реализовано, расскажу сейчас поподробнее. Профит мы получили, так как, если я не ошибаюсь, тесты гонялись где-то в районе 20 минут, может быть, даже больше. Но сейчас это 3,5 минуты, то есть мы получили огромный выигрыш по времени. По поводу реализации, мы разбиваем запуск на 11 потоков, при этом suites формируются так, что они берут время из определённой базы, которая сформирована на основе базы TeamCity-сервера. Мы знаем, сколько гоняется каждый тест, мы собираем эту информацию, если я не ошибаюсь, за 7 дней, берём какое-то среднее значение и, соответственно, знаем, сколько этот тест в среднем гоняется. На основе этой информации собирается эта статистика и формируется 11 одинаковых потоков и идёт запуск. Потоки получаются полностью сбалансированными, там даже выдаётся результат, сколько тесты будут идти, такой взгляд в будущее.

Антон Сергеев: Ясно. А есть какие-то мысли по поводу того, как это можно ещё улучшить, куда можно двигаться дальше? Может быть, в дальнейшем вы это в open-source выложите, чтобы и другие могли попользоваться и порадоваться?

Владислав Чернов: Да, Илья Кудинов обещал, что уже в ближайшие несколько месяцев мы сможем это сделать. Просто сейчас это немножко кастомизировано под нас и, соответственно, нам нужно это оформить просто под Jenkins, например, и выложить это в open-source. Я думаю, что это будет сделано, и все смогут попробовать и поиграться с этим.

Антон Сергеев: Здорово. Вы, конечно, молодцы, потому что и последнее время много рассказываете на конференциях о том, как вы вообще разрабатываете, статьи на Хабре пишете и, опять же, вот к нам в подкаст с удовольствием приходите. Это очень интересно, и думаю, что многим разработчикам интересно послушать про ваши инструменты. Потому что есть технологии, которые сейчас крупные компании и крупные игроки на рынке выкладывают, и вот они многие, честно говоря, какие-то спорные, а многие технологии даже никто и не использует, о них только говорят на конференциях. Я не буду конкретно говорить, но вот у меня есть такое мнение по поводу определённых вещей, систем, что они слишком уж кастомные и не очень интересные для комьюнити. В вашем случае, я думаю, что это совсем не так, поэтому желаю удачи в том, чтобы вы доработали и выложили эти инструменты на GitHub либо ещё куда-то. У нас есть немножко времени напоследок, давайте поговорим про девелоперское окружение. Вы говорите, что у вас есть полная копия production непосредственно в офисе, где сидят разработчики. Как вы подходите к вопросу девелоперского окружения, есть ли у каждого разработчика свой какой-то sandbox, что собой представляет эта ваша копия production, какая у вас здесь структура?

Антон Копылов: Ну да, и используются ли какие-то средства для повтора окружения, типа Vagrant или Puppet?

Олег Оямяэ: Да. У нас в production есть два дата-центра основных, в Праге и в Майами. Соответственно, нам требуется на devel’e воссоздать также две площадки, чтобы можно было тестировать какие-то кроссплатформенные вещи. База у нас абсолютная копия, структура абсолютно такая же. Но тем не менее, вся конфигурация полностью совпадает, тем самым позволяет нам без каких-либо проблем разрабатывать код, тестировать его, все сервисы ― всё поднято, и разработчикам вполне комфортно разрабатывать.

Антон Сергеев: Это единая какая-то конфигурация, то есть там Puppet или Chef используется?

Олег Оямяэ: Да, используется Puppet для production и для всего, то есть все вещи раскладываются через него, все конфиги. За счёт этого у нас все конфиги консистенты и нет никаких проблем с тем, что на одной машине один конфиг, а на другой ― другой.

Антон Сергеев: Кстати, классный подход. Но вот мы, например, тоже используем Puppet, но мы создали отдельный конфиг для девелопмента. Почему? Потому что несколько отличается у нас от девелопмента среда. Например, мы MongoDB на ту же тачку, в общем-то, кладём, где у нас идёт обращение к API или к вебу, к фронтенду. И у нас они чуть-чуть отличаются, эти конфиги, но в общем мы тоже довольны, потому что мы их оперативно обновляем. Если у нас обновляется, скажем, PHP, либо что-то ещё, либо драйвер Mongo-вский, то это занимает немного времени. А вот с машинами разработчиков как у вас обстоят дела? У вас, кстати, исторически больше разработчиков на «винде», либо на «маках», либо на Linux, как у вас происходит на локальных машинах разработка и первое тестирование?

Олег Оямяэ: На самом деле разработка ведётся на DEV-серверах в большинстве случаев. Некоторые разработчики поднимают у себя локальный nginx или ещё что-то, но, наверно, для каких-то очень узкоспециализированных и маленьких задач. Но невозможно на локальной машине поднять всё окружение, и просто даже не нужно. То есть разработчики себе разрабатывают в своей домашней директории на devel’e. Соответственно, у каждого разработчика есть свой виртуальный хост, который маппится в его домашнюю директорию в специальную папку. По поводу того, каких операционных систем больше, я вот в офисе видел, по-моему, только одного разработчика на «винде», может двух, но, в основном, это «маки» и Linux, но в процентном соотношении, не знаю, мне кажется, 50 на 50.

Антон Сергеев: Вот так вот, интересно. Но в вашем случае непринципиально, на чём сидит разработчик, потому что он всё равно всё делает где-то там на devel, там единственная разница будет, что у него, может быть, будут несколько другие средства, GUI для доступа к базе в зависимости от платформы. И насколько я знаю, многие нормальные разработчики сейчас всё больше к нативным инструментам прибегают. В базу из консоли заходят, поэтому тут тоже проблем никаких. Я почему ещё спросил, потому что есть практика, когда девелопментная среда поднимается, но, например, под тем же Vagrant’ом. Сначала разработчик пишет и сохраняет свой код на эту виртуалку с Vagrant’ом; там, скажем, какой-нибудь Linux-сервер крутится, а потом уже оно заливается на DEV-сервак. Но я так понял, в вашем случае этого лишнего звена нет, вы сразу разрабатываете и тестируете на devel, потом оттуда сразу собираете и на стейджинг.

Владислав Чернов: Да, это так, потому что, на самом деле наша серверная ― это как раз и есть набор виртуальных машин. И единственное место, где мы используем сейчас облачные технологии. Виртуальные серваки мы используем, но это devel-oкружение, и мы не используем виртуалки под какие-то конкретные задачи, единственное, понятно, где нам нужны виртуальные машины, определённая ось, либо ещё что-то ― это, конечно же, для тестирования и для разных браузеров, тогда мы поднимаем виртуальные машины именно для таких конкретных задач. А так нам действительно хватает нашего devel, тем более он поддерживает огромное количество функциональности, которая у нас есть на production. Это гораздо удобнее, чем поднимать виртуальную машину для какой-то конкретной задачи.

Антон Сергеев: Здорово, что вы всё-таки с этим разобрались, что поддерживаете нормальный DEV, потому что, насколько я знаю, в компаниях среднего размера это постоянная головная боль, особенно то, что тестится не на той платформе, на которой это будет работать. Версии ― и то могут отличаться, и даже иногда разница небольшая в версиях, а на production из-за этого может всё поломаться, и это очень важно, потому что много времени тратится на то, чтобы понять и пофиксить. И если это происходит постоянно, то это неправильная процедура тестирования и неправильное окружение.
А давайте перед самым завершением нашего сегодняшнего диалога вы дадите какие-то рекомендации от себя, что почитать в плане книг, статей, на какие конференции можно сходить, если, вы интересуетесь тестированием, автоматизацией, тем самым деплоем либо созданием распределённых больших систем, похожими на ваши.


Владислав Чернов: Ну, как минимум подписывайтесь на наш блог на Хабре, и, может быть, мы что-то ещё там интересное для вас расскажем. У нас там много интересных статей. Если говорить не про непрерывную интеграцию, то стоит всё-таки читать Бергмана, он как минимум даёт какие-то начальные знания и основные понятия, и вот эти книжки:


Они достаточно интересны. Если мы говорим о больших системах, то, если честно, мало кто с удовольствием рассказывает про бизнес-процессы, про конфигурационное управление, про релиз-инжиниринг, и это очень грустно.

Антон Сергеев: Наверное, просто каждый проект, он уникален, есть какие-то свои фишки, свои ноу-хау, но многие компании, действительно, имея высоконагруженный проект, становятся всё более и более закрытыми. Тут можно «ВКонтакте» привести в качестве примера, потому что они очень мало инфы наружу дают, и их появление на конференциях всегда воспринимается «на ура», но тем не менее, вытянуть из них что-то очень сложно. Я, по своему опыту общения на HighLoad, могу сказать, что там очень порционно удаётся информацию о них получать. Поэтому большое спасибо вам за статьи на Хабре, они очень интересные и, в принципе, оттуда некоторые мысли и решения мной были позаимствованы для своего проекта.

Антон Сергеев: Ну вот и всё, о чём мы хотели вам рассказать сегодня, дорогие слушатели. Спасибо, что присылаете вопросы. Конечно, пока что лишь некоторые пользователи нам их шлют, но, думаю, что со временем и другие тоже будут формулировать свои вопросы и задавать их нашим гостям. Мы будем стараться давать больше времени между анонсом выпуска и до его фактической записи, для того чтобы можно было обдумать, что-то ещё спросить. Я напомню, что сегодня с вами были ведущие подкаста Антон Копылов и я, Антон Сергеев.

Антон Копылов: И наши гости из компании Badoo ― это релиз-инженеры Олег Оямяэ и Владислав Чернов. Спасибо большое, ребят.

Антон Сергеев: Да, спасибо за интересный рассказ, было очень здорово и интересно.

Олег Оямяэ: Спасибо вам за интервью.

Антон Сергеев: Слушайте наши выпуски на сайте «www.itkompot.ru», также на подкаст-терминале podfm.ru, подписывайтесь в iTunes. Удачной вам разработки и услышимся, пока.

Слушать подкаст полностью.

Скачать выпуск подкаста.
Автор: @Badoo
Badoo
рейтинг 294,03

Комментарии (41)

  • +45
    Лучше заплатите девочке за найденные "неприятные моменты".
    • +28
      Зашел чтобы прочитать этот коммент.
  • 0
    >Владислав Чернов: Мы используем git rebase, мы именно его используем, потому что git revert нас не устраивает, так как мы разрабатываем каждую задачу в отдельной ветке. Если мы откатываем с помощью revert после сливания ветки релиза и ветки мастера, то разработчику придётся делать revert на revert, поэтому мы используем git rebase. Мы моментально откатываемся, соответственно, собираем новую сборку и выкладываемся на стейджинг.

    Признайте честно, что просто не осилили git revert и cherry-pick. В результате, например, разработчикам под страхом страшной смерти нельзя мержится от ветки, к которой ещё могут запустить git rebase.
    • +7
      А зачем разработчику мержить себе в ветку релиз, если он через 4 часа всё равно будет в мастере? Если есть какая-то зависимость между задачами, то можно замержить отдельную задачу, это намного безопаснее.
      • +3
        Например, разработчик может сам разрешать конфликты, поскольку лучше понимает функционал, чем релиз-инженер. Вообще же, замена функционала итп часто обратно несовместима, и на дев-платформах это легко разрешать банальным мержем с мастером/релизом.

        Помимо этого, схема с ребейзом непригодна для отката мержа, дошедшего до мастера-продакшена, и в ряде случаев всё равно быстро можно будет сделать только реверт или ребейз, а последний в этом случае заведомо вызовет непредсказуемые проблемы.

        Кстати, привет 2 хейтерам из Баду.
        • +1
          Все конфликты решают разработчики, релиз-инженер этим не занимается. Вот, как сейчас. Вы задаёте конфликтные вопросы, а отвечают на них разработчики =)
          • –2
            Эгегей — Хейтеры из Баду, friendly fire, свои! не надо минусить мои комменты! Или тут не только из Баду хейтеры таки? =))
        • +3
          Про мастер-продакшен вы правы, если мы это делаем то откатываем через revert.
          Но это бывает крайне редко.
          Здесь говорилось только про ветку релиза.
        • +1
          По поводу конфликтов у нас сделано просто благодаря той самой автоматизации. если автомерж не смог залить какую-то ветку в билд, то задаче выставляется специальный флаг в Jira чтобы предотвратить дальнейшие попытки автомержа и с AIDA переводится обратно на разработчика с комментарием что в такой-то билд её не удалось замержить.
          • –1
            Логично. Проблема в том, что после этого разработчик мог бы просто смержить в свою ветку мастер/релиз и таким образом легко разрешить конфликт. А так, придётся угадывать ветку, с которой произошёл конфликт, мержиться с ней, и всё равно иметь проблемы в случае отката ребейзом любой из этих веток.
      • +3
        А можете более развернуто описать Ваш workflow? И как откатываете изменения.
        • +3
          Да, будет отдельная статья про то как мы откатываем изменения из ветки релиза и небольшое описание нашего flow.
        • +3
          Про флоу мы уже писали в статьях тут и тут. Но отдельной статьи, посвященной именно флоу, у нас еще не было. Обязательно напишем. Так же, как Влад уже написал, готовится отдельная статья про автоматизированные откаты задач из ветки релиза.
        • +2
          Довольно похожий рабочий процесс рассказан в следующем докладе:
          techforum.mail.ru/report/56
          • 0
            Спасибо. Но меня интересовал именно git workflow (возможно, мне стоило уточнить это). У нас прижился такой подход:

            1. ветка от мастера
            2. работа
            3. подливаем мастер в ветку
            4. мерджим ветку в мастер

            ИМХО, он наиболее демократичен и гибок.

            При возникновении проблем, в мастере делается реверт. Но иногда возникают ситуации, когда реверт на реверт на реверт и уже сам путаешься.

            Хотелось узнать хотя бы на пальцах про откат ребейзом и общие принципы ветвления, принятые у Вас.
            • 0
              Выше uyga уже дал ссылки, в частности вторую:
              habrahabr.ru/company/badoo/blog/169417/
            • +4
              1) Ветка от мастера для задачи — работа — Code review — тестирование
              2) Ветка релиза от мастера
              3) Автомерж веток готовых и протестированных задач в ветку релиза — интеграционное тестирование и staging
              4) Нашли багу, откатываем смерженный коммит задачи из релиза c помощью rebase — сборка — повторная проверка на staging
              5) Едем на продакшен — проверяем опционально
              6) Если все хорошо — сливаем релиз в мастер
              7) Все плохо(исключительный случай:)) перекидываем линк на предыдущий релиз.

              Два релиза в день, по времени, автомерж тасок останавливается за 2 часа до выкладки на продакшен очередного релиза.

              Если кратко:)
  • +2
    Если не сложно, ответьте на несколько простых вопросов:

    1. Если представить, что у вас есть две группы разработки, серверная и клиентская, плюс группа системных администраторов, то как вы выкатываетесь?

    2. Прошу пояснить что в вашем понимании 100 тасков в день.

    3. Как тестировщики успевают протестировать весь проект всего за одинь день?

    4. Какие критерии вы используете оценки что релиз «удался»

    5. Кто может ставить таски на разработчиков?

    6. Есть ли у вас ручное тестирование интерфейсов. Если есть, то какое у них воркфоу?

    • 0
      Подключусь к вопросам

      7. Если Stage работает с продакшен базой, как происходит тестирование при изменении схемы(мажор фича, к примеру)? Используются ли инструменты для миграций?

      8. Я так понял ветвитесь только в один уровень, а если нужно работать группой разработчиков над одной фичей и каждый будет ветвится от этой фича-ветки?

      9. Были ли случаи, когда на продакшен ушла очередная фича, но через несколько релизов оказалось, что её нужно откатить. Как происходит этот процес?
      • +5
        7. С базой у нас все просто если нужно что то добавить мы просто заранее делаем нужный альтер, и старый код работает как работал, потом выезжает новый код начинает работать с тем что мы добавили, проверяем все ли хорошо (при этом это уже проверялось на devel окружении), дальше при надобности удаляем ненужное. Миграция — боюсь ошибиться, но нет.
        8. Нет каждый будет создавать свою из мастера (декомпозиция задач смотрите выше). Можно вести разработку в одной ветке, либо при надобности смержить их. Смерженные таски отслеживаются на уровне Git и Jira и задача если зависит от другой по коду не уедет в релиз автоматически.
        9. Если вы про откат фичи с багом, то нет так как слишком много этапов тестирования и много тестов, так что все баги ловятся на этапе релиза. Бывает реверт из мастера раз в полгода, но это отлавливалось в тот же день. Если вы про выпиливании работающий фичи, то она выключается как и включалась, после этого аккуратно выпиливается код.
        • +4
          с базой чуть-чуть сложнее
          * если код не может работать прозрачно с новой схемой — сначала идет фикс-релиз кода (так стараемся не писать, но всяко бывает)
          * альтер по-живому (если по кластеру — то шард за шардом)
          * релиз, использующий новую схему
          * (опционально) clean-up процедуры над базами
          а вообще хотя задача и сложная чисто теоретически (100% плавного алгоритма на все случаи жизни нет), на практике организационно все разруливается довольно легко
    • +5
      Спасибо за вопросы
      1. Не надо даже представлять, так и есть. Только вы забыли еще группу релиз инженеров. Если говорить об обновлении, то системные администраторы обновляют сервисы и происходит это в момент наименьшего трафика на сайт. Сервер обновляется два раза в день, при этом серверное API (имеется ввиду сервер-клиент) пишется так чтобы не ломались старые версии приложений(если что разработчики меня поправят) и параллельно разрабатывается клиент. Тестируем чтобы новая фича ничего не сломала, что она работает на сервере, что работает с клиентом и выкатывается на сервер. Когда выходит новая версия клиента она использует новую функциональность на сервере.
      2. У нас большие фичи декомпозируются на множество мелких задач, разрабатываются и тестируются (например на тестовых пользователях) именно в такой архитектуре, притом последней уезжает таска которая включает данную большую фичу для всех пользователей. Так что это может быть совершенно разные задачи, начиная от багфиксов и заканчивая включением новой большой функциональности на продакшен.
      3. Мы используем большое количество автотестов на всех этапах тестирования, и стараемся особо покрывать критичные моменты. Плюс постфактум за проектом следит отдел мониторинга у которого огромное количество различных графиков и триггеров. Ну и конечно ручное тестирование задач которые в релизе. Опционально также проверяем продакшен вручную.
      4. Работают новые фичи + ничего не сломалось при выкатке= релиз удался
      Если что то случилось, мы не говорим что релиз плохой, а в максимально короткие сроки либо откатываемся, либо фиксим проблемы если они не так критичны и фикс займет очень короткое количество времени.
      5. Если баг то QA, сами разработчи, если фича то продукт совместно с лидами, если рефакторинг сами разработчики. Жесткой бюрократии у нас нет.
      6. Я не очень понял вопрос, думаю что тестирование ответит вам гораздо лучше:) Илья?
      • +1
        Расскажите как вы поддерживаете консистентность данных. Если я правильно понял, то из за шардинга вы не можете использовать выстроенные в ДБ механизмы типа внешних/уникальных ключей.
        • +6
          Тут путаница. Уникальные ключи, конечно, есть. В шардированной схеме мы внешние ключи не используем по историческим причинам, но это можно сделать. Консистентность будет в пределах шарда, но это как раз нормально — именно это и требуется. Тем не менее, жить без нее не сильно сложнее, как показала практика. Отказ от внешних ключей для датабазника может показаться очень странным (я сам до этого сидел 3 года на оракле), но консистентность по внешним ключам действительно оказалась почти не нужной. Каскадные удаления — фактически единственное реальное удобство, которого нет. Но мы не удаляем данные, а олдскульно помечаем статусами. Удаляется все потом единообразная системой пуржинга. Вообще один-два раза в года я рассказываю об этом подробнее на семинаре в рамках девконфа, например.
          • +3
            Спасибо за ответ. А статья по теме «БД в Баду» не планируется?
    • +2
      6. Ручное тестирование есть и флоу у него ничем не отличается от описанного выше. Задачи (новые фичи, багфиксы и т.п.) приходят в QA сразу после выполнения. На этот момент задача уже прошла code-review и прогнаны автоматом юнит-тесты (в тикете в джире есть репорт об этом). Тестировщики тестят это в девелоперском окружении, если все хорошо — следующий этап это тестирование задачи в шоте. Шот — это пре-продакшен для отдельной ветки кода. Если, опять же, все хорошо, то следующий этап — тестирование билда из смерженных фич на стейджинге. Ну и все что протестировано на стейджинге, уезжает в продакшен. Все эти этапы тестирования включают как ручное, так и автоматизированное тестирование. Интеграционные тесты QA-инженеры пишут на phpUnit, с использованием Selenium WD. Ручное тестирование включает в себя как регрессионные проверки фич, для которых по тем или иным причинам еще нет селениум-тестов, так и exploratory-тестирование фич. Ну и проверка фронтенда (верстка, js и т.д.) в разных браузерах, в зависимости от популярности по статистике посещения.
      • +1
        А можете чуть подробнее рассказать о шотах?
        Если они не изолированы друг от друга, т.е используют одинаковые подключения к базам, то, получается, они могут влиять друг на друга(общий кеш, поменялась структура данных уходящих в очередь и тд)?
        В функциональных тестах какая база используется? Та же, что и в девелоперском окружении? Если да, то при постоянном запуске(100 задач * 18000 тестов) она будет забиваться различными данными. Или все же используются для этого отдельные снапшоты/фикстуры БД?
        • +2
          Шот это просто папка с гитом, где счекаучена ветка задачи + настройки nginx, чтобы можно было зайдя по определенным точкам входа увидеть веб-морду, апи для клиентов и т.д. Эта папка выгружается на одну из машин в боевом окружении, где и тестируется.
          По другим ресурсам — базам, мемкешам, демонам — они не изолированы, вы правы. И риски о которых вы говорите тоже имеются, никуда от этого не деться. Но мы минимизируем эти риски, когда тестируем задачу до шотов — в девел окружении. Где все вышеперечисленные ресурсы отделены от продакшена.
          Интеграционные селениум-тесты гоняются в двух окружениях — девелоперском и стейджинговом. Для них используется отдельный пулл объектов, не затрагивающий основных пользователей ресурса.
          Для девел-окружения, где (и только где) гоняются еще и юнит-тесты и функциональные тесты, отдельных снапшотов с данными не используем. Данные после сетов тестов либо роллбечим в транзакциях (где это возможно), либо используем моки таблиц. У нас есть свои классы/механизмы для этого, мы подменяем на лету таблицы и запросы к ним в коде. Таблицы делаются темповыми (за небольшими исключениями) и сами удаляются после тестов движком БД. Для тех мест, где нельзя использовать темповые таблицы, есть оффлайновый скрипт, который пробегается и чистит такие таблицы.
          Безусловно, бывают ситуации, когда тесты все же оставляют данные в девелоперских базах, но это не критично, ибо 1) используем подход «каждый тест должен сам для себя готовить данные, независимо от того, что в БД или других общих ресурсах было до него» и 2) ничто не мешает в любой момент перезалить девелоперскую БД.
      • +1
        Ведете ли вы общий тест-план проекта, что в него попадает и смогли ли вы автоматизировать его пополнение?
        • 0
          От части таким тест-планом выступает набор автотестов. Отдельно от этого ничего не ведем. Ну если не считать описание фич в confluence, которое ведется продактами и корректируется по ходу реализации.
  • +1
    Расскажите, пожалуйста, о базах: что используете, почему используете и какие действия предпринимаются когда нужно сделать миграцию или откатить ее.
    • +4
      Используем mysql, по историческим причинам (ну и вообще — отличная база, просто не нужно стрелять себе в ногу и всё). У нас кстати одна из крупнейших ферм MySQL — под 500 уже наверное нод в двух ДЦ. Миграция — это выполнение в паралелль по нескольким сотням нод какой-то операции, есть фреймворк под это дело, откатить — ну так же как и на одной базе. Вы умеете на одной базе откатить альтер, например? Я — нет. Надо снова альтерить — опять в параллель пускаем операции на нодах. Всё олдскульненько.
      • 0
        MyISAM?
        • +1
          боже упаси. InnoDB конечно
  • +7
    Спасибо большое за интервью. Сам проработал много лет релиз-инженером, отлично понимаю, насколько важную работу и насколько хорошо ребята выполяют в команде.

    Удач и успехов, в общем, пишите ещё.
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        Кстати, Сергей Авдюшкин не в этой же команде часом?
  • 0
    ребята, решите что-то с ресайзом фотографий.
    а то глаз режет (

    image
    • 0
      Да, согласны, мы сейчас решаем как раз этот вопрос.
  • 0
    Расскажите, как файлы, которые разработчик пишет на своей локальной машине, оказываются на его dev-сервере? Монтирование, синхронизация?
    • +1
      В данный момент наши разработчики используют каждый, кто во что горазд :).
      Варианты, как минимум:

      — sshfs
      — SMB
      — rsync «руками»
      — загрузка изменений, встроенная в PHPStorm
      — realsync
      — моя утилита, вместо realsync, которая умеет синхронизироваться на несколько серверов (сильно альфа :))

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка