read

Работая над одним большим и старым проектом, однажды ночью я отправил в репозиторий коммит, и уже собираясь закончить работу, решил посмотреть статус коммита на CI-сервере. Коммит был небольшой, и на первый взгляд просто не мог ничего сломать. Но большим был проект, а количество нарушенных в нём архитектурных принципов было столь велико, что надеяться на удачу не приходилось. Тесты шли около 10 минут, и… Не прошли! Интересно. Упавшие тесты относились к подсистеме биллинга, и содержали утверждения относительно дат окончания оплаченных тарифов. Я не работал с этой частью системы раньше (и позже тоже), и не знал её особенностей - пытаться разобраться в исходниках казалось плохой идеей. Переключился на мастер и запустил тесты биллинга - не прошли. Закралась мысль об особенностях конфигурации локальной машины и её отличиях от production и testing окружений. Зашел на тестовый сервер и вручную запустил сборку мастер ветки. Последняя дневная сборка была успешной. 5, 7, 10 минут - тесты не прошли! Сборка упала на тех же самых тестах, при этом этот же код успешно проходил все тесты днём ранее. Выглядело всё это странно и ничего не оставалось, кроме как погрузиться в детальное изучение возникавшей во время теста ошибки. Ошибка гласила что ожидаемая дата отличается от актуального значения на 1 день. Где даты и время - там проблемы работы с часовыми поясами. Утром коллеги с улыбкой поведали мне о том, что эти тесты всегда падают ночью и что об этом не стоит беспокоиться. Действительно, перезапустив ту же самую сборку, которую я запустил ночью, я убедился в том что все тесты прошли успешно.

В чём же ошибка?

Представьте себе что у вас есть временная метка - запись о дате и времени какого-либо события. Например истечения срока действия пробного периода вашего продукта. Дата может быть записана так (формат ISO 8601): 2016-10-17T01:30:00+03:00. Данная запись содержит в себе информацию о часовом поясе - +03:00, т.е. половина второго ночи будет в часовом поясе +03. Тоже самое время по Гринвичу будет: 2016-10-16T22:30:00+00:00 - вчерашнее относительно исходного времени, но - то же самое. В связи с этим нужно быть аккуратным при извлечении даты из временной метки, как видно - в данном случае они (даты) могут быть разными, в зависимости от того в каком формате представлена временная метка.

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

Пишите тесты и спокойной вам ночи!)

Blog Logo

Василий Колесников


Published

Image

Опавшие листья

О программировании, науке и не только.

Back to Overview