mirror of
https://github.com/wolfcw/libfaketime.git
synced 2026-05-17 00:26:16 +03:00
Overhaul testing library constructors
We want to make it easier to test a bunch of different functions that might be invoked in constructors of other libraries. It seems conceivable that with these snippets, we could design other tests that also work across a wide range of intercepted functions.
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -2,10 +2,8 @@
|
|||||||
*.so.1
|
*.so.1
|
||||||
timetest
|
timetest
|
||||||
test/getrandom_test
|
test/getrandom_test
|
||||||
test/lib*.o
|
|
||||||
test/lib*.so
|
test/lib*.so
|
||||||
test/use_lib_random
|
test/use_lib_*
|
||||||
test/use_lib_getpid
|
|
||||||
test/repeat_random
|
test/repeat_random
|
||||||
test/getentropy_test
|
test/getentropy_test
|
||||||
test/syscall_test
|
test/syscall_test
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ LDFLAGS = -lrt -lpthread
|
|||||||
SRC = timetest.c
|
SRC = timetest.c
|
||||||
OBJ = ${SRC:.c=.o}
|
OBJ = ${SRC:.c=.o}
|
||||||
|
|
||||||
|
TESTFUNCS = $(notdir $(basename $(wildcard snippets/*.c)))
|
||||||
|
|
||||||
all: timetest test
|
all: timetest test
|
||||||
|
|
||||||
.c.o:
|
.c.o:
|
||||||
@@ -25,7 +27,7 @@ functest:
|
|||||||
%_test: %_test.c
|
%_test: %_test.c
|
||||||
${CC} -o $@ ${CFLAGS} $<
|
${CC} -o $@ ${CFLAGS} $<
|
||||||
|
|
||||||
randomtest: getrandom_test use_lib_random librandom.so repeat_random getentropy_test
|
randomtest: getrandom_test use_lib_getrandom libgetrandom.so repeat_random getentropy_test
|
||||||
./randomtest.sh
|
./randomtest.sh
|
||||||
|
|
||||||
getpidtest: use_lib_getpid libgetpid.so
|
getpidtest: use_lib_getpid libgetpid.so
|
||||||
@@ -34,17 +36,23 @@ getpidtest: use_lib_getpid libgetpid.so
|
|||||||
syscalltest: syscall_test
|
syscalltest: syscall_test
|
||||||
./syscalltest.sh
|
./syscalltest.sh
|
||||||
|
|
||||||
lib%.o: lib%.c
|
|
||||||
${CC} -c -o $@ -fpic ${CFLAGS} $<
|
|
||||||
|
|
||||||
lib%.so: lib%.o
|
## testing when interception points get called in library constructors:
|
||||||
${CC} -o $@ -shared ${CFLAGS} $<
|
|
||||||
|
|
||||||
use_lib_%: use_lib_%.c lib%.so
|
test_library_constructors: test_constructors.sh $(foreach f,${TESTFUNCS},use_lib_${f} lib${f}.so)
|
||||||
${CC} -L. -o $@ ${CFLAGS} $< -l$*
|
true $(foreach f,${TESTFUNCS},&& ./test_constructors.sh ${f})
|
||||||
|
|
||||||
|
lib%.so: _libtest.c snippets/%.c
|
||||||
|
sed s/FUNC_NAME/$*/g < _libtest.c | ${CC} -shared -o $@ -fpic ${CFLAGS} -x c -
|
||||||
|
|
||||||
|
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$*
|
||||||
|
|
||||||
|
|
||||||
|
## cleanup and metainformation
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -f ${OBJ} timetest getrandom_test lib*.o lib*.so use_lib_random use_lib_getpid syscall_test
|
@rm -f ${OBJ} timetest getrandom_test syscall_test $(foreach f,${TESTFUNCS},use_lib_${f} lib${f}.so)
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
@echo
|
@echo
|
||||||
|
|||||||
8
test/_libtest.c
Normal file
8
test/_libtest.c
Normal file
@@ -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"
|
||||||
|
}
|
||||||
7
test/_use_lib_test.c
Normal file
7
test/_use_lib_test.c
Normal file
@@ -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"
|
||||||
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
void getpid_func() {
|
|
||||||
printf(" called getpid_func()\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static __attribute__((constructor)) void getpid_init() {
|
|
||||||
pid_t pid = getpid();
|
|
||||||
printf(" getpid() yielded %d\n", pid);
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#ifndef __LIBGETPID_H__
|
|
||||||
#define __LIBGETPID_H__
|
|
||||||
|
|
||||||
extern void getpid_func();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <sys/random.h>
|
|
||||||
|
|
||||||
void func() {
|
|
||||||
printf(" called func()\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static __attribute__((constructor)) void rnd_init() {
|
|
||||||
unsigned int targ;
|
|
||||||
ssize_t ret = getrandom(&targ, sizeof(targ), 0);
|
|
||||||
if (ret == sizeof(targ)) {
|
|
||||||
printf(" getrandom() yielded 0x%08x\n", targ);
|
|
||||||
} else {
|
|
||||||
printf(" getrandom() failed with only %zd\n", ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#ifndef __LIBRANDOM_H__
|
|
||||||
#define __LIBRANDOM_H__
|
|
||||||
|
|
||||||
extern void func();
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -35,12 +35,12 @@ for iface in getrandom getentropy; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
printf 'testing shared object with getrandom() in library constructor\n'
|
printf 'testing shared object with getrandom() in library constructor\n'
|
||||||
LD_LIBRARY_PATH=. ./use_lib_random
|
LD_LIBRARY_PATH=. ./use_lib_getrandom
|
||||||
printf 'now with LD_PRELOAD and FAKERANDOM_SEED\n'
|
printf 'now with LD_PRELOAD and FAKERANDOM_SEED\n'
|
||||||
FAKERANDOM_SEED=0x0000000000000000 LD_PRELOAD="$FTPL" LD_LIBRARY_PATH=. ./use_lib_random
|
FAKERANDOM_SEED=0x0000000000000000 LD_PRELOAD="$FTPL" LD_LIBRARY_PATH=. ./use_lib_getrandom
|
||||||
# this demonstrates the crasher from https://github.com/wolfcw/libfaketime/issues/295
|
# this demonstrates the crasher from https://github.com/wolfcw/libfaketime/issues/295
|
||||||
printf 'now with LD_PRELOAD without FAKERANDOM_SEED\n'
|
printf 'now with LD_PRELOAD without FAKERANDOM_SEED\n'
|
||||||
LD_PRELOAD="$FTPL" LD_LIBRARY_PATH=. ./use_lib_random
|
LD_PRELOAD="$FTPL" LD_LIBRARY_PATH=. ./use_lib_getrandom
|
||||||
|
|
||||||
|
|
||||||
FAKERANDOM_SEED=0xDEADBEEFDEADBEEF LD_PRELOAD="$FTPL" ./repeat_random 3 5 > repeat3x5
|
FAKERANDOM_SEED=0xDEADBEEFDEADBEEF LD_PRELOAD="$FTPL" ./repeat_random 3 5 > repeat3x5
|
||||||
|
|||||||
32
test/snippets/README
Normal file
32
test/snippets/README
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
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).
|
||||||
|
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 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_library_constructors in ../Makefile for
|
||||||
|
an example.
|
||||||
2
test/snippets/getpid.c
Normal file
2
test/snippets/getpid.c
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
pid_t pid = getpid();
|
||||||
|
printf("[%s] getpid() yielded %d\n", where, pid);
|
||||||
7
test/snippets/getrandom.c
Normal file
7
test/snippets/getrandom.c
Normal file
@@ -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);
|
||||||
|
}
|
||||||
4
test/snippets/include_headers.h
Normal file
4
test/snippets/include_headers.h
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/random.h>
|
||||||
10
test/test_constructors.sh
Executable file
10
test/test_constructors.sh
Executable file
@@ -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"
|
||||||
@@ -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();
|
|
||||||
printf(" getpid() -> %d\n", pid);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
#include "librandom.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
func();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user