]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Add Ondrej Zajicek Unit Testing Framework
authorPavel Tvrdík <pawel.tvrdik@gmail.cz>
Tue, 3 Mar 2015 12:51:35 +0000 (13:51 +0100)
committerPavel Tvrdík <pawel.tvrdik@gmail.cz>
Sat, 7 Mar 2015 09:30:55 +0000 (10:30 +0100)
 - Add Ondrej Zajicek Unit Testing Framework -- BirdTest
 - An Integration the BirdTest (BT) into the BIRD's build system.

birdtest/birdtest.c [new file with mode: 0644]
birdtest/birdtest.h [new file with mode: 0644]
tools/Makefile-top.in
tools/Makefile.in
tools/Rules.in

diff --git a/birdtest/birdtest.c b/birdtest/birdtest.c
new file mode 100644 (file)
index 0000000..cafadb2
--- /dev/null
@@ -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");
+}
diff --git a/birdtest/birdtest.h b/birdtest/birdtest.h
new file mode 100644 (file)
index 0000000..19a2d4f
--- /dev/null
@@ -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)
index cf59f7a1742717f5d3a70e4291f7a23be6513528..83ff4f58f0a8f8c257b44781b5382934e1417cd6 100644 (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:
index 062ba916170d073a6aad1d0ecdedeefd7892b4b1..174b3e81fa74bfcd8b92d5dbd7444bf0c4af49e5 100644 (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
index ca930ec8f24a826e0ddb63cc15a72ad5c230cc21..79bf0761f4e990dd252643dae4b117dd61f9adbd 100644 (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