We cheat time: about testing with “fake” time on Linux and Docker
- Tutorial
When developing the next bot for a group in Telegram, I had to test it with different values of the system time. This bot at the end of each day sends (or, depending on a number of conditions, does not send) a message to the chat and manipulates some of its previous messages (or, again, does not ).
Change system time globally oh howdid not want. It’s a chore, plus I’ve got so much in it, do not let Gd make a mistake (unlikely, but never mind). I thought about launching VirtualBox, but it was too lazy to put a “clean” Ubuntu, to share folders, etc., especially since this optioneats like troglodyte seriously consumes machine resources.
But just recently, I started picking Docker. “He simply has to have a mechanism to control the system time inside the container,” I thought. Consider what happened as a result.
Docker did not help out
So, create a container and climb into it:
docker run -it ubuntu bashI must say right away that in the container I work as root, therefore sudoit is not required.
I try:
date --set='2017-04-20 23:59:50'Gives out date: cannot set date: Operation not permitted
I try:
hwclock --set --date='2017-04-20 23:59:50'Gives out hwclock: Cannot access the Hardware Clock via any known method.
Does not exceed. A little googling, I come across this answer . It seems that Docker does not do as much virtualization as it seemed to me. He uses the system time, and there is no way to get out. Unless you can play around with time zones, but in my case it does not work, I need full control over time.
The decision was not docker
Another option is to intercept calls to the system time in my program itself, but, again, is dreary. But literally a floor above there is an answer pointing to a certain libfaketime library . Using it, you can substitute "fake time" for the process to start. So, I install it in the container:
git clone https://github.com/wolfcw/libfaketime.git
cd libfaketime
make installNext, following the instructions in the answer, I launch the bot with the given environment variables:
LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME_NO_CACHE=1 FAKETIME="2017-04-19 23:59:50" ./run.sh --debug#Where we LD_PRELOADsubstitute the freshly installed library, and at the FAKETIMEtime we write, which we want to set for the starting process. FAKETIME_NO_CACHEused in the example and supposedly disables caching used to improve performance. I have not experienced it, but I believe that this parameter is optional.
So, the program started, and indeed the time was set as I wanted. With only one problem - time has stopped . Debug messages are shown constantly [2017-04-19 23:59:50]. There is one non-intuitive feature in this library. A simple task of time really sets and fixes it. What would the time just start from a given point, you need to ask him how FAKETIME='@2017-04-19 23:59:50'. And time will go from this point.
Analog from repositories
It turns out that everything is even simpler. A little later, I discovered that this library is in the standard Ubuntu repositories, and is quietly installed through apt-get install faketime. And it starts like this:
faketime -f '@2017-04-20 23:59:50' ./run.shDo not forget about @ before time, the same syntax is here, but in a rather brief manit is not said. Only in the detailed description on Github.
Instead of a conclusion
Thus, you can quickly and easily adjust the time perceived by the program being launched, whether it is in the Docker container or on the host system. The answer stated that if you need to change the "fake time" from the program itself, then just change the global variable. For example, in Python:
os.environ["FAKETIME"] = "2020-01-01"Perhaps there are other, more convenient ways to control the time for the process? Tell us about them in the comments.