]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
unit-tests: add some test cases for watcher
authorMartin Willi <martin@revosec.ch>
Tue, 25 Jun 2013 15:10:23 +0000 (17:10 +0200)
committerMartin Willi <martin@revosec.ch>
Wed, 17 Jul 2013 15:11:00 +0000 (17:11 +0200)
src/libstrongswan/tests/Makefile.am
src/libstrongswan/tests/test_runner.c
src/libstrongswan/tests/test_runner.h
src/libstrongswan/tests/test_watcher.c [new file with mode: 0644]

index ca0a8c1ed87f20814180a99a445bdfd029b5e085..0a28a6fc4861c085f9f26e15c214a63e35cdbd25 100644 (file)
@@ -7,7 +7,7 @@ test_runner_SOURCES = \
   test_linked_list.c test_enumerator.c test_linked_list_enumerator.c \
   test_bio_reader.c test_bio_writer.c test_chunk.c test_enum.c test_hashtable.c \
   test_identification.c test_threading.c test_utils.c test_vectors.c \
-  test_ecdsa.c test_rsa.c
+  test_watcher.c test_ecdsa.c test_rsa.c
 
 test_runner_CFLAGS = \
   -I$(top_srcdir)/src/libstrongswan \
index 2f9e4dc0ab85121a968596a3d621b59183fd8545..f3a2d5740785afd61f098c72825a4d756d6c2bce 100644 (file)
@@ -82,6 +82,7 @@ int main()
        srunner_add_suite(sr, threading_suite_create());
        srunner_add_suite(sr, utils_suite_create());
        srunner_add_suite(sr, vectors_suite_create());
+       srunner_add_suite(sr, watcher_suite_create());
        if (lib->plugins->has_feature(lib->plugins,
                                                                  PLUGIN_DEPENDS(PRIVKEY_GEN, KEY_RSA)))
        {
index 5c60588e9a5b18c9d82bd587a7c5762b98f96e55..7a8f1c3abe984dd85463a40a78b97d8b3bdd18fa 100644 (file)
@@ -32,5 +32,6 @@ Suite *utils_suite_create();
 Suite *vectors_suite_create();
 Suite *ecdsa_suite_create();
 Suite *rsa_suite_create();
+Suite *watcher_suite_create();
 
 #endif /** TEST_RUNNER_H_ */
diff --git a/src/libstrongswan/tests/test_watcher.c b/src/libstrongswan/tests/test_watcher.c
new file mode 100644 (file)
index 0000000..868a020
--- /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("writewrite");
+       tcase_add_test(tc, test_multiwrite);
+       suite_add_tcase(s, tc);
+
+       return s;
+}