From: Martin Willi Date: Tue, 25 Jun 2013 15:10:23 +0000 (+0200) Subject: unit-tests: add some test cases for watcher X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=89f969ffb1d1e6608c9f715b5b43520d76a70887;p=thirdparty%2Fstrongswan.git unit-tests: add some test cases for watcher --- diff --git a/src/libstrongswan/tests/Makefile.am b/src/libstrongswan/tests/Makefile.am index ca0a8c1ed8..0a28a6fc48 100644 --- a/src/libstrongswan/tests/Makefile.am +++ b/src/libstrongswan/tests/Makefile.am @@ -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 \ diff --git a/src/libstrongswan/tests/test_runner.c b/src/libstrongswan/tests/test_runner.c index 2f9e4dc0ab..f3a2d57407 100644 --- a/src/libstrongswan/tests/test_runner.c +++ b/src/libstrongswan/tests/test_runner.c @@ -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))) { diff --git a/src/libstrongswan/tests/test_runner.h b/src/libstrongswan/tests/test_runner.h index 5c60588e9a..7a8f1c3abe 100644 --- a/src/libstrongswan/tests/test_runner.h +++ b/src/libstrongswan/tests/test_runner.h @@ -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 index 0000000000..868a02004d --- /dev/null +++ b/src/libstrongswan/tests/test_watcher.c @@ -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 . + * + * 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 + +#include +#include +#include + +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; +}