From 66ab9bc651f04894a27f6fc083d74b101ddce950 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Wed, 5 Jun 2024 11:14:28 +0800 Subject: [PATCH 1/2] Resolve issue 749 --- .../event_admin/gtest/src/CelixEventAdminTestSuite.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bundles/event_admin/event_admin/gtest/src/CelixEventAdminTestSuite.cc b/bundles/event_admin/event_admin/gtest/src/CelixEventAdminTestSuite.cc index eb4d45af8..5bc39a039 100644 --- a/bundles/event_admin/event_admin/gtest/src/CelixEventAdminTestSuite.cc +++ b/bundles/event_admin/event_admin/gtest/src/CelixEventAdminTestSuite.cc @@ -606,21 +606,26 @@ TEST_F(CelixEventAdminTestSuite, PostEventWithInvalidArgumentsTest) { } static bool g_blockingHandlerCalled = false; +static bool g_handlingEvent = false; TEST_F(CelixEventAdminTestSuite, AsyncEventQueueFullTest) { g_blockingHandlerCalled = true; + g_handlingEvent = false; TestPublishEvent("org/celix/test", nullptr, [](celix_event_admin_t *ea) { - for (int i = 0; i < 512 + 1/*handling event*/; ++i) { + for (int i = 0; i < 512; ++i) { auto status = celix_eventAdmin_postEvent(ea, "org/celix/test", nullptr); EXPECT_EQ(CELIX_SUCCESS, status); } - usleep(30000); + while (!g_handlingEvent) usleep(1000); auto status = celix_eventAdmin_postEvent(ea, "org/celix/test", nullptr); + EXPECT_EQ(CELIX_SUCCESS, status); + status = celix_eventAdmin_postEvent(ea, "org/celix/test", nullptr); EXPECT_EQ(CELIX_ILLEGAL_STATE, status); g_blockingHandlerCalled = false; }, [](void *handle, const char *topic, const celix_properties_t *props) { (void)handle; (void)props; (void)topic; + g_handlingEvent = true; while (g_blockingHandlerCalled) usleep(1000); return CELIX_SUCCESS; }); From 21172764c6599cfb683713056ae28ee39dfc80be Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Fri, 7 Jun 2024 21:12:54 +0800 Subject: [PATCH 2/2] Use feature/promise to synchronize thread in unit test --- .../gtest/src/CelixEventAdminTestSuite.cc | 40 ++++++++++++------- .../src/CelixEventAdminTestSuiteBaseClass.h | 17 +++++--- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/bundles/event_admin/event_admin/gtest/src/CelixEventAdminTestSuite.cc b/bundles/event_admin/event_admin/gtest/src/CelixEventAdminTestSuite.cc index 5bc39a039..e05cc19df 100644 --- a/bundles/event_admin/event_admin/gtest/src/CelixEventAdminTestSuite.cc +++ b/bundles/event_admin/event_admin/gtest/src/CelixEventAdminTestSuite.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "CelixEventAdminTestSuiteBaseClass.h" @@ -605,41 +606,50 @@ TEST_F(CelixEventAdminTestSuite, PostEventWithInvalidArgumentsTest) { }); } -static bool g_blockingHandlerCalled = false; -static bool g_handlingEvent = false; TEST_F(CelixEventAdminTestSuite, AsyncEventQueueFullTest) { - g_blockingHandlerCalled = true; - g_handlingEvent = false; - TestPublishEvent("org/celix/test", nullptr, [](celix_event_admin_t *ea) { + std::promise promise1; + auto future1 = promise1.get_future(); + std::promise promise2; + auto future2 = promise2.get_future(); + TestPublishEvent("org/celix/test", nullptr, [&promise2, &future1](celix_event_admin_t *ea) { for (int i = 0; i < 512; ++i) { auto status = celix_eventAdmin_postEvent(ea, "org/celix/test", nullptr); EXPECT_EQ(CELIX_SUCCESS, status); } - while (!g_handlingEvent) usleep(1000); + future1.get(); auto status = celix_eventAdmin_postEvent(ea, "org/celix/test", nullptr); EXPECT_EQ(CELIX_SUCCESS, status); status = celix_eventAdmin_postEvent(ea, "org/celix/test", nullptr); EXPECT_EQ(CELIX_ILLEGAL_STATE, status); - g_blockingHandlerCalled = false; - }, [](void *handle, const char *topic, const celix_properties_t *props) { + promise2.set_value(); + }, [&promise1, &future2](void *handle, const char *topic, const celix_properties_t *props) { (void)handle; (void)props; (void)topic; - g_handlingEvent = true; - while (g_blockingHandlerCalled) usleep(1000); + static bool firstCalled{true}; + if (firstCalled) { + promise1.set_value(); + future2.get(); + firstCalled = false; + } return CELIX_SUCCESS; }); } TEST_F(CelixEventAdminTestSuite, RemoveEventHandlerAfterEventAdminStopTest) { - g_blockingHandlerCalled = true; + std::promise promise; + auto future = promise.get_future(); celix_event_handler_service_t handler; - handler.handle = nullptr; + handler.handle = &future; handler.handleEvent = [](void *handle, const char *topic, const celix_properties_t *props) { - (void)handle; + auto feature = static_cast*>(handle); (void)topic; (void)props; - while (g_blockingHandlerCalled) usleep(1000); + static bool firstCalled{true}; + if (firstCalled) { + feature->get(); + firstCalled = false; + } return CELIX_SUCCESS; }; auto props = celix_properties_create(); @@ -674,7 +684,7 @@ TEST_F(CelixEventAdminTestSuite, RemoveEventHandlerAfterEventAdminStopTest) { EXPECT_EQ(CELIX_SUCCESS, status); } - g_blockingHandlerCalled = false; + promise.set_value(); status = celix_eventAdmin_stop(ea); EXPECT_EQ(CELIX_SUCCESS, status); diff --git a/bundles/event_admin/event_admin/gtest/src/CelixEventAdminTestSuiteBaseClass.h b/bundles/event_admin/event_admin/gtest/src/CelixEventAdminTestSuiteBaseClass.h index de0ad6092..7da83485e 100644 --- a/bundles/event_admin/event_admin/gtest/src/CelixEventAdminTestSuiteBaseClass.h +++ b/bundles/event_admin/event_admin/gtest/src/CelixEventAdminTestSuiteBaseClass.h @@ -20,6 +20,7 @@ #ifndef CELIX_CELIX_EVENT_ADMIN_TEST_SUITE_BASE_CLASS_H #define CELIX_CELIX_EVENT_ADMIN_TEST_SUITE_BASE_CLASS_H +#include #include "celix_event_admin.h" #include "celix_event_handler_service.h" @@ -137,16 +138,22 @@ class CelixEventAdminTestSuiteBaseClass : public ::testing::Test { celix_eventAdmin_destroy(ea); } - void TestPublishEvent(const char *handlerTopics, const char *eventFilter, void (*testBody)(celix_event_admin_t *ea), - celix_status_t (*onHandleEvent)(void *handle, const char *topic, const celix_properties_t *props), bool asyncUnordered = false) { + void TestPublishEvent(const char *handlerTopics, const char *eventFilter, std::function testBody, + std::function onHandleEvent, bool asyncUnordered = false) { auto ea = celix_eventAdmin_create(ctx.get()); EXPECT_TRUE(ea != nullptr); auto status = celix_eventAdmin_start(ea); EXPECT_EQ(CELIX_SUCCESS, status); - + struct celix_handle_event_callback_data { + std::function onHandleEvent; + void* handle; + } data{onHandleEvent, ea}; celix_event_handler_service_t handler; - handler.handle = ea; - handler.handleEvent = onHandleEvent; + handler.handle = &data; + handler.handleEvent = [](void *handle, const char *topic, const celix_properties_t *props) { + auto data = static_cast(handle); + return data->onHandleEvent(data->handle, topic, props); + }; auto props = celix_properties_create(); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_VERSION, CELIX_EVENT_HANDLER_SERVICE_VERSION); celix_properties_set(props, CELIX_EVENT_TOPIC, handlerTopics);