[devel] Сборочница (IV). Рефакторинг имеющейся сборочницы.
Igor Vlasenko
vlasenko на imath.kiev.ua
Пн Фев 19 18:10:32 MSK 2018
Уважаемые господа!
Продолжаю серию писем по улучшению сборочницы.
Темой сегодняшнего письма является рефакторинг сборочницы.
Ранее я привел несколько предложений по улучшению
нашей сборочницы, которые можно внедрить, как промежуточные.
Кроме того, это может ускорить производительность в несколько раз.
Повторю эти предложения.
* Вынести все тесты в сборочные процессы.
Некоторые из них придется повторить на этапе merge,
чтобы обеспечить целостность репозитория,
но раз они будут выполнены повторно на той же транзакции,
то существенную часть данных для тестов можно закешировать и повторно использовать,
* Сделать merge явным отдельным этапом -
когда сборка закончится, выставить task'y статус
BUILT(ожидает merge)
Сделать merge отдельным скриптом, который можно будет запускать
параллельно сборочным, который будет брать из очереди
task'и в статус BUILT(ожидает merge)
и последовательно мержить.
* Выбросить из мержа все тесты, не связанные с поддержанием
целостности репозитория.
Предлагаю оставить
** (кешированный) тест на наследование
** (кешированный) тест на символы в бинарниках
** тест на unmets
хочу ответить на заданные вопросы.
> Неочевидный выбор. По идее, все тесты, выполняемые на новом состоянии
> репозитория (после создания индексов для нового состояния репозитория) -
> это тесты на целостность репозитория. Возьмём, например, install check.
> Если его выбросить из мержа, то мы даже не протестируем устанавливаемость
> собранных пакетов в том репозитории, в который мы их отправляем.
Здесь хотел бы остановиться подробнее.
Все заинтересованные участники дискуссии уже, наверное, согласны с моим
анализом, что мерж транзакций в репозиторий --- бутылочное горлышко
нашей сборочницы.
Поэтому выносим оттуда все лишнее, к примеру, тесты. Однако далее
я предлагаю некоторые тесты повторить, не смотря на то, что они
замедляют мерж.
Почему именно их и почему не install check?
Потому что эти тесты нам гарантируют __постоянное__
присутствие в репозитории некоторых свойств,
еще и относительно дешево (за константное время).
К примеру, потратив время при merge на тест на unmets,
мы получим гарантию, что во всех итерациях репозитория
unmets не будет.
В отличие от него, install check никаких гарантий на будущие
репозитории не дает. Хочу это подчеркнуть.
Не прохождение install check -- достаточное основание,
чтобы отсеять (не пропустить) пакет в репозиторий.
А прохождение install check -- не достаточное основание,
чтобы гарантировать, что install check будет проходить успешно и
в последующих репозиториях.
Не буду приводить примеры, такие примеры легко построить всем
слушателям, когда пакет A нормально устанавливается неделю,
месяц, год, а потом в репозиторий попадает пакет B и ломает A.
Поможет ли против пакета B (со средним ожиданием в год)
повторный install check? С вероятностью 99.99999% -- не поможет.
Да, формально, существует вероятность, 0.00001%, что
пакет-злодей B будет отправлен в тот же день и час, при чем
смержится после начала билда A но до мержа A.
Но проверять это бессмысленно:
даже не потому, что это в bottleneck-е, одна машина поперек
дороги блокирует всю трассу,
даже не потому, что 0.00001%, а потому,
что слона то мы и не приметили.
на случай 0.00001% -- тест есть,
а на случай 99.99999% -- теста нет.
Когда пакет B попадет в репозиторий, он сломает install check.
(а он попадет, это же у A сломается install check, а не у B)
Вопрос, как мы узнаем об этом?
Ответ - надо делать супербихайв=rebuild+check. Регулярно
прогонять уже имеющиеся пакеты через install check,
Таким образом, логическая ошибка здесь:
> Если его выбросить из мержа, то мы даже не протестируем устанавливаемость
> собранных пакетов в том репозитории, в который мы их отправляем.
собрали A с репозиторием R_1
проверили A с репозиторием R_2 (куда A отправляем)
отправили B в R_3. A сломался в R_3.
Помогла нам проверка A на R_2?
нет, не помогла. По сути-бесполезная проверка.
install check по своей сути похож на rebuild check.
Мы отправляем в Сизиф хорошие, годные, собирающиеся пакеты.
А они там в Сизифе ломаются :(.
Другими словами, все тесты можно разделить на 2 типа:
тесты, отсеивающие пакеты, и тесты,
гарантирующие некое свойство репозитория.
отсеивающие тесты надо выполнять сразу после сборки,
чтобы они выполнялись параллельно и ускоряли сборочницу.
На тесты, гарантирующие некое свойство репозитория,
придется урывать драгоценное время мержа.
Поэтому желательно при мерже их ускорить:
если предварительно выполнить при билде в параллельном
потоке как отсеивающие, и при этом
собранные символы и т.д. закешировать
и повторно использовать при проверке в мерже.
--
I V
Подробная информация о списке рассылки Devel