kernel-netlink: Add a stress test with several threads doing Netlink exchanges
authorMartin Willi <martin@revosec.ch>
Mon, 14 Jul 2014 14:56:30 +0000 (16:56 +0200)
committerMartin Willi <martin@revosec.ch>
Fri, 21 Nov 2014 09:55:45 +0000 (10:55 +0100)
src/libhydra/plugins/kernel_netlink/suites/test_socket.c

index 2ff8a99..415a936 100644 (file)
@@ -15,6 +15,8 @@
 
 #include <test_suite.h>
 
+#include <threading/thread.h>
+
 #include "../kernel_netlink_shared.h"
 
 START_TEST(test_echo)
@@ -52,6 +54,62 @@ START_TEST(test_echo)
 }
 END_TEST
 
+CALLBACK(stress, void*,
+       netlink_socket_t *s)
+{
+       struct nlmsghdr *out, *current;
+       struct rtgenmsg *msg;
+       size_t len;
+       int i;
+       netlink_buf_t request = {
+               .hdr = {
+                       .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
+                       .nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT,
+                       .nlmsg_type = RTM_GETLINK,
+               },
+       };
+
+       msg = NLMSG_DATA(&request.hdr);
+       msg->rtgen_family = AF_UNSPEC;
+
+       for (i = 0; i < 10; i++)
+       {
+               ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS);
+               current = out;
+               while (TRUE)
+               {
+                       ck_assert(NLMSG_OK(current, len));
+                       if (current->nlmsg_type == NLMSG_DONE)
+                       {
+                               break;
+                       }
+                       ck_assert_int_eq(current->nlmsg_type, RTM_NEWLINK);
+                       current = NLMSG_NEXT(current, len);
+               }
+               free(out);
+       }
+       return NULL;
+}
+
+START_TEST(test_stress)
+{
+       thread_t *threads[10];
+       netlink_socket_t *s;
+       int i;
+
+       s = netlink_socket_create(NETLINK_ROUTE, NULL);
+       for (i = 0; i < countof(threads); i++)
+       {
+               threads[i] = thread_create(stress, s);
+       }
+       for (i = 0; i < countof(threads); i++)
+       {
+               threads[i]->join(threads[i]);
+       }
+       s->destroy(s);
+}
+END_TEST
+
 Suite *socket_suite_create()
 {
        Suite *s;
@@ -63,5 +121,9 @@ Suite *socket_suite_create()
        tcase_add_test(tc, test_echo);
        suite_add_tcase(s, tc);
 
+       tc = tcase_create("stress");
+       tcase_add_test(tc, test_stress);
+       suite_add_tcase(s, tc);
+
        return s;
 }