--- /dev/null
+/*
+ * 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");
+}
--- /dev/null
+/*
+ * 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)
objdir=@objdir@
-all depend tags install install-docs:
+all depend tags install install-docs check:
$(MAKE) -C $(objdir) $@
docs userdocs progdocs:
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
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