mirror of
https://github.com/wolfcw/libfaketime.git
synced 2026-05-17 00:26:16 +03:00
Implement FAKETIME_FOLLOW_ABSOLUTE feature
See README for feature intent. Simple regression test at test_follow_absolute.sh.
This commit is contained in:
9
README
9
README
@@ -420,6 +420,15 @@ LD_PRELOAD=/path/to/libfaketime.so.1 \
|
||||
# (in a different terminal window or whatever)
|
||||
touch -t 2002290123.45 /tmp/my-demo-file.tmp
|
||||
|
||||
Setting the environment variable FAKETIME_FOLLOW_ABSOLUTE=1 enables a submode
|
||||
of FAKETIME_FOLLOW_FILE behavior where fake time ONLY advances when the follow
|
||||
file's timestamp advances. In this mode an application that is not subject to
|
||||
libfaketime LD_PRELOAD intercept can absolutely control time for applications
|
||||
that are hooked by libfaketime. For example, a host application can control the
|
||||
timestamp of a follow file mapped into a container to implement (relatively)
|
||||
clean pause/resume behavior for fake time applications running within the
|
||||
container.
|
||||
|
||||
|
||||
Changing the 'x' modifier during run-time
|
||||
-----------------------------------------
|
||||
|
||||
@@ -2701,12 +2701,33 @@ static void parse_ft_string(const char *user_faked_time)
|
||||
else
|
||||
{
|
||||
user_faked_time_timespec.tv_sec = master_file_stats.st_mtime;
|
||||
user_faked_time_timespec.tv_nsec = 0;
|
||||
if (NULL == getenv("FAKETIME_FOLLOW_ABSOLUTE"))
|
||||
{
|
||||
/* Normal FAKETIME_FOLLOW_FILE behavior; fake time coasts between mtime updates */
|
||||
user_faked_time_timespec.tv_nsec = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set fake time to nanosecond-precision mtime */
|
||||
user_faked_time_timespec.tv_nsec = master_file_stats.st_mtim.tv_nsec;
|
||||
|
||||
/* Freeze fake time (mtime is absolute truth in this mode) */
|
||||
if (ft_mode != FT_NOOP)
|
||||
{
|
||||
ft_mode = FT_FREEZE;
|
||||
}
|
||||
|
||||
/* Bypass parse_modifiers since we have absolute time */
|
||||
user_faked_time_set = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (NULL == getenv("FAKETIME_DONT_RESET"))
|
||||
reset_time();
|
||||
goto parse_modifiers;
|
||||
if (!user_faked_time_set)
|
||||
{
|
||||
goto parse_modifiers;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
|
||||
79
test/functests/test_follow_absolute.sh
Normal file
79
test/functests/test_follow_absolute.sh
Normal file
@@ -0,0 +1,79 @@
|
||||
# Tests for FAKETIME_FOLLOW_ABSOLUTE feature.
|
||||
#
|
||||
# When FAKETIME_FOLLOW_ABSOLUTE=1 is set alongside FAKETIME="%" and
|
||||
# FAKETIME_FOLLOW_FILE, time freezes at the follow file's mtime
|
||||
# and only advances when the file's mtime changes.
|
||||
|
||||
FOLLOW_FILE=".follow_absolute_test_file"
|
||||
|
||||
init()
|
||||
{
|
||||
typeset testsuite="$1"
|
||||
PLATFORM=$(platform)
|
||||
if [ -z "$PLATFORM" ]; then
|
||||
echo "$testsuite: unknown platform! quitting"
|
||||
return 1
|
||||
fi
|
||||
echo "# PLATFORM=$PLATFORM"
|
||||
return 0
|
||||
}
|
||||
|
||||
run()
|
||||
{
|
||||
init
|
||||
|
||||
run_testcase follow_absolute_basic
|
||||
run_testcase follow_absolute_freeze
|
||||
run_testcase follow_absolute_tracks_mtime
|
||||
|
||||
rm -f "$FOLLOW_FILE"
|
||||
}
|
||||
|
||||
# Helper to run a command with follow-absolute configuration
|
||||
follow_absolute_cmd()
|
||||
{
|
||||
FAKETIME_FOLLOW_FILE="$FOLLOW_FILE" \
|
||||
FAKETIME_FOLLOW_ABSOLUTE=1 \
|
||||
fakecmd "%" "$@"
|
||||
}
|
||||
|
||||
# Test that time matches the follow file's mtime
|
||||
follow_absolute_basic()
|
||||
{
|
||||
touch -d "2020-03-15 10:30:00 UTC" "$FOLLOW_FILE"
|
||||
typeset actual
|
||||
actual=$(follow_absolute_cmd date -u +"%Y-%m-%d %H:%M:%S")
|
||||
asserteq "$actual" "2020-03-15 10:30:00" \
|
||||
"time should match follow file mtime"
|
||||
}
|
||||
|
||||
# Test that time stays frozen (does not advance with real time)
|
||||
follow_absolute_freeze()
|
||||
{
|
||||
touch -d "2020-03-15 10:30:00 UTC" "$FOLLOW_FILE"
|
||||
typeset timestamps
|
||||
timestamps=$(follow_absolute_cmd \
|
||||
perl -e 'print time(), "\n"; sleep(2); print time(), "\n"')
|
||||
typeset first second
|
||||
first=$(echo "$timestamps" | head -1)
|
||||
second=$(echo "$timestamps" | tail -1)
|
||||
asserteq "$first" "$second" \
|
||||
"time should stay frozen within a single process"
|
||||
}
|
||||
|
||||
# Test that time tracks file mtime changes at millisecond precision
|
||||
follow_absolute_tracks_mtime()
|
||||
{
|
||||
touch -d "2020-03-15 10:30:00.000 UTC" "$FOLLOW_FILE"
|
||||
typeset first
|
||||
first=$(follow_absolute_cmd \
|
||||
perl -MTime::HiRes=time -e 'printf "%.3f\n", time()')
|
||||
|
||||
touch -d "2020-03-15 10:30:00.005 UTC" "$FOLLOW_FILE"
|
||||
typeset second
|
||||
second=$(follow_absolute_cmd \
|
||||
perl -MTime::HiRes=time -e 'printf "%.3f\n", time()')
|
||||
|
||||
assertneq "$first" "$second" \
|
||||
"time should advance with file mtime (ms precision)"
|
||||
}
|
||||
Reference in New Issue
Block a user