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

pnoltes pushed a commit to branch feature/print-celix-err-after-bnd-start
in repository https://gitbox.apache.org/repos/asf/celix.git

commit 621741b8c476eaaa8a60f6d1ac6e8d7793f81fc7
Author: Pepijn Noltes <[email protected]>
AuthorDate: Sun Dec 3 16:44:02 2023 +0100

    Add celix err message print in fw after each bundle start
---
 libs/framework/gtest/CMakeLists.txt                |  3 ++
 .../framework/gtest/src/CelixFrameworkTestSuite.cc | 18 ++++++++++
 .../framework/gtest/src/activator_with_celix_err.c | 40 ++++++++++++++++++++++
 libs/framework/src/framework.c                     | 19 +++++++++-
 4 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/libs/framework/gtest/CMakeLists.txt 
b/libs/framework/gtest/CMakeLists.txt
index e6697b94..f2b836c6 100644
--- a/libs/framework/gtest/CMakeLists.txt
+++ b/libs/framework/gtest/CMakeLists.txt
@@ -31,6 +31,7 @@ add_celix_bundle(simple_cxx_dep_man_bundle SOURCES 
src/HelloWorldCxxActivatorWit
 add_celix_bundle(cmp_test_bundle SOURCES src/CmpTestBundleActivator.cc VERSION 
1.0.0)
 add_celix_bundle(cond_test_bundle SOURCES src/CondTestBundleActivator.cc 
VERSION 1.0.0)
 add_subdirectory(subdir) #simple_test_bundle4, simple_test_bundle5 and sublib
+add_celix_bundle(celix_err_test_bundle SOURCES src/activator_with_celix_err.c 
VERSION 1.0.0)
 
 add_celix_bundle(unresolvable_bundle SOURCES src/nop_activator.c VERSION 1.0.0)
 if (CMAKE_BUILD_TYPE STREQUAL "Debug")
@@ -107,6 +108,8 @@ configure_file(framework1.properties.in 
framework1.properties @ONLY)
 configure_file(framework2.properties.in framework2.properties @ONLY)
 configure_file(install_and_start_bundles.properties.in 
install_and_start_bundles.properties @ONLY)
 
+celix_target_bundle_set_definition(test_framework NAME CELIX_ERR_TEST_BUNDLE 
celix_err_test_bundle)
+
 target_compile_definitions(test_framework PRIVATE
         SIMPLE_TEST_BUNDLE1_LOCATION="${SIMPLE_TEST_BUNDLE1}"
         SIMPLE_TEST_BUNDLE2_LOCATION="${SIMPLE_TEST_BUNDLE2}"
diff --git a/libs/framework/gtest/src/CelixFrameworkTestSuite.cc 
b/libs/framework/gtest/src/CelixFrameworkTestSuite.cc
index 6a695181..ea3920ec 100644
--- a/libs/framework/gtest/src/CelixFrameworkTestSuite.cc
+++ b/libs/framework/gtest/src/CelixFrameworkTestSuite.cc
@@ -351,3 +351,21 @@ TEST_F(FrameworkFactoryTestSuite, 
LaunchFrameworkWithConfigTest) {
     framework_waitForStop(fw);
     framework_destroy(fw);
 }
+
+TEST_F(FrameworkFactoryTestSuite, BundleWithErrMessageTest) {
+    // Given a framework
+    auto* fw = celix_frameworkFactory_createFramework(nullptr);
+    ASSERT_TRUE(fw != nullptr);
+
+    // When installing a bundle with an activator that pushes an error message 
to celix err and returns an error
+    // during stop if there is still a message in the celix err queue.
+    long bndId = celix_framework_installBundle(fw, CELIX_ERR_TEST_BUNDLE, 
true);
+
+    // Then the bundle installs
+    EXPECT_GT(bndId, CELIX_FRAMEWORK_BUNDLE_ID);
+
+    // And the bundle stops without an error return code, because the celix 
err message count is 0 -> error is printed
+    // by the framework
+    bool stopped = celix_framework_stopBundle(fw, bndId);
+    EXPECT_TRUE(stopped);
+}
diff --git a/libs/framework/gtest/src/activator_with_celix_err.c 
b/libs/framework/gtest/src/activator_with_celix_err.c
new file mode 100644
index 00000000..210cb46a
--- /dev/null
+++ b/libs/framework/gtest/src/activator_with_celix_err.c
@@ -0,0 +1,40 @@
+/*
+ * 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 "celix_bundle_activator.h"
+#include "celix_compiler.h"
+#include "celix_err.h"
+
+typedef struct bundle_activator {
+    //empty
+} bundle_activator_t;
+
+static celix_status_t act_start(bundle_activator_t *act CELIX_UNUSED, 
celix_bundle_context_t *ctx CELIX_UNUSED) {
+    //reset and create a celix err message for testing purposes
+    celix_err_resetErrors();
+    celix_err_push("Test error");
+    return celix_err_getErrorCount() == 1 ? CELIX_SUCCESS : 
CELIX_BUNDLE_EXCEPTION;
+}
+
+static celix_status_t act_stop(bundle_activator_t *act CELIX_UNUSED, 
celix_bundle_context_t *ctx CELIX_UNUSED) {
+    //test whether the error is cleared (because the framework printed the 
error after bundle start)
+    return celix_err_getErrorCount() == 0 ? CELIX_SUCCESS : 
CELIX_BUNDLE_EXCEPTION;
+}
+
+CELIX_GEN_BUNDLE_ACTIVATOR(bundle_activator_t, act_start, act_stop);
diff --git a/libs/framework/src/framework.c b/libs/framework/src/framework.c
index 2cfdf979..30c9e98c 100644
--- a/libs/framework/src/framework.c
+++ b/libs/framework/src/framework.c
@@ -43,10 +43,10 @@
 #include "bundle_context_private.h"
 #include "bundle_private.h"
 #include "framework_private.h"
-#include "linked_list_iterator.h"
 #include "service_reference_private.h"
 #include "service_registration_private.h"
 #include "celix_scheduled_event.h"
+#include "celix_err.h"
 #include "utils.h"
 
 struct celix_bundle_activator {
@@ -2189,6 +2189,22 @@ void celix_framework_startBundleAsync(celix_framework_t 
*fw, long bndId) {
     celix_framework_startBundleInternal(fw, bndId, true);
 }
 
+static void celix_framework_printCelixErrForBundleEntry(celix_framework_t* 
framework,
+                                                        
celix_framework_bundle_entry_t* bndEntry) {
+    if (celix_err_getErrorCount() > 0) {
+        celix_framework_log(framework->logger, CELIX_LOG_LEVEL_WARNING, NULL, 
NULL, 0,
+               "Found unprocessed celix err messages for bundle %s 
[bndId=%li]. Unprocessed celix err messages:",
+               celix_bundle_getSymbolicName(bndEntry->bnd),
+               bndEntry->bndId);
+        int count = 1;
+        while (celix_err_getErrorCount() > 0) {
+            const char* msg = celix_err_popLastError();
+            celix_framework_log(framework->logger, CELIX_LOG_LEVEL_ERROR, 
NULL, NULL, 0,
+                                "Message nr %i: %s", count++, msg);
+        }
+    }
+}
+
 celix_status_t celix_framework_startBundleEntry(celix_framework_t* framework, 
celix_framework_bundle_entry_t* bndEntry) {
     assert(!celix_framework_isCurrentThreadTheEventLoop(framework));
     celix_status_t status = CELIX_SUCCESS;
@@ -2272,6 +2288,7 @@ celix_status_t 
celix_framework_startBundleEntry(celix_framework_t* framework, ce
                         if (activator->start != NULL) {
                             status = CELIX_DO_IF(status, 
activator->start(userData, context));
                         }
+                        celix_framework_printCelixErrForBundleEntry(framework, 
bndEntry);
                     }
 
                     status = CELIX_DO_IF(status, 
bundle_setState(bndEntry->bnd, CELIX_BUNDLE_STATE_ACTIVE));

Reply via email to