Add tests for `try_catch` and `try_catch_enclosure` 93/258693/5
authorMichał Szaknis <m.szaknis@samsung.com>
Fri, 21 May 2021 14:17:20 +0000 (16:17 +0200)
committerMichał Szaknis <m.szaknis@samsung.com>
Tue, 25 May 2021 10:42:13 +0000 (12:42 +0200)
Change-Id: If74b22ad53961a32c75d3d7feae48f2a41d09508

unit-tests/test_client-common.cpp

index 9c306bf..34a60fb 100644 (file)
  */
 
 #include <boost_macros_wrapper.h>
+#include <cxxabi.h>
+#include <pthread.h>
+#include <stdexcept>
 #include <string>
+#include <thread>
+#include <type_traits>
+#include "ckm/ckm-error.h"
 #include "client-common.h"
+#include "message-buffer.h"
 
 namespace {
 const std::string OWNER_ID = "some_id";
 const std::string NAME = "some_name";
 
 const std::string EMPTY_OWNER_ID = "";
+
+const auto throw_forced_unwind = [] {
+    pthread_exit(NULL);
+    return 0;
+};
+
+static_assert(
+    std::is_same_v<decltype(CKM::try_catch), decltype(CKM::try_catch_enclosure)>,
+    "`try_catch` and `try_catch_enclosure declarations doesn't match."
+);
+using ConvertingFunction = decltype(CKM::try_catch);
+
+void test_forced_unwind_throw(ConvertingFunction func) {
+    // I used this custom try-catch insted of BOOST_CHECK_THROW,
+    // beacuse the abi::__forced_unwind exception needs to be rethrown
+    // for thread cancellation not to occur.
+
+    bool __forced_unwind_thrown = false;
+    std::thread([func, &__forced_unwind_thrown] {
+        try {
+            func(throw_forced_unwind);
+        } catch (const abi::__forced_unwind& ) {
+            __forced_unwind_thrown = true;
+            throw;
+        }
+    }).join();
+
+    BOOST_REQUIRE(__forced_unwind_thrown);
+}
 }
 
 BOOST_AUTO_TEST_SUITE(CLIENT_COMMON)
@@ -51,4 +87,45 @@ NEGATIVE_TEST_CASE(AliasTest) {
     BOOST_REQUIRE(empty_alias_support.getOwner() == "");
 }
 
+POSITIVE_TEST_CASE(try_catch_test) {
+    const auto throw_message_buffer_base_exception = [] {
+        throw CKM::MessageBuffer::Exception::Base("", "", 0);
+        return 0;
+    };
+    const auto throw_runtime_error = [] {
+        throw std::runtime_error("");
+        return 0;
+    };
+    const auto throw_unknown_exception = [] {
+        struct {} annonymous;
+        throw annonymous;
+        return 0;
+    };
+    const auto throw_bad_alloc = [] { throw std::bad_alloc(); return 0; };
+    const auto throw_msgbuffer_exception = [] {
+        throw CKM::MessageBuffer::Exception();
+        return 0;
+    };
+    const auto no_throw = [] { return 0; };
+
+    BOOST_REQUIRE(CKM::try_catch(throw_message_buffer_base_exception) == CKM_API_ERROR_UNKNOWN);
+    BOOST_REQUIRE(CKM::try_catch(throw_runtime_error) == CKM_API_ERROR_UNKNOWN);
+    BOOST_REQUIRE(CKM::try_catch(throw_unknown_exception) == CKM_API_ERROR_UNKNOWN);
+    BOOST_REQUIRE(CKM::try_catch(throw_msgbuffer_exception) == CKM_API_ERROR_UNKNOWN);
+    BOOST_REQUIRE(CKM::try_catch(no_throw) == CKM_API_SUCCESS);
+    test_forced_unwind_throw(&CKM::try_catch);
+
+    BOOST_REQUIRE(CKM::try_catch_enclosure(throw_bad_alloc) == CKMC_ERROR_OUT_OF_MEMORY);
+    BOOST_REQUIRE(CKM::try_catch_enclosure(throw_runtime_error) == CKMC_ERROR_UNKNOWN);
+    BOOST_REQUIRE(CKM::try_catch_enclosure(throw_unknown_exception) == CKMC_ERROR_UNKNOWN);
+    BOOST_REQUIRE(CKM::try_catch_enclosure(no_throw) == CKM_API_SUCCESS);
+    test_forced_unwind_throw(&CKM::try_catch_enclosure);
+
+}
+
+NEGATIVE_TEST_CASE(try_catch_test) {
+    BOOST_REQUIRE(CKM::try_catch(nullptr) == CKM_API_ERROR_UNKNOWN);
+    BOOST_REQUIRE(CKM::try_catch_enclosure(nullptr) == CKMC_ERROR_UNKNOWN);
+}
+
 BOOST_AUTO_TEST_SUITE_END()