unit-tests: Add a few test cases for watcher
authorMartin Willi <martin@revosec.ch>
Wed, 16 Oct 2013 11:45:48 +0000 (13:45 +0200)
committerMartin Willi <martin@revosec.ch>
Wed, 6 Nov 2013 09:31:02 +0000 (10:31 +0100)
src/libstrongswan/tests/Makefile.am
src/libstrongswan/tests/suites/test_watcher.c [new file with mode: 0644]
src/libstrongswan/tests/test_runner.c
src/libstrongswan/tests/test_runner.h

index c9d10e9..8506037 100644 (file)
@@ -14,6 +14,7 @@ test_runner_SOURCES = \
   suites/test_hashtable.c \
   suites/test_identification.c \
   suites/test_threading.c \
+  suites/test_watcher.c \
   suites/test_utils.c \
   suites/test_vectors.c \
   suites/test_array.c \
diff --git a/src/libstrongswan/tests/suites/test_watcher.c b/src/libstrongswan/tests/suites/test_watcher.c
new file mode 100644 (file)
index 0000000..9415bea
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2013 Martin Willi
+ * Copyright (C) 2013 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <library.h>
+
+#include <sched.h>
+#include <unistd.h>
+#include <errno.h>
+
+static char testbuf[1] = "";
+
+static bool readcb(void *data, int fd, watcher_event_t event)
+{
+       ck_assert_int_eq(*(int*)data, fd);
+       ck_assert_int_eq(event, WATCHER_READ);
+
+       if (recv(fd, testbuf, 1, MSG_DONTWAIT) != 1)
+       {
+               ck_assert(errno == EAGAIN || errno == EWOULDBLOCK);
+       }
+       return TRUE;
+}
+
+START_TEST(test_read)
+{
+       int fd[2];
+       char c;
+
+       lib->processor->set_threads(lib->processor, 8);
+
+       ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != -1);
+
+       lib->watcher->add(lib->watcher, fd[0], WATCHER_READ, readcb, &fd[0]);
+
+       for (c = 'a'; c <= 'z'; c++)
+       {
+               ck_assert_int_eq(write(fd[1], &c, 1), 1);
+               while (testbuf[0] != c)
+               {
+                       sched_yield();
+               }
+       }
+
+       lib->watcher->remove(lib->watcher, fd[0]);
+       close(fd[0]);
+       close(fd[1]);
+
+       lib->processor->cancel(lib->processor);
+}
+END_TEST
+
+static bool writecb(void *data, int fd, watcher_event_t event)
+{
+       ck_assert_int_eq(event, WATCHER_WRITE);
+       if (send(fd, data, 1, MSG_DONTWAIT) != 1)
+       {
+               ck_assert(errno == EAGAIN || errno == EWOULDBLOCK);
+       }
+       return TRUE;
+}
+
+START_TEST(test_write)
+{
+       int fd[2];
+       char in = 'x', out;
+
+       lib->processor->set_threads(lib->processor, 8);
+
+       ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != -1);
+
+       lib->watcher->add(lib->watcher, fd[1], WATCHER_WRITE, writecb, &in);
+
+       ck_assert_int_eq(read(fd[0], &out, 1), 1);
+       ck_assert_int_eq(out, in);
+
+       lib->watcher->remove(lib->watcher, fd[1]);
+       close(fd[1]);
+       close(fd[0]);
+
+       lib->processor->cancel(lib->processor);
+}
+END_TEST
+
+static bool multiread(void *data, int fd, watcher_event_t event)
+{
+       ck_assert_int_eq(event, WATCHER_READ);
+       if (recv(fd, data, 1, MSG_DONTWAIT) != 1)
+       {
+               ck_assert(errno == EAGAIN || errno == EWOULDBLOCK);
+       }
+       return TRUE;
+}
+
+START_TEST(test_multiread)
+{
+       int fd[10][2], i;
+       char in, out[countof(fd)];
+
+       lib->processor->set_threads(lib->processor, 8);
+
+       for (i = 0; i < countof(fd); i++)
+       {
+               ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, fd[i]) != -1);
+               lib->watcher->add(lib->watcher, fd[i][0],
+                                                 WATCHER_READ, multiread, &out[i]);
+       }
+
+       for (i = 0; i < countof(fd); i++)
+       {
+               for (in = 'a'; in <= 'z'; in++)
+               {
+                       ck_assert_int_eq(write(fd[i][1], &in, 1), 1);
+                       while (out[i] != in)
+                       {
+                               sched_yield();
+                       }
+               }
+       }
+
+       for (i = 0; i < countof(fd); i++)
+       {
+               lib->watcher->remove(lib->watcher, fd[i][0]);
+               close(fd[i][1]);
+               close(fd[i][0]);
+       }
+
+       lib->processor->cancel(lib->processor);
+}
+END_TEST
+
+static bool multiwrite(void *data, int fd, watcher_event_t event)
+{
+       ck_assert_int_eq(event, WATCHER_WRITE);
+       if (send(fd, data, 1, MSG_DONTWAIT) != 1)
+       {
+               ck_assert(errno == EAGAIN || errno == EWOULDBLOCK);
+       }
+       return TRUE;
+}
+
+START_TEST(test_multiwrite)
+{
+       int fd[10][2], i, j;
+       u_char out, in[countof(fd)];
+
+       lib->processor->set_threads(lib->processor, 8);
+
+       for (i = 0; i < countof(fd); i++)
+       {
+               ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, fd[i]) != -1);
+               in[i] = i;
+               lib->watcher->add(lib->watcher, fd[i][1],
+                                                 WATCHER_WRITE, multiwrite, &in[i]);
+       }
+
+       for (j = 0; j < 10; j++)
+       {
+               for (i = 0; i < countof(fd); i++)
+               {
+                       ck_assert_int_eq(read(fd[i][0], &out, 1), 1);
+                       ck_assert_int_eq(out, i);
+               }
+       }
+
+       for (i = 0; i < countof(fd); i++)
+       {
+               lib->watcher->remove(lib->watcher, fd[i][1]);
+               close(fd[i][1]);
+               close(fd[i][0]);
+       }
+
+       lib->processor->cancel(lib->processor);
+}
+END_TEST
+
+Suite *watcher_suite_create()
+{
+       Suite *s;
+       TCase *tc;
+
+       s = suite_create("watcher");
+
+       tc = tcase_create("read");
+       tcase_add_test(tc, test_read);
+       suite_add_tcase(s, tc);
+
+       tc = tcase_create("write");
+       tcase_add_test(tc, test_write);
+       suite_add_tcase(s, tc);
+
+       tc = tcase_create("multiread");
+       tcase_add_test(tc, test_multiread);
+       suite_add_tcase(s, tc);
+
+       tc = tcase_create("multiwrite");
+       tcase_add_test(tc, test_multiwrite);
+       suite_add_tcase(s, tc);
+
+       return s;
+}
index 2b63ec7..09f4254 100644 (file)
@@ -105,6 +105,7 @@ static array_t *load_suites()
        array_insert(suites, -1, array_suite_create());
        array_insert(suites, -1, identification_suite_create());
        array_insert(suites, -1, threading_suite_create());
+       array_insert(suites, -1, watcher_suite_create());
        array_insert(suites, -1, utils_suite_create());
        array_insert(suites, -1, host_suite_create());
        array_insert(suites, -1, vectors_suite_create());
index a35c012..ea881da 100644 (file)
@@ -29,6 +29,7 @@ Suite *hashtable_suite_create();
 Suite *array_suite_create();
 Suite *identification_suite_create();
 Suite *threading_suite_create();
+Suite *watcher_suite_create();
 Suite *utils_suite_create();
 Suite *vectors_suite_create();
 Suite *ecdsa_suite_create();