rascio
rascio

Reputation: 9279

Mock time in docker(-compose)

With the scope of testing a docker image executing a job, I would need to mock a container date during its execution, in order to do some accurate testing involving time.

Looking around the internet I didn't find any solution yet, just some paths that can be followed.
What I need is a way to change the system date, without having to connect manually to a shell, I'm planning to setup the tests using docker-compose, and I would like to configure the date as a configuration parameter.

Do you ever had similar experience? How did you solved?

First issue is changing the date, I've only found the date command to do it.

I'm looking for 2 methods:

  1. Extend the base image and execute date before the entrypoint. I don't feel to re-create an image for each container a problem, but I don't like the fact that I can't "proxy" the entrypoint, the only way I've found to execute the date command is to redefine the entrypoint with an sh that execute it and then call the old entrypoint, but it have to "know" what it was, I didn't find a way to do whatever the base image is.
  2. Use an NTP server. I'm a less-than-a-junior on this matter, but I was thinking about injecting in the network created by docker an ntp server that tells my mocked date to the other containers in its network. But I didn't find a way to configure a mocked ntp server in docker with fake time.

Currently I'm stucked, also a "You can't use the NTP server because blablabla..." would be helpful, or if you have some way to do it would be also better!

Upvotes: 4

Views: 2789

Answers (2)

fritzelr
fritzelr

Reputation: 91

I found libfaketime to be useful for this. It installs a wrapper for this purpose called faketime(1). According to the man page:

The given command will be tricked into believing that the current system time is the one specified in the timestamp. Filesystem timestamps will also be reported relative to this timestamp. The wall clock will continue to run from this date and time unless specified otherwise (see advanced options).

In your container, simply install libfaketime and use the faketime(1) wrapper like so:

faketime "2019-09-18 19:46:00" my-script

The library appears to be available in many distributions' repos; e.g. EPEL for RHEL-based systems:

dnf install -y epel-release && dnf install -y libfaketime

On Debian/Ubuntu:

apt update -y && apt install -y libfaketime

For Alpine Linux 3.18, the package is not available in the stable repo, but it is in the edge-community repo:

echo 'https://dl-cdn.alpinelinux.org/alpine/edge/community' >>/etc/apk/repositories
apk update && apk install libfaketime

Upvotes: 0

maxm
maxm

Reputation: 3667

I actually can't change the date inside my docker container. The docker clock is synced to the system clock.

There are other solutions though: Is it possible change date in docker container?

From what I understand about ntp, ntp clients try and update the system clock. So presumably you can't use NTP because a naive installation will try and change the system clock and then will be unable to do so inside docker. Maybe there is an ntp client that mocks, but I think you're back to the same problem and you're likely better off using the mocking lib in that link.

Testing clock skew is important (https://aphyr.com/posts/299-the-trouble-with-timestamps) and I'm also surprised there isn't more about this on the internet.

Upvotes: 3

Related Questions