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
|
||||
timetest
|
||||
test/getrandom_test
|
||||
test/lib*.o
|
||||
test/lib*.so
|
||||
test/use_lib_random
|
||||
test/use_lib_getpid
|
||||
test/use_lib_*
|
||||
test/repeat_random
|
||||
test/getentropy_test
|
||||
test/syscall_test
|
||||
|
||||
@@ -6,6 +6,8 @@ LDFLAGS = -lrt -lpthread
|
||||
SRC = timetest.c
|
||||
OBJ = ${SRC:.c=.o}
|
||||
|
||||
TESTFUNCS = $(notdir $(basename $(wildcard snippets/*.c)))
|
||||
|
||||
all: timetest test
|
||||
|
||||
.c.o:
|
||||
@@ -25,7 +27,7 @@ functest:
|
||||
%_test: %_test.c
|
||||
${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
|
||||
|
||||
getpidtest: use_lib_getpid libgetpid.so
|
||||
@@ -34,17 +36,23 @@ getpidtest: use_lib_getpid libgetpid.so
|
||||
syscalltest: syscall_test
|
||||
./syscalltest.sh
|
||||
|
||||
lib%.o: lib%.c
|
||||
${CC} -c -o $@ -fpic ${CFLAGS} $<
|
||||
|
||||
lib%.so: lib%.o
|
||||
${CC} -o $@ -shared ${CFLAGS} $<
|
||||
## testing when interception points get called in library constructors:
|
||||
|
||||
use_lib_%: use_lib_%.c lib%.so
|
||||
${CC} -L. -o $@ ${CFLAGS} $< -l$*
|
||||
test_library_constructors: test_constructors.sh $(foreach f,${TESTFUNCS},use_lib_${f} lib${f}.so)
|
||||
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:
|
||||
@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
|
||||
@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
|
||||
|
||||
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'
|
||||
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
|
||||
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
|
||||
|
||||
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