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

pengzheng pushed a commit to branch feature/556-osgi-uninstall
in repository https://gitbox.apache.org/repos/asf/celix.git

commit 26fffc9412622e6a38987f2346ae9671a0b562c4
Author: PengZheng <[email protected]>
AuthorDate: Sat May 27 21:11:09 2023 +0800

    Add tests for normal bundle archive creation failures.
---
 libs/framework/gtest/CMakeLists.txt                |   1 +
 .../BundleArchiveWithErrorInjectionTestSuite.cc    | 110 +++++++++++++++------
 .../src/CelixBundleCacheErrorInjectionTestSuite.cc |   4 +-
 libs/framework/src/bundle_archive.c                |  47 +++++----
 4 files changed, 111 insertions(+), 51 deletions(-)

diff --git a/libs/framework/gtest/CMakeLists.txt 
b/libs/framework/gtest/CMakeLists.txt
index 3cc35fb5..7828126b 100644
--- a/libs/framework/gtest/CMakeLists.txt
+++ b/libs/framework/gtest/CMakeLists.txt
@@ -146,6 +146,7 @@ if (LINKER_WRAP_SUPPORTED)
             Celix::dlfcn_ei
             Celix::unistd_ei
             Celix::hash_map_ei
+            Celix::properties_ei
             GTest::gtest GTest::gtest_main
     )
 
diff --git 
a/libs/framework/gtest/src/BundleArchiveWithErrorInjectionTestSuite.cc 
b/libs/framework/gtest/src/BundleArchiveWithErrorInjectionTestSuite.cc
index 98ffcbe8..bd8e71a9 100644
--- a/libs/framework/gtest/src/BundleArchiveWithErrorInjectionTestSuite.cc
+++ b/libs/framework/gtest/src/BundleArchiveWithErrorInjectionTestSuite.cc
@@ -18,24 +18,27 @@
  */
 
 #include <gtest/gtest.h>
-#include "bundle_archive_private.h"
-#include "celix/FrameworkFactory.h"
+
 #include "celix_constants.h"
+#include "celix_file_utils.h"
 #include "celix_framework_utils.h"
-#include "malloc_ei.h"
+#include "celix_log.h"
+#include "celix_properties_ei.h"
 #include "celix_utils_ei.h"
-#include "asprintf_ei.h"
 
-//extern declarations for testing purposes. Note signatures are not correct, 
but that is not important for the test.
-extern "C" celix_status_t celix_bundleRevision_create(void);
+#include "celix/FrameworkFactory.h"
+
+#include "asprintf_ei.h"
+#include "bundle_archive_private.h"
+#include "bundle_revision_private.h"
+#include "framework_private.h"
+#include "malloc_ei.h"
 
 class BundleArchiveWithErrorInjectionTestSuite : public ::testing::Test {
-public:
+  public:
     BundleArchiveWithErrorInjectionTestSuite() {
-        fw = celix::createFramework({
-             {"CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL", "trace"},
-             {CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE, "true"}
-        });
+        fw = celix::createFramework(
+            {{"CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL", "trace"}, 
{CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE, "true"}});
         ctx = fw->getFrameworkBundleContext();
     }
 
@@ -46,6 +49,7 @@ public:
     }
 
     void teardownErrorInjectors() {
+        celix_ei_expect_celix_properties_create(nullptr, 0, nullptr);
         celix_ei_expect_asprintf(nullptr, 0, 0);
         celix_ei_expect_calloc(nullptr, 0, nullptr);
         celix_ei_expect_malloc(nullptr, 0, nullptr);
@@ -58,41 +62,47 @@ public:
     }
 
     void installBundleAndExpectFailure() {
-        //When I create bundle from a bundle zip by installing a bundle
-        //Then the bundle install fails, and the bundle id is < 0
+        // When I create bundle from a bundle zip by installing a bundle
+        // Then the bundle install fails, and the bundle id is < 0
         long bndId = ctx->installBundle(SIMPLE_TEST_BUNDLE1_LOCATION);
         EXPECT_LT(bndId, 0);
     }
 
-protected:
+  protected:
     std::shared_ptr<celix::Framework> fw{};
     std::shared_ptr<celix::BundleContext> ctx{};
 };
 
-
 TEST_F(BundleArchiveWithErrorInjectionTestSuite, 
BundleArchiveCreatedFailedTest) {
     teardownErrorInjectors();
-    //Given a mocked calloc which returns NULL from a (indirect) call from 
bundleArchive_create
+    // Given a mocked calloc which returns NULL from a (indirect) call from 
bundleArchive_create
     celix_ei_expect_calloc((void*)celix_bundleArchive_create, 0, nullptr);
     installBundleAndExpectFailure();
 
     teardownErrorInjectors();
-    //Given a mocked celix_utils_strdup which returns NULL from a (indirect) 
call from bundleArchive_create
     celix_ei_expect_celix_utils_strdup((void*)celix_bundleArchive_create, 0, 
nullptr);
     installBundleAndExpectFailure();
 
     teardownErrorInjectors();
-    //Given a mocked malloc which returns NULL from a call from manifest_create
+    celix_ei_expect_celix_utils_strdup((void*)celix_bundleArchive_create, 0, 
nullptr, 2);
+    installBundleAndExpectFailure();
+
+    teardownErrorInjectors();
+    celix_ei_expect_asprintf((void*)celix_bundleArchive_create, 0, -1);
+    installBundleAndExpectFailure();
+
+    teardownErrorInjectors();
+    // Given a mocked malloc which returns NULL from a call from 
manifest_create
     celix_ei_expect_malloc((void*)manifest_create, 0, nullptr);
     installBundleAndExpectFailure();
 
     teardownErrorInjectors();
-    //Given a mocked calloc which returns NULL from a call from 
bundleRevision_create
+    // Given a mocked calloc which returns NULL from a call from 
bundleRevision_create
     celix_ei_expect_calloc((void*)celix_bundleRevision_create, 0, nullptr);
     installBundleAndExpectFailure();
 
     teardownErrorInjectors();
-    //Given a mocked celix_utils_strdup which returns NULL from a call from 
bundleRevision_create
+    // Given a mocked celix_utils_strdup which returns NULL from a call from 
bundleRevision_create
     celix_ei_expect_celix_utils_strdup((void*)celix_bundleRevision_create, 0, 
nullptr);
     installBundleAndExpectFailure();
 
@@ -102,40 +112,80 @@ TEST_F(BundleArchiveWithErrorInjectionTestSuite, 
BundleArchiveCreatedFailedTest)
 
 TEST_F(BundleArchiveWithErrorInjectionTestSuite, 
BundleArchiveCreateCacheDirectoryFailedTest) {
     teardownErrorInjectors();
-    //Given a mocked celix_utils_createDirectory which returns 
CELIX_FILE_IO_EXCEPTION from a (indirect) call from
-    //bundleArchive_create
+    // Given a mocked celix_utils_createDirectory which returns 
CELIX_FILE_IO_EXCEPTION from a (indirect) call from
+    // bundleArchive_create
     
celix_ei_expect_celix_utils_createDirectory((void*)celix_bundleArchive_create, 
1, CELIX_FILE_IO_EXCEPTION);
     installBundleAndExpectFailure();
 
     teardownErrorInjectors();
-    //Given a mocked asprintf which returns -1 from a (indirect) call from 
bundleArchive_create
+    // Given a mocked asprintf which returns -1 from a (indirect) call from 
bundleArchive_create
     celix_ei_expect_asprintf((void*)celix_bundleArchive_create, 1, -1);
     installBundleAndExpectFailure();
 
     teardownErrorInjectors();
-    //Given a mocked celix_utils_createDirectory which returns 
CELIX_FILE_IO_EXCEPTION from a second (indirect) call
-    // from bundleArchive_create
+    // Given a mocked celix_utils_createDirectory which returns 
CELIX_FILE_IO_EXCEPTION from a second (indirect) call
+    //  from bundleArchive_create
     
celix_ei_expect_celix_utils_createDirectory((void*)celix_bundleArchive_create, 
1, CELIX_FILE_IO_EXCEPTION, 2);
     installBundleAndExpectFailure();
 
     teardownErrorInjectors();
-    //Given a mocked asprintf which returns -1 from a (indirect) call from 
bundleArchive_create
+    // Given a mocked asprintf which returns -1 from a (indirect) call from 
bundleArchive_create
     celix_ei_expect_asprintf((void*)celix_bundleArchive_create, 1, -1, 2);
     installBundleAndExpectFailure();
 
     teardownErrorInjectors();
-    //Given a mocked celix_utils_createDirectory which returns 
CELIX_FILE_IO_EXCEPTION from a third (indirect) call
-    // from bundleArchive_create
+    // Given a mocked celix_utils_createDirectory which returns 
CELIX_FILE_IO_EXCEPTION from a third (indirect) call
+    //  from bundleArchive_create
     
celix_ei_expect_celix_utils_createDirectory((void*)celix_bundleArchive_create, 
1, CELIX_FILE_IO_EXCEPTION, 3);
     installBundleAndExpectFailure();
 
     teardownErrorInjectors();
-    //Given a mocked celix_utils_strdup which returns NULL from a (indirect) 
call from bundleArchive_create
+    // Given a mocked celix_utils_strdup which returns NULL from a (indirect) 
call from bundleArchive_create
     celix_ei_expect_celix_utils_strdup((void*)celix_bundleArchive_create, 1, 
nullptr);
     installBundleAndExpectFailure();
 
     teardownErrorInjectors();
-    //Given a mocked celix_utils_strdup which returns NULL from a second 
(indirect) call from bundleArchive_create
+    // Given a mocked celix_utils_strdup which returns NULL from a second 
(indirect) call from bundleArchive_create
     celix_ei_expect_celix_utils_strdup((void*)celix_bundleArchive_create, 1, 
nullptr, 2);
     installBundleAndExpectFailure();
 }
+
+constexpr const char* const TEST_ARCHIVE_ROOT = ".test_archive_root";
+
+class CelixBundleArchiveErrorInjectionTestSuite : public ::testing::Test {
+  public:
+    CelixBundleArchiveErrorInjectionTestSuite() {
+        fw.configurationMap = celix_properties_create();
+        fw.logger = celix_frameworkLogger_create(CELIX_LOG_LEVEL_TRACE);
+    }
+    ~CelixBundleArchiveErrorInjectionTestSuite() override {
+        celix_frameworkLogger_destroy(fw.logger);
+        celix_properties_destroy(fw.configurationMap);
+    }
+    void createCache(celix_bundle_cache_t** cache) {
+        celix_properties_setBool(fw.configurationMap, 
CELIX_FRAMEWORK_CACHE_USE_TMP_DIR, true);
+        EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_create(&fw, &fw.cache));
+        *cache = fw.cache;
+    }
+    struct celix_framework fw {};
+};
+
+TEST_F(CelixBundleArchiveErrorInjectionTestSuite, ArchiveCreateErrorTest) {
+    celix_bundle_cache_t* cache = nullptr;
+    createCache(&cache);
+
+    bundle_archive_t* archive = nullptr;
+    celix_ei_expect_calloc((void*)celix_bundleRevision_create, 0, nullptr);
+    EXPECT_EQ(CELIX_ENOMEM,
+              celix_bundleArchive_create(&fw, TEST_ARCHIVE_ROOT, 1, 
SIMPLE_TEST_BUNDLE1_LOCATION, &archive));
+    EXPECT_EQ(nullptr, archive);
+    EXPECT_FALSE(celix_utils_directoryExists(TEST_ARCHIVE_ROOT));
+
+    celix_ei_expect_celix_properties_create((void*)celix_bundleArchive_create, 
1, nullptr);
+    EXPECT_EQ(CELIX_ENOMEM,
+              celix_bundleArchive_create(&fw, TEST_ARCHIVE_ROOT, 1, 
SIMPLE_TEST_BUNDLE1_LOCATION, &archive));
+    EXPECT_EQ(nullptr, archive);
+    EXPECT_FALSE(celix_utils_directoryExists(TEST_ARCHIVE_ROOT));
+
+    EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroy(cache));
+}
\ No newline at end of file
diff --git 
a/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc 
b/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc
index fc8ddf83..38aa3b3c 100644
--- a/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc
+++ b/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc
@@ -109,15 +109,13 @@ TEST_F(CelixBundleCacheErrorInjectionTestSuite, 
ArchiveCreateErrorTest) {
     EXPECT_EQ(nullptr, archive);
     EXPECT_EQ(-1, celix_bundleCache_findBundleIdForLocation(cache, 
SIMPLE_TEST_BUNDLE1_LOCATION));
     EXPECT_FALSE(celix_bundleCache_isBundleIdAlreadyUsed(cache, 1));
-    EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroy(cache));
 
-    EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_create(&fw, &cache));
-    fw.cache = cache;
     celix_ei_expect_calloc((void*)celix_bundleArchive_create, 0, nullptr);
     EXPECT_EQ(CELIX_ENOMEM, celix_bundleCache_createArchive(cache, 1, 
SIMPLE_TEST_BUNDLE1_LOCATION, &archive));
     EXPECT_EQ(nullptr, archive);
     EXPECT_EQ(-1, celix_bundleCache_findBundleIdForLocation(cache, 
SIMPLE_TEST_BUNDLE1_LOCATION));
     EXPECT_FALSE(celix_bundleCache_isBundleIdAlreadyUsed(cache, 1));
+
     EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroy(cache));
 }
 
diff --git a/libs/framework/src/bundle_archive.c 
b/libs/framework/src/bundle_archive.c
index ceae451e..668d113d 100644
--- a/libs/framework/src/bundle_archive.c
+++ b/libs/framework/src/bundle_archive.c
@@ -61,23 +61,25 @@ struct bundleArchive {
     char* location;
 };
 
-static void celix_bundleArchive_storeBundleStateProperties(bundle_archive_pt 
archive) {
+static celix_status_t 
celix_bundleArchive_storeBundleStateProperties(bundle_archive_pt archive) {
     celix_properties_t* bundleStateProperties = celix_properties_create();
-    if (bundleStateProperties != NULL) {
-        celixThreadMutex_lock(&archive->lock);
-        //set/update bundle cache state properties
-        celix_properties_setLong(bundleStateProperties, 
CELIX_BUNDLE_ARCHIVE_BUNDLE_ID_PROPERTY_NAME, archive->id);
-        celix_properties_set(bundleStateProperties, 
CELIX_BUNDLE_ARCHIVE_LOCATION_PROPERTY_NAME, archive->location);
-        celix_properties_set(bundleStateProperties, 
CELIX_BUNDLE_ARCHIVE_SYMBOLIC_NAME_PROPERTY_NAME,
-                             archive->bundleSymbolicName);
-        celix_properties_set(bundleStateProperties, 
CELIX_BUNDLE_ARCHIVE_VERSION_PROPERTY_NAME, archive->bundleVersion);
-
-        //save bundle cache state properties
-        celix_properties_store(bundleStateProperties, 
archive->savedBundleStatePropertiesPath,
-                               "Bundle State Properties");
-        celixThreadMutex_unlock(&archive->lock);
+    if (bundleStateProperties == NULL) {
+        return CELIX_ENOMEM;
     }
+    celixThreadMutex_lock(&archive->lock);
+    //set/update bundle cache state properties
+    celix_properties_setLong(bundleStateProperties, 
CELIX_BUNDLE_ARCHIVE_BUNDLE_ID_PROPERTY_NAME, archive->id);
+    celix_properties_set(bundleStateProperties, 
CELIX_BUNDLE_ARCHIVE_LOCATION_PROPERTY_NAME, archive->location);
+    celix_properties_set(bundleStateProperties, 
CELIX_BUNDLE_ARCHIVE_SYMBOLIC_NAME_PROPERTY_NAME,
+                         archive->bundleSymbolicName);
+    celix_properties_set(bundleStateProperties, 
CELIX_BUNDLE_ARCHIVE_VERSION_PROPERTY_NAME, archive->bundleVersion);
+
+    //save bundle cache state properties
+    celix_properties_store(bundleStateProperties, 
archive->savedBundleStatePropertiesPath,
+                           "Bundle State Properties");
+    celixThreadMutex_unlock(&archive->lock);
     celix_properties_destroy(bundleStateProperties);
+    return CELIX_SUCCESS;
 }
 
 celix_status_t celix_bundleArchive_extractBundle(
@@ -256,15 +258,24 @@ celix_status_t 
celix_bundleArchive_create(celix_framework_t* fw, const char *arc
     status = celix_bundleRevision_create(fw, archive->archiveRoot, 
archive->location, manifest, &archive->revision);
     if (status != CELIX_SUCCESS) {
         error = "Could not create bundle revision.";
-        goto init_failed;
+        goto revision_failed;
     }
 
     if (!isSystemBundle) {
-        celix_bundleArchive_storeBundleStateProperties(archive);
+        status = celix_bundleArchive_storeBundleStateProperties(archive);
+        if (status != CELIX_SUCCESS) {
+            error = "Could not store properties.";
+            goto store_prop_failed;
+        }
     }
 
     *bundle_archive = archive;
     return CELIX_SUCCESS;
+store_prop_failed:
+revision_failed:
+    if (!isSystemBundle) {
+        celix_utils_deleteDirectory(archive->archiveRoot, NULL);
+    }
 init_failed:
     bundleArchive_destroy(archive);
 calloc_failed:
@@ -436,9 +447,9 @@ revise_finished:
 
 
 celix_status_t bundleArchive_rollbackRevise(bundle_archive_pt archive, bool 
*rolledback) {
-       *rolledback = true;
+    *rolledback = true;
     fw_log(archive->fw->logger, CELIX_LOG_LEVEL_ERROR, "Revise rollback not 
supported.");
-       return CELIX_BUNDLE_EXCEPTION;
+    return CELIX_BUNDLE_EXCEPTION;
 }
 
 celix_status_t bundleArchive_close(bundle_archive_pt archive) {

Reply via email to