0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2025-01-08 18:11:54 +00:00

Add Ondrej Zajicek Unit Testing Framework

- Add Ondrej Zajicek Unit Testing Framework -- BirdTest
 - An Integration the BirdTest (BT) into the BIRD's build system.
This commit is contained in:
Pavel Tvrdík 2015-03-03 13:51:35 +01:00
parent 4e63974471
commit 02a844cbf9
5 changed files with 232 additions and 1 deletions

160
birdtest/birdtest.c Normal file
View File

@ -0,0 +1,160 @@
/*
* BIRD Internet Routing Daemon -- BIRD Unit Testing Framework
*
* (c) 2015 Ondrej Zajicek <santiago@crfreenet.org>
* (c) 2015 CZ.NIC z.s.p.o.
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include "birdtest.h"
static const char *request;
static int list_tests;
static int do_core;
static int no_fork;
static int no_timeout;
int bt_verbose;
const char *bt_filename;
const char *bt_test_id;
void
bt_init(int argc, char *argv[])
{
int c;
bt_filename = argv[0];
while ((c = getopt(argc, argv, "lcftv")) >= 0)
switch (c)
{
case 'l':
printf(" List of test cases:\n");
list_tests = 1;
return;
case 'c':
do_core = 1;
break;
case 'f':
no_fork = 1;
break;
case 't':
no_timeout = 1;
break;
case 'v':
bt_verbose = 1;
break;
default:
goto usage;
}
/* Optional requested test_id */
if ((optind + 1) == argc)
request = argv[optind++];
if (optind != argc)
goto usage;
if (do_core)
{
struct rlimit rl = {RLIM_INFINITY, RLIM_INFINITY};
int rv = setrlimit(RLIMIT_CORE, &rl);
bt_syscall(rv < 0, "setrlimit RLIMIT_CORE");
}
return;
usage:
printf("Usage: %s [-l] [-c] [-f] [-t] [-v] [<test_id>]\n", argv[0]);
exit(3);
}
void
bt_test_case2(int (*test_fn)(void), const char *test_id, const char *dsc, int forked, int timeout)
{
if (list_tests)
{
printf("%-12s - %s\n", test_id, dsc);
return;
}
if (no_fork)
forked = 0;
if (no_timeout)
timeout = 0;
if (request && strcmp(test_id, request))
return;
int result = 0;
bt_test_id = test_id;
bt_note("Starting");
if (!forked)
{
alarm(timeout);
result = test_fn();
}
else
{
pid_t pid = fork();
bt_syscall(pid < 0, "fork");
if (pid == 0)
{
alarm(timeout);
result = test_fn();
_exit(result);
}
int s;
int rv = waitpid(pid, &s, 0);
bt_syscall(rv < 0, "waitpid");
result = 2;
if (WIFEXITED(s))
result = WEXITSTATUS(s);
else if (WIFSIGNALED(s))
{
int sn = WTERMSIG(s);
if (sn == SIGALRM)
bt_log("Timeout expired");
else if (sn == SIGSEGV)
bt_log("Segmentation fault");
else if (sn != SIGABRT)
bt_log("Signal %d received", sn);
}
if (WCOREDUMP(s))
bt_log("Core dumped");
}
if (result)
{
bt_log("Test case failed");
exit(result);
}
bt_note("Test case OK");
}

46
birdtest/birdtest.h Normal file
View File

@ -0,0 +1,46 @@
/*
* BIRD Internet Routing Daemon -- BIRD Unit Testing Framework
*
* (c) 2015 Ondrej Zajicek <santiago@crfreenet.org>
* (c) 2015 CZ.NIC z.s.p.o.
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
extern int bt_verbose;
extern const char *bt_filename;
extern const char *bt_test_id;
void bt_init(int argc, char **argv);
void bt_test_case2(int (*fn)(void), const char *id, const char *dsc, int forked, int timeout);
#define bt_test_case(fn,dsc,f,t) \
bt_test_case2(fn, #fn, dsc, f, t)
#define bt_log(format, ...) \
fprintf(stderr, "%s: " format "\n", bt_filename, ##__VA_ARGS__)
#define bt_note(format, ...) \
do { if (bt_verbose) bt_log(format, ##__VA_ARGS__); } while (0)
#define bt_abort() \
bt_abort_msg("Aborted at %s:%d", __FILE__, __LINE__)
#define bt_abort_msg(format, ...) \
do { bt_log(format, ##__VA_ARGS__); abort(); } while (0)
#define bt_assert(test) \
bt_assert_msg(test, "Assertion (%s) failed at %s:%d", #test, __FILE__, __LINE__)
#define bt_assert_msg(test,format, ...) \
do { if (!(test)) bt_abort_msg(format, ##__VA_ARGS__); } while (0)
#define bt_syscall(test,format, ...) \
do { if (test) { bt_log(format ": %s", ##__VA_ARGS__, strerror(errno)); exit(3); } } while (0)

View File

@ -3,7 +3,7 @@
objdir=@objdir@
all depend tags install install-docs:
all depend tags install install-docs check:
$(MAKE) -C $(objdir) $@
docs userdocs progdocs:

View File

@ -7,6 +7,20 @@ include Rules
all: sysdep/paths.h .dep-stamp subdir daemon birdcl @CLIENT@
check: build-tests
find . -name '*_test' -executable -exec {} \;
build-tests: subdir birdtest/birdtest.a
set -e ; for a in $(dynamic-dirs) ; do $(MAKE) -C $$a build-test ; done
set -e ; for a in $(static-dirs) $(client-dirs) ; do $(MAKE) -C $$a -f $(srcdir_abs)/$$a/Makefile build-test ; done
birdtest/birdtest.a: birdtest/birdtest.o
$(AR) rcs $@ $^
birdtest/birdtest.o: $(srcdir)/birdtest/birdtest.c
mkdir -p birdtest
$(CC) $(CFLAGS) -I$(srcdir)/birdtest $(TARGET_ARCH) -c $^ $(LDLIBS) -o $@
daemon: $(exedir)/bird
birdc: $(exedir)/birdc

View File

@ -49,6 +49,17 @@ ifdef dir-name
src-path := $(srcdir)/$(dir-name)/
endif
build-test:
for i in $(source); do \
test_name=`echo $$i | sed 's/\.c$$/_test/g'` ; \
test_source=$(src-path)$${test_name}.c ; \
test_obj=$${test_name}.o ; \
if [ -f $$test_source ]; then \
$(CC) $(CFLAGS) -I $(srcdir)/birdtest/ -o $$test_obj -c $$test_source ; \
$(CC) $(LDFLAGS) $$test_obj -o $$test_name $(root-rel)birdtest/birdtest.a ; \
fi ; \
done
all:
cd $(root-rel) && make