Skip to content

Commit

Permalink
Merge pull request #20 from rbalint/deterministic-time
Browse files Browse the repository at this point in the history
Advance time with each time(), gettimeofday(), etc. call
  • Loading branch information
wolfcw committed Aug 15, 2013
2 parents 946f8e2 + 2451de2 commit c127aec
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 1 deletion.
6 changes: 6 additions & 0 deletions README
Expand Up @@ -248,6 +248,12 @@ FAKETIME="+1y x0,5"
will make the clock run only half as fast. As stated above, the fraction
delimiter depends on your locale.

FAKETIME="+1y i2,0"

will make the clock step two seconds per each time(), etc. call, running
completely independently from the system clock. It helps running programs
with some determinism.

For testing, your should run a command like

LD_PRELOAD=./libfaketime.so.1 FAKETIME="+1,5y x10,0" \
Expand Down
4 changes: 3 additions & 1 deletion man/faketime.1
Expand Up @@ -32,6 +32,7 @@ faketime 'last Friday 5 pm' /bin/date
faketime '2008-12-24 08:15:42' /bin/date
faketime -f '+2,5y x10,0' /bin/bash -c 'date; while true; do echo $SECONDS ; sleep 1 ; done'
faketime -f '+2,5y x0,50' /bin/bash -c 'date; while true; do echo $SECONDS ; sleep 1 ; done'
faketime -f '+2,5y i2,0' /bin/bash -c 'date; while true; do echo $SECONDS ; sleep 1 ; done'
(Please note that it depends on your locale settings whether . or , has to be used for fractional offsets)
.fi
.SH ADVANCED TIMESTAMP FORMAT
Expand All @@ -49,7 +50,8 @@ This is the most often used format and specifies the faked time relatively to th
Start-at timestamps: \fB"@YYYY-MM-DD hh:mm:ss"\fR
The wall clock will start counting at the given timestamp for the program. This can be used for specifying absolute timestamps without freezing the clock.
.SH ADVANCED USAGE
When using relative time offsets or start-at timestamps (see ADVANCED TIMESTAMP FORMAT above and option \fB\-f\fR), the clock speed can be adjusted, i.e. time may run faster or slower for the executed program. For example, \fB"+5y x10"\fR will set the faked time 5 years into the future and make the time pass 10 times as fast (one real second equals 10 seconds measured by the program). Similarly, the flow of time can be slowed, e.g. using \fB"-7d x0,2"\fR, which will set the faked time 7 days in the past and set the clock speed to 20 percent, i.e. it takes five real world seconds for one second measured by the program. Again, depending on your locale, either "x2.0" or "x2,0" may be required regarding the delimiter.
When using relative time offsets or start-at timestamps (see ADVANCED TIMESTAMP FORMAT above and option \fB\-f\fR), the clock speed can be adjusted, i.e. time may run faster or slower for the executed program. For example, \fB"+5y x10"\fR will set the faked time 5 years into the future and make the time pass 10 times as fast (one real second equals 10 seconds measured by the program). Similarly, the flow of time can be slowed, e.g. using \fB"-7d x0,2"\fR, which will set the faked time 7 days in the past and set the clock speed to 20 percent, i.e. it takes five real world seconds for one second measured by the program. Again, depending on your locale, either "x2.0" or "x2,0" may be required regarding the delimiter. You can also make faketime to advance the reported time by a preset interval upon each time() call independently from the system's time using \fB"-7d i2,0"\fR, where
\fB"i"\fR is followed by the increase interval in seconds.
.PP
Faking times for multiple programs or even system-wide can be simplified by using ~/.faketimerc files and /etc/faketimerc. Please refer to the README that came with faketime for warnings and details.
.SH AUTHOR
Expand Down
1 change: 1 addition & 0 deletions src/faketime
Expand Up @@ -63,6 +63,7 @@ if [ -z "$offset" -o "$offset" = "-h" -o "$offset" = "-?" -o "$offset" = "--help
echo "$0 '2008-12-24 08:15:42' /bin/date"
echo "$0 -f '+2,5y x10,0' /bin/bash -c 'date; while true; do echo \$SECONDS ; sleep 1 ; done'"
echo "$0 -f '+2,5y x0,50' /bin/bash -c 'date; while true; do echo \$SECONDS ; sleep 1 ; done'"
echo "$0 -f '+2,5y i2,0' /bin/bash -c 'date; while true; do echo \$SECONDS ; sleep 1 ; done'"
echo "(Please note that it depends on your locale settings whether . or , has to be used for fractions)"
echo ""
if [ -z "$offset" ] ; then
Expand Down
12 changes: 12 additions & 0 deletions src/faketime.c
Expand Up @@ -97,6 +97,11 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp);

static int fake_stat_disabled = 0;

/**
* When advancing time linearly with each time(), etc. call, the calls are
* counted here */
static long int ticks = 0;

/* Contributed by Philipp Hachtmann in version 0.6 */
int __xstat (int ver, const char *path, struct stat *buf) {
static int (*real_stat) (int, const char *, struct stat *);
Expand Down Expand Up @@ -639,6 +644,7 @@ time_t fake_time(time_t *time_tptr) {
char filename[BUFSIZ], line[BUFFERLEN];
FILE *faketimerc;
static const char *user_faked_time_fmt = NULL;
char * tmp_time_fmt;

/* variables used for caching, introduced in version 0.6 */
static time_t last_data_fetch = 0; /* not fetched previously at first call */
Expand Down Expand Up @@ -852,6 +858,9 @@ static pthread_mutex_t time_mutex=PTHREAD_MUTEX_INITIALIZER;
const long tdiff = (long long) *time_tptr - (long long)ftpl_starttime;
const double timeadj = tdiff * (rate - 1.0);
*time_tptr += (long) timeadj;
} else if (NULL != (tmp_time_fmt = strchr(user_faked_time, 'i'))) {
/* increment time with every time() call*/
*time_tptr = atof(tmp_time_fmt + 1) * ticks++;
}

*time_tptr += (long) frac_user_offset;
Expand All @@ -873,6 +882,9 @@ static pthread_mutex_t time_mutex=PTHREAD_MUTEX_INITIALIZER;
const long tdiff = (long long) *time_tptr - (long long)ftpl_starttime;
const double timeadj = tdiff * (rate - 1.0);
*time_tptr += (long) timeadj;
} else if (NULL != (tmp_time_fmt = strchr(user_faked_time, 'i'))) {
/* increment time with every time() call*/
*time_tptr = atof(tmp_time_fmt + 1) * ticks++;
}

*time_tptr += user_offset;
Expand Down

0 comments on commit c127aec

Please sign in to comment.