Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Система непрерывной интеграции

Оригинал: A Continuous Integration System
Автор: Malini Das
Дата публикации: July 12, 2016
Перевод: Н.Ромоданов
Дата перевода: октябрь 2016 г.

Предыдущая часть статьи

Диаграмма потока управления

На рисунке 2.1 представлена общая схема нашей системы. В этой схеме предполагается, что все три файла (repo_observer.py, dispatcher.py и test_runner.py) уже работают, и описываются действия, которые выполняет каждый процесс, когда обрабатывается новый коммит.

Рис.1. Поток управления

Запуск кода

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

$ python dispatcher.py

В новой оболочке, мы запускаем средство запуска тестов (так что оно может самостоятельно зарегистрировать себя в диспетчере):

$ python test_runner.py <path/to/test_repo_clone_runner>

Средство запуска тестов само выберет себе порт в диапазоне 8900-9000. Вы можете запустить такое количество его экземпляров, какое пожелаете.

И, наконец, давайте в еще одной командной оболочке запустим наблюдателя за репозитарием:

$ python repo_observer.py --dispatcher-server=localhost:8888 <path/to/repo_clone_obs>

Теперь, когда все настроено, давайте запускать тесты! Для того, чтобы это сделать, мы должны создать новый коммит. Перейдите в главный репозитарий и сделайте любое изменение:

$ cd /path/to/test_repo
$ touch new_file
$ git add new_file
$ git commit -m"new file" new_file

После этого repo_observer.py сообразит, что есть новый коммит и сообщить об этом диспетчеру. Вы можете это проконтролировать, т. к. увидите результаты в в виде выходных данных в соответствующих командных оболочках. После того, как диспетчер получит результаты тестирования, он сохранит их в каталоге test_results/ в файле с именем файла, совпадающем с ID коммита.

Обработка ошибок

В этой системе непрерывной интеграции есть простой механизм обработки ошибок.

Если вы уничтожите процесс test_runner.py, диспетчер dispatcher.py обнаружит, что средство запуска тестов уже недоступно и удалит его из пула.

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

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

Заключение

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

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

Запуск теста для каждого коммита

Имеющаяся система будет периодически выполнять проверку для того, чтобы узнать, были ли запущены новые коммиты, и будет запускать тесты для самого последнего коммита. Систему можно улучшить и сделать так, чтобы она тестировала каждый коммит. Для этого вы можете изменить алгоритм периодической проверки и запускать тесты для каждого коммита после последнего уже оттестированного коммита и до самого последнего выполненного коммита.

Интеллектуальный запуск тестов

Если средство запуска тестов обнаруживает, что диспетчер не отвечает на запросы, оно прекращает свою работу. Это происходит даже тогда, когда оно еще выполняет тесты! Было бы лучше, если бы оно ожидало в течение некоторого периода времени (или неопределенно долго в случае, если вы не экономите ии ресурсами) пока диспетчер не будет доступен по сети. В таком случае, если диспетчер останавливается в тот момент когда средство запуска тестов активно выполняет тесты, то оно вместо остановки завершит выполнение тестов и будет ожидать, пока диспетчер не появится в сети, и сообщит ему о результатах. Это гарантирует, что мы не заставим средство запуска тестов напрасно выполнять работу и будет выполнять ровно по одному тесту для каждого коммита.

Отчеты

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

Менеджер запусков

На данный момент для того, чтобы запустить средство запуска тестов, вы должны вручную запускать test_runner.py. Вместо этого вы можете создать процесс менеджера запусков тестов, который будет оценивать текущую нагрузку, связанную с запросами на тестирование, поступающими от диспетчера, и соответствующим образом изменять количество активных экземпляров средства запуска тестов. Этот процесс будет получать сообщения runtest и будет запускать новый экземпляр для каждого запроса, а когда нагрузка будет снижаться, этот процесс будет уничтожать неиспользуемые процессы.

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

Если вы хотите увидеть, какого уровня гибкости могут достигнуть системы непрерывной интеграции, то можно взглянуть на систему Jenkins, очень надежную систему непрерывной интеграции с открытым исходным кодом и написанную на языке Java. Она предоставляется в виде базового комплекта системы непрерывной интеграции, которую можно расширить с помощью плагинов. Вы также можете получить доступ к ее исходному коду в GitHub. Другой проект, который можно вам порекомендовать, это система Travis CI, написанная на языке Ruby, и исходный код которой также доступен в GitHub.

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

1. Интерпретатор Bash используется потому, что нам нужно проверять наличие файлов, создавать файлы, а также пользоваться системой Git, а для достижения этих целей наиболее прямым и простым способом является скрипт командной оболочки. В качестве альтернативы имеются кросс-платформенные пакеты языка Python, которыми вы можете воспользоваться; например, для доступа к файловой систем может быть использован модуль языка Python, встроенный в операционную систему, а для доступа к Git может быть использован пакет GitPython, но они выполняют свои действия более окольным способом.

Перейти к началу статьи.