This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch feature/celix_err
in repository https://gitbox.apache.org/repos/asf/celix.git

commit 40b85559e78d05174bf16a163d71525f92e34b98
Author: Pepijn Noltes <pepijnnol...@gmail.com>
AuthorDate: Tue May 2 14:04:43 2023 +0200

    Refactor threads cpputest to gtest and add a tss test
---
 libs/utils/CMakeLists.txt                      |   6 -
 libs/utils/gtest/CMakeLists.txt                |   1 +
 libs/utils/gtest/src/ThreadsTestSuite.cc       | 438 ++++++++++++++++++++
 libs/utils/private/test/celix_threads_test.cpp | 537 -------------------------
 4 files changed, 439 insertions(+), 543 deletions(-)

diff --git a/libs/utils/CMakeLists.txt b/libs/utils/CMakeLists.txt
index d57c0c7c..83db2b41 100644
--- a/libs/utils/CMakeLists.txt
+++ b/libs/utils/CMakeLists.txt
@@ -128,10 +128,6 @@ if (ENABLE_TESTING)
         target_include_directories(array_list_test PRIVATE include_deprecated)
         target_link_libraries(array_list_test  Celix::utils CppUTest::CppUTest 
pthread)
 
-        add_executable(celix_threads_test private/test/celix_threads_test.cpp)
-        target_include_directories(celix_threads_test PRIVATE 
include_deprecated)
-        target_link_libraries(celix_threads_test Celix::utils 
CppUTest::CppUTest ${CppUTest_EXT_LIBRARIES} pthread)
-
         add_executable(linked_list_test private/test/linked_list_test.cpp)
         target_include_directories(linked_list_test PRIVATE include_deprecated)
         target_link_libraries(linked_list_test  Celix::utils 
CppUTest::CppUTest pthread)
@@ -160,7 +156,6 @@ if (ENABLE_TESTING)
 
         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)
         add_test(NAME run_properties_test COMMAND properties_test)
         add_test(NAME run_ip_utils_test COMMAND ip_utils_test)
@@ -168,7 +163,6 @@ if (ENABLE_TESTING)
 
         setup_target_for_coverage(array_list_test)
         setup_target_for_coverage(hash_map_test)
-        setup_target_for_coverage(celix_threads_test)
         setup_target_for_coverage(linked_list_test)
         setup_target_for_coverage(properties_test)
         setup_target_for_coverage(ip_utils_test)
diff --git a/libs/utils/gtest/CMakeLists.txt b/libs/utils/gtest/CMakeLists.txt
index e0c2951f..79c14238 100644
--- a/libs/utils/gtest/CMakeLists.txt
+++ b/libs/utils/gtest/CMakeLists.txt
@@ -34,6 +34,7 @@ add_executable(test_utils
         src/CelixUtilsTestSuite.cc
         src/ConvertUtilsTestSuite.cc
         src/ErrTestSuite.cc
+        src/ThreadsTestSuite.cc
         ${CELIX_UTIL_TEST_SOURCES_FOR_CXX_HEADERS}
 )
 
diff --git a/libs/utils/gtest/src/ThreadsTestSuite.cc 
b/libs/utils/gtest/src/ThreadsTestSuite.cc
new file mode 100644
index 00000000..6c1773b9
--- /dev/null
+++ b/libs/utils/gtest/src/ThreadsTestSuite.cc
@@ -0,0 +1,438 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "celix_threads.h"
+
+class ThreadsTestSuite : public ::testing::Test {
+public:
+};
+
+//----------------------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_lock(void *);
+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_once(void*);
+static void thread_test_func_once_init();
+static int thread_test_func_once_init_times_called = 0;
+
+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;
+};
+
+//----------------------CELIX THREADS TESTS----------------------
+
+TEST_F(ThreadsTestSuite, CreateTest) {
+    celix_thread_t thread;
+    int ret;
+    char* testStr = nullptr;
+
+    ret = celixThread_create(&thread, nullptr, &thread_test_func_create,
+                             &testStr);
+    EXPECT_EQ(CELIX_SUCCESS, ret);
+    celixThread_join(thread, nullptr);
+
+    EXPECT_STREQ("SUCCESS", testStr);
+
+    free(testStr);
+}
+
+TEST_F(ThreadsTestSuite, ExitTest) {
+    int ret, *status;
+    celix_thread_t thread;
+
+    ret = celixThread_create(&thread, nullptr, &thread_test_func_exit, 
nullptr);
+    EXPECT_EQ(CELIX_SUCCESS, ret);
+    celixThread_join(thread, (void**) &status);
+    EXPECT_EQ(666, *status);
+    free(status);
+}
+
+TEST_F(ThreadsTestSuite, DetachTest) {
+    int ret;
+    celix_thread_t thread;
+
+    celixThread_create(&thread, nullptr, thread_test_func_detach, nullptr);
+    ret = celixThread_detach(thread);
+    EXPECT_EQ(CELIX_SUCCESS, ret);
+}
+
+TEST_F(ThreadsTestSuite, SelfTest) {
+    celix_thread_t thread;
+    celix_thread_t thread2;
+
+    celixThread_create(&thread, nullptr, thread_test_func_self, &thread2);
+    celixThread_join(thread, nullptr);
+    EXPECT_TRUE(celixThread_equals(thread, thread2));
+}
+
+TEST_F(ThreadsTestSuite, InitializedTest) {
+    celix_thread_t thread;
+    EXPECT_FALSE(celixThread_initialized(thread));
+
+    celixThread_create(&thread, nullptr, thread_test_func_detach, nullptr);
+    EXPECT_TRUE(celixThread_initialized(thread));
+    celixThread_join(thread, nullptr);
+}
+
+TEST_F(ThreadsTestSuite, CnceTest) {
+    int *status;
+    celix_thread_t thread;
+    celix_thread_t thread2;
+    struct func_param* params = (struct func_param*) calloc(1,sizeof(struct 
func_param));
+
+    celixThread_create(&thread, nullptr, &thread_test_func_once, params);
+    celixThread_join(thread, (void**) &status);
+
+    celixThread_create(&thread2, nullptr, &thread_test_func_once, params);
+    celixThread_join(thread2, (void**) &status);
+
+    free(params);
+
+    EXPECT_EQ(1, thread_test_func_once_init_times_called);
+}
+
+//----------------------CELIX THREADS KILL TESTS----------------------
+
+TEST_F(ThreadsTestSuite, KillTest){
+    //setup signal handler to ignore SIGUSR1
+    struct sigaction sigact;
+    struct sigaction sigactold;
+    memset(&sigact, 0, sizeof(sigact));
+    sigact.sa_handler = [](int) {/*nop*/};;
+    sigaction(SIGUSR1, &sigact, &sigactold);
+
+
+    int * ret;
+    celix_thread_t thread;
+    celixThread_create(&thread, nullptr, thread_test_func_kill, nullptr);
+    sleep(1);
+
+    celixThread_kill(thread, SIGUSR1);
+    celixThread_join(thread, (void**)&ret);
+
+    EXPECT_EQ(-1, *ret); // -1 returned from usleep (interrupted by signal)
+    free(ret);
+
+    sigaction(SIGUSR1, &sigactold, nullptr);
+}
+
+//----------------------CELIX THREADS MUTEX TESTS----------------------
+
+TEST_F(ThreadsTestSuite, CreateMutexTest) {
+    celix_thread_mutex_t mu;
+    EXPECT_EQ(CELIX_SUCCESS, celixThreadMutex_create(&mu, nullptr));
+    EXPECT_EQ(CELIX_SUCCESS, celixThreadMutex_destroy(&mu));
+}
+
+
+TEST_F(ThreadsTestSuite, LockTest) {
+    celix_thread_t thread;
+    struct func_param * params = (struct func_param*) calloc(1,
+                                                             sizeof(struct 
func_param));
+
+    celixThreadMutex_create(&params->mu, nullptr);
+
+    celixThreadMutex_lock(&params->mu);
+    celixThread_create(&thread, nullptr, thread_test_func_lock, params);
+
+    sleep(1);
+
+    EXPECT_EQ(0, params->i);
+
+    //possible race condition, not perfect test
+    celixThreadMutex_unlock(&params->mu);
+
+    sleep(1);
+
+    celixThreadMutex_lock(&params->mu2);
+    EXPECT_EQ(666, params->i);
+    celixThreadMutex_unlock(&params->mu2);
+    celixThread_join(thread, nullptr);
+    free(params);
+}
+
+TEST_F(ThreadsTestSuite, AttrCreateTest) {
+    celix_thread_mutexattr_t mu_attr;
+    EXPECT_EQ(CELIX_SUCCESS, celixThreadMutexAttr_create(&mu_attr));
+    EXPECT_EQ(CELIX_SUCCESS, celixThreadMutexAttr_destroy(&mu_attr));
+}
+
+TEST_F(ThreadsTestSuite, AttrSettypeTest) {
+    celix_thread_mutex_t mu;
+    celix_thread_mutexattr_t mu_attr;
+    celixThreadMutexAttr_create(&mu_attr);
+
+    //test recursive mutex
+    celixThreadMutexAttr_settype(&mu_attr, CELIX_THREAD_MUTEX_RECURSIVE);
+    celixThreadMutex_create(&mu, &mu_attr);
+    //if program doesnt deadlock: success! also check factorial of 10, for 
reasons unknown
+    EXPECT_EQ(3628800, thread_test_func_recur_lock(&mu, 10));
+    celixThreadMutex_destroy(&mu);
+
+    //test deadlock check mutex
+    celixThreadMutexAttr_settype(&mu_attr, CELIX_THREAD_MUTEX_ERRORCHECK);
+    celixThreadMutex_create(&mu, &mu_attr);
+    //get deadlock error
+    celixThreadMutex_lock(&mu);
+    EXPECT_TRUE(celixThreadMutex_lock(&mu) != CELIX_SUCCESS);
+    //do not get deadlock error
+    celixThreadMutex_unlock(&mu);
+    EXPECT_EQ(CELIX_SUCCESS, celixThreadMutex_lock(&mu));
+    //get unlock error
+    celixThreadMutex_unlock(&mu);
+    EXPECT_TRUE(celixThreadMutex_unlock(&mu) != CELIX_SUCCESS);
+
+    celixThreadMutex_destroy(&mu);
+    celixThreadMutexAttr_destroy(&mu_attr);
+}
+
+//----------------------CELIX THREAD CONDITIONS TESTS----------------------
+
+TEST_F(ThreadsTestSuite, InitCondTest) {
+    celix_thread_cond_t cond;
+    EXPECT_EQ(CELIX_SUCCESS, celixThreadCondition_init(&cond, nullptr));
+    EXPECT_EQ(CELIX_SUCCESS, celixThreadCondition_destroy(&cond));
+}
+
+//test wait and signal
+TEST_F(ThreadsTestSuite, WaitCondTest) {
+    celix_thread_t thread;
+    struct func_param * param = (struct func_param*) calloc(1,
+                                                            sizeof(struct 
func_param));
+    celixThreadMutex_create(&param->mu, nullptr);
+    celixThreadCondition_init(&param->cond, nullptr);
+
+    celixThreadMutex_lock(&param->mu);
+
+    sleep(2);
+
+    celixThread_create(&thread, nullptr, thread_test_func_cond_wait, param);
+    EXPECT_EQ(0, param->i);
+
+    celixThreadCondition_wait(&param->cond, &param->mu);
+    EXPECT_EQ(666, param->i);
+    celixThreadMutex_unlock(&param->mu);
+
+    celixThread_join(thread, nullptr);
+    free(param);
+}
+
+//test wait and broadcast on multiple threads
+TEST_F(ThreadsTestSuite, CondBroadcastTest) {
+    celix_thread_t thread;
+    celix_thread_t thread2;
+    struct func_param * param = (struct func_param*) calloc(1,sizeof(struct 
func_param));
+    celixThreadMutex_create(&param->mu, nullptr);
+    celixThreadMutex_create(&param->mu2, nullptr);
+    celixThreadCondition_init(&param->cond, nullptr);
+
+    celixThread_create(&thread, nullptr, thread_test_func_cond_broadcast, 
param);
+    celixThread_create(&thread2, nullptr, thread_test_func_cond_broadcast, 
param);
+
+    sleep(1);
+    celixThreadMutex_lock(&param->mu);
+    EXPECT_EQ(0, param->i);
+    celixThreadMutex_unlock(&param->mu);
+
+    celixThreadMutex_lock(&param->mu);
+    celixThreadCondition_broadcast(&param->cond);
+    celixThreadMutex_unlock(&param->mu);
+    sleep(1);
+    celixThreadMutex_lock(&param->mu);
+    EXPECT_EQ(2, param->i);
+    celixThreadMutex_unlock(&param->mu);
+
+    celixThread_join(thread, nullptr);
+    celixThread_join(thread2, nullptr);
+    free(param);
+}
+
+//----------------------CELIX READ-WRITE LOCK TESTS----------------------
+
+TEST_F(ThreadsTestSuite, CreateRwLockTest) {
+    celix_thread_rwlock_t alock;
+    celix_status_t status;
+    status = celixThreadRwlock_create(&alock, nullptr);
+    if (status != CELIX_SUCCESS) {
+        fprintf(stderr, "Found error '%s'\n", strerror(status));
+    }
+    EXPECT_EQ(CELIX_SUCCESS, status);
+    status = celixThreadRwlock_destroy(&alock);
+    EXPECT_EQ(CELIX_SUCCESS, status);
+}
+
+TEST_F(ThreadsTestSuite, ReadLockTest) {
+    int status;
+    celix_thread_rwlock_t lock;
+    memset(&lock, 0x00, sizeof(celix_thread_rwlock_t));
+    //struct func_param * param = (struct func_param*) calloc(1,sizeof(struct 
func_param));
+
+    celixThreadRwlock_create(&lock, nullptr);
+
+    status = celixThreadRwlock_readLock(&lock);
+    EXPECT_EQ(0, status);
+    status = celixThreadRwlock_readLock(&lock);
+    EXPECT_EQ(0, status);
+    status = celixThreadRwlock_unlock(&lock);
+    EXPECT_EQ(0, status);
+    status = celixThreadRwlock_unlock(&lock);
+    EXPECT_EQ(0, status);
+
+    celixThreadRwlock_destroy(&lock);
+}
+
+TEST_F(ThreadsTestSuite, WriteLockTest) {
+    int status;
+    celix_thread_rwlock_t lock;
+    celixThreadRwlock_create(&lock, nullptr);
+
+    status = celixThreadRwlock_writeLock(&lock);
+    EXPECT_EQ(0, status);
+    status = celixThreadRwlock_writeLock(&lock);
+    //EDEADLK ErNo: Resource deadlock avoided
+    EXPECT_EQ(EDEADLK, status);
+
+    celixThreadRwlock_unlock(&lock);
+}
+
+TEST_F(ThreadsTestSuite, RwLockAttrTest) {
+    celix_thread_rwlockattr_t attr;
+    celixThreadRwlockAttr_create(&attr);
+    celixThreadRwlockAttr_destroy(&attr);
+}
+
+TEST_F(ThreadsTestSuite, TssTest) {
+    celix_tss_key_t key;
+    celix_status_t status = celix_tss_create(&key, [](void* ptr) { free(ptr); 
});
+    EXPECT_EQ(CELIX_SUCCESS, status);
+
+    int* value = (int*)malloc(sizeof(int));
+    *value = 123;
+    status = celix_tss_set(key, value);
+    EXPECT_EQ(CELIX_SUCCESS, status);
+
+    value = (int*)celix_tss_get(key);
+    EXPECT_EQ(123, *value);
+
+    status = celix_tss_delete(key);
+    EXPECT_EQ(CELIX_SUCCESS, status);
+}
+
+static void * thread_test_func_create(void * arg) {
+    char ** test_str = (char**) arg;
+    *test_str = strdup("SUCCESS");
+
+    return nullptr;
+}
+
+static void * thread_test_func_exit(void *) {
+    int *pi = (int*) calloc(1, sizeof(int));
+    *pi = 666;
+
+    celixThread_exit(pi);
+    return nullptr;
+}
+
+static void * thread_test_func_detach(void *) {
+    return nullptr;
+}
+
+static void * thread_test_func_self(void * arg) {
+    *((celix_thread*) arg) = celixThread_self();
+    return nullptr;
+}
+
+static void * thread_test_func_once(void * arg) {
+    struct func_param *param = (struct func_param *) arg;
+    celixThread_once(&param->once_control, thread_test_func_once_init);
+    return nullptr;
+}
+
+static void thread_test_func_once_init() {
+    thread_test_func_once_init_times_called += 1;
+}
+
+static void * thread_test_func_lock(void *arg) {
+    struct func_param *param = (struct func_param *) arg;
+
+    celixThreadMutex_lock(&param->mu2);
+    celixThreadMutex_lock(&param->mu);
+    param->i = 666;
+    celixThreadMutex_unlock(&param->mu);
+    celixThreadMutex_unlock(&param->mu2);
+
+    return nullptr;
+}
+
+static void * thread_test_func_cond_wait(void *arg) {
+    struct func_param *param = (struct func_param *) arg;
+
+    celixThreadMutex_lock(&param->mu);
+
+    param->i = 666;
+
+    celixThreadCondition_signal(&param->cond);
+    celixThreadMutex_unlock(&param->mu);
+    return nullptr;
+}
+
+static void * thread_test_func_cond_broadcast(void *arg) {
+    struct func_param *param = (struct func_param *) arg;
+
+    celixThreadMutex_lock(&param->mu);
+    celixThreadCondition_wait(&param->cond, &param->mu);
+    celixThreadMutex_unlock(&param->mu);
+    celixThreadMutex_lock(&param->mu);
+    param->i++;
+    celixThreadMutex_unlock(&param->mu);
+    return nullptr;
+}
+
+static int thread_test_func_recur_lock(celix_thread_mutex_t *mu, int i) {
+    int temp;
+    if (i == 1) {
+        return 1;
+    } else {
+        celixThreadMutex_lock(mu);
+        temp = thread_test_func_recur_lock(mu, i - 1);
+        temp *= i;
+        celixThreadMutex_unlock(mu);
+        return temp;
+    }
+}
+
+static void * thread_test_func_kill(void __attribute__((unused)) *arg){
+    int * ret = (int*) malloc(sizeof(*ret));
+    //sleep for about a minute, or until a kill signal (USR1) is received
+    *ret = usleep(60000000);
+    return ret;
+}
diff --git a/libs/utils/private/test/celix_threads_test.cpp 
b/libs/utils/private/test/celix_threads_test.cpp
deleted file mode 100644
index b6c6cb64..00000000
--- a/libs/utils/private/test/celix_threads_test.cpp
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-/**
- * array_list_test.cpp
- *
- *  \date       Sep 15, 2015
- *  \author     <a href="mailto:d...@celix.apache.org";>Apache Celix Project 
Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-#include <stdio.h>
-#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"
-
-
-static char* my_strdup(const char* s) {
-    if (s == NULL) {
-        return NULL;
-    }
-
-    size_t len = strlen(s);
-
-    char *d = (char*) calloc(len + 1, sizeof(char));
-
-    if (d == NULL) {
-        return NULL;
-    }
-
-    strncpy(d, s, len);
-    return d;
-}
-
-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 __atomic_load_n(&thread1->thread, __ATOMIC_ACQUIRE) == 
__atomic_load_n(&thread2->thread, __ATOMIC_ACQUIRE) &&
-            __atomic_load_n(&thread1->threadInitialized, __ATOMIC_ACQUIRE) == 
__atomic_load_n(&thread2->threadInitialized, __ATOMIC_ACQUIRE);
-}
-
-static const 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", (unsigned 
long)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();
-static void * thread_test_func_lock(void *);
-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) {
-    MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
-    return RUN_ALL_TESTS(argc, argv);
-}
-
-//----------------------TESTGROUP DEFINES----------------------
-
-TEST_GROUP(celix_thread) {
-    celix_thread thread;
-
-    void setup() override {
-    }
-
-    void teardown() override {
-    }
-};
-
-TEST_GROUP(celix_thread_kill) {
-    celix_thread thread;
-    struct sigaction sigact, sigactold;
-
-    void setup() override {
-        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() override {
-        sigaction(SIGUSR1, &sigactold, &sigact);
-
-        mock_c()->removeAllComparatorsAndCopiers();
-    }
-};
-
-TEST_GROUP(celix_thread_mutex) {
-    celix_thread thread;
-    celix_thread_mutex_t mu;
-
-    void setup() override {
-    }
-
-    void teardown() override {
-    }
-};
-
-TEST_GROUP(celix_thread_condition) {
-    celix_thread thread;
-    celix_thread_mutex_t mu;
-    celix_thread_cond_t cond;
-
-    void setup() {
-    }
-
-    void teardown() {
-    }
-};
-
-TEST_GROUP(celix_thread_rwlock) {
-    celix_thread thread;
-
-    void setup() {
-    }
-
-    void teardown() {
-    }
-};
-
-//----------------------CELIX THREADS TESTS----------------------
-
-TEST(celix_thread, create) {
-    int ret;
-    char * test_str;
-
-    ret = celixThread_create(&thread, NULL, &thread_test_func_create,
-            &test_str);
-    LONGS_EQUAL(CELIX_SUCCESS, ret);
-    celixThread_join(thread, NULL);
-
-    CHECK(test_str != NULL);
-    STRCMP_EQUAL("SUCCESS", test_str);
-
-    free(test_str);
-}
-
-TEST(celix_thread, exit) {
-    int ret, *status;
-
-    ret = celixThread_create(&thread, NULL, &thread_test_func_exit, NULL);
-    LONGS_EQUAL(CELIX_SUCCESS, ret);
-    celixThread_join(thread, (void**) &status);
-    LONGS_EQUAL(666, *status);
-    free(status);
-}
-
-//HORRIBLE TEST
-TEST(celix_thread, detach) {
-    int ret;
-
-    celixThread_create(&thread, NULL, thread_test_func_detach, NULL);
-    ret = celixThread_detach(thread);
-    LONGS_EQUAL(CELIX_SUCCESS, ret);
-}
-
-TEST(celix_thread, self) {
-    celix_thread thread2;
-
-    celixThread_create(&thread, NULL, thread_test_func_self, &thread2);
-    celixThread_join(thread, NULL);
-    CHECK(celixThread_equals(thread, thread2));
-}
-
-TEST(celix_thread, initialized) {
-    CHECK(!celixThread_initialized(thread));
-    celixThread_create(&thread, NULL, thread_test_func_detach, NULL);
-    CHECK(celixThread_initialized(thread));
-    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) {
-    LONGS_EQUAL(CELIX_SUCCESS, celixThreadMutex_create(&mu, NULL));
-    LONGS_EQUAL(CELIX_SUCCESS, celixThreadMutex_destroy(&mu));
-}
-
-//check normal lock behaviour
-TEST(celix_thread_mutex, lock) {
-    struct func_param * params = (struct func_param*) calloc(1,
-            sizeof(struct func_param));
-
-    celixThreadMutex_create(&params->mu, NULL);
-
-    celixThreadMutex_lock(&params->mu);
-    celixThread_create(&thread, NULL, thread_test_func_lock, params);
-
-    sleep(2);
-
-    LONGS_EQUAL(0, params->i);
-
-    //possible race condition, not perfect test
-    celixThreadMutex_unlock(&params->mu);
-
-    sleep(2);
-
-    celixThreadMutex_lock(&params->mu2);
-    LONGS_EQUAL(666, params->i);
-    celixThreadMutex_unlock(&params->mu2);
-    celixThread_join(thread, NULL);
-    free(params);
-}
-
-TEST(celix_thread_mutex, attrCreate) {
-    celix_thread_mutexattr_t mu_attr;
-    LONGS_EQUAL(CELIX_SUCCESS, celixThreadMutexAttr_create(&mu_attr));
-    LONGS_EQUAL(CELIX_SUCCESS, celixThreadMutexAttr_destroy(&mu_attr));
-}
-
-TEST(celix_thread_mutex, attrSettype) {
-    celix_thread_mutex_t mu;
-    celix_thread_mutexattr_t mu_attr;
-    celixThreadMutexAttr_create(&mu_attr);
-
-    //test recursive mutex
-    celixThreadMutexAttr_settype(&mu_attr, CELIX_THREAD_MUTEX_RECURSIVE);
-    celixThreadMutex_create(&mu, &mu_attr);
-    //if program doesnt deadlock: success! also check factorial of 10, for 
reasons unknown
-    LONGS_EQUAL(3628800, thread_test_func_recur_lock(&mu, 10));
-    celixThreadMutex_destroy(&mu);
-
-    //test deadlock check mutex
-    celixThreadMutexAttr_settype(&mu_attr, CELIX_THREAD_MUTEX_ERRORCHECK);
-    celixThreadMutex_create(&mu, &mu_attr);
-    //get deadlock error
-    celixThreadMutex_lock(&mu);
-    CHECK(celixThreadMutex_lock(&mu) != CELIX_SUCCESS);
-    //do not get deadlock error
-    celixThreadMutex_unlock(&mu);
-    LONGS_EQUAL(CELIX_SUCCESS, celixThreadMutex_lock(&mu));
-    //get unlock error
-    celixThreadMutex_unlock(&mu);
-    CHECK(celixThreadMutex_unlock(&mu) != CELIX_SUCCESS);
-
-    celixThreadMutex_destroy(&mu);
-    celixThreadMutexAttr_destroy(&mu_attr);
-}
-
-//----------------------CELIX THREAD CONDITIONS TESTS----------------------
-
-TEST(celix_thread_condition, init) {
-    LONGS_EQUAL(CELIX_SUCCESS, celixThreadCondition_init(&cond, NULL));
-    LONGS_EQUAL(CELIX_SUCCESS, celixThreadCondition_destroy(&cond));
-}
-
-//test wait and signal
-TEST(celix_thread_condition, wait) {
-    struct func_param * param = (struct func_param*) calloc(1,
-            sizeof(struct func_param));
-    celixThreadMutex_create(&param->mu, NULL);
-    celixThreadCondition_init(&param->cond, NULL);
-
-    celixThreadMutex_lock(&param->mu);
-
-    sleep(2);
-
-    celixThread_create(&thread, NULL, thread_test_func_cond_wait, param);
-    LONGS_EQUAL(0, param->i);
-
-    celixThreadCondition_wait(&param->cond, &param->mu);
-    LONGS_EQUAL(666, param->i);
-    celixThreadMutex_unlock(&param->mu);
-
-    celixThread_join(thread, NULL);
-    free(param);
-}
-
-//test wait and broadcast on multiple threads
-TEST(celix_thread_condition, broadcast) {
-    celix_thread_t thread2;
-    struct func_param * param = (struct func_param*) calloc(1,sizeof(struct 
func_param));
-    celixThreadMutex_create(&param->mu, NULL);
-    celixThreadMutex_create(&param->mu2, NULL);
-    celixThreadCondition_init(&param->cond, NULL);
-
-    celixThread_create(&thread, NULL, thread_test_func_cond_broadcast, param);
-    celixThread_create(&thread2, NULL, thread_test_func_cond_broadcast, param);
-
-    sleep(1);
-    celixThreadMutex_lock(&param->mu);
-    LONGS_EQUAL(0, param->i);
-    celixThreadMutex_unlock(&param->mu);
-
-    celixThreadMutex_lock(&param->mu);
-    celixThreadCondition_broadcast(&param->cond);
-    celixThreadMutex_unlock(&param->mu);
-    sleep(1);
-    celixThreadMutex_lock(&param->mu);
-    LONGS_EQUAL(2, param->i);
-    celixThreadMutex_unlock(&param->mu);
-
-    celixThread_join(thread, NULL);
-    celixThread_join(thread2, NULL);
-    free(param);
-}
-
-//----------------------CELIX READ-WRITE LOCK TESTS----------------------
-
-TEST(celix_thread_rwlock, create){
-    celix_thread_rwlock_t alock;
-    celix_status_t status;
-    status = celixThreadRwlock_create(&alock, NULL);
-    if (status != CELIX_SUCCESS) {
-        fprintf(stderr, "Found error '%s'\n", strerror(status));
-    }
-    LONGS_EQUAL(CELIX_SUCCESS, status);
-    status = celixThreadRwlock_destroy(&alock);
-    LONGS_EQUAL(CELIX_SUCCESS, status);
-}
-
-TEST(celix_thread_rwlock, readLock){
-    int status;
-    celix_thread_rwlock_t lock;
-    memset(&lock, 0x00, sizeof(celix_thread_rwlock_t));
-    //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");
-
-    return NULL;
-}
-
-static void * thread_test_func_exit(void *) {
-    int *pi = (int*) calloc(1, sizeof(int));
-    *pi = 666;
-
-    celixThread_exit(pi);
-    return NULL;
-}
-
-static void * thread_test_func_detach(void *) {
-    return NULL;
-}
-
-static void * thread_test_func_self(void * arg) {
-    *((celix_thread*) arg) = celixThread_self();
-    return NULL;
-}
-
-static void * thread_test_func_once(void * arg) {
-    struct func_param *param = (struct func_param *) arg;
-    celixThread_once(&param->once_control, thread_test_func_once_init);
-
-    return NULL;
-}
-
-static void thread_test_func_once_init() {
-    mock_c()->actualCall("thread_test_func_once_init");
-}
-
-static void * thread_test_func_lock(void *arg) {
-    struct func_param *param = (struct func_param *) arg;
-
-    celixThreadMutex_lock(&param->mu2);
-    celixThreadMutex_lock(&param->mu);
-    param->i = 666;
-    celixThreadMutex_unlock(&param->mu);
-    celixThreadMutex_unlock(&param->mu2);
-
-    return NULL;
-}
-
-static void * thread_test_func_cond_wait(void *arg) {
-    struct func_param *param = (struct func_param *) arg;
-
-    celixThreadMutex_lock(&param->mu);
-
-    param->i = 666;
-
-    celixThreadCondition_signal(&param->cond);
-    celixThreadMutex_unlock(&param->mu);
-    return NULL;
-}
-
-static void * thread_test_func_cond_broadcast(void *arg) {
-    struct func_param *param = (struct func_param *) arg;
-
-    celixThreadMutex_lock(&param->mu);
-    celixThreadCondition_wait(&param->cond, &param->mu);
-    celixThreadMutex_unlock(&param->mu);
-    celixThreadMutex_lock(&param->mu);
-    param->i++;
-    celixThreadMutex_unlock(&param->mu);
-    return NULL;
-}
-
-static int thread_test_func_recur_lock(celix_thread_mutex_t *mu, int i) {
-    int temp;
-    if (i == 1) {
-        return 1;
-    } else {
-        celixThreadMutex_lock(mu);
-        temp = thread_test_func_recur_lock(mu, i - 1);
-        temp *= i;
-        celixThreadMutex_unlock(mu);
-        return temp;
-    }
-}
-
-static void * thread_test_func_kill(void __attribute__((unused)) *arg){
-    int * ret = (int*) malloc(sizeof(*ret));
-    //sleep for a about a minute, or until a kill signal (USR1) is received
-    *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);
-}
-}

Reply via email to