Как стать автором
Обновить

Обманываем время: о тестировании с «подставным» временем на Linux и Docker

Время на прочтение3 мин
Количество просмотров14K

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


Менять системное время глобально ой, как не хотелось. Муторно, плюс у меня в ней столько всего понаставлено, не дай Б-г что-то заглючит (вряд ли, но мало ли). Думал запустить VirtualBox, но уж больно лень было ставить «чистую» Убунту, расшаривать папки, и т. д., тем более что этот вариант жрёт, как троглодит серьёзно потребляет машинные ресурсы.


Но буквально недавно я начал ковырять Docker. «У него просто обязан быть механизм контроля системного времени внутри контейнера», — подумал я. Рассмотрим, что же в результате вышло.


Докер не выручил


Итак, создаём контейнер и залезаем в него:


docker run -it ubuntu bash

Сразу скажу, что в контейнере я работаю как root, поэтому sudo не требуется.


Пробую:


date --set='2017-04-20 23:59:50'

Выдаёт date: cannot set date: Operation not permitted


Пробую:


hwclock --set --date='2017-04-20 23:59:50'

Выдаёт hwclock: Cannot access the Hardware Clock via any known method.


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


Решение оказалось не докеровским


Ещё один вариант — в самой моей программе перехватывать вызовы к системному времени, но, опять же, муторно. Но буквально этажом выше есть ответ, указывающий на некую библиотеку libfaketime. С помощью неё можно подставить «фальшивое время» для запускаемого процесса. Итак, устанавливаю её в контейнер:


git clone https://github.com/wolfcw/libfaketime.git
cd libfaketime
make install

Далее, следуя инструкции в ответе, запускаю бота с заданными переменными окружения:


LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME_NO_CACHE=1 FAKETIME="2017-04-19 23:59:50" ./run.sh --debug#

Где в LD_PRELOAD подставляем свежеустановленную библиотеку, а в FAKETIME пишем время, которое хотим выставить для запускаемого процесса. FAKETIME_NO_CACHE использовался в примере и предположительно отключает кеширование, используемое для повышения производительности. Не испытывал, но полагаю, что этот параметр необязателен.


Итак, программа запустилась, и действительно время выставилось так, как я хотел. Лишь с одной проблемой — время остановилось. Сообщения дебага показывают постоянно [2017-04-19 23:59:50]. В этой библиотеке есть одна неинтуитивная особенность. Простое задание времени действительно задаёт и фиксирует его. Что бы время именно начиналось от данной точки, надо задать его, как FAKETIME='@2017-04-19 23:59:50'. И врёмя пойдёт от этой точки.


Аналог из репозиториев


Оказывается, всё даже проще. Чуть позже я обнаружил, что эта библиотека есть в стандартных репозиториях Ubuntu, и спокойно ставится через apt-get install faketime. А запускается так:


faketime -f '@2017-04-20 23:59:50' ./run.sh

Не забываем про @ перед временем, здесь такой же синтаксис, но в довольно кратком man это не сказано. Только в подробном описании на Гитхабе.


Вместо заключения


Таким образом можно быстро и просто регулировать время, воспринимаемое запускаемой программой, будь она в контейнере Docker или в системе-хосте. В ответе указывалось, что если нужно изменить «фальшивое время» из самой программы, то достаточно изменить глобальную переменную. К примеру, на Питоне:


os.environ["FAKETIME"] = "2020-01-01"

Возможно есть другие, более удобные способы регулирования времени для процесса? Расскажите о них в комментариях.

Теги:
Хабы:
Всего голосов 32: ↑28 и ↓4+24
Комментарии21

Публикации

Истории

Работа

Python разработчик
130 вакансий
Data Scientist
78 вакансий

Ближайшие события

27 августа – 7 октября
Премия digital-кейсов «Проксима»
МоскваОнлайн
11 сентября
Митап по BigData от Честного ЗНАКа
Санкт-ПетербургОнлайн
14 сентября
Конференция Practical ML Conf
МоскваОнлайн
19 сентября
CDI Conf 2024
Москва
20 – 22 сентября
BCI Hack Moscow
Москва
24 сентября
Конференция Fin.Bot 2024
МоскваОнлайн
25 сентября
Конференция Yandex Scale 2024
МоскваОнлайн
28 – 29 сентября
Конференция E-CODE
МоскваОнлайн
28 сентября – 5 октября
О! Хакатон
Онлайн
30 сентября – 1 октября
Конференция фронтенд-разработчиков FrontendConf 2024
МоскваОнлайн