summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>2021-02-25 21:41:25 -0500
committerDaniel Kahn Gillmor <dkg@fifthhorseman.net>2021-02-25 23:17:25 -0500
commit0872c6c0c08c2483cf2c06e3ce2400ea3fe17144 (patch)
tree9d9871d15d748e9a883a75b2c5849484c75a78ee
parenta51a38d0ae7f465e960a884a827435c0bc36e5f5 (diff)
downloadlibfaketime-0872c6c0c08c2483cf2c06e3ce2400ea3fe17144.tar.gz
Add test_variable_data framework that reuses the snippets
Most of these snippets are likely to have some env var that causes the data to hold constant, while the data will otherwise be likely to vary over time. This framework offers a way to test those snippets, by dropping the variable and an example value in the test/snippets/FOO.variable one-line file. Note that the test/snippets/syscall.c snippet is *not* expected to vary over time (or to differ when any given variable is set), so we simply don't add any test/snippets/syscall.variable file to avoid it being tested in this way.
-rw-r--r--.gitignore1
-rw-r--r--test/Makefile11
-rw-r--r--test/_run_test.c5
-rw-r--r--test/snippets/README15
-rw-r--r--test/snippets/getpid.variable1
-rw-r--r--test/snippets/getrandom.variable1
-rwxr-xr-xtest/test_variable_data.sh54
7 files changed, 81 insertions, 7 deletions
diff --git a/.gitignore b/.gitignore
index 80a2439..0a10c6a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ timetest
test/getrandom_test
test/lib*.so
test/use_lib_*
+test/run_*
test/repeat_random
test/getentropy_test
test/syscall_test
diff --git a/test/Makefile b/test/Makefile
index 6a568e2..ee398dd 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -7,6 +7,7 @@ SRC = timetest.c
OBJ = ${SRC:.c=.o}
TESTFUNCS = $(notdir $(basename $(wildcard snippets/*.c)))
+EXPECTATIONS= $(notdir $(basename $(wildcard snippets/*.variable)))
all: timetest test
@@ -37,6 +38,14 @@ syscalltest: syscall_test
./syscalltest.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)
@@ -52,7 +61,7 @@ use_lib_%: _use_lib_test.c snippets/%.c lib%.so
## cleanup and metainformation
clean:
- @rm -f ${OBJ} timetest getrandom_test syscall_test $(foreach f,${TESTFUNCS},use_lib_${f} lib${f}.so)
+ @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/_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/snippets/README b/test/snippets/README
index 665004d..446f080 100644
--- a/test/snippets/README
+++ b/test/snippets/README
@@ -15,10 +15,13 @@ 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).
-And it should ideally be stable when the associated variable
-(e.g. FAKETIME, FAKETIME_FAKEPID, or FAKERANDOM_SEED) is set, and
-likely to vary otherwise, especially across a delay of a second or
-more.
+
+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,
@@ -28,5 +31,5 @@ Testing across functions
------------------------
If you want to test something systemically, autogenerate code that
-uses each snippet. See test_library_constructors in ../Makefile for
-an example.
+uses each snippet. See test_variable_data or
+test_library_constructors in ../Makefile for an example.
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.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/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