Repository: celix Updated Branches: refs/heads/develop 43f64ce9b -> 3bb41b8e1
CELIX-320: refactor utils tests Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/3bb41b8e Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/3bb41b8e Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/3bb41b8e Branch: refs/heads/develop Commit: 3bb41b8e16ed44527b006c9cfabb4892c8f78b09 Parents: 43f64ce Author: Bjoern Petri <[email protected]> Authored: Thu Dec 10 15:27:25 2015 +0100 Committer: Bjoern Petri <[email protected]> Committed: Thu Dec 10 15:27:25 2015 +0100 ---------------------------------------------------------------------- utils/CMakeLists.txt | 29 ++-- utils/private/test/celix_threads_test.cpp | 202 +++++++++++++++++++++++-- utils/private/test/hash_map_test.cpp | 8 +- 3 files changed, 204 insertions(+), 35 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/3bb41b8e/utils/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index 095c9e8..93ff353 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -54,7 +54,7 @@ if (UTILS) celix_subproject(UTILS-TESTS "Option to build the utilities library tests" "OFF") - if (ENABLE_TESTING) + if (ENABLE_TESTING AND UTILS-TESTS) find_package(CppUTest REQUIRED) include_directories(${CUNIT_INCLUDE_DIRS}) @@ -69,30 +69,19 @@ if (UTILS) target_link_libraries(array_list_test celix_utils ${CPPUTEST_LIBRARY} pthread) add_executable(celix_threads_test private/test/celix_threads_test.cpp) - target_link_libraries(celix_threads_test celix_utils ${CPPUTEST_LIBRARY} pthread) + target_link_libraries(celix_threads_test celix_utils ${CPPUTEST_LIBRARY} ${CPPUTEST_EXT_LIBRARY} pthread) add_executable(linked_list_test private/test/linked_list_test.cpp) target_link_libraries(linked_list_test celix_utils ${CPPUTEST_LIBRARY} pthread) - - #run_test(array_list_test) - #run_test(hash_map_test) - #run_test(linked_list_test) - #ADD_TARGET_FOR_TEST(array_list_test) add_test(NAME run_array_list_test COMMAND array_list_test) + add_test(NAME run_hash_map_test COMMAND hash_map_test) + add_test(NAME run_celix_threads_test COMMAND celix_threads_test) + add_test(NAME run_linked_list_test COMMAND linked_list_test) SETUP_TARGET_FOR_COVERAGE(array_list_test array_list_test ${CMAKE_BINARY_DIR}/coverage/array_list_test/array_list_test) + SETUP_TARGET_FOR_COVERAGE(hash_map hash_map_test ${CMAKE_BINARY_DIR}/coverage/hash_map_test/hash_map_test) + SETUP_TARGET_FOR_COVERAGE(celix_threads_test celix_threads_test ${CMAKE_BINARY_DIR}/coverage/celix_threads_test/celix_threads_test) + SETUP_TARGET_FOR_COVERAGE(linked_list_test linked_list_test ${CMAKE_BINARY_DIR}/coverage/linked_list_test/linked_list_test) - #ADD_TARGET_FOR_TEST(hash_map_test) - add_test(NAME run_hash_map_test COMMAND hash_map_test) - SETUP_TARGET_FOR_COVERAGE(hash_map hash_map_test ${CMAKE_BINARY_DIR}/coverage/hash_map_test/hash_map_test) - - #ADD_TARGET_FOR_TEST(celix_threads_test) - add_test(NAME run_celix_threads_test COMMAND celix_threads_test) - SETUP_TARGET_FOR_COVERAGE(celix_threads_test celix_threads_test ${CMAKE_BINARY_DIR}/coverage/celix_threads_test/celix_threads_test) - - #ADD_TARGET_FOR_TEST(linked_list_test) - add_test(NAME run_linked_list_test COMMAND linked_list_test) - SETUP_TARGET_FOR_COVERAGE(linked_list_test linked_list_test ${CMAKE_BINARY_DIR}/coverage/linked_list_test/linked_list_test) - - endif(ENABLE_TESTING) + endif(ENABLE_TESTING AND UTILS-TESTS) endif (UTILS) http://git-wip-us.apache.org/repos/asf/celix/blob/3bb41b8e/utils/private/test/celix_threads_test.cpp ---------------------------------------------------------------------- diff --git a/utils/private/test/celix_threads_test.cpp b/utils/private/test/celix_threads_test.cpp index 620b42b..f75f8db 100644 --- a/utils/private/test/celix_threads_test.cpp +++ b/utils/private/test/celix_threads_test.cpp @@ -27,42 +27,77 @@ #include <stdlib.h> #include <unistd.h> #include <string.h> +#include <signal.h> #include "CppUTest/TestHarness.h" #include "CppUTest/TestHarness_c.h" #include "CppUTest/CommandLineTestRunner.h" +#include "CppUTestExt/MockSupport.h" extern "C" { #include "celix_threads.h" -} +#include "CppUTestExt/MockSupport_c.h" -int main(int argc, char** argv) { - return RUN_ALL_TESTS(argc, argv); -} static char* my_strdup(const char* s) { - char *d = (char*) malloc(strlen(s) + 1); - if (d == NULL) + if (s == NULL) { + return NULL; + } + + size_t len = strlen(s); + + char *d = (char*) calloc(len + 1, sizeof(char)); + + if (d == NULL) { return NULL; - strcpy(d, s); + } + + strncpy(d, s, len); return d; } -//----------------------TEST THREAD FUNCTION DECLARATIONS---------------------- +static int celix_thread_t_equals(const void * object, const void * compareTo){ + celix_thread_t * thread1 = (celix_thread_t*) object; + celix_thread_t * thread2 = (celix_thread_t*) compareTo; + return thread1->thread == thread2->thread && + thread1->threadInitialized == thread2->threadInitialized; +} + +static char * celix_thread_t_toString(const void * object){ + celix_thread_t * thread = (celix_thread_t*) object; + char buff[512]; + snprintf(buff, 512, "thread: %lu, threadInitialized: %s", thread->thread, (thread->threadInitialized ? "true" : "false")); + + return my_strdup(buff); +} + +//----------------------TEST THREAD FUNCTION DECLARATIONS---------------------- static void * thread_test_func_create(void *); static void * thread_test_func_exit(void *); static void * thread_test_func_detach(void *); static void * thread_test_func_self(void *); +static void * thread_test_func_once(void*); +static void thread_test_func_once_init(void); static void * thread_test_func_lock(void *); -static void * thread_test_func_cond_wait(void *arg); -static void * thread_test_func_cond_broadcast(void *arg); +static void * thread_test_func_cond_wait(void *); +static void * thread_test_func_cond_broadcast(void *); static int thread_test_func_recur_lock(celix_thread_mutex_t*, int); +static void * thread_test_func_kill(void*); +static void thread_test_func_kill_handler(int); struct func_param{ int i, i2; celix_thread_mutex_t mu, mu2; celix_thread_cond_t cond, cond2; + celix_thread_once_t once_control; + celix_thread_rwlock_t rwlock; }; +} + +int main(int argc, char** argv) { + return RUN_ALL_TESTS(argc, argv); +} + //----------------------TESTGROUP DEFINES---------------------- TEST_GROUP(celix_thread) { @@ -75,6 +110,25 @@ TEST_GROUP(celix_thread) { } }; +TEST_GROUP(celix_thread_kill) { + celix_thread thread; + struct sigaction sigact, sigactold; + + void setup(void) { + memset(&sigact, 0, sizeof(sigact)); + sigact.sa_handler = thread_test_func_kill_handler; + sigaction(SIGUSR1, &sigact, &sigactold); + + mock_c()->installComparator("celix_thread_t", celix_thread_t_equals, celix_thread_t_toString); + } + + void teardown(void) { + sigaction(SIGUSR1, &sigactold, &sigact); + + mock_c()->removeAllComparators(); + } +}; + TEST_GROUP(celix_thread_mutex) { celix_thread thread; celix_thread_mutex_t mu; @@ -98,6 +152,16 @@ TEST_GROUP(celix_thread_condition) { } }; +TEST_GROUP(celix_thread_rwlock) { + celix_thread thread; + + void setup(void) { + } + + void teardown(void) { + } +}; + //----------------------CELIX THREADS TESTS---------------------- TEST(celix_thread, create) { @@ -149,6 +213,45 @@ TEST(celix_thread, initalized) { celixThread_detach(thread); } +TEST(celix_thread, once) { + int *status; + celix_thread thread2; + struct func_param * params = (struct func_param*) calloc(1, + sizeof(struct func_param)); + + mock().expectOneCall("thread_test_func_once_init"); + + celixThread_create(&thread, NULL, &thread_test_func_once, params); + celixThread_join(thread, (void**) &status); + + celixThread_create(&thread2, NULL, &thread_test_func_once, params); + celixThread_join(thread2, (void**) &status); + + free(params); + + mock().checkExpectations(); + mock().clear(); +} +//----------------------CELIX THREADS KILL TESTS---------------------- +TEST(celix_thread_kill, kill){ + int * ret; + celixThread_create(&thread, NULL, thread_test_func_kill, NULL); + sleep(2); + + mock().expectOneCall("thread_test_func_kill_handler") + .withParameter("signo", SIGUSR1) + .withParameterOfType("celix_thread_t", "inThread", (const void*) &thread); + + celixThread_kill(thread, SIGUSR1); + celixThread_join(thread, (void**)&ret); + + LONGS_EQUAL(-1, *ret); + free(ret); + + mock().checkExpectations(); + mock().clear(); +} + //----------------------CELIX THREADS MUTEX TESTS---------------------- TEST(celix_thread_mutex, create) { @@ -274,8 +377,58 @@ TEST(celix_thread_condition, broadcast) { free(param); } -//----------------------TEST THREAD FUNCTION DEFINES---------------------- +//----------------------CELIX READ-WRITE LOCK TESTS---------------------- +TEST(celix_thread_rwlock, create){ + celix_thread_rwlock_t lock; + celix_status_t status; + status = celixThreadRwlock_create(&lock, NULL); + LONGS_EQUAL(CELIX_SUCCESS, status); + status = celixThreadRwlock_destroy(&lock); + LONGS_EQUAL(CELIX_SUCCESS, status); +} + +TEST(celix_thread_rwlock, readLock){ + int status; + celix_thread_rwlock_t lock; + //struct func_param * param = (struct func_param*) calloc(1,sizeof(struct func_param)); + + celixThreadRwlock_create(&lock, NULL); + + status = celixThreadRwlock_readLock(&lock); + LONGS_EQUAL(0, status); + status = celixThreadRwlock_readLock(&lock); + LONGS_EQUAL(0, status); + status = celixThreadRwlock_unlock(&lock); + LONGS_EQUAL(0, status); + status = celixThreadRwlock_unlock(&lock); + LONGS_EQUAL(0, status); + + celixThreadRwlock_destroy(&lock); +} + +TEST(celix_thread_rwlock, writeLock){ + int status; + celix_thread_rwlock_t lock; + celixThreadRwlock_create(&lock, NULL); + + status = celixThreadRwlock_writeLock(&lock); + LONGS_EQUAL(0, status); + status = celixThreadRwlock_writeLock(&lock); + //EDEADLK ErNo: Resource deadlock avoided + LONGS_EQUAL(EDEADLK, status); + + celixThreadRwlock_unlock(&lock); +} + +TEST(celix_thread_rwlock, attr){ + celix_thread_rwlockattr_t attr; + celixThreadRwlockAttr_create(&attr); + celixThreadRwlockAttr_destroy(&attr); +} + +//----------------------TEST THREAD FUNCTION DEFINES---------------------- +extern "C" { static void * thread_test_func_create(void * arg) { char ** test_str = (char**) arg; *test_str = my_strdup("SUCCESS"); @@ -300,6 +453,17 @@ static void * thread_test_func_self(void * arg) { return NULL; } +static void * thread_test_func_once(void * arg) { + struct func_param *param = (struct func_param *) arg; + celixThread_once(¶m->once_control, thread_test_func_once_init); + + return NULL; +} + +static void thread_test_func_once_init(void) { + mock_c()->actualCall("thread_test_func_once_init"); +} + static void * thread_test_func_lock(void *arg) { struct func_param *param = (struct func_param *) arg; @@ -348,3 +512,19 @@ static int thread_test_func_recur_lock(celix_thread_mutex_t *mu, int i) { return temp; } } + +static void * thread_test_func_kill(void *arg){ + int * ret = (int*) malloc(sizeof(*ret)); + //sleep for a about a minute, or until a kill signal (USR1) is recieved + *ret = usleep(60000000); + return ret; +} + +static void thread_test_func_kill_handler(int signo){ + celix_thread_t inThread = celixThread_self(); + + mock_c()->actualCall("thread_test_func_kill_handler") + ->withLongIntParameters("signo", signo) + ->withParameterOfType("celix_thread_t", "inThread", (const void*) &inThread); +} +} http://git-wip-us.apache.org/repos/asf/celix/blob/3bb41b8e/utils/private/test/hash_map_test.cpp ---------------------------------------------------------------------- diff --git a/utils/private/test/hash_map_test.cpp b/utils/private/test/hash_map_test.cpp index 2051942..eac9ea0 100644 --- a/utils/private/test/hash_map_test.cpp +++ b/utils/private/test/hash_map_test.cpp @@ -167,10 +167,10 @@ TEST(hash_map, create){ CHECK(map != NULL); LONGS_EQUAL(0, map->size); // This fails on windows due to dllimport providing a proxy for exported functions. - CHECK_EQUAL(&hashMap_equals, map->equalsKey); - CHECK_EQUAL(&hashMap_equals, map->equalsValue); - CHECK_EQUAL(&hashMap_hashCode, map->hashKey); - CHECK_EQUAL(&hashMap_hashCode, map->hashValue); + POINTERS_EQUAL(hashMap_equals, map->equalsKey); + POINTERS_EQUAL(hashMap_equals, map->equalsValue); + POINTERS_EQUAL(hashMap_hashCode, map->hashKey); + POINTERS_EQUAL(hashMap_hashCode, map->hashValue); } TEST(hash_map, size){
