From 1eda2f8a538541bdf701945146b4bcae7a5ef151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Mon, 12 Nov 2012 22:18:04 +0100 Subject: [PATCH] Add thread queue tests --- src/ucore_threadqueue.c | 2 +- test/test_runner.c | 2 + test/test_threadqueue.c | 169 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 test/test_threadqueue.c diff --git a/src/ucore_threadqueue.c b/src/ucore_threadqueue.c index fa1e445..b18c8c0 100644 --- a/src/ucore_threadqueue.c +++ b/src/ucore_threadqueue.c @@ -175,7 +175,7 @@ int uc_thread_queue_walk(struct uc_threadqueue *queue, uc_thread_queue_walk_func } //maybe caller should supply a callback for cleaning the elements ? -int uc_thread_queue_cleanup(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func) +int uc_thread_queue_destroy(struct uc_threadqueue *queue, uc_thread_queue_walk_func free_func) { int rc; diff --git a/test/test_runner.c b/test/test_runner.c index a587196..5634360 100644 --- a/test/test_runner.c +++ b/test/test_runner.c @@ -10,6 +10,7 @@ extern Suite *container_of_suite(void); extern Suite *read_file_suite(void); extern Suite *pack_suite(void); extern Suite *logging_suite(void); +extern Suite *threadqueue_suite(void); int main (int argc, char *argv[]) @@ -29,6 +30,7 @@ main (int argc, char *argv[]) srunner_add_suite(sr, read_file_suite()); srunner_add_suite(sr, pack_suite()); srunner_add_suite(sr, logging_suite()); + srunner_add_suite(sr, threadqueue_suite()); srunner_run_all (sr, CK_VERBOSE); diff --git a/test/test_threadqueue.c b/test/test_threadqueue.c new file mode 100644 index 0000000..d6c70aa --- /dev/null +++ b/test/test_threadqueue.c @@ -0,0 +1,169 @@ +#include +#include +#include +#include +#include "ucore_threadqueue.h" + +struct thr_msg { + struct uc_threadmsg msg; + int a,b; + char data[32]; +}; + +START_TEST (test_thread_queue_length) + + struct uc_threadqueue queue; + int i; + + fail_if(uc_thread_queue_init(&queue, 100) != 0); + for(i = 0; i < 51; i++) { + struct thr_msg *msg = malloc(sizeof *msg); + fail_if(msg == NULL); + fail_if(uc_thread_queue_add(&queue, &msg->msg) != 0); + } + + fail_if(uc_thread_queue_length(&queue) != 51); + +END_TEST + +START_TEST (test_thread_queue_one_thread) + + struct uc_threadqueue queue; + int i; + + fail_if(uc_thread_queue_init(&queue, 100) != 0); + for(i = 0; i < 51; i++) { + struct thr_msg *msg = malloc(sizeof *msg); + fail_if(msg == NULL); + msg->a = i; + fail_if(uc_thread_queue_add(&queue, &msg->msg) != 0); + } + + for(i = 0; i < 51; i++) { + struct uc_threadmsg *msg; + struct thr_msg *my_msg; + fail_if(uc_thread_queue_get(&queue, NULL, &msg) != 0); + my_msg = (struct thr_msg *)msg; + fail_if(my_msg->a != i); + free(my_msg); + } + fail_if(uc_thread_queue_destroy(&queue, NULL) != 0); + +END_TEST + + +//pretty ugly.. +static int test_thread_queue_walk_global; +static void test_thread_queue_walk_func(struct uc_threadmsg *msg) +{ + struct thr_msg *my_msg = (struct thr_msg *)msg; + fail_if(my_msg->a != test_thread_queue_walk_global); + test_thread_queue_walk_global++; +} + +START_TEST (test_thread_queue_walk) + + struct uc_threadqueue queue; + int i; + + fail_if(uc_thread_queue_init(&queue, 100) != 0); + for(i = 0; i < 51; i++) { + struct thr_msg *msg = malloc(sizeof *msg); + fail_if(msg == NULL); + msg->a = i; + fail_if(uc_thread_queue_add(&queue, &msg->msg) != 0); + } + + test_thread_queue_walk_global = 0; + + uc_thread_queue_walk(&queue, test_thread_queue_walk_func); + +END_TEST + +#define READER_WRITER_NUM_MSG 20000 + +static void *test_thread_queue_reader_writer_func(void *arg) +{ + struct uc_threadqueue *queue = arg; + int i; + + for(i = 0; i < READER_WRITER_NUM_MSG; i++) { + struct uc_threadmsg *msg; + struct thr_msg *my_msg; + fail_if(uc_thread_queue_get(queue, NULL, &msg) != 0); + my_msg = (struct thr_msg *)msg; + fail_if(my_msg->a != i); + free(my_msg); + } +} + +START_TEST (test_thread_queue_reader_writer) + + struct uc_threadqueue queue; + int i; + pthread_t tid; + + fail_if(uc_thread_queue_init(&queue, 1000) != 0); + fail_if(pthread_create(&tid, NULL, test_thread_queue_reader_writer_func, &queue) != 0); + sched_yield(); + + for(i = 0; i < READER_WRITER_NUM_MSG; i++) { + struct thr_msg *msg = malloc(sizeof *msg); + fail_if(msg == NULL); + msg->a = i; + fail_if(uc_thread_queue_add(&queue, &msg->msg) != 0); + } + + pthread_join(tid, NULL); + + fail_if(uc_thread_queue_destroy(&queue, NULL) != 0); + +END_TEST + +START_TEST (test_thread_queue_reader_writer_len_1) + + struct uc_threadqueue queue; + int i; + pthread_t tid; + + fail_if(uc_thread_queue_init(&queue, 1) != 0); + fail_if(pthread_create(&tid, NULL, test_thread_queue_reader_writer_func, &queue) != 0); + sched_yield(); + + for(i = 0; i < READER_WRITER_NUM_MSG; i++) { + struct thr_msg *msg = malloc(sizeof *msg); + fail_if(msg == NULL); + msg->a = i; + fail_if(uc_thread_queue_add(&queue, &msg->msg) != 0); + } + + pthread_join(tid, NULL); + +END_TEST + +START_TEST (test_thread_queue_zero_len) + + struct uc_threadqueue queue; + + fail_if(uc_thread_queue_init(&queue, 0) == 0); //thread_queue_init should fail + +END_TEST + + +Suite *threadqueue_suite(void) +{ + Suite *s = suite_create("treadqueue"); + TCase *tc1 = tcase_create("thread queue"); + + tcase_add_test(tc1, test_thread_queue_length); + tcase_add_test(tc1, test_thread_queue_one_thread); + tcase_add_test(tc1, test_thread_queue_walk); + tcase_add_test(tc1, test_thread_queue_reader_writer); + tcase_add_test(tc1, test_thread_queue_reader_writer_len_1); + tcase_add_test(tc1, test_thread_queue_zero_len); + + suite_add_tcase(s, tc1); + + return s; +} +