Мониторинг и оповещения относятся к области управления надежностью, где хорошо известно понятие «бюджет ошибок»225, тогда как непрерывная интеграция все еще опирается на абсолютные значения. Отношение к непрерывной интеграции как к «сдвигу оповещений влево» позволяет шире рассуждать об этих политиках и находить более удачные практики:
• Обеспечение 100 % зеленых тестов на этапе непрерывной интеграции, как и 100 % безотказности службы в продакшене, стоит ужасно дорого. Если вы действительно ставите перед собой такую цель, то одной из самых больших проблем для вас станет состояние гонки между тестированием и фиксациями.
• Рассматривать все оповещения как равноценные причины для тревоги обычно неправильно. Если оповещение появляется в продакшене, но в действительности не влияет на работу службы, то правильнее будет отключить такое оповещение. То же относится к ошибкам в тестах: пока наши системы непрерывной интеграции не научатся говорить: «Известно, что этот тест терпит неудачу по несущественным причинам», — нам, вероятно, следует более либерально принимать изменения, которые отключают тест, терпящий неудачу. Не все неудачи при тестировании могут служить признаками предстоящих проблем в продакшене.
• Политики, гласящие: «Никто не должен выполнять фиксацию в репозиторий, пока цикл непрерывной интеграции не завершится успехом», — скорее всего, ошибочны. Если непрерывная интеграция сообщает о проблеме, ее обязательно нужно исследовать, прежде чем позволить инженерам зафиксировать новые изменения или усугубить проблему. Но если причина хорошо изучена и не влияет на работоспособность в продакшене, то блокировать фиксации будет неразумно.
Такое отношение к системе непрерывной интеграции, как к «системе оповещения», пока не получило широкого распространения, и мы все еще пытаемся понять, какие параллели более уместны. Принимая во внимание высокие ставки, неудивительно, что специалисты по надежности тщательно проанализировали опыт, связанный с мониторингом и оповещениями, но все еще считают непрерывную интеграцию роскошью226. В ближайшие несколько лет задача программной инженерии будет состоять в том, чтобы переосмыслить существующую практику поддержания высокой надежности и безотказности в контексте непрерывной интеграции, чтобы помочь реформировать ландшафт тестирования и непрерывной интеграции — и, возможно, передовой опыт тестирования сможет помочь прояснить цели и политики мониторинга и оповещения.
Тестирование до и после фиксации
Итак, какие тесты следует выполнять перед фиксацией? Мы следуем общему правилу: только быстрые и надежные. На этапе тестирования перед фиксацией можно пожертвовать некоторой полнотой охвата, но это означает, что вы должны выявить любые оставшиеся проблемы на следующем этапе тестирования после фиксации и быть готовыми выполнить некоторое количество откатов. После фиксации можно позволить себе потратить больше времени на борьбу с нестабильностью, если для этого есть надлежащие механизмы.
В разделе «Непрерывная интеграция в Google» мы увидим, как TAP осуществляет управление сбоями.
Мы не хотим жертвовать продуктивностью инженеров, поэтому на этапе предварительной проверки выполняем только тесты для проекта, в котором происходят изменения. Мы также выполняем тесты параллельно, поэтому учитываем затраты вычислительных ресурсов. Наконец, мы не хотим выполнять ненадежные тесты на этапе предварительной проверки, потому что слишком высока стоимость привлечения инженеров к устранению проблемы, которая не связана с изменениями.
На этапе предварительной проверки большинство команд в Google выполняют свои маленькие тесты (например, юнит-тесты)224, которые, как правило, самые быстрые и надежные. Но есть ли смысл выполнять тесты с широким охватом перед фиксацией? Ответ на этот вопрос зависит от команды. Команды, считающие нужным их выполнять, используют проверенный подход герметичного тестирования, помогающий уменьшить нестабильность, свойственную таким тестам. Другой возможный подход: выполнять ненадежные тесты с широким охватом при предварительной проверке, но отключать их, когда они начинают терпеть неудачу.
Почему тестирования перед фиксацией недостаточно
Стараясь как можно быстрее выявлять проблемные изменения и выполнять автоматическое тестирование перед фиксацией, вы можете задаться вопросом: почему нельзя просто запускать все тесты перед фиксацией?
Во-первых, это слишком дорого. Продуктивность инженера имеет высокую цену, и долгое ожидание выполнения всех тестов во время фиксации может серьезно снизить ее. Кроме того, устраняя ограничение на полноту предварительных проверок, можно добиться значительного увеличения эффективности, если тесты будут завершаться успехом гораздо чаще, чем неудачей. Например, тесты могут ограничиваться определенными областями или выбираться на основе модели, прогнозирующей вероятность обнаружения сбоя.
Точно так же слишком дорого будут обходиться простои инженеров из-за сбоев нестабильных тестов, не имеющих ничего общего с фиксируемым изменением.
Во-вторых, пока мы выполняем тесты перед фиксацией, чтобы убедиться в безопасности изменения, база кода в репозитории может измениться и стать несовместимой с тестируемыми изменениями. То есть два изменения, затрагивающие совершенно разные файлы, могут вызвать сбой теста. Мы называем эту ситуацию столкновением в воздухе, и в масштабе нашей компании оно очень редко случается. Системы непрерывной интеграции для небольших репозиториев или проектов могут выстраивать фиксации в очередь, чтобы не было разницы между тем, что предполагалось добавить, и тем, что в итоге добавлено.