summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Hommel <wolfcw@users.noreply.github.com>2021-02-26 20:28:38 +0100
committerGitHub <noreply@github.com>2021-02-26 20:28:38 +0100
commit1297568caf75400779febc2e9761179d7c270a5b (patch)
treefd4275adca4b27d868ca874260ca1cdfcc132b7a
parentc89582fc1f55c03d7781d562b187a2e97e6ce560 (diff)
parent940502b3debaba2b03b23dcf6615cc88729a3d61 (diff)
downloadlibfaketime-1297568caf75400779febc2e9761179d7c270a5b.tar.gz
Merge pull request #306 from dkg/cleanup-tests
Overhaul recently-added tests (new additional snippet-driven testing framework)
-rw-r--r--.gitignore6
-rw-r--r--src/libfaketime.c2
-rw-r--r--test/Makefile34
-rw-r--r--test/_libtest.c8
-rw-r--r--test/_run_test.c5
-rw-r--r--test/_use_lib_test.c7
-rw-r--r--test/getentropy_test.c14
-rw-r--r--test/getrandom_test.c29
-rw-r--r--test/libgetpid.c13
-rw-r--r--test/libgetpid.h6
-rw-r--r--test/librandom.c17
-rw-r--r--test/librandom.h6
-rwxr-xr-xtest/pidtest.sh26
-rwxr-xr-xtest/randomtest.sh49
-rw-r--r--test/snippets/README35
-rw-r--r--test/snippets/getentropy.c6
-rw-r--r--test/snippets/getentropy.variable1
-rw-r--r--test/snippets/getpid.c2
-rw-r--r--test/snippets/getpid.variable1
-rw-r--r--test/snippets/getrandom.c7
-rw-r--r--test/snippets/getrandom.variable1
-rw-r--r--test/snippets/include_headers.h8
-rw-r--r--test/snippets/syscall.c2
-rw-r--r--test/snippets/syscall_clock_gettime.c8
-rw-r--r--test/snippets/syscall_clock_gettime.variable1
-rw-r--r--test/syscall_test.c11
-rwxr-xr-xtest/syscalltest.sh29
-rwxr-xr-xtest/test_constructors.sh10
-rwxr-xr-xtest/test_variable_data.sh54
-rw-r--r--test/use_lib_getpid.c12
-rw-r--r--test/use_lib_random.c6
31 files changed, 188 insertions, 228 deletions
diff --git a/.gitignore b/.gitignore
index 6a63c72..0a10c6a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,12 +2,12 @@
*.so.1
timetest
test/getrandom_test
-test/lib*.o
test/lib*.so
-test/use_lib_random
-test/use_lib_getpid
+test/use_lib_*
+test/run_*
test/repeat_random
test/getentropy_test
+test/syscall_test
src/libfaketime.dylib.1
src/libfaketime.1.dylib
diff --git a/src/libfaketime.c b/src/libfaketime.c
index 4ec6f45..071be7b 100644
--- a/src/libfaketime.c
+++ b/src/libfaketime.c
@@ -3799,6 +3799,8 @@ long syscall(long number, ...) {
for (int i = 0; i < syscall_max_args; i++)
a[i] = va_arg(ap, vararg_promotion_t);
va_end(ap);
+ if (!initialized)
+ ftpl_init();
return real_syscall(number, a[0], a[1], a[2], a[3], a[4], a[5]);
}
#endif
diff --git a/test/Makefile b/test/Makefile
index 572e604..fc663c2 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -6,6 +6,9 @@ LDFLAGS = -lrt -lpthread
SRC = timetest.c
OBJ = ${SRC:.c=.o}
+TESTFUNCS = $(notdir $(basename $(wildcard snippets/*.c)))
+EXPECTATIONS= $(notdir $(basename $(wildcard snippets/*.variable)))
+
all: timetest test
.c.o:
@@ -25,26 +28,33 @@ functest:
%_test: %_test.c
${CC} -o $@ ${CFLAGS} $<
-randomtest: getrandom_test use_lib_random librandom.so repeat_random getentropy_test
+randomtest: repeat_random
./randomtest.sh
-getpidtest: use_lib_getpid libgetpid.so
- ./pidtest.sh
+## test variables
+
+test_variable_data: test_variable_data.sh $(foreach f,${EXPECTATIONS},run_${f})
+ ./test_variable_data.sh ${EXPECTATIONS}
+
+run_%: _run_test.c snippets/%.c
+ sed s/FUNC_NAME/$*/g < _run_test.c | ${CC} -o $@ ${CFLAGS} -x c -
+
+## testing when interception points get called in library constructors:
+
+test_library_constructors: test_constructors.sh $(foreach f,${TESTFUNCS},use_lib_${f} lib${f}.so)
+ true $(foreach f,${TESTFUNCS},&& ./test_constructors.sh ${f})
-syscalltest: syscall_test
- ./syscalltest.sh
+lib%.so: _libtest.c snippets/%.c
+ sed s/FUNC_NAME/$*/g < _libtest.c | ${CC} -shared -o $@ -fpic ${CFLAGS} -x c -
-lib%.o: lib%.c
- ${CC} -c -o $@ -fpic ${CFLAGS} $<
+use_lib_%: _use_lib_test.c snippets/%.c lib%.so
+ sed s/FUNC_NAME/$*/g < _use_lib_test.c | ${CC} -L. -o $@ ${CFLAGS} -x c - -l$*
-lib%.so: lib%.o
- ${CC} -o $@ -shared ${CFLAGS} $<
-use_lib_%: use_lib_%.c lib%.so
- ${CC} -L. -o $@ ${CFLAGS} $< -l$*
+## cleanup and metainformation
clean:
- @rm -f ${OBJ} timetest getrandom_test lib*.o lib*.so use_lib_random use_lib_getpid
+ @rm -f ${OBJ} timetest getrandom_test syscall_test $(foreach f,${TESTFUNCS},use_lib_${f} lib${f}.so run_${f})
distclean: clean
@echo
diff --git a/test/_libtest.c b/test/_libtest.c
new file mode 100644
index 0000000..2fa0bc9
--- /dev/null
+++ b/test/_libtest.c
@@ -0,0 +1,8 @@
+#include "snippets/include_headers.h"
+#define where "library"
+void FUNC_NAME_as_needed() {
+ printf(" called FUNC_NAME_as_needed() \n");
+}
+static __attribute__((constructor)) void init_FUNC_NAME() {
+#include "snippets/FUNC_NAME.c"
+}
diff --git a/test/_run_test.c b/test/_run_test.c
new file mode 100644
index 0000000..63672f9
--- /dev/null
+++ b/test/_run_test.c
@@ -0,0 +1,5 @@
+#include "snippets/include_headers.h"
+#define where "direct"
+int main() {
+#include "snippets/FUNC_NAME.c"
+}
diff --git a/test/_use_lib_test.c b/test/_use_lib_test.c
new file mode 100644
index 0000000..24d8cc7
--- /dev/null
+++ b/test/_use_lib_test.c
@@ -0,0 +1,7 @@
+#include "snippets/include_headers.h"
+extern void FUNC_NAME_as_needed();
+#define where "program"
+int main() {
+ FUNC_NAME_as_needed();
+#include "snippets/FUNC_NAME.c"
+}
diff --git a/test/getentropy_test.c b/test/getentropy_test.c
deleted file mode 100644
index a3d02e6..0000000
--- a/test/getentropy_test.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <unistd.h>
-#include <stdio.h>
-
-int main() {
- unsigned char buf[16];
- if (getentropy(buf, sizeof(buf))) {
- perror("failed to getentropy()");
- return 1;
- }
- for (size_t i = 0; i < sizeof(buf); i++)
- printf("%02x", buf[i]);
- printf("\n");
- return 0;
-}
diff --git a/test/getrandom_test.c b/test/getrandom_test.c
deleted file mode 100644
index 8b134e3..0000000
--- a/test/getrandom_test.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <stdio.h>
-#include <sys/random.h>
-#include <stdlib.h>
-
-int base() {
- char *buf = calloc(100, 1);
- size_t buflen = 100;
- unsigned flags = GRND_NONBLOCK;
-
- fprintf(stdout, "Before getrandom:\n");
- for (size_t i=0; i < buflen; i++) { fprintf(stdout, "%hhu ", buf[i]); }
- fprintf(stdout, "\n");
-
- int result = getrandom(buf, buflen, flags);
- fprintf(stdout, "getrandom() result: %d\n", result);
- if (result == -1) perror("getrandom() unsuccessful");
-
-
- fprintf(stdout, "After getrandom:\n");
- for (size_t i=0; i < buflen; i++) { fprintf(stdout, "%hhu ", buf[i]); }
- fprintf(stdout, "\n");
-
- free(buf);
- return 0;
-}
-
-int main() {
- return base() + base();
-}
diff --git a/test/libgetpid.c b/test/libgetpid.c
deleted file mode 100644
index 1fb84c5..0000000
--- a/test/libgetpid.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-void getpid_func() {
- fprintf(stderr, " called getpid_func()\n");
-}
-
-
-static __attribute__((constructor)) void getpid_init() {
- pid_t pid = getpid();
- fprintf(stderr, " getpid() yielded %d\n", pid);
-}
diff --git a/test/libgetpid.h b/test/libgetpid.h
deleted file mode 100644
index e18c61d..0000000
--- a/test/libgetpid.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __LIBGETPID_H__
-#define __LIBGETPID_H__
-
-extern void getpid_func();
-
-#endif
diff --git a/test/librandom.c b/test/librandom.c
deleted file mode 100644
index d11ba23..0000000
--- a/test/librandom.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <stdio.h>
-#include <sys/random.h>
-
-void func() {
- fprintf(stderr, " called func()\n");
-}
-
-
-static __attribute__((constructor)) void rnd_init() {
- unsigned int targ;
- ssize_t ret = getrandom(&targ, sizeof(targ), 0);
- if (ret == sizeof(targ)) {
- fprintf(stderr, " getrandom() yielded 0x%08x\n", targ);
- } else {
- fprintf(stderr, " getrandom() failed with only %zd\n", ret);
- }
-}
diff --git a/test/librandom.h b/test/librandom.h
deleted file mode 100644
index 9037fce..0000000
--- a/test/librandom.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __LIBRANDOM_H__
-#define __LIBRANDOM_H__
-
-extern void func();
-
-#endif
diff --git a/test/pidtest.sh b/test/pidtest.sh
deleted file mode 100755
index 83e0771..0000000
--- a/test/pidtest.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-
-FTPL="${FAKETIME_TESTLIB:-../src/libfaketime.so.1}"
-
-set -e
-run1=$(LD_PRELOAD="$FTPL" sh -c 'echo $$')
-run2=$(LD_PRELOAD="$FTPL" sh -c 'echo $$')
-
-if [ $run1 = $run2 ]; then
- printf >&2 'got the same pid twice in a row without setting FAKETIME_FAKEPID\n'
- exit 1
-fi
-
-output=$(FAKETIME_FAKEPID=13 LD_PRELOAD="$FTPL" sh -c 'echo $$')
-
-if [ $output != 13 ]; then
- printf >&2 'Failed to enforce a rigid response to getpid()\n'
- exit 2
-fi
-
-printf 'testing shared object with getpid() in library constructor\n'
-LD_LIBRARY_PATH=. ./use_lib_getpid
-printf 'now with LD_PRELOAD and FAKETIME_FAKEPID\n'
-FAKETIME_FAKEPID=25 LD_PRELOAD="$FTPL" LD_LIBRARY_PATH=. ./use_lib_getpid
-printf 'now with LD_PRELOAD without FAKETIME_FAKEPID\n'
-LD_PRELOAD="$FTPL" LD_LIBRARY_PATH=. ./use_lib_getpid
diff --git a/test/randomtest.sh b/test/randomtest.sh
index 4055188..6256d9f 100755
--- a/test/randomtest.sh
+++ b/test/randomtest.sh
@@ -6,53 +6,14 @@ set -e
error=0
-for iface in getrandom getentropy; do
- printf "Testing %s() interception...\n" "$iface"
+repeat3x5="$(FAKERANDOM_SEED=0xDEADBEEFDEADBEEF LD_PRELOAD="$FTPL" ./repeat_random 3 5)"
+repeat5x3="$(FAKERANDOM_SEED=0xDEADBEEFDEADBEEF LD_PRELOAD="$FTPL" ./repeat_random 5 3)"
- "./${iface}_test" > "${iface}.alone"
- LD_PRELOAD="$FTPL" "./${iface}_test" > "${iface}.preload"
- FAKERANDOM_SEED=0x12345678DEADBEEF LD_PRELOAD="$FTPL" "./${iface}_test" > "${iface}.preload.seed0"
- FAKERANDOM_SEED=0x12345678DEADBEEF LD_PRELOAD="$FTPL" "./${iface}_test" > "${iface}.preload.seed1"
- FAKERANDOM_SEED=0x0000000000000000 LD_PRELOAD="$FTPL" "./${iface}_test" > "${iface}.preload.seed2"
-
- if diff -u "${iface}.alone" "${iface}.preload" > /dev/null; then
- error=1
- printf >&2 '%s() without the LD_PRELOAD matches a run without LD_PRELOAD\n' "$iface"
- fi
- if diff -u "${iface}.preload" "${iface}.preload.seed0" > /dev/null; then
- error=2
- printf >&2 '%s() without a seed produced the same data as a run with a seed!\n' "$iface"
- fi
- if ! diff -u "${iface}.preload.seed0" "${iface}.preload.seed1"; then
- error=3
- printf >&2 '%s() with identical seeds differed!\n' "$iface"
- fi
- if diff -u "${iface}.preload.seed1" "${iface}.preload.seed2" >/dev/null; then
- error=4
- printf >&2 '%s() with different seeds produced the same data!\n' "$iface"
- fi
- rm -f "${iface}.alone" "${iface}.preload" "${iface}.preload.seed0" "${iface}.preload.seed1" "${iface}.preload.seed2"
-done
-
-printf 'testing shared object with getrandom() in library constructor\n'
-LD_LIBRARY_PATH=. ./use_lib_random
-printf 'now with LD_PRELOAD and FAKERANDOM_SEED\n'
-FAKERANDOM_SEED=0x0000000000000000 LD_PRELOAD="$FTPL" LD_LIBRARY_PATH=. ./use_lib_random
-# this demonstrates the crasher from https://github.com/wolfcw/libfaketime/issues/295
-printf 'now with LD_PRELOAD without FAKERANDOM_SEED\n'
-LD_PRELOAD="$FTPL" LD_LIBRARY_PATH=. ./use_lib_random
-
-
-FAKERANDOM_SEED=0xDEADBEEFDEADBEEF LD_PRELOAD="$FTPL" ./repeat_random 3 5 > repeat3x5
-FAKERANDOM_SEED=0xDEADBEEFDEADBEEF LD_PRELOAD="$FTPL" ./repeat_random 5 3 > repeat5x3
-
-if ! diff -u repeat3x5 repeat5x3; then
- error=5
- printf >&2 '5 calls of getrandom(3) did not produce the same stream as 3 calls of getrandom(5)\n'
+if [ "$repeat3x5" != "$repeat5x3" ]; then
+ error=1
+ printf >&2 '5 calls of getrandom(3) got %s\n3 calls of getrandom(5) got %s\n' "$repeat3x5" "$repeat5x3"
fi
-rm -f repeat3x5 repeat5x3
-
if [ 0 = $error ]; then
printf 'getrandom interception test successful.\n'
fi
diff --git a/test/snippets/README b/test/snippets/README
new file mode 100644
index 0000000..446f080
--- /dev/null
+++ b/test/snippets/README
@@ -0,0 +1,35 @@
+Bulk testing of function interception
+=====================================
+
+Faketime intercepts some C library functions. We want to make it
+easier to apply certain generic tests across many different functions.
+
+Including a new function
+------------------------
+
+To test a function FOO, supply a C snippet in this directory named
+<FOO.c>. This should be a small bit of code that exercises the
+function FOO. It should be self-contained, and it should produce some
+kind of description of what happened to stdout. Take a look at
+getpid.c for a simple example.
+
+The data sent to stdout should include the const char* "where" value
+(which is an indication of which test framework is using the snippet).
+
+If the output of the snippet is expected to be stable when the
+associated variable (e.g. FAKETIME, FAKETIME_FAKEPID, or
+FAKERANDOM_SEED) is set, and is likely to vary otherwise, especially
+across a delay of a second or more, add a single-line file
+FOO.variable that contains the name of the variable separated by a
+space and then the value of the variable.
+
+If the snippet needs to additional #include headers, please add them
+in include_headers.h. These #includes will be used by every snippet,
+so try to keep it minimal.
+
+Testing across functions
+------------------------
+
+If you want to test something systemically, autogenerate code that
+uses each snippet. See test_variable_data or
+test_library_constructors in ../Makefile for an example.
diff --git a/test/snippets/getentropy.c b/test/snippets/getentropy.c
new file mode 100644
index 0000000..333c826
--- /dev/null
+++ b/test/snippets/getentropy.c
@@ -0,0 +1,6 @@
+unsigned int targ;
+if (getentropy(&targ, sizeof(targ)) == 0) {
+ printf("[%s] getentropy() yielded 0x%08x\n", where, targ);
+} else {
+ printf("[%s] getentropy() failed with %d (%s)\n", where, errno, strerror(errno));
+}
diff --git a/test/snippets/getentropy.variable b/test/snippets/getentropy.variable
new file mode 100644
index 0000000..d9d942d
--- /dev/null
+++ b/test/snippets/getentropy.variable
@@ -0,0 +1 @@
+FAKERANDOM_SEED 0x0123456789ABCDEF
diff --git a/test/snippets/getpid.c b/test/snippets/getpid.c
new file mode 100644
index 0000000..695d3db
--- /dev/null
+++ b/test/snippets/getpid.c
@@ -0,0 +1,2 @@
+pid_t pid = getpid();
+printf("[%s] getpid() yielded %d\n", where, pid);
diff --git a/test/snippets/getpid.variable b/test/snippets/getpid.variable
new file mode 100644
index 0000000..fdd9fd5
--- /dev/null
+++ b/test/snippets/getpid.variable
@@ -0,0 +1 @@
+FAKETIME_FAKEPID 1
diff --git a/test/snippets/getrandom.c b/test/snippets/getrandom.c
new file mode 100644
index 0000000..03b0980
--- /dev/null
+++ b/test/snippets/getrandom.c
@@ -0,0 +1,7 @@
+unsigned int targ;
+ssize_t ret = getrandom(&targ, sizeof(targ), 0);
+if (ret == sizeof(targ)) {
+ printf("[%s] getrandom() yielded 0x%08x\n", where, targ);
+} else {
+ printf("[%s] getrandom() failed with only %zd\n", where, ret);
+}
diff --git a/test/snippets/getrandom.variable b/test/snippets/getrandom.variable
new file mode 100644
index 0000000..9d67e9f
--- /dev/null
+++ b/test/snippets/getrandom.variable
@@ -0,0 +1 @@
+FAKERANDOM_SEED 0xDEADBEEFDEADBEEF
diff --git a/test/snippets/include_headers.h b/test/snippets/include_headers.h
new file mode 100644
index 0000000..55cd48f
--- /dev/null
+++ b/test/snippets/include_headers.h
@@ -0,0 +1,8 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/random.h>
+#include <sys/syscall.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
diff --git a/test/snippets/syscall.c b/test/snippets/syscall.c
new file mode 100644
index 0000000..c475a83
--- /dev/null
+++ b/test/snippets/syscall.c
@@ -0,0 +1,2 @@
+long uid = syscall(__NR_getuid);
+printf("[%s] syscall(__NR_getuid) -> %ld\n", where, uid);
diff --git a/test/snippets/syscall_clock_gettime.c b/test/snippets/syscall_clock_gettime.c
new file mode 100644
index 0000000..21b99ba
--- /dev/null
+++ b/test/snippets/syscall_clock_gettime.c
@@ -0,0 +1,8 @@
+struct timespec ts;
+clockid_t ckid = CLOCK_REALTIME;
+long ret = syscall(__NR_clock_gettime, ckid, &ts);
+if (ret == 0)
+ printf("[%s] syscall(__NR_gettime, CLOCK_REALTIME[%d], &ts) -> {%lld, %ld}\n", where, ckid, (long long)ts.tv_sec, ts.tv_nsec);
+else
+ printf("[%s] syscall(__NR_gettime, CLOCK_REALTIME[%d], &ts) returned non-zero (%ld)\n", where, ckid, ret);
+
diff --git a/test/snippets/syscall_clock_gettime.variable b/test/snippets/syscall_clock_gettime.variable
new file mode 100644
index 0000000..e89e166
--- /dev/null
+++ b/test/snippets/syscall_clock_gettime.variable
@@ -0,0 +1 @@
+FAKETIME 2020-01-01 00:00:00
diff --git a/test/syscall_test.c b/test/syscall_test.c
deleted file mode 100644
index cf9f9f9..0000000
--- a/test/syscall_test.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-
-int main() {
- int d = 0;
- long r = syscall(__NR_getrandom, &d, sizeof(d), 0);
- printf("getrandom(%d, <ptr>, %zd, 0) returned %ld and yielded 0x%08x\n",
- __NR_getrandom, sizeof(d), r, d);
- return 0;
-}
diff --git a/test/syscalltest.sh b/test/syscalltest.sh
deleted file mode 100755
index 0b5a4cf..0000000
--- a/test/syscalltest.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-
-FTPL="${FAKETIME_TESTLIB:-../src/libfaketime.so.1}"
-
-set -e
-
-error=0
-run0=$(./syscall_test)
-run1=$(LD_PRELOAD="$FTPL" ./syscall_test)
-run2=$(FAKERANDOM_SEED=0x0000000000000000 LD_PRELOAD="$FTPL" ./syscall_test)
-run3=$(FAKERANDOM_SEED=0x0000000000000000 LD_PRELOAD="$FTPL" ./syscall_test)
-run4=$(FAKERANDOM_SEED=0xDEADBEEFDEADBEEF LD_PRELOAD="$FTPL" ./syscall_test)
-
-if [ "$run0" = "$run1" ] ; then
- error=1
- printf >&2 'test run without LD_PRELOAD matches run with LD_PRELOAD. This is very unlikely.\n'
-fi
-if [ "$run1" = "$run2" ] ; then
- error=2
- printf >&2 'test with LD_PRELOAD but without FAKERANDOM_SEED matches run with LD_PRELOAD and FAKERANDOM_SEED. This is also very unlikely.\n'
-fi
-if [ "$run2" != "$run3" ]; then
- error=1
- printf >&2 'test run with same seed produces different outputs.\n'
-fi
-if [ "$run3" = "$run4" ]; then
- error=1
- printf >&2 'test runs with different seeds produce the same outputs.\n'
-fi
diff --git a/test/test_constructors.sh b/test/test_constructors.sh
new file mode 100755
index 0000000..5a628c4
--- /dev/null
+++ b/test/test_constructors.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+FTPL="${FAKETIME_TESTLIB:-../src/libfaketime.so.1}"
+
+function="$1"
+
+printf 'Testing library init for %s (no LD_PRELOAD)\n' "$function"
+LD_LIBRARY_PATH=. "./use_lib_$function"
+printf 'Testing library init for %s (LD_PRELOAD)\n' "$function"
+LD_LIBRARY_PATH=. LD_PRELOAD="$FTPL" "./use_lib_$function"
diff --git a/test/test_variable_data.sh b/test/test_variable_data.sh
new file mode 100755
index 0000000..c8c9a91
--- /dev/null
+++ b/test/test_variable_data.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+set -e
+
+FTPL="${FAKETIME_TESTLIB:-../src/libfaketime.so.1}"
+DELAY="${DELAY:-2}"
+
+declare -A firstunset first second delayed delayedunset
+
+err=0
+for func in "$@"; do
+ if ! [ -x "./run_$func" ]; then
+ printf >&2 '%s does not exist, failing\n' "./run_$func"
+ exit 1
+ fi
+ read varname value < "snippets/$func.variable"
+ unset $varname
+ firstunset[$func]="$(env LD_PRELOAD="$FTPL" "./run_$func")"
+ first[$func]="$(env LD_PRELOAD="$FTPL" "$varname=$value" "./run_$func")"
+ second[$func]="$(env LD_PRELOAD="$FTPL" "$varname=$value" "./run_$func")"
+ if [ "${first[$func]}" != "${second[$func]}" ]; then
+ printf >&2 '[%s] Set %s="%s", but got two different outputs:\n - %s\n - %s\n' "$func" "$varname" "$value" "${first[$func]}" "${second[$func]}"
+ err=$(( $err + 1 ))
+ fi
+ if [ "${first[$func]}" == "${firstunset[$func]}" ]; then
+ printf >&2 '[%s] Same answer when %s="%s" and when unset:\n - set: %s\n - unset: %s\n' "$func" "$varname" "$value" "${first[$func]}" "${firstunset[$func]}"
+ err=$(( $err + 1 ))
+ fi
+done
+
+printf "Sleeping %d seconds..." "$DELAY"
+sleep "$DELAY"
+printf 'done\n'
+
+for func in "$@"; do
+ read varname value < "snippets/$func.variable"
+ unset $varname
+ delayed[$func]="$(env LD_PRELOAD="$FTPL" "$varname=$value" "./run_$func")"
+ delayedunset[$func]="$(LD_PRELOAD="$FTPL" "./run_$func")"
+ if [ "${first[$func]}" != "${delayed[$func]}" ]; then
+ printf >&2 '[%s] Vary across delay of %d seconds (%s="%s"):\n - before: %s\n - after: %s\n' "$func" "$DELAY" "$varname" "$value" "${first[$func]}" "${delayed[$func]}"
+ err=$(( $err + 1 ))
+ fi
+ if [ "${firstunset[$func]}" == "${delayedunset[$func]}" ]; then
+ printf >&2 '[%s] Same answer when unset across delay of %d seconds:\n - before: %s\n - after: %s\n' "$func" "$DELAY" "${firstunset[$func]}" "${delayedunset[$func]}"
+ err=$(( $err + 1 ))
+ fi
+done
+
+if [ "$err" -gt 0 ]; then
+ printf >&2 'Got %d errors, failing\n' "$err"
+ exit 1
+fi
+exit 0
diff --git a/test/use_lib_getpid.c b/test/use_lib_getpid.c
deleted file mode 100644
index c9f3deb..0000000
--- a/test/use_lib_getpid.c
+++ /dev/null
@@ -1,12 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include "libgetpid.h"
-
-int main() {
- pid_t pid;
- getpid_func();
- pid = getpid();
- fprintf(stderr, " getpid() -> %d\n", pid);
- return 0;
-}
diff --git a/test/use_lib_random.c b/test/use_lib_random.c
deleted file mode 100644
index 583608d..0000000
--- a/test/use_lib_random.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "librandom.h"
-
-int main() {
- func();
- return 0;
-}