summaryrefslogtreecommitdiffstats
path: root/tests/deckard/contrib/libfaketime/test
diff options
context:
space:
mode:
Diffstat (limited to 'tests/deckard/contrib/libfaketime/test')
-rw-r--r--tests/deckard/contrib/libfaketime/test/Makefile31
-rw-r--r--tests/deckard/contrib/libfaketime/test/Makefile.OSX30
-rw-r--r--tests/deckard/contrib/libfaketime/test/README-testframe.txt39
-rw-r--r--tests/deckard/contrib/libfaketime/test/functests/common.inc63
-rw-r--r--tests/deckard/contrib/libfaketime/test/functests/dont_test_false.sh6
-rw-r--r--tests/deckard/contrib/libfaketime/test/functests/test_exclude_mono.sh87
-rw-r--r--tests/deckard/contrib/libfaketime/test/functests/test_null.sh13
-rw-r--r--tests/deckard/contrib/libfaketime/test/functests/test_true.sh7
-rwxr-xr-xtests/deckard/contrib/libfaketime/test/functests/test_walkone.sh67
-rwxr-xr-xtests/deckard/contrib/libfaketime/test/test.sh66
-rwxr-xr-xtests/deckard/contrib/libfaketime/test/test_OSX.sh46
-rw-r--r--tests/deckard/contrib/libfaketime/test/testframe.inc55
-rwxr-xr-xtests/deckard/contrib/libfaketime/test/testframe.sh99
-rw-r--r--tests/deckard/contrib/libfaketime/test/timetest.c284
14 files changed, 893 insertions, 0 deletions
diff --git a/tests/deckard/contrib/libfaketime/test/Makefile b/tests/deckard/contrib/libfaketime/test/Makefile
new file mode 100644
index 0000000..94d1a2e
--- /dev/null
+++ b/tests/deckard/contrib/libfaketime/test/Makefile
@@ -0,0 +1,31 @@
+CC = gcc
+
+CFLAGS = -std=gnu99 -Wall -DFAKE_STAT -Werror -Wextra
+LDFLAGS = -lrt -lpthread
+
+SRC = timetest.c
+OBJ = ${SRC:.c=.o}
+
+all: timetest test
+
+.c.o:
+ ${CC} -c ${CFLAGS} $<
+
+timetest: ${OBJ}
+ ${CC} -o $@ ${OBJ} ${LDFLAGS}
+
+test: timetest functest
+ @echo
+ @./test.sh
+
+# run functional tests
+functest:
+ ./testframe.sh functests
+
+clean:
+ @rm -f ${OBJ} timetest
+
+distclean: clean
+ @echo
+
+.PHONY: all test clean distclean
diff --git a/tests/deckard/contrib/libfaketime/test/Makefile.OSX b/tests/deckard/contrib/libfaketime/test/Makefile.OSX
new file mode 100644
index 0000000..209d19f
--- /dev/null
+++ b/tests/deckard/contrib/libfaketime/test/Makefile.OSX
@@ -0,0 +1,30 @@
+CC ?= clang
+
+CFLAGS += -std=gnu99 -Wall -DFAKE_STAT
+
+SRC = timetest.c
+OBJ = ${SRC:.c=.o}
+
+all: timetest test
+
+.c.o:
+ ${CC} -c ${CFLAGS} $<
+
+timetest: ${OBJ}
+ ${CC} -o $@ ${OBJ} ${LDFLAGS}
+
+test: timetest functest
+ @echo
+ @./test_OSX.sh
+
+# run functional tests
+functest:
+ ./testframe.sh functests
+
+clean:
+ @rm -f ${OBJ} timetest
+
+distclean: clean
+ @echo
+
+.PHONY: all test clean distclean
diff --git a/tests/deckard/contrib/libfaketime/test/README-testframe.txt b/tests/deckard/contrib/libfaketime/test/README-testframe.txt
new file mode 100644
index 0000000..d6980c3
--- /dev/null
+++ b/tests/deckard/contrib/libfaketime/test/README-testframe.txt
@@ -0,0 +1,39 @@
+# here's how the testframe script works.
+#
+# Usage for testing:
+# usage: testframe.sh DIR
+# testframe.sh runs each testsuite script found within DIR.
+# (in the context of libfaketime, the DIR is functest.)
+# exits with status 0 if all tests succeed.
+#
+# Interface:
+# by convention, each testsuite script (within DIR) must be
+# a bash script named test_*.sh. the script must define a
+# function named "run". run takes no arguments. run is
+# expected to call the framework-provided function
+# run_testcase once for each test function. run_testcase
+# uses the global vars NFAIL and NSUCC to keep track of how
+# many testcases failed/succeeded.
+#
+# the test function is expected to call something like
+# asserteq or assertneq (again, framework-provided).
+#
+# fine print: for each testsuite, the framework creates a
+# subshell and dots in the script. also dotted in are
+# testframe.inc and DIR/common.inc (if it exists). the
+# testsuite script can make use of any functions defined
+# in these inc files. the environment variable
+# TESTSUITE_NAME is set to the filename of the testsuite
+# script, for possible use in warning or info messages.
+#
+# see functests/test_true.sh for a simple example of
+# a test suite script.
+#
+# Simple steps to add a new testsuite:
+# 1. decide its name - eg, XXX.
+# 2. choose a DIR of similar testsuites to put it in, or create a new one.
+# 3. create DIR/test_XXX.sh.
+# 4. write a run function and testcase functions in DIR/test_XXX.sh.
+# 5. within the run function, call run_testcase for each testcase function.
+# 6. within each testcase function, call assertneq or asserteq, or do
+# the equivalent.
diff --git a/tests/deckard/contrib/libfaketime/test/functests/common.inc b/tests/deckard/contrib/libfaketime/test/functests/common.inc
new file mode 100644
index 0000000..d184ae2
--- /dev/null
+++ b/tests/deckard/contrib/libfaketime/test/functests/common.inc
@@ -0,0 +1,63 @@
+# libfaketime-specific common support routines for tests
+
+# say which *_fakecmd wrapper to use
+platform()
+{
+ # may want to expand the pattern for linuxlike
+ typeset out=$(uname)
+ case "$out" in
+ *Darwin*) echo "mac" ;;
+ *Linux*) echo "linuxlike" ;;
+ GNU|GNU/kFreeBSD) echo "linuxlike" ;;
+ *SunOS*) echo "sunos" ;;
+ *) echo 1>&2 unsupported platform, uname=\"$out\" ;;
+ esac
+}
+
+# run faked command on a mac
+# UNTESTED
+mac_fakecmd()
+{
+ typeset timestring="$1"; shift
+ typeset fakelib=../src/libfaketime.1.dylib
+ export DYLD_INSERT_LIBRARIES=$fakelib
+ export DYLD_FORCE_FLAT_NAMESPACE=1
+ FAKETIME="$timestring" \
+ "$@"
+}
+
+sunos_fakecmd()
+{
+ typeset timestring="$1"; shift
+ typeset fakelib=../src/libfaketime.so.1
+ export LD_PRELOAD=$fakelib
+ FAKETIME="$timestring" \
+ "$@"
+}
+
+# run faked command on linuxlike OS
+linuxlike_fakecmd()
+{
+ typeset timestring="$1"; shift
+ typeset fakelib=../src/libfaketime.so.1
+ export LD_PRELOAD=$fakelib
+ FAKETIME="$timestring" \
+ "$@"
+}
+
+# run a command with libfaketime using the given timestring
+fakecmd()
+{
+ ${PLATFORM}_fakecmd "$@"
+}
+
+# generate a sequence of numbers from a to b
+range()
+{
+ typeset a=$1 b=$2
+ typeset i=$a
+ while ((i <= b)); do
+ echo $i
+ ((i = i+1))
+ done
+}
diff --git a/tests/deckard/contrib/libfaketime/test/functests/dont_test_false.sh b/tests/deckard/contrib/libfaketime/test/functests/dont_test_false.sh
new file mode 100644
index 0000000..65457ef
--- /dev/null
+++ b/tests/deckard/contrib/libfaketime/test/functests/dont_test_false.sh
@@ -0,0 +1,6 @@
+# a testsuite that will force failure - for testing purposes
+
+run()
+{
+ run_testcase false
+}
diff --git a/tests/deckard/contrib/libfaketime/test/functests/test_exclude_mono.sh b/tests/deckard/contrib/libfaketime/test/functests/test_exclude_mono.sh
new file mode 100644
index 0000000..f68fc20
--- /dev/null
+++ b/tests/deckard/contrib/libfaketime/test/functests/test_exclude_mono.sh
@@ -0,0 +1,87 @@
+# Checks that setting DONT_FAKE_MONOTONIC actually prevent
+# libfaketime from faking monotonic clocks.
+#
+# We do this by freezing time at a specific and arbitrary date with faketime,
+# and making sure that if we set DONT_FAKE_MONOTONIC to 1, calling
+# clock_gettime(CLOCK_MONOTONIC) returns two different values.
+#
+# We also make sure that if we don't set DONT_FAKE_MONOTONIC to 1, in other
+# words when we use the default behavior, two subsequent calls to
+# clock_gettime(CLOCK_MONOTONIC) do return different values.
+
+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 dont_fake_mono
+ run_testcase fake_mono
+}
+
+get_token()
+{
+ string=$1
+ token_index=$2
+ separator=$3
+
+ echo $string | cut -d "$separator" -f $token_index
+}
+
+assert_timestamps_neq()
+{
+ timestamps=$1
+ msg=$2
+
+ first_timestamp=$(get_token "${timestamps}" 1 ' ')
+ second_timestamp=$(get_token "${timestamps}" 2 ' ')
+
+ assertneq "${first_timestamp}" "${second_timestamp}" "${msg}"
+}
+
+assert_timestamps_eq()
+{
+ timestamps=$1
+ msg=$2
+
+ first_timestamp=$(get_token "${timestamps}" 1 ' ')
+ second_timestamp=$(get_token "${timestamps}" 2 ' ')
+
+ asserteq "${first_timestamp}" "${second_timestamp}" "${msg}"
+}
+
+get_monotonic_time()
+{
+ dont_fake_mono=$1; shift;
+ clock_id=$1; shift;
+ DONT_FAKE_MONOTONIC=${dont_fake_mono} fakecmd "2014-07-21 09:00:00" \
+ /bin/bash -c "for i in 1 2; do \
+ perl -w -MTime::HiRes=clock_gettime,${clock_id} -E \
+ 'say clock_gettime(${clock_id})'; \
+ sleep 1; \
+ done"
+}
+
+dont_fake_mono()
+{
+ timestamps=$(get_monotonic_time 1 CLOCK_MONOTONIC)
+ msg="When not faking monotonic time, timestamps should be different"
+ assert_timestamps_neq "${timestamps}" "${msg}"
+}
+
+fake_mono()
+{
+ timestamps=$(get_monotonic_time 0 CLOCK_MONOTONIC)
+ msg="When faking monotonic, timestamps should be equal"
+ assert_timestamps_eq "${timestamps}" "${msg}"
+}
diff --git a/tests/deckard/contrib/libfaketime/test/functests/test_null.sh b/tests/deckard/contrib/libfaketime/test/functests/test_null.sh
new file mode 100644
index 0000000..09e7560
--- /dev/null
+++ b/tests/deckard/contrib/libfaketime/test/functests/test_null.sh
@@ -0,0 +1,13 @@
+# check that the date doesn't happen to be 0.
+
+run()
+{
+ run_testcase nulltest
+}
+
+nulltest()
+{
+ typeset tdate=${I2DATES[0]}
+
+ assertneq 0 "$(date +%s)" "($tdate)"
+}
diff --git a/tests/deckard/contrib/libfaketime/test/functests/test_true.sh b/tests/deckard/contrib/libfaketime/test/functests/test_true.sh
new file mode 100644
index 0000000..0025bcf
--- /dev/null
+++ b/tests/deckard/contrib/libfaketime/test/functests/test_true.sh
@@ -0,0 +1,7 @@
+# test suite that always succeeds - for testing framework
+
+run()
+{
+ run_testcase true
+ return 0
+}
diff --git a/tests/deckard/contrib/libfaketime/test/functests/test_walkone.sh b/tests/deckard/contrib/libfaketime/test/functests/test_walkone.sh
new file mode 100755
index 0000000..b27df9a
--- /dev/null
+++ b/tests/deckard/contrib/libfaketime/test/functests/test_walkone.sh
@@ -0,0 +1,67 @@
+# walking-1 test.
+# sourced in from testframe.sh.
+#
+# this script defines a suite of functional tests
+# that verifies the correct operation of libfaketime
+# with the date command.
+
+run()
+{
+ init
+
+ for i in $(range 0 30); do
+ run_testcase test_with_i $i
+ done
+}
+
+# ----- support routines
+init()
+{
+ typeset testsuite="$1"
+ PLATFORM=$(platform)
+ if [ -z "$PLATFORM" ]; then
+ echo "$testsuite: unknown platform! quitting"
+ return 1
+ fi
+ echo "# PLATFORM=$PLATFORM"
+ return 0
+}
+
+
+# run date cmd under faketime, print time in secs
+fakedate()
+{
+ #
+ # let the time format be raw seconds since Epoch
+ # for both input to libfaketime, and output of the date cmd.
+ #
+ typeset fmt='%s'
+ export FAKETIME_FMT=$fmt
+ fakecmd "$1" date +$fmt
+}
+
+#
+# compute x**n.
+# use only the shell, in case we need to run on machines
+# without bc, dc, perl, etc.
+#
+pow()
+{
+ typeset x="$1" n="$2"
+ typeset r=1
+ typeset i=0
+ while ((i < n)); do
+ ((r = r*x))
+ ((i++))
+ done
+ echo $r
+}
+
+# run a fakedate test with a given time t
+test_with_i()
+{
+ typeset i="$1"
+ typeset t=$(pow 2 $i)
+
+ asserteq $(fakedate $t) $t "(secs since Epoch)"
+}
diff --git a/tests/deckard/contrib/libfaketime/test/test.sh b/tests/deckard/contrib/libfaketime/test/test.sh
new file mode 100755
index 0000000..630cec6
--- /dev/null
+++ b/tests/deckard/contrib/libfaketime/test/test.sh
@@ -0,0 +1,66 @@
+#!/bin/sh
+
+if [ -f /etc/faketimerc ] ; then
+ echo "Running the test program with your system-wide default in /etc/faketimerc"
+ echo "\$ LD_PRELOAD=../src/libfaketime.so.1 ./timetest"
+ LD_PRELOAD=../src/libfaketime.so.1 ./timetest
+ echo
+else
+ echo "Running the test program with no faked time specified"
+ echo "\$ LD_PRELOAD=../src/libfaketime.so.1 ./timetest"
+ LD_PRELOAD=../src/libfaketime.so.1 ./timetest
+ echo
+fi
+
+echo "============================================================================="
+echo
+
+echo "Running the test program with absolute date 2003-01-01 10:00:05 specified"
+echo "\$ LD_PRELOAD=../src/libfaketime.so.1 FAKETIME=\"2003-01-01 10:00:05\" ./timetest"
+LD_PRELOAD=../src/libfaketime.so.1 FAKETIME="2003-01-01 10:00:05" ./timetest
+echo
+
+echo "============================================================================="
+echo
+
+echo "Running the test program with START date @2005-03-29 14:14:14 specified"
+echo "\$ LD_PRELOAD=../src/libfaketime.so.1 FAKETIME=\"@2005-03-29 14:14:14\" ./timetest"
+LD_PRELOAD=../src/libfaketime.so.1 FAKETIME="@2005-03-29 14:14:14" ./timetest
+echo
+
+echo "============================================================================="
+echo
+
+echo "Running the test program with 10 days negative offset specified"
+echo "LD_PRELOAD=../src/libfaketime.so.1 FAKETIME=\"-10d\" ./timetest"
+LD_PRELOAD=../src/libfaketime.so.1 FAKETIME="-10d" ./timetest
+echo
+
+echo "============================================================================="
+echo
+
+echo "Running the test program with 10 days negative offset specified, and FAKE_STAT disabled"
+echo "\$ LD_PRELOAD=../src/libfaketime.so.1 FAKETIME=\"-10d\" NO_FAKE_STAT=1 ./timetest"
+LD_PRELOAD=../src/libfaketime.so.1 FAKETIME="-10d" NO_FAKE_STAT=1 ./timetest
+echo
+
+echo "============================================================================="
+echo
+
+echo "Running the test program with 10 days positive offset specified, and sped up 2 times"
+echo "\$ LD_PRELOAD=../src/libfaketime.so.1 FAKETIME=\"+10d x2\" ./timetest"
+LD_PRELOAD=../src/libfaketime.so.1 FAKETIME="+10d x2" NO_FAKE_STAT=1 ./timetest
+echo
+
+echo "============================================================================="
+echo
+
+echo "Running the 'date' command with 15 days negative offset specified"
+echo "\$ LD_PRELOAD=../src/libfaketime.so.1 FAKETIME=\"-15d\" date"
+LD_PRELOAD=../src/libfaketime.so.1 FAKETIME="-15d" date
+echo
+
+echo "============================================================================="
+echo "Testing finished."
+
+exit 0
diff --git a/tests/deckard/contrib/libfaketime/test/test_OSX.sh b/tests/deckard/contrib/libfaketime/test/test_OSX.sh
new file mode 100755
index 0000000..a259275
--- /dev/null
+++ b/tests/deckard/contrib/libfaketime/test/test_OSX.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+export DYLD_FORCE_FLAT_NAMESPACE=1
+export DYLD_INSERT_LIBRARIES=../src/libfaketime.1.dylib
+
+if [ -f /etc/faketimerc ] ; then
+ echo "Running the test program with your system-wide default in /etc/faketimerc"
+ ./timetest
+ echo
+else
+ echo "Running the test program with no faked time specified"
+ ./timetest
+ echo
+fi
+
+echo "Running the test program with absolute date 2003-01-01 10:00:05 specified"
+echo "FAKETIME=\"2003-01-01 10:00:05\" ./timetest"
+FAKETIME="2003-01-01 10:00:05" ./timetest
+echo
+
+echo "Running the test program with START date @2005-03-29 14:14:14 specified"
+echo "FAKETIME=\"@2005-03-29 14:14:14\" ./timetest"
+FAKETIME="@2005-03-29 14:14:14" ./timetest
+echo
+
+echo "Running the test program with 10 days negative offset specified"
+echo "FAKETIME=\"-10d\" ./timetest"
+FAKETIME="-10d" ./timetest
+echo
+
+echo "Running the test program with 10 days negative offset specified, and FAKE_STAT disabled"
+echo "FAKETIME=\"-10d\" NO_FAKE_STAT=1 ./timetest"
+FAKETIME="-10d" NO_FAKE_STAT=1 ./timetest
+echo
+
+echo "Running the test program with 10 days positive offset specified, and sped up 2 times"
+echo "FAKETIME=\"+10d x2\" ./timetest"
+FAKETIME="+10d x2" NO_FAKE_STAT=1 ./timetest
+echo
+
+echo "Running the 'date' command with 15 days negative offset specified"
+echo "FAKETIME=\"-15d\" date"
+FAKETIME="-15d" date
+echo
+
+exit 0
diff --git a/tests/deckard/contrib/libfaketime/test/testframe.inc b/tests/deckard/contrib/libfaketime/test/testframe.inc
new file mode 100644
index 0000000..b5f66a3
--- /dev/null
+++ b/tests/deckard/contrib/libfaketime/test/testframe.inc
@@ -0,0 +1,55 @@
+# framework common functions for use in test suites and test cases
+
+#
+# run a test and keep stats on success/failure.
+# arguments: a command, possibly a shell function.
+# return value: 0 on success, 1 on failure.
+# side effects: increments global var NSUCC on success, NFAIL on failure.
+#
+run_testcase()
+{
+ if "$@"; then
+ ((NSUCC++))
+ return 0
+ else
+ ((NFAIL++))
+ return 1
+ fi
+}
+
+#
+# verbosely check that the test output matches the expected value.
+# arguments: the test output, the expected value, and a description.
+# return value: 0 on if test output equals expected value; 1 otherwise.
+# side effects: prints a descriptive message.
+#
+asserteq()
+{
+ typeset out="$1" expected="$2" desc="$3"
+ echo -n "out=$out $desc"
+ if [ "$out" = "$expected" ]; then
+ echo " - ok"
+ return 0
+ else
+ echo " expected=$expected - bad"
+ return 1
+ fi
+}
+
+#
+# verbosely check that the test output doesn't match the reference value.
+# return value: 1 on if test output equals expected value; 0 if not equal.
+# side effects: prints descriptive message.
+#
+assertneq()
+{
+ typeset out="$1" ref="$2" desc="$3"
+ echo -n "out=$out $desc"
+ if [ "$out" = "$ref" ]; then
+ echo " ref=$ref - bad"
+ return 1
+ else
+ echo " ref=$ref - ok"
+ return 0
+ fi
+}
diff --git a/tests/deckard/contrib/libfaketime/test/testframe.sh b/tests/deckard/contrib/libfaketime/test/testframe.sh
new file mode 100755
index 0000000..22975b6
--- /dev/null
+++ b/tests/deckard/contrib/libfaketime/test/testframe.sh
@@ -0,0 +1,99 @@
+#! /bin/bash
+# testframe.sh DIR
+# bare-bones testing framework.
+# run the test suites in the given DIR;
+# exit with nonzero status if any of them failed.
+# see README.testframe.txt for details.
+#
+
+# echo labelled error/warning message to stderr
+report()
+{
+ echo $PROG: $* 1>&2
+}
+
+# echo OK or BAD depending on argument (0 or not)
+status_word()
+{
+ if [ "$1" -eq 0 ]; then
+ echo OK
+ else
+ echo BAD
+ fi
+}
+
+# run the given testsuite, return nonzero if any testcase failed.
+run_testsuite()
+{
+ typeset testsuite="$1"
+
+ NFAIL=0
+ NSUCC=0
+
+ # add testsuite dir to PATH for convenience
+ typeset dir=$(dirname $testsuite)
+ PATH=$dir:$PATH
+ . testframe.inc
+ if [ -f $dir/common.inc ]; then
+ . $dir/common.inc
+ fi
+ . $testsuite
+ export TESTSUITE_NAME=$testsuite
+
+ echo ""
+ echo "# Begin $testsuite"
+
+ run
+ typeset runstat=$?
+
+ echo "# $testsuite summary: $NSUCC succeeded, $NFAIL failed"
+ if [ $runstat -ne 0 ]; then
+ ((NFAIL++))
+ report "error: $testsuite run exit_status=$runstat!"
+ fi
+ echo "# End $testsuite -" $(status_word $NFAIL)
+ [ $NFAIL -eq 0 ]
+}
+
+#
+# list all testsuite scripts in the given directories.
+# a testsuite file must be a bash script whose name is of the form test_*.sh .
+#
+list_testsuites()
+{
+ for dir in "$@"; do
+ ls $dir/test_*.sh 2>/dev/null
+ done
+}
+
+main()
+{
+ TS_NFAIL=0
+ TS_NSUCC=0
+
+ echo "# Begin Test Suites in $*"
+ typeset testsuites=$(list_testsuites "$@")
+
+ if [ -z "$testsuites" ]; then
+ report "error: no testsuites found"
+ exit 1
+ fi
+
+ for testsuite in $testsuites; do
+ if run_testsuite $testsuite; then
+ ((TS_NSUCC++))
+ else
+ ((TS_NFAIL++))
+ fi
+ done
+
+ echo ""
+ echo "# Test Suites summary: $TS_NSUCC succeeded, $TS_NFAIL failed"
+ echo "# End Test Suites -" $(status_word $TS_NFAIL)
+ [ $TS_NFAIL -eq 0 ]
+}
+
+# ----- start of mainline code
+PROG=${0##*/}
+
+main "${@:-.}"
diff --git a/tests/deckard/contrib/libfaketime/test/timetest.c b/tests/deckard/contrib/libfaketime/test/timetest.c
new file mode 100644
index 0000000..4e3515c
--- /dev/null
+++ b/tests/deckard/contrib/libfaketime/test/timetest.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2003,2007 Wolfgang Hommel
+ *
+ * This file is part of the FakeTime Preload Library.
+ *
+ * The FakeTime Preload Library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * The FakeTime Preload Library is distributed in the hope that it will
+ * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with the FakeTime Preload Library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/timeb.h>
+
+#ifdef FAKE_STAT
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#endif
+
+#ifndef __APPLE__
+#include <pthread.h>
+#include <errno.h>
+#include <signal.h>
+
+#define VERBOSE 0
+
+#define SIG SIGUSR1
+
+static void
+handler(int sig, siginfo_t *si, void *uc)
+{
+ /* Note: calling printf() from a signal handler is not
+ strictly correct, since printf() is not async-signal-safe;
+ see signal(7) */
+
+ if ((si == NULL) || (si != uc))
+ {
+ printf("Caught signal %d\n", sig);
+ }
+}
+
+void* pthread_test(void* args)
+{
+ pthread_mutex_t fakeMutex = PTHREAD_MUTEX_INITIALIZER;
+ pthread_cond_t fakeCond = PTHREAD_COND_INITIALIZER;
+
+ pthread_cond_t monotonic_cond;
+ pthread_condattr_t attr;
+
+ struct timespec timeToWait, now;
+ int rt;
+
+ args = args; // silence compiler warning about unused argument
+
+ clock_gettime(CLOCK_REALTIME, &now);
+ timeToWait.tv_sec = now.tv_sec+1;
+ timeToWait.tv_nsec = now.tv_nsec;
+
+ printf("pthread_cond_timedwait: CLOCK_REALTIME test\n");
+ printf("(Intentionally sleeping 1 second...)\n");
+ fflush(stdout);
+
+ pthread_mutex_lock(&fakeMutex);
+ rt = pthread_cond_timedwait(&fakeCond, &fakeMutex, &timeToWait);
+ if (rt != ETIMEDOUT)
+ {
+ printf("pthread_cond_timedwait failed\n");
+ exit(EXIT_FAILURE);
+ }
+ pthread_mutex_unlock(&fakeMutex);
+
+
+ pthread_condattr_init(&attr);
+ pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+ pthread_cond_init(&monotonic_cond, &attr);
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ timeToWait.tv_sec = now.tv_sec+1;
+ timeToWait.tv_nsec = now.tv_nsec;
+
+ printf("pthread_cond_timedwait: CLOCK_MONOTONIC test\n");
+ printf("(Intentionally sleeping 1 second...)\n");
+ fflush(stdout);
+
+ pthread_mutex_lock(&fakeMutex);
+ rt = pthread_cond_timedwait(&monotonic_cond, &fakeMutex, &timeToWait);
+ if (rt != ETIMEDOUT)
+ {
+ printf("pthread_cond_timedwait failed\n");
+ exit(EXIT_FAILURE);
+ }
+ pthread_mutex_unlock(&fakeMutex);
+
+ pthread_cond_destroy(&monotonic_cond);
+
+ return NULL;
+}
+
+#endif
+
+int main (int argc, char **argv)
+{
+ time_t now;
+ struct timeb tb;
+ struct timeval tv;
+#ifndef __APPLE__
+ struct timespec ts;
+ timer_t timerid1 = 0, timerid2;
+ struct sigevent sev;
+ struct itimerspec its;
+ sigset_t mask;
+ struct sigaction sa;
+#endif
+#ifdef FAKE_STAT
+ struct stat buf;
+#endif
+
+#ifndef __APPLE__
+ pthread_t thread;
+ void *ret;
+
+ pthread_create(&thread, NULL, pthread_test, NULL);
+ pthread_join(thread, &ret);
+
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = handler;
+ sigemptyset(&sa.sa_mask);
+ if (sigaction(SIGUSR1, &sa, NULL) == -1)
+ {
+ perror("sigaction");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Block timer signal temporarily */
+ printf("Blocking signal %d\n", SIGUSR1);
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGUSR1);
+ if (sigprocmask(SIG_SETMASK, &mask, NULL) == -1)
+ {
+ perror("sigaction");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Create the timer */
+ sev.sigev_notify = SIGEV_SIGNAL;
+ sev.sigev_signo = SIGUSR1;
+ sev.sigev_value.sival_ptr = &timerid1;
+ if (timer_create(CLOCK_REALTIME, &sev, &timerid1) == -1)
+ {
+ perror("timer_create");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Start timer1 */
+
+ /* start timer ticking after one second */
+ its.it_value.tv_sec = 1;
+ its.it_value.tv_nsec = 0;
+ /* fire in every 0.3 seconds */
+ its.it_interval.tv_sec = 0;
+ its.it_interval.tv_nsec = 300000000;
+
+ if (timer_settime(timerid1, 0, &its, NULL) == -1)
+ {
+ perror("timer_settime");
+ exit(EXIT_FAILURE);
+ }
+
+ sev.sigev_value.sival_ptr = &timerid2;
+ if (timer_create(CLOCK_REALTIME, &sev, &timerid2) == -1)
+ {
+ perror("timer_create");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Start timer2 */
+
+ clock_gettime(CLOCK_REALTIME, &its.it_value);
+ /* start timer ticking after one second */
+ its.it_value.tv_sec += 3;
+ /* fire once */
+ its.it_interval.tv_sec = 0;
+ its.it_interval.tv_nsec = 0;
+
+ if (timer_settime(timerid2, TIMER_ABSTIME, &its, NULL) == -1)
+ {
+ perror("timer_settime");
+ exit(EXIT_FAILURE);
+ }
+#endif
+
+ time(&now);
+ printf("time() : Current date and time: %s", ctime(&now));
+ printf("time(NULL) : Seconds since Epoch : %u\n", (unsigned int)time(NULL));
+
+ ftime(&tb);
+ printf("ftime() : Current date and time: %s", ctime(&tb.time));
+
+ printf("(Intentionally sleeping 2 seconds...)\n");
+ fflush(stdout);
+ if (argc < 3)
+ {
+ sleep(1);
+ usleep(1000000);
+ }
+
+ gettimeofday(&tv, NULL);
+ printf("gettimeofday() : Current date and time: %s", ctime(&tv.tv_sec));
+
+#ifndef __APPLE__
+ if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1)
+ {
+ perror("sigprocmask");
+ exit(EXIT_FAILURE);
+ }
+
+ clock_gettime(CLOCK_REALTIME, &ts);
+ printf("clock_gettime(): Current date and time: %s", ctime(&ts.tv_sec));
+
+ int timer_getoverrun_timerid1 = timer_getoverrun(timerid1);
+ if (timer_getoverrun_timerid1 != 3)
+ {
+ printf("timer_getoverrun(timerid1) FAILED, must be 3 but got: %d\n", timer_getoverrun_timerid1);
+ }
+
+ timer_gettime(timerid1, &its);
+ if (VERBOSE == 1)
+ {
+ printf("timer_gettime(timerid1, &its); its = {{%ld, %ld}, {%ld, %ld}}}\n",
+ (long)its.it_interval.tv_sec, (long)its.it_interval.tv_nsec,
+ (long)its.it_value.tv_sec, (long)its.it_value.tv_nsec);
+ }
+
+ int timer_getoverrun_timerid2 = timer_getoverrun(timerid2);
+ if (timer_getoverrun_timerid2 != 0)
+ {
+ printf("timer_getoverrun(timerid2) FAILED, must be 0 but got: %d\n", timer_getoverrun_timerid2);
+ }
+
+ timer_gettime(timerid2, &its);
+ if (VERBOSE == 1)
+ {
+ printf("timer_gettime(timerid2, &its); its = {{%ld, %ld}, {%ld, %ld}}}\n",
+ (long)its.it_interval.tv_sec, (long)its.it_interval.tv_nsec,
+ (long)its.it_value.tv_sec, (long)its.it_value.tv_nsec);
+ }
+#endif
+
+#ifdef FAKE_STAT
+ lstat(argv[0], &buf);
+ printf("stat(): mod. time of file '%s': %s", argv[0], ctime(&buf.st_mtime));
+#endif
+
+ return 0;
+}
+
+/*
+ * Editor modelines
+ *
+ * Local variables:
+ * c-basic-offset: 2
+ * tab-width: 2
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=2 tabstop=2 expandtab:
+ * :indentSize=2:tabSize=2:noTabs=true:
+ */
+
+/* eof */