You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pe...@apache.org on 2023/05/18 01:39:44 UTC
[celix] branch feature/556-osgi-uninstall created (now 821ab600)
This is an automated email from the ASF dual-hosted git repository.
pengzheng pushed a change to branch feature/556-osgi-uninstall
in repository https://gitbox.apache.org/repos/asf/celix.git
at 821ab600 Add through unit test for bundle cache.
This branch includes the following new commits:
new e62f269f Add celix_bundleCache_destroyArchive to support OSGi uninstall.
new a0a37549 Add more test cases for celix_bundleCache_create error handling.
new 821ab600 Add through unit test for bundle cache.
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[celix] 01/03: Add celix_bundleCache_destroyArchive to support OSGi uninstall.
Posted by pe...@apache.org.
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 e62f269fa946f09aa54500d83e654d6f3698ca08
Author: PengZheng <ho...@gmail.com>
AuthorDate: Tue May 16 22:02:48 2023 +0800
Add celix_bundleCache_destroyArchive to support OSGi uninstall.
And some unit tests for bundle cache are added.
---
libs/error_injector/CMakeLists.txt | 1 +
libs/error_injector/celix_hash_map/CMakeLists.txt | 25 ++++++++
.../celix_hash_map/include/celix_hash_map_ei.h | 34 ++++++++++
.../celix_hash_map/src/celix_hash_map_ei.cc | 29 +++++++++
libs/framework/gtest/CMakeLists.txt | 2 +
.../src/CelixBundleCacheErrorInjectionTestSuite.cc | 60 ++++++++++++++++++
libs/framework/src/bundle_archive.c | 16 ++---
libs/framework/src/celix_bundle_cache.c | 74 ++++++++++++++--------
libs/framework/src/celix_bundle_cache.h | 11 ++++
libs/framework/src/framework.c | 9 +--
10 files changed, 216 insertions(+), 45 deletions(-)
diff --git a/libs/error_injector/CMakeLists.txt b/libs/error_injector/CMakeLists.txt
index 1607671e..bdf096fe 100644
--- a/libs/error_injector/CMakeLists.txt
+++ b/libs/error_injector/CMakeLists.txt
@@ -44,6 +44,7 @@ add_subdirectory(celix_log_helper)
add_subdirectory(celix_bundle)
add_subdirectory(celix_version)
add_subdirectory(dfi)
+add_subdirectory(celix_hash_map)
celix_subproject(ERROR_INJECTOR_MDNSRESPONDER "Option to enable building the mdnsresponder error injector" OFF)
if (ERROR_INJECTOR_MDNSRESPONDER)
diff --git a/libs/error_injector/celix_hash_map/CMakeLists.txt b/libs/error_injector/celix_hash_map/CMakeLists.txt
new file mode 100644
index 00000000..dbef2bb6
--- /dev/null
+++ b/libs/error_injector/celix_hash_map/CMakeLists.txt
@@ -0,0 +1,25 @@
+# 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.
+
+add_library(hash_map_ei STATIC src/celix_hash_map_ei.cc)
+
+target_include_directories(hash_map_ei PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)
+target_link_libraries(hash_map_ei PUBLIC Celix::error_injector Celix::utils)
+target_link_options(hash_map_ei INTERFACE
+ LINKER:--wrap,celix_stringHashMap_create
+)
+add_library(Celix::hash_map_ei ALIAS hash_map_ei)
diff --git a/libs/error_injector/celix_hash_map/include/celix_hash_map_ei.h b/libs/error_injector/celix_hash_map/include/celix_hash_map_ei.h
new file mode 100644
index 00000000..3c38ad41
--- /dev/null
+++ b/libs/error_injector/celix_hash_map/include/celix_hash_map_ei.h
@@ -0,0 +1,34 @@
+/*
+ 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.
+ */
+
+#ifndef CELIX_CELIX_HASH_MAP_EI_H
+#define CELIX_CELIX_HASH_MAP_EI_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "celix_string_hash_map.h"
+#include "celix_error_injector.h"
+
+CELIX_EI_DECLARE(celix_stringHashMap_create, celix_string_hash_map_t*);
+
+#ifdef __cplusplus
+}
+#endif
+#endif //CELIX_CELIX_HASH_MAP_EI_H
diff --git a/libs/error_injector/celix_hash_map/src/celix_hash_map_ei.cc b/libs/error_injector/celix_hash_map/src/celix_hash_map_ei.cc
new file mode 100644
index 00000000..4edbc381
--- /dev/null
+++ b/libs/error_injector/celix_hash_map/src/celix_hash_map_ei.cc
@@ -0,0 +1,29 @@
+/*
+ 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_hash_map_ei.h"
+
+extern "C" {
+celix_string_hash_map_t* __real_celix_stringHashMap_create();
+CELIX_EI_DEFINE(celix_stringHashMap_create, celix_string_hash_map_t*);
+celix_string_hash_map_t* __wrap_celix_stringHashMap_create() {
+ CELIX_EI_IMPL(celix_stringHashMap_create);
+ return __real_celix_stringHashMap_create();
+}
+}
diff --git a/libs/framework/gtest/CMakeLists.txt b/libs/framework/gtest/CMakeLists.txt
index c05fe4f5..e71fd953 100644
--- a/libs/framework/gtest/CMakeLists.txt
+++ b/libs/framework/gtest/CMakeLists.txt
@@ -127,6 +127,7 @@ if (LINKER_WRAP_SUPPORTED)
src/BundleArchiveWithErrorInjectionTestSuite.cc
src/CelixFrameworkUtilsErrorInjectionTestSuite.cc
src/CelixBundleContextBundlesWithErrorTestSuite.cc
+ src/CelixBundleCacheErrorInjectionTestSuite.cc
)
target_compile_definitions(test_framework_with_ei PRIVATE
SIMPLE_TEST_BUNDLE1_LOCATION="${SIMPLE_TEST_BUNDLE1}"
@@ -142,6 +143,7 @@ if (LINKER_WRAP_SUPPORTED)
Celix::utils_ei
Celix::asprintf_ei
Celix::dlfcn_ei
+ Celix::hash_map_ei
GTest::gtest GTest::gtest_main
)
diff --git a/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc b/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc
new file mode 100644
index 00000000..dd181972
--- /dev/null
+++ b/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc
@@ -0,0 +1,60 @@
+/*
+ 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 "asprintf_ei.h"
+#include "celix_constants.h"
+#include "celix_bundle_cache.h"
+#include "celix_properties.h"
+#include "celix_log.h"
+#include "framework_private.h"
+#include "gtest/gtest.h"
+#include "celix_hash_map_ei.h"
+#include "malloc_ei.h"
+
+class CelixBundleCacheErrorInjectionTestSuite : public ::testing::Test {
+public:
+ CelixBundleCacheErrorInjectionTestSuite() {
+ fw.configurationMap = celix_properties_create();
+ fw.logger = celix_frameworkLogger_create(CELIX_LOG_LEVEL_TRACE);
+ }
+
+ ~CelixBundleCacheErrorInjectionTestSuite() override {
+ celix_ei_expect_asprintf(nullptr, 0, -1);
+ celix_ei_expect_celix_stringHashMap_create(nullptr, 0, nullptr);
+ celix_ei_expect_calloc(nullptr, 0, nullptr);
+ celix_frameworkLogger_destroy(fw.logger);
+ celix_properties_destroy(fw.configurationMap);
+ }
+ struct celix_framework fw{};
+};
+
+TEST_F(CelixBundleCacheErrorInjectionTestSuite, CacheCreateErrorTest) {
+ celix_bundle_cache_t *cache = nullptr;
+ celix_ei_expect_calloc((void *) celix_bundleCache_create, 0, nullptr);
+ EXPECT_EQ(CELIX_ENOMEM, celix_bundleCache_create(&fw, &cache));
+ EXPECT_EQ(nullptr, cache);
+ celix_ei_expect_celix_stringHashMap_create((void *) celix_bundleCache_create, 0, nullptr);
+ EXPECT_EQ(CELIX_ENOMEM, celix_bundleCache_create(&fw, &cache));
+ EXPECT_EQ(nullptr, cache);
+ celix_properties_setBool(fw.configurationMap, CELIX_FRAMEWORK_CACHE_USE_TMP_DIR, true);
+ celix_ei_expect_asprintf((void *) celix_bundleCache_create, 0, -1);
+ EXPECT_EQ(CELIX_ENOMEM, celix_bundleCache_create(&fw, &cache));
+ EXPECT_EQ(nullptr, cache);
+ celix_properties_setBool(fw.configurationMap, CELIX_FRAMEWORK_CACHE_USE_TMP_DIR, false);
+}
\ No newline at end of file
diff --git a/libs/framework/src/bundle_archive.c b/libs/framework/src/bundle_archive.c
index b06300b8..2fa5ab7e 100644
--- a/libs/framework/src/bundle_archive.c
+++ b/libs/framework/src/bundle_archive.c
@@ -461,18 +461,12 @@ celix_status_t bundleArchive_close(bundle_archive_pt archive) {
}
celix_status_t bundleArchive_closeAndDelete(bundle_archive_pt archive) {
- celix_status_t status = CELIX_SUCCESS;
-
- status = bundleArchive_close(archive);
- if (status == CELIX_SUCCESS) {
- const char* err = NULL;
- status = celix_utils_deleteDirectory(archive->archiveRoot, &err);
- framework_logIfError(archive->fw->logger, status, NULL, "Failed to delete archive root '%s': %s", archive->archiveRoot, err);
- }
-
- framework_logIfError(archive->fw->logger, status, NULL, "Failed to close and delete archive");
+ celix_status_t status = CELIX_SUCCESS;
- return status;
+ const char* err = NULL;
+ status = celix_utils_deleteDirectory(archive->archiveRoot, &err);
+ framework_logIfError(archive->fw->logger, status, NULL, "Failed to delete archive root '%s': %s", archive->archiveRoot, err);
+ return status;
}
const char* celix_bundleArchive_getPersistentStoreRoot(bundle_archive_t* archive) {
diff --git a/libs/framework/src/celix_bundle_cache.c b/libs/framework/src/celix_bundle_cache.c
index c315164a..1b52a00f 100644
--- a/libs/framework/src/celix_bundle_cache.c
+++ b/libs/framework/src/celix_bundle_cache.c
@@ -54,6 +54,8 @@ struct celix_bundle_cache {
celix_string_hash_map_t* locationToBundleIdLookupMap; //key = location, value = bundle id.
};
+static void celix_bundleCache_updateIdForLocationLookupMap(celix_bundle_cache_t* cache);
+
static const char* bundleCache_progamName() {
#if defined(__APPLE__) || defined(__FreeBSD__)
return getprogname();
@@ -118,14 +120,18 @@ celix_status_t celix_bundleCache_create(celix_framework_t* fw, celix_bundle_cach
celix_bundle_cache_t *cache = calloc(1, sizeof(*cache));
if (!cache) {
status = CELIX_ENOMEM;
- fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot create bundle cache, out of memory");
- return status;
+ goto cache_calloc_failure;
}
+ cache->fw = fw;
bool useTmpDir = celix_bundleCache_useTmpDir(fw);
cache->deleteOnCreate = celix_bundleCache_cleanOnCreate(fw);
cache->deleteOnDestroy = useTmpDir; //if tmp dir is used, delete on destroy
cache->locationToBundleIdLookupMap = celix_stringHashMap_create();
+ if (NULL == cache->locationToBundleIdLookupMap) {
+ status = CELIX_ENOMEM;
+ goto cache_map_failure;
+ }
celixThreadMutex_create(&cache->mutex, NULL);
if (useTmpDir) {
@@ -135,12 +141,15 @@ celix_status_t celix_bundleCache_create(celix_framework_t* fw, celix_bundle_cach
if (pg == NULL) {
pg = "";
}
-
asprintf(&cache->cacheDir, "/tmp/celix-cache-%s-%s", pg, celix_framework_getUUID(fw));
} else {
const char* cacheDir = celix_bundleCache_cacheDirPath(fw);
cache->cacheDir = celix_utils_strdup(cacheDir);
}
+ if (NULL == cache->cacheDir) {
+ status = CELIX_ENOMEM;
+ goto cache_dir_failure;
+ }
if (cache->deleteOnCreate) {
status = celix_bundleCache_deleteCacheDir(cache);
@@ -157,9 +166,16 @@ celix_status_t celix_bundleCache_create(celix_framework_t* fw, celix_bundle_cach
celix_bundleCache_destroy(cache);
return status;
}
-
+ celix_bundleCache_updateIdForLocationLookupMap(cache);
*out = cache;
- return status;
+ return CELIX_SUCCESS;
+cache_dir_failure:
+ celixThreadMutex_destroy(&cache->mutex);
+ celix_stringHashMap_destroy(cache->locationToBundleIdLookupMap);
+cache_map_failure:
+ free(cache);
+cache_calloc_failure:
+ return status;
}
celix_status_t celix_bundleCache_destroy(celix_bundle_cache_t* cache) {
@@ -178,6 +194,9 @@ celix_status_t celix_bundleCache_deleteCacheDir(celix_bundle_cache_t* cache) {
const char* err = NULL;
celixThreadMutex_lock(&cache->mutex);
celix_status_t status = celix_utils_deleteDirectory(cache->cacheDir, &err);
+ if (status == CELIX_SUCCESS) {
+ celix_stringHashMap_clear(cache->locationToBundleIdLookupMap);
+ }
celixThreadMutex_unlock(&cache->mutex);
if (status != CELIX_SUCCESS) {
fw_logCode(cache->fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot delete bundle cache directory %s: %s", cache->cacheDir, err);
@@ -194,6 +213,9 @@ celix_status_t celix_bundleCache_createArchive(celix_framework_t* fw, long id, c
if (archiveRoot) {
celixThreadMutex_lock(&fw->cache->mutex);
status = celix_bundleArchive_create(fw, archiveRoot, id, location, &archive);
+ if (status == CELIX_SUCCESS) {
+ celix_stringHashMap_put(fw->cache->locationToBundleIdLookupMap, location, (void*)id);
+ }
celixThreadMutex_unlock(&fw->cache->mutex);
celix_utils_freeStringIfNotEqual(archiveRootBuffer, archiveRoot);
} else {
@@ -203,12 +225,6 @@ celix_status_t celix_bundleCache_createArchive(celix_framework_t* fw, long id, c
fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Failed to create archive.");
return status;
}
-
- //add bundle id and location to lookup maps
- celixThreadMutex_lock(&fw->cache->mutex);
- celix_stringHashMap_put(fw->cache->locationToBundleIdLookupMap, location, (void*)id);
- celixThreadMutex_unlock(&fw->cache->mutex);
-
*archiveOut = archive;
return status;
}
@@ -217,16 +233,28 @@ celix_status_t celix_bundleCache_createSystemArchive(celix_framework_t* fw, bund
return celix_bundleCache_createArchive(fw, CELIX_FRAMEWORK_BUNDLE_ID, NULL, archive);
}
+celix_status_t celix_bundleCache_destroyArchive(celix_bundle_cache_t *cache, bundle_archive_pt archive) {
+ celix_status_t status = CELIX_SUCCESS;
+ const char* loc = NULL;
+ celixThreadMutex_lock(&cache->mutex);
+ (void)bundleArchive_getLocation(archive, &loc);
+ (void)celix_stringHashMap_remove(cache->locationToBundleIdLookupMap, loc);
+ status = bundleArchive_closeAndDelete(archive);
+ celixThreadMutex_unlock(&cache->mutex);
+ (void)bundleArchive_destroy(archive);
+ return status;
+}
+
/**
* Update location->bundle id lookup map.
* Assumes that bundle cache dir are not removed, so only adding not removing entries.
*/
-static void celix_bundleCache_updateIdForLocationLookupMap(celix_framework_t* fw) {
- celixThreadMutex_lock(&fw->cache->mutex);
- DIR* dir = opendir(fw->cache->cacheDir);
+static void celix_bundleCache_updateIdForLocationLookupMap(celix_bundle_cache_t* cache) {
+ celixThreadMutex_lock(&cache->mutex);
+ DIR* dir = opendir(cache->cacheDir);
if (dir == NULL) {
- fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, CELIX_BUNDLE_EXCEPTION, "Cannot open bundle cache directory %s", fw->cache->cacheDir);
- celixThreadMutex_unlock(&fw->cache->mutex);
+ fw_logCode(cache->fw->logger, CELIX_LOG_LEVEL_ERROR, CELIX_BUNDLE_EXCEPTION, "Cannot open bundle cache directory %s", cache->cacheDir);
+ celixThreadMutex_unlock(&cache->mutex);
return;
}
char archiveRootBuffer[CELIX_DEFAULT_STRING_CREATE_BUFFER_SIZE];
@@ -236,22 +264,22 @@ static void celix_bundleCache_updateIdForLocationLookupMap(celix_framework_t* fw
continue;
}
char *bundleStateProperties = celix_utils_writeOrCreateString(archiveRootBuffer, sizeof(archiveRootBuffer),
- "%s/%s/%s", fw->cache->cacheDir, dent->d_name,
+ "%s/%s/%s", cache->cacheDir, dent->d_name,
CELIX_BUNDLE_ARCHIVE_STATE_PROPERTIES_FILE_NAME);
if (celix_utils_fileExists(bundleStateProperties)) {
celix_properties_t *props = celix_properties_load(bundleStateProperties);
const char *visitLoc = celix_properties_get(props, CELIX_BUNDLE_ARCHIVE_LOCATION_PROPERTY_NAME, NULL);
long bndId = celix_properties_getAsLong(props, CELIX_BUNDLE_ARCHIVE_BUNDLE_ID_PROPERTY_NAME, -1);
if (visitLoc != NULL && bndId >= 0) {
- fw_log(fw->logger, CELIX_LOG_LEVEL_TRACE, "Adding location %s -> bnd id %li to lookup map",
+ fw_log(cache->fw->logger, CELIX_LOG_LEVEL_TRACE, "Adding location %s -> bnd id %li to lookup map",
visitLoc, bndId);
- celix_stringHashMap_putLong(fw->cache->locationToBundleIdLookupMap, visitLoc, bndId);
+ celix_stringHashMap_putLong(cache->locationToBundleIdLookupMap, visitLoc, bndId);
}
celix_properties_destroy(props);
}
}
closedir(dir);
- celixThreadMutex_unlock(&fw->cache->mutex);
+ celixThreadMutex_unlock(&cache->mutex);
}
long celix_bundleCache_findBundleIdForLocation(celix_framework_t *fw, const char *location) {
@@ -261,12 +289,6 @@ long celix_bundleCache_findBundleIdForLocation(celix_framework_t *fw, const char
bndId = celix_stringHashMap_getLong(fw->cache->locationToBundleIdLookupMap, location, -1);
}
celixThreadMutex_unlock(&fw->cache->mutex);
- if (bndId == -1) {
- celix_bundleCache_updateIdForLocationLookupMap(fw);
- celixThreadMutex_lock(&fw->cache->mutex);
- bndId = celix_stringHashMap_getLong(fw->cache->locationToBundleIdLookupMap, location, -1);
- celixThreadMutex_unlock(&fw->cache->mutex);
- }
return bndId;
}
diff --git a/libs/framework/src/celix_bundle_cache.h b/libs/framework/src/celix_bundle_cache.h
index e1829044..06810b54 100644
--- a/libs/framework/src/celix_bundle_cache.h
+++ b/libs/framework/src/celix_bundle_cache.h
@@ -87,6 +87,17 @@ celix_bundleCache_createArchive(celix_framework_t *fw, long id, const char *loca
*/
celix_status_t celix_bundleCache_createSystemArchive(celix_framework_t* fw, bundle_archive_pt *archive);
+/**
+ * @brief Destroy the archive from the cache.
+ * It releases all resources allocated in celix_bundleCache_createArchive and deletes the archive directory.
+ * @param [in] cache The bundle cache to destroy archive from.
+ * @param [in] archive The archive to destroy.
+ * @return Status code indication failure or success:
+ * - CELIX_SUCCESS when no errors are encountered.
+ * - CELIX_FILE_IO_EXCEPTION when root of the archive is not a directory.
+ * - errno when the directory cannot be deleted for other reasons, check error codes of fts_open/fts_read/remove.
+ */
+celix_status_t celix_bundleCache_destroyArchive(celix_bundle_cache_t *cache, bundle_archive_pt archive);
/**
* @brief Deletes the entire bundle cache.
diff --git a/libs/framework/src/framework.c b/libs/framework/src/framework.c
index 44662850..8e9dd886 100644
--- a/libs/framework/src/framework.c
+++ b/libs/framework/src/framework.c
@@ -654,14 +654,7 @@ celix_status_t celix_framework_installBundleInternal(celix_framework_t *framewor
long id = alreadyExistingBndId == -1 ? framework_getNextBundleId(framework) : alreadyExistingBndId;
bundle_archive_t* archive = NULL;
status = CELIX_DO_IF(status, celix_bundleCache_createArchive(framework, id, bndLoc, &archive));
- if (status != CELIX_SUCCESS) {
- bundleArchive_destroy(archive);
- }
-
- if (status == CELIX_SUCCESS) {
- status = celix_bundle_createFromArchive(framework, archive, &bundle);
- }
-
+ status = CELIX_DO_IF(status, celix_bundle_createFromArchive(framework, archive, &bundle));
if (status == CELIX_SUCCESS) {
celix_framework_bundle_entry_t *bEntry = fw_bundleEntry_create(bundle);
celix_framework_bundleEntry_increaseUseCount(bEntry);
[celix] 02/03: Add more test cases for celix_bundleCache_create error handling.
Posted by pe...@apache.org.
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 a0a37549f27322836011e045e6155d97dcc756da
Author: PengZheng <ho...@gmail.com>
AuthorDate: Wed May 17 12:35:56 2023 +0800
Add more test cases for celix_bundleCache_create error handling.
---
.../src/CelixBundleCacheErrorInjectionTestSuite.cc | 26 +++++++++++++++++-----
libs/framework/src/celix_bundle_cache.c | 22 +++++++++---------
libs/utils/include/celix_file_utils.h | 2 +-
3 files changed, 32 insertions(+), 18 deletions(-)
diff --git a/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc b/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc
index dd181972..c5d894f6 100644
--- a/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc
+++ b/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc
@@ -18,14 +18,15 @@
*/
#include "asprintf_ei.h"
-#include "celix_constants.h"
#include "celix_bundle_cache.h"
-#include "celix_properties.h"
+#include "celix_constants.h"
+#include "celix_hash_map_ei.h"
#include "celix_log.h"
+#include "celix_properties.h"
+#include "celix_utils_ei.h"
#include "framework_private.h"
-#include "gtest/gtest.h"
-#include "celix_hash_map_ei.h"
#include "malloc_ei.h"
+#include "gtest/gtest.h"
class CelixBundleCacheErrorInjectionTestSuite : public ::testing::Test {
public:
@@ -35,13 +36,17 @@ public:
}
~CelixBundleCacheErrorInjectionTestSuite() override {
+ celix_ei_expect_celix_utils_createDirectory(nullptr, 0, CELIX_SUCCESS);
+ celix_ei_expect_celix_utils_deleteDirectory(nullptr, 0, CELIX_SUCCESS);
+ celix_ei_expect_celix_utils_strdup(nullptr, 0, nullptr);
celix_ei_expect_asprintf(nullptr, 0, -1);
celix_ei_expect_celix_stringHashMap_create(nullptr, 0, nullptr);
celix_ei_expect_calloc(nullptr, 0, nullptr);
celix_frameworkLogger_destroy(fw.logger);
celix_properties_destroy(fw.configurationMap);
}
- struct celix_framework fw{};
+
+ struct celix_framework fw {};
};
TEST_F(CelixBundleCacheErrorInjectionTestSuite, CacheCreateErrorTest) {
@@ -57,4 +62,15 @@ TEST_F(CelixBundleCacheErrorInjectionTestSuite, CacheCreateErrorTest) {
EXPECT_EQ(CELIX_ENOMEM, celix_bundleCache_create(&fw, &cache));
EXPECT_EQ(nullptr, cache);
celix_properties_setBool(fw.configurationMap, CELIX_FRAMEWORK_CACHE_USE_TMP_DIR, false);
+ celix_ei_expect_celix_utils_strdup((void *) celix_bundleCache_create, 0, nullptr);
+ EXPECT_EQ(CELIX_ENOMEM, celix_bundleCache_create(&fw, &cache));
+ EXPECT_EQ(nullptr, cache);
+ celix_properties_setBool(fw.configurationMap, CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE, true);
+ celix_ei_expect_celix_utils_deleteDirectory((void *) celix_bundleCache_create, 1, CELIX_FILE_IO_EXCEPTION);
+ EXPECT_EQ(CELIX_FILE_IO_EXCEPTION, celix_bundleCache_create(&fw, &cache));
+ EXPECT_EQ(nullptr, cache);
+ celix_properties_setBool(fw.configurationMap, CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE, false);
+ celix_ei_expect_celix_utils_createDirectory((void *) celix_bundleCache_create, 0, CELIX_FILE_IO_EXCEPTION);
+ EXPECT_EQ(CELIX_FILE_IO_EXCEPTION, celix_bundleCache_create(&fw, &cache));
+ EXPECT_EQ(nullptr, cache);
}
\ No newline at end of file
diff --git a/libs/framework/src/celix_bundle_cache.c b/libs/framework/src/celix_bundle_cache.c
index 1b52a00f..59cf01a4 100644
--- a/libs/framework/src/celix_bundle_cache.c
+++ b/libs/framework/src/celix_bundle_cache.c
@@ -54,8 +54,6 @@ struct celix_bundle_cache {
celix_string_hash_map_t* locationToBundleIdLookupMap; //key = location, value = bundle id.
};
-static void celix_bundleCache_updateIdForLocationLookupMap(celix_bundle_cache_t* cache);
-
static const char* bundleCache_progamName() {
#if defined(__APPLE__) || defined(__FreeBSD__)
return getprogname();
@@ -152,23 +150,18 @@ celix_status_t celix_bundleCache_create(celix_framework_t* fw, celix_bundle_cach
}
if (cache->deleteOnCreate) {
- status = celix_bundleCache_deleteCacheDir(cache);
- if (status != CELIX_SUCCESS) {
- celix_bundleCache_destroy(cache);
- return status;
- }
+ CELIX_GOTO_IF_ERR(status = celix_bundleCache_deleteCacheDir(cache), manipulate_dir_failure);
}
-
const char* errorStr;
status = celix_utils_createDirectory(cache->cacheDir, false, &errorStr);
if (status != CELIX_SUCCESS) {
fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot create bundle cache directory %s, error %s", cache->cacheDir, errorStr);
- celix_bundleCache_destroy(cache);
- return status;
+ goto manipulate_dir_failure;
}
- celix_bundleCache_updateIdForLocationLookupMap(cache);
*out = cache;
return CELIX_SUCCESS;
+manipulate_dir_failure:
+ free(cache->cacheDir);
cache_dir_failure:
celixThreadMutex_destroy(&cache->mutex);
celix_stringHashMap_destroy(cache->locationToBundleIdLookupMap);
@@ -247,7 +240,6 @@ celix_status_t celix_bundleCache_destroyArchive(celix_bundle_cache_t *cache, bu
/**
* Update location->bundle id lookup map.
- * Assumes that bundle cache dir are not removed, so only adding not removing entries.
*/
static void celix_bundleCache_updateIdForLocationLookupMap(celix_bundle_cache_t* cache) {
celixThreadMutex_lock(&cache->mutex);
@@ -289,6 +281,12 @@ long celix_bundleCache_findBundleIdForLocation(celix_framework_t *fw, const char
bndId = celix_stringHashMap_getLong(fw->cache->locationToBundleIdLookupMap, location, -1);
}
celixThreadMutex_unlock(&fw->cache->mutex);
+ if (bndId == -1) {
+ celix_bundleCache_updateIdForLocationLookupMap(fw->cache);
+ celixThreadMutex_lock(&fw->cache->mutex);
+ bndId = celix_stringHashMap_getLong(fw->cache->locationToBundleIdLookupMap, location, -1);
+ celixThreadMutex_unlock(&fw->cache->mutex);
+ }
return bndId;
}
diff --git a/libs/utils/include/celix_file_utils.h b/libs/utils/include/celix_file_utils.h
index f71cdab0..bff99763 100644
--- a/libs/utils/include/celix_file_utils.h
+++ b/libs/utils/include/celix_file_utils.h
@@ -41,7 +41,7 @@ CELIX_UTILS_EXPORT bool celix_utils_fileExists(const char* path);
CELIX_UTILS_EXPORT bool celix_utils_directoryExists(const char* path);
/**
- * @brief Create dir and if needed subdirs.
+ * @brief Create dir and if needed parent direcotries.
* @param path The directory to create.
* @param failIfPresent Whether to fail if the directory already exists.
* @param errorOut An optional error output argument. If an error occurs this will point to a (static) error message.
[celix] 03/03: Add through unit test for bundle cache.
Posted by pe...@apache.org.
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 821ab6006d43d2ab18bb8f8f9c6ce30ec72e152e
Author: PengZheng <ho...@gmail.com>
AuthorDate: Wed May 17 22:02:44 2023 +0800
Add through unit test for bundle cache.
---
libs/framework/gtest/CMakeLists.txt | 1 +
.../BundleArchiveWithErrorInjectionTestSuite.cc | 22 ++-
.../src/CelixBundleCacheErrorInjectionTestSuite.cc | 81 +++++++++-
.../gtest/src/CelixBundleCacheTestSuite.cc | 83 ++++++++++
libs/framework/src/bundle_archive.c | 24 +--
libs/framework/src/bundle_archive_private.h | 3 +
libs/framework/src/celix_bundle_cache.c | 170 +++++++++++----------
libs/framework/src/celix_bundle_cache.h | 26 ++--
libs/framework/src/framework.c | 6 +-
9 files changed, 288 insertions(+), 128 deletions(-)
diff --git a/libs/framework/gtest/CMakeLists.txt b/libs/framework/gtest/CMakeLists.txt
index e71fd953..d98a9b37 100644
--- a/libs/framework/gtest/CMakeLists.txt
+++ b/libs/framework/gtest/CMakeLists.txt
@@ -56,6 +56,7 @@ set(CELIX_FRAMEWORK_TEST_SOURCES
src/CxxBundleActivatorTestSuite.cc
src/BundleArchiveTestSuite.cc
src/CelixLauncherTestSuite.cc
+ src/CelixBundleCacheTestSuite.cc
)
add_executable(test_framework ${CELIX_FRAMEWORK_TEST_SOURCES})
diff --git a/libs/framework/gtest/src/BundleArchiveWithErrorInjectionTestSuite.cc b/libs/framework/gtest/src/BundleArchiveWithErrorInjectionTestSuite.cc
index 350fd3f1..98ffcbe8 100644
--- a/libs/framework/gtest/src/BundleArchiveWithErrorInjectionTestSuite.cc
+++ b/libs/framework/gtest/src/BundleArchiveWithErrorInjectionTestSuite.cc
@@ -18,7 +18,7 @@
*/
#include <gtest/gtest.h>
-
+#include "bundle_archive_private.h"
#include "celix/FrameworkFactory.h"
#include "celix_constants.h"
#include "celix_framework_utils.h"
@@ -27,8 +27,6 @@
#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_bundleArchive_create(void);
-extern "C" celix_status_t manifest_create(void);
extern "C" celix_status_t celix_bundleRevision_create(void);
class BundleArchiveWithErrorInjectionTestSuite : public ::testing::Test {
@@ -75,12 +73,12 @@ protected:
TEST_F(BundleArchiveWithErrorInjectionTestSuite, BundleArchiveCreatedFailedTest) {
teardownErrorInjectors();
//Given a mocked calloc which returns NULL from a (indirect) call from bundleArchive_create
- celix_ei_expect_calloc((void*)celix_bundleArchive_create, 1, nullptr);
+ 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, 1, nullptr);
+ celix_ei_expect_celix_utils_strdup((void*)celix_bundleArchive_create, 0, nullptr);
installBundleAndExpectFailure();
teardownErrorInjectors();
@@ -106,38 +104,38 @@ TEST_F(BundleArchiveWithErrorInjectionTestSuite, BundleArchiveCreateCacheDirecto
teardownErrorInjectors();
//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, 2, CELIX_FILE_IO_EXCEPTION);
+ 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
- celix_ei_expect_asprintf((void*)celix_bundleArchive_create, 2, -1);
+ 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
- celix_ei_expect_celix_utils_createDirectory((void*)celix_bundleArchive_create, 2, CELIX_FILE_IO_EXCEPTION, 2);
+ 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
- celix_ei_expect_asprintf((void*)celix_bundleArchive_create, 2, -1, 2);
+ 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
- celix_ei_expect_celix_utils_createDirectory((void*)celix_bundleArchive_create, 2, CELIX_FILE_IO_EXCEPTION, 3);
+ 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
- celix_ei_expect_celix_utils_strdup((void*)celix_bundleArchive_create, 2, nullptr);
+ 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
- celix_ei_expect_celix_utils_strdup((void*)celix_bundleArchive_create, 2, nullptr, 2);
+ celix_ei_expect_celix_utils_strdup((void*)celix_bundleArchive_create, 1, nullptr, 2);
installBundleAndExpectFailure();
}
diff --git a/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc b/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc
index c5d894f6..ecd39064 100644
--- a/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc
+++ b/libs/framework/gtest/src/CelixBundleCacheErrorInjectionTestSuite.cc
@@ -18,8 +18,10 @@
*/
#include "asprintf_ei.h"
+#include "bundle_archive_private.h"
#include "celix_bundle_cache.h"
#include "celix_constants.h"
+#include "celix_file_utils.h"
#include "celix_hash_map_ei.h"
#include "celix_log.h"
#include "celix_properties.h"
@@ -27,6 +29,7 @@
#include "framework_private.h"
#include "malloc_ei.h"
#include "gtest/gtest.h"
+#include <string>
class CelixBundleCacheErrorInjectionTestSuite : public ::testing::Test {
public:
@@ -36,6 +39,7 @@ public:
}
~CelixBundleCacheErrorInjectionTestSuite() override {
+ celix_ei_expect_celix_utils_writeOrCreateString(nullptr, 0, nullptr);
celix_ei_expect_celix_utils_createDirectory(nullptr, 0, CELIX_SUCCESS);
celix_ei_expect_celix_utils_deleteDirectory(nullptr, 0, CELIX_SUCCESS);
celix_ei_expect_celix_utils_strdup(nullptr, 0, nullptr);
@@ -51,26 +55,91 @@ public:
TEST_F(CelixBundleCacheErrorInjectionTestSuite, CacheCreateErrorTest) {
celix_bundle_cache_t *cache = nullptr;
- celix_ei_expect_calloc((void *) celix_bundleCache_create, 0, nullptr);
+ celix_ei_expect_calloc((void*) celix_bundleCache_create, 0, nullptr);
EXPECT_EQ(CELIX_ENOMEM, celix_bundleCache_create(&fw, &cache));
EXPECT_EQ(nullptr, cache);
- celix_ei_expect_celix_stringHashMap_create((void *) celix_bundleCache_create, 0, nullptr);
+ celix_ei_expect_celix_stringHashMap_create((void*) celix_bundleCache_create, 0, nullptr);
EXPECT_EQ(CELIX_ENOMEM, celix_bundleCache_create(&fw, &cache));
EXPECT_EQ(nullptr, cache);
celix_properties_setBool(fw.configurationMap, CELIX_FRAMEWORK_CACHE_USE_TMP_DIR, true);
- celix_ei_expect_asprintf((void *) celix_bundleCache_create, 0, -1);
+ celix_ei_expect_asprintf((void*) celix_bundleCache_create, 0, -1);
EXPECT_EQ(CELIX_ENOMEM, celix_bundleCache_create(&fw, &cache));
EXPECT_EQ(nullptr, cache);
celix_properties_setBool(fw.configurationMap, CELIX_FRAMEWORK_CACHE_USE_TMP_DIR, false);
- celix_ei_expect_celix_utils_strdup((void *) celix_bundleCache_create, 0, nullptr);
+ celix_ei_expect_celix_utils_strdup((void*) celix_bundleCache_create, 0, nullptr);
EXPECT_EQ(CELIX_ENOMEM, celix_bundleCache_create(&fw, &cache));
EXPECT_EQ(nullptr, cache);
celix_properties_setBool(fw.configurationMap, CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE, true);
- celix_ei_expect_celix_utils_deleteDirectory((void *) celix_bundleCache_create, 1, CELIX_FILE_IO_EXCEPTION);
+ celix_ei_expect_celix_utils_deleteDirectory((void*) celix_bundleCache_create, 1, CELIX_FILE_IO_EXCEPTION);
EXPECT_EQ(CELIX_FILE_IO_EXCEPTION, celix_bundleCache_create(&fw, &cache));
EXPECT_EQ(nullptr, cache);
celix_properties_setBool(fw.configurationMap, CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE, false);
- celix_ei_expect_celix_utils_createDirectory((void *) celix_bundleCache_create, 0, CELIX_FILE_IO_EXCEPTION);
+ celix_ei_expect_celix_utils_createDirectory((void*) celix_bundleCache_create, 0, CELIX_FILE_IO_EXCEPTION);
EXPECT_EQ(CELIX_FILE_IO_EXCEPTION, celix_bundleCache_create(&fw, &cache));
EXPECT_EQ(nullptr, cache);
+}
+
+TEST_F(CelixBundleCacheErrorInjectionTestSuite, CacheDeleteErrorTest) {
+ celix_bundle_cache_t *cache = nullptr;
+ celix_properties_setBool(fw.configurationMap, CELIX_FRAMEWORK_CACHE_USE_TMP_DIR, true);
+ EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_create(&fw, &cache));
+ celix_ei_expect_celix_utils_deleteDirectory((void*) celix_bundleCache_deleteCacheDir, 0, CELIX_FILE_IO_EXCEPTION);
+ EXPECT_EQ(CELIX_FILE_IO_EXCEPTION, celix_bundleCache_deleteCacheDir(cache));
+ EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroy(cache));
+}
+
+TEST_F(CelixBundleCacheErrorInjectionTestSuite, ArchiveCreateErrorTest) {
+ celix_bundle_cache_t *cache = nullptr;
+ bundle_archive_t* archive = nullptr;
+ celix_properties_setBool(fw.configurationMap, CELIX_FRAMEWORK_CACHE_USE_TMP_DIR, true);
+ EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_create(&fw, &cache));
+ fw.cache = cache;
+ celix_ei_expect_celix_utils_writeOrCreateString((void*) celix_bundleCache_createArchive, 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));
+
+ 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));
+}
+
+TEST_F(CelixBundleCacheErrorInjectionTestSuite, ArchiveDestroyErrorTest) {
+ celix_bundle_cache_t *cache = nullptr;
+ bundle_archive_t* archive = nullptr;
+ celix_properties_setBool(fw.configurationMap, CELIX_FRAMEWORK_CACHE_USE_TMP_DIR, true);
+ EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_create(&fw, &cache));
+ fw.cache = cache;
+ EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_createArchive(cache, 1, SIMPLE_TEST_BUNDLE1_LOCATION, &archive));
+ celix_ei_expect_celix_utils_deleteDirectory((void*) celix_bundleCache_destroyArchive, 1, CELIX_FILE_IO_EXCEPTION);
+ std::string storeRoot = celix_bundleArchive_getPersistentStoreRoot(archive);
+ EXPECT_EQ(CELIX_FILE_IO_EXCEPTION, celix_bundleCache_destroyArchive(cache, archive));
+ EXPECT_TRUE(celix_utils_directoryExists(storeRoot.c_str()));
+ EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroy(cache));
+}
+
+TEST_F(CelixBundleCacheErrorInjectionTestSuite, CreateBundleArchivesCacheErrorTest) {
+ celix_bundle_cache_t *cache = nullptr;
+ celix_properties_set(fw.configurationMap, CELIX_AUTO_START_1, SIMPLE_TEST_BUNDLE1_LOCATION);
+ celix_properties_setBool(fw.configurationMap, CELIX_FRAMEWORK_CACHE_USE_TMP_DIR, true);
+ EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_create(&fw, &cache));
+ fw.cache = cache;
+ celix_ei_expect_celix_utils_deleteDirectory((void*) celix_bundleCache_createBundleArchivesCache, 0, CELIX_FILE_IO_EXCEPTION);
+ EXPECT_EQ(CELIX_FILE_IO_EXCEPTION, celix_bundleCache_createBundleArchivesCache(&fw, true));
+ celix_ei_expect_celix_utils_writeOrCreateString((void*) celix_bundleCache_createBundleArchivesCache, 1, nullptr);
+ EXPECT_EQ(CELIX_ENOMEM, celix_bundleCache_createBundleArchivesCache(&fw, true));
+ celix_properties_unset(fw.configurationMap, CELIX_AUTO_START_1);
+ celix_properties_set(fw.configurationMap, CELIX_AUTO_INSTALL, SIMPLE_TEST_BUNDLE1_LOCATION);
+ celix_ei_expect_celix_utils_writeOrCreateString((void*) celix_bundleCache_createBundleArchivesCache, 1, nullptr);
+ EXPECT_EQ(CELIX_ENOMEM, celix_bundleCache_createBundleArchivesCache(&fw, true));
+ celix_ei_expect_celix_utils_writeOrCreateString((void*) celix_bundleCache_createArchive, 0, nullptr);
+ EXPECT_EQ(CELIX_ENOMEM, celix_bundleCache_createBundleArchivesCache(&fw, true));
+ EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroy(cache));
}
\ No newline at end of file
diff --git a/libs/framework/gtest/src/CelixBundleCacheTestSuite.cc b/libs/framework/gtest/src/CelixBundleCacheTestSuite.cc
new file mode 100644
index 00000000..8333d587
--- /dev/null
+++ b/libs/framework/gtest/src/CelixBundleCacheTestSuite.cc
@@ -0,0 +1,83 @@
+/*
+ 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 "bundle_archive_private.h"
+#include "celix_bundle_cache.h"
+#include "celix_constants.h"
+#include "celix_file_utils.h"
+#include "celix_log.h"
+#include "celix_properties.h"
+#include "framework_private.h"
+#include "gtest/gtest.h"
+#include <string>
+
+class CelixBundleCacheTestSuite : public ::testing::Test {
+public:
+ CelixBundleCacheTestSuite() {
+ celix_bundle_cache_t* bundleCache = nullptr;
+ fw.configurationMap = celix_properties_create();
+ celix_properties_setBool(fw.configurationMap, CELIX_FRAMEWORK_CACHE_USE_TMP_DIR, true);
+ fw.logger = celix_frameworkLogger_create(CELIX_LOG_LEVEL_TRACE);
+ EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_create(&fw, &bundleCache));
+ fw.cache = bundleCache;
+ }
+
+ ~CelixBundleCacheTestSuite() override {
+ EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroy(fw.cache));
+ celix_frameworkLogger_destroy(fw.logger);
+ celix_properties_destroy(fw.configurationMap);
+ }
+
+ struct celix_framework fw{};
+};
+
+TEST_F(CelixBundleCacheTestSuite, ArchiveCreateDestroyTest) {
+ bundle_archive_t* archive = nullptr;
+ EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_createArchive(fw.cache, 1, SIMPLE_TEST_BUNDLE1_LOCATION, &archive));
+ EXPECT_NE(nullptr, archive);
+ EXPECT_EQ(1, celix_bundleCache_findBundleIdForLocation(fw.cache, SIMPLE_TEST_BUNDLE1_LOCATION));
+ EXPECT_TRUE(celix_bundleCache_isBundleIdAlreadyUsed(fw.cache, 1));
+ std::string loc = celix_bundleArchive_getPersistentStoreRoot(archive);
+ EXPECT_TRUE(celix_utils_directoryExists(loc.c_str()));
+ EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroyArchive(fw.cache, archive));
+ EXPECT_EQ(-1, celix_bundleCache_findBundleIdForLocation(fw.cache, SIMPLE_TEST_BUNDLE1_LOCATION));
+ EXPECT_FALSE(celix_bundleCache_isBundleIdAlreadyUsed(fw.cache, 1));
+ EXPECT_FALSE(celix_utils_directoryExists(loc.c_str()));
+}
+
+TEST_F(CelixBundleCacheTestSuite, SystemArchiveCreateDestroyTest) {
+ bundle_archive_t* archive = nullptr;
+ const char* archiveRoot = nullptr;
+ EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_createSystemArchive(&fw, &archive));
+ EXPECT_NE(nullptr, archive);
+ EXPECT_EQ(0, celix_bundleArchive_getId(archive));
+ EXPECT_EQ(CELIX_SUCCESS, bundleArchive_getArchiveRoot(archive, &archiveRoot));
+ EXPECT_EQ(nullptr, archiveRoot);
+ EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroyArchive(fw.cache, archive));
+}
+
+TEST_F(CelixBundleCacheTestSuite, CreateBundleArchivesCacheTest) {
+ celix_properties_set(fw.configurationMap, CELIX_AUTO_START_1, SIMPLE_TEST_BUNDLE1_LOCATION);
+ celix_properties_set(fw.configurationMap, CELIX_AUTO_INSTALL, SIMPLE_TEST_BUNDLE2_LOCATION);
+ EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_createBundleArchivesCache(&fw, true));
+ EXPECT_EQ(1, celix_bundleCache_findBundleIdForLocation(fw.cache, SIMPLE_TEST_BUNDLE1_LOCATION));
+ EXPECT_TRUE(celix_bundleCache_isBundleIdAlreadyUsed(fw.cache, 1));
+ EXPECT_EQ(2, celix_bundleCache_findBundleIdForLocation(fw.cache, SIMPLE_TEST_BUNDLE2_LOCATION));
+ EXPECT_TRUE(celix_bundleCache_isBundleIdAlreadyUsed(fw.cache, 2));
+}
\ No newline at end of file
diff --git a/libs/framework/src/bundle_archive.c b/libs/framework/src/bundle_archive.c
index 2fa5ab7e..bd08bb24 100644
--- a/libs/framework/src/bundle_archive.c
+++ b/libs/framework/src/bundle_archive.c
@@ -207,13 +207,8 @@ celix_status_t celix_bundleArchive_createCacheDirectory(bundle_archive_pt archiv
return status;
}
-/**
- * Create a bundle archive for the given root, id, location and revision nr.
- *
- * Also create the bundle cache dir and if will reuse a existing bundle resource cache dir if the provided
- * bundle zip location is older then the existing bundle resource cache dir.
- */
-celix_status_t celix_bundleArchive_createArchiveInternal(celix_framework_t* fw, const char* archiveRoot, long id, const char *location, bundle_archive_pt* bundle_archive) {
+
+celix_status_t celix_bundleArchive_create(celix_framework_t* fw, const char *archiveRoot, long id, const char *location, bundle_archive_pt *bundle_archive) {
celix_status_t status = CELIX_SUCCESS;
bundle_archive_pt archive = calloc(1, sizeof(*archive));
@@ -242,7 +237,7 @@ celix_status_t celix_bundleArchive_createArchiveInternal(celix_framework_t* fw,
rc = asprintf(&archive->savedBundleStatePropertiesPath, "%s/%s", archiveRoot,
CELIX_BUNDLE_ARCHIVE_STATE_PROPERTIES_FILE_NAME);
if (rc < 0 || archive->location == NULL || archive->savedBundleStatePropertiesPath == NULL
- || archive->archiveRoot == NULL) {
+ || archive->archiveRoot == NULL) {
status = CELIX_ENOMEM;
fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Could not create archive. Out of memory.");
bundleArchive_destroy(archive);
@@ -281,10 +276,6 @@ celix_status_t celix_bundleArchive_createArchiveInternal(celix_framework_t* fw,
return status;
}
-celix_status_t celix_bundleArchive_create(celix_framework_t* fw, const char *archiveRoot, long id, const char *location, bundle_archive_pt *bundle_archive) {
- return celix_bundleArchive_createArchiveInternal(fw, archiveRoot, id, location, bundle_archive);
-}
-
celix_status_t bundleArchive_destroy(bundle_archive_pt archive) {
if (archive != NULL) {
free(archive->location);
@@ -462,10 +453,11 @@ celix_status_t bundleArchive_close(bundle_archive_pt archive) {
celix_status_t bundleArchive_closeAndDelete(bundle_archive_pt archive) {
celix_status_t status = CELIX_SUCCESS;
-
- const char* err = NULL;
- status = celix_utils_deleteDirectory(archive->archiveRoot, &err);
- framework_logIfError(archive->fw->logger, status, NULL, "Failed to delete archive root '%s': %s", archive->archiveRoot, err);
+ if (!archive->isSystemBundle) {
+ const char* err = NULL;
+ status = celix_utils_deleteDirectory(archive->archiveRoot, &err);
+ framework_logIfError(archive->fw->logger, status, NULL, "Failed to delete archive root '%s': %s", archive->archiveRoot, err);
+ }
return status;
}
diff --git a/libs/framework/src/bundle_archive_private.h b/libs/framework/src/bundle_archive_private.h
index 29e65102..e8c7e229 100644
--- a/libs/framework/src/bundle_archive_private.h
+++ b/libs/framework/src/bundle_archive_private.h
@@ -41,6 +41,9 @@ extern "C" {
/**
* @brief Create bundle archive.
+ * Create a bundle archive for the given root, id, location and revision nr.
+ * Also create the bundle cache dir and if will reuse a existing bundle resource cache dir if the provided
+ * bundle zip location is older then the existing bundle resource cache dir.
*/
celix_status_t celix_bundleArchive_create(celix_framework_t* fw, const char *archiveRoot, long id, const char *location, bundle_archive_pt *bundle_archive);
diff --git a/libs/framework/src/celix_bundle_cache.c b/libs/framework/src/celix_bundle_cache.c
index 59cf01a4..aa0bbce8 100644
--- a/libs/framework/src/celix_bundle_cache.c
+++ b/libs/framework/src/celix_bundle_cache.c
@@ -56,26 +56,26 @@ struct celix_bundle_cache {
static const char* bundleCache_progamName() {
#if defined(__APPLE__) || defined(__FreeBSD__)
- return getprogname();
+ return getprogname();
#elif defined(_GNU_SOURCE)
- return program_invocation_short_name;
+ return program_invocation_short_name;
#else
- return "";
+ return "";
#endif
}
static const char* celix_bundleCache_cacheDirPath(celix_framework_t* fw) {
bool found = false;
const char* cacheDir = celix_framework_getConfigProperty(fw,
- CELIX_FRAMEWORK_FRAMEWORK_CACHE_DIR,
- CELIX_FRAMEWORK_FRAMEWORK_CACHE_DIR_DEFAULT,
- &found);
+ CELIX_FRAMEWORK_FRAMEWORK_CACHE_DIR,
+ CELIX_FRAMEWORK_FRAMEWORK_CACHE_DIR_DEFAULT,
+ &found);
if (!found) {
//falling back to old property
cacheDir = celix_framework_getConfigProperty(fw,
- OSGI_FRAMEWORK_FRAMEWORK_STORAGE,
- CELIX_FRAMEWORK_FRAMEWORK_CACHE_DIR_DEFAULT,
- NULL);
+ OSGI_FRAMEWORK_FRAMEWORK_STORAGE,
+ CELIX_FRAMEWORK_FRAMEWORK_CACHE_DIR_DEFAULT,
+ NULL);
}
return cacheDir;
}
@@ -83,15 +83,15 @@ static const char* celix_bundleCache_cacheDirPath(celix_framework_t* fw) {
static bool celix_bundleCache_useTmpDir(celix_framework_t* fw) {
bool converted = false;
bool useTmp = celix_framework_getConfigPropertyAsBool(fw,
- CELIX_FRAMEWORK_CACHE_USE_TMP_DIR,
- CELIX_FRAMEWORK_CACHE_USE_TMP_DIR_DEFAULT,
- &converted);
+ CELIX_FRAMEWORK_CACHE_USE_TMP_DIR,
+ CELIX_FRAMEWORK_CACHE_USE_TMP_DIR_DEFAULT,
+ &converted);
if (!converted) {
//falling back to old property
useTmp = celix_framework_getConfigPropertyAsBool(fw,
- CELIX_FRAMEWORK_STORAGE_USE_TMP_DIR,
- CELIX_FRAMEWORK_CACHE_USE_TMP_DIR_DEFAULT,
- NULL);
+ CELIX_FRAMEWORK_STORAGE_USE_TMP_DIR,
+ CELIX_FRAMEWORK_CACHE_USE_TMP_DIR_DEFAULT,
+ NULL);
}
return useTmp;
}
@@ -99,23 +99,23 @@ static bool celix_bundleCache_useTmpDir(celix_framework_t* fw) {
static bool celix_bundleCache_cleanOnCreate(celix_framework_t* fw) {
bool converted = false;
bool cleanOnCreate = celix_framework_getConfigPropertyAsBool(fw,
- CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE,
- CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE_DEFAULT,
- &converted);
+ CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE,
+ CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE_DEFAULT,
+ &converted);
if (!converted) {
//falling back to old property
cleanOnCreate = celix_framework_getConfigPropertyAsBool(fw,
- CELIX_FRAMEWORK_FRAMEWORK_STORAGE_CLEAN_NAME,
- CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE_DEFAULT,
- NULL);
+ CELIX_FRAMEWORK_FRAMEWORK_STORAGE_CLEAN_NAME,
+ CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE_DEFAULT,
+ NULL);
}
return cleanOnCreate;
}
-celix_status_t celix_bundleCache_create(celix_framework_t* fw, celix_bundle_cache_t **out) {
+celix_status_t celix_bundleCache_create(celix_framework_t* fw, celix_bundle_cache_t** out) {
celix_status_t status = CELIX_SUCCESS;
- celix_bundle_cache_t *cache = calloc(1, sizeof(*cache));
+ celix_bundle_cache_t* cache = calloc(1, sizeof(*cache));
if (!cache) {
status = CELIX_ENOMEM;
goto cache_calloc_failure;
@@ -135,7 +135,7 @@ celix_status_t celix_bundleCache_create(celix_framework_t* fw, celix_bundle_cach
if (useTmpDir) {
//Using /tmp dir for cache, so that multiple frameworks can be launched
//instead of cacheDir = ".cache";
- const char *pg = bundleCache_progamName();
+ const char* pg = bundleCache_progamName();
if (pg == NULL) {
pg = "";
}
@@ -155,32 +155,33 @@ celix_status_t celix_bundleCache_create(celix_framework_t* fw, celix_bundle_cach
const char* errorStr;
status = celix_utils_createDirectory(cache->cacheDir, false, &errorStr);
if (status != CELIX_SUCCESS) {
- fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot create bundle cache directory %s, error %s", cache->cacheDir, errorStr);
+ fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot create bundle cache directory %s, error %s",
+ cache->cacheDir, errorStr);
goto manipulate_dir_failure;
}
*out = cache;
return CELIX_SUCCESS;
-manipulate_dir_failure:
+ manipulate_dir_failure:
free(cache->cacheDir);
-cache_dir_failure:
+ cache_dir_failure:
celixThreadMutex_destroy(&cache->mutex);
celix_stringHashMap_destroy(cache->locationToBundleIdLookupMap);
-cache_map_failure:
+ cache_map_failure:
free(cache);
-cache_calloc_failure:
+ cache_calloc_failure:
return status;
}
celix_status_t celix_bundleCache_destroy(celix_bundle_cache_t* cache) {
celix_status_t status = CELIX_SUCCESS;
- if (cache->deleteOnDestroy) {
+ if (cache->deleteOnDestroy) {
status = celix_bundleCache_deleteCacheDir(cache);
- }
- free(cache->cacheDir);
+ }
+ free(cache->cacheDir);
celix_stringHashMap_destroy(cache->locationToBundleIdLookupMap);
celixThreadMutex_destroy(&cache->mutex);
- free(cache);
- return status;
+ free(cache);
+ return status;
}
celix_status_t celix_bundleCache_deleteCacheDir(celix_bundle_cache_t* cache) {
@@ -192,30 +193,33 @@ celix_status_t celix_bundleCache_deleteCacheDir(celix_bundle_cache_t* cache) {
}
celixThreadMutex_unlock(&cache->mutex);
if (status != CELIX_SUCCESS) {
- fw_logCode(cache->fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot delete bundle cache directory %s: %s", cache->cacheDir, err);
+ fw_logCode(cache->fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot delete bundle cache directory %s: %s",
+ cache->cacheDir, err);
}
return status;
}
-celix_status_t celix_bundleCache_createArchive(celix_framework_t* fw, long id, const char *location, bundle_archive_t** archiveOut) {
+celix_status_t
+celix_bundleCache_createArchive(celix_bundle_cache_t* cache, long id, const char* location, bundle_archive_t** archiveOut) {
celix_status_t status = CELIX_SUCCESS;
bundle_archive_t* archive = NULL;
char archiveRootBuffer[CELIX_DEFAULT_STRING_CREATE_BUFFER_SIZE];
- char *archiveRoot = celix_utils_writeOrCreateString(archiveRootBuffer, sizeof(archiveRootBuffer), CELIX_BUNDLE_ARCHIVE_ROOT_FORMAT, fw->cache->cacheDir, id);
+ char* archiveRoot = celix_utils_writeOrCreateString(archiveRootBuffer, sizeof(archiveRootBuffer),
+ CELIX_BUNDLE_ARCHIVE_ROOT_FORMAT, cache->cacheDir, id);
if (archiveRoot) {
- celixThreadMutex_lock(&fw->cache->mutex);
- status = celix_bundleArchive_create(fw, archiveRoot, id, location, &archive);
+ celixThreadMutex_lock(&cache->mutex);
+ status = celix_bundleArchive_create(cache->fw, archiveRoot, id, location, &archive);
if (status == CELIX_SUCCESS) {
- celix_stringHashMap_put(fw->cache->locationToBundleIdLookupMap, location, (void*)id);
+ celix_stringHashMap_put(cache->locationToBundleIdLookupMap, location, (void*) id);
}
- celixThreadMutex_unlock(&fw->cache->mutex);
+ celixThreadMutex_unlock(&cache->mutex);
celix_utils_freeStringIfNotEqual(archiveRootBuffer, archiveRoot);
} else {
status = CELIX_ENOMEM;
}
if (status != CELIX_SUCCESS) {
- fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Failed to create archive.");
+ fw_logCode(cache->fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Failed to create archive.");
return status;
}
*archiveOut = archive;
@@ -223,18 +227,18 @@ celix_status_t celix_bundleCache_createArchive(celix_framework_t* fw, long id, c
}
celix_status_t celix_bundleCache_createSystemArchive(celix_framework_t* fw, bundle_archive_pt* archive) {
- return celix_bundleCache_createArchive(fw, CELIX_FRAMEWORK_BUNDLE_ID, NULL, archive);
+ return celix_bundleCache_createArchive(fw->cache, CELIX_FRAMEWORK_BUNDLE_ID, NULL, archive);
}
-celix_status_t celix_bundleCache_destroyArchive(celix_bundle_cache_t *cache, bundle_archive_pt archive) {
- celix_status_t status = CELIX_SUCCESS;
+celix_status_t celix_bundleCache_destroyArchive(celix_bundle_cache_t* cache, bundle_archive_pt archive) {
+ celix_status_t status = CELIX_SUCCESS;
const char* loc = NULL;
celixThreadMutex_lock(&cache->mutex);
- (void)bundleArchive_getLocation(archive, &loc);
- (void)celix_stringHashMap_remove(cache->locationToBundleIdLookupMap, loc);
+ (void) bundleArchive_getLocation(archive, &loc);
+ (void) celix_stringHashMap_remove(cache->locationToBundleIdLookupMap, loc);
status = bundleArchive_closeAndDelete(archive);
celixThreadMutex_unlock(&cache->mutex);
- (void)bundleArchive_destroy(archive);
+ (void) bundleArchive_destroy(archive);
return status;
}
@@ -245,7 +249,8 @@ static void celix_bundleCache_updateIdForLocationLookupMap(celix_bundle_cache_t*
celixThreadMutex_lock(&cache->mutex);
DIR* dir = opendir(cache->cacheDir);
if (dir == NULL) {
- fw_logCode(cache->fw->logger, CELIX_LOG_LEVEL_ERROR, CELIX_BUNDLE_EXCEPTION, "Cannot open bundle cache directory %s", cache->cacheDir);
+ fw_logCode(cache->fw->logger, CELIX_LOG_LEVEL_ERROR, CELIX_BUNDLE_EXCEPTION,
+ "Cannot open bundle cache directory %s", cache->cacheDir);
celixThreadMutex_unlock(&cache->mutex);
return;
}
@@ -255,12 +260,12 @@ static void celix_bundleCache_updateIdForLocationLookupMap(celix_bundle_cache_t*
if (strncmp(dent->d_name, "bundle", 6) != 0) {
continue;
}
- char *bundleStateProperties = celix_utils_writeOrCreateString(archiveRootBuffer, sizeof(archiveRootBuffer),
+ char* bundleStateProperties = celix_utils_writeOrCreateString(archiveRootBuffer, sizeof(archiveRootBuffer),
"%s/%s/%s", cache->cacheDir, dent->d_name,
CELIX_BUNDLE_ARCHIVE_STATE_PROPERTIES_FILE_NAME);
if (celix_utils_fileExists(bundleStateProperties)) {
- celix_properties_t *props = celix_properties_load(bundleStateProperties);
- const char *visitLoc = celix_properties_get(props, CELIX_BUNDLE_ARCHIVE_LOCATION_PROPERTY_NAME, NULL);
+ celix_properties_t* props = celix_properties_load(bundleStateProperties);
+ const char* visitLoc = celix_properties_get(props, CELIX_BUNDLE_ARCHIVE_LOCATION_PROPERTY_NAME, NULL);
long bndId = celix_properties_getAsLong(props, CELIX_BUNDLE_ARCHIVE_BUNDLE_ID_PROPERTY_NAME, -1);
if (visitLoc != NULL && bndId >= 0) {
fw_log(cache->fw->logger, CELIX_LOG_LEVEL_TRACE, "Adding location %s -> bnd id %li to lookup map",
@@ -274,49 +279,52 @@ static void celix_bundleCache_updateIdForLocationLookupMap(celix_bundle_cache_t*
celixThreadMutex_unlock(&cache->mutex);
}
-long celix_bundleCache_findBundleIdForLocation(celix_framework_t *fw, const char *location) {
+long celix_bundleCache_findBundleIdForLocation(celix_bundle_cache_t* cache, const char* location) {
long bndId = -1;
- celixThreadMutex_lock(&fw->cache->mutex);
- if (celix_stringHashMap_hasKey(fw->cache->locationToBundleIdLookupMap, location)) {
- bndId = celix_stringHashMap_getLong(fw->cache->locationToBundleIdLookupMap, location, -1);
+ celixThreadMutex_lock(&cache->mutex);
+ if (celix_stringHashMap_hasKey(cache->locationToBundleIdLookupMap, location)) {
+ bndId = celix_stringHashMap_getLong(cache->locationToBundleIdLookupMap, location, -1);
}
- celixThreadMutex_unlock(&fw->cache->mutex);
+ celixThreadMutex_unlock(&cache->mutex);
if (bndId == -1) {
- celix_bundleCache_updateIdForLocationLookupMap(fw->cache);
- celixThreadMutex_lock(&fw->cache->mutex);
- bndId = celix_stringHashMap_getLong(fw->cache->locationToBundleIdLookupMap, location, -1);
- celixThreadMutex_unlock(&fw->cache->mutex);
+ celix_bundleCache_updateIdForLocationLookupMap(cache);
+ celixThreadMutex_lock(&cache->mutex);
+ bndId = celix_stringHashMap_getLong(cache->locationToBundleIdLookupMap, location, -1);
+ celixThreadMutex_unlock(&cache->mutex);
}
return bndId;
}
-bool celix_bundleCache_isBundleIdAlreadyUsed(celix_framework_t *fw, long bndId) {
+bool celix_bundleCache_isBundleIdAlreadyUsed(celix_bundle_cache_t* cache, long bndId) {
bool found = false;
- celixThreadMutex_lock(&fw->cache->mutex);
- CELIX_STRING_HASH_MAP_ITERATE(fw->cache->locationToBundleIdLookupMap, iter) {
+ celixThreadMutex_lock(&cache->mutex);
+ CELIX_STRING_HASH_MAP_ITERATE(cache->locationToBundleIdLookupMap, iter) {
if (iter.value.longValue == bndId) {
found = true;
break;
}
}
- celixThreadMutex_unlock(&fw->cache->mutex);
+ celixThreadMutex_unlock(&cache->mutex);
return found;
}
-static celix_status_t celix_bundleCache_createBundleArchivesForSpaceSeparatedList(celix_framework_t *fw, long* bndId, const char* list, bool logProgress) {
+static celix_status_t
+celix_bundleCache_createBundleArchivesForSpaceSeparatedList(celix_framework_t* fw, long* bndId, const char* list,
+ bool logProgress) {
celix_status_t status = CELIX_SUCCESS;
char delims[] = " ";
- char *savePtr = NULL;
+ char* savePtr = NULL;
char zipFileListBuffer[CELIX_DEFAULT_STRING_CREATE_BUFFER_SIZE];
char* zipFileList = celix_utils_writeOrCreateString(zipFileListBuffer, sizeof(zipFileListBuffer), "%s", list);
if (zipFileList) {
- char *location = strtok_r(zipFileList, delims, &savePtr);
+ char* location = strtok_r(zipFileList, delims, &savePtr);
while (location != NULL) {
bundle_archive_t* archive = NULL;
- status = celix_bundleCache_createArchive(fw, (*bndId)++, location, &archive);
+ status = celix_bundleCache_createArchive(fw->cache, (*bndId)++, location, &archive);
if (status != CELIX_SUCCESS) {
- fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, CELIX_BUNDLE_EXCEPTION, "Cannot create bundle archive for %s", location);
+ fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status,
+ "Cannot create bundle archive for %s", location);
break;
} else {
celix_log_level_e lvl = logProgress ? CELIX_LOG_LEVEL_INFO : CELIX_LOG_LEVEL_DEBUG;
@@ -335,18 +343,22 @@ static celix_status_t celix_bundleCache_createBundleArchivesForSpaceSeparatedLis
return status;
}
-celix_status_t celix_bundleCache_createBundleArchivesCache(celix_framework_t *fw, bool logProgress) {
+celix_status_t celix_bundleCache_createBundleArchivesCache(celix_framework_t* fw, bool logProgress) {
celix_status_t status = CELIX_SUCCESS;
- const char* const cosgiKeys[] = {"cosgi.auto.start.0","cosgi.auto.start.1","cosgi.auto.start.2","cosgi.auto.start.3","cosgi.auto.start.4","cosgi.auto.start.5","cosgi.auto.start.6", NULL};
- const char* const celixKeys[] = {CELIX_AUTO_START_0, CELIX_AUTO_START_1, CELIX_AUTO_START_2, CELIX_AUTO_START_3, CELIX_AUTO_START_4, CELIX_AUTO_START_5, CELIX_AUTO_START_6, NULL};
+ const char* const cosgiKeys[] = {"cosgi.auto.start.0", "cosgi.auto.start.1", "cosgi.auto.start.2",
+ "cosgi.auto.start.3", "cosgi.auto.start.4", "cosgi.auto.start.5",
+ "cosgi.auto.start.6", NULL};
+ const char* const celixKeys[] = {CELIX_AUTO_START_0, CELIX_AUTO_START_1, CELIX_AUTO_START_2, CELIX_AUTO_START_3,
+ CELIX_AUTO_START_4, CELIX_AUTO_START_5, CELIX_AUTO_START_6, NULL};
CELIX_BUILD_ASSERT(sizeof(*cosgiKeys) == sizeof(*celixKeys));
- long bndId = CELIX_FRAMEWORK_BUNDLE_ID+1; //note cleaning cache, so starting bundle id at 1
+ long bndId = CELIX_FRAMEWORK_BUNDLE_ID + 1; //note cleaning cache, so starting bundle id at 1
const char* errorStr = NULL;
status = celix_utils_deleteDirectory(fw->cache->cacheDir, &errorStr);
if (status != CELIX_SUCCESS) {
- fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Failed to delete bundle cache directory %s: %s", fw->cache->cacheDir, errorStr);
+ fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Failed to delete bundle cache directory %s: %s",
+ fw->cache->cacheDir, errorStr);
return status;
} else {
celix_log_level_e lvl = logProgress ? CELIX_LOG_LEVEL_INFO : CELIX_LOG_LEVEL_DEBUG;
@@ -354,14 +366,15 @@ celix_status_t celix_bundleCache_createBundleArchivesCache(celix_framework_t *fw
}
for (int i = 0; celixKeys[i] != NULL; ++i) {
- const char *autoStart = celix_framework_getConfigProperty(fw, celixKeys[i], NULL, NULL);
+ const char* autoStart = celix_framework_getConfigProperty(fw, celixKeys[i], NULL, NULL);
if (autoStart == NULL) {
autoStart = celix_framework_getConfigProperty(fw, cosgiKeys[i], NULL, NULL);
}
if (autoStart) {
status = celix_bundleCache_createBundleArchivesForSpaceSeparatedList(fw, &bndId, autoStart, logProgress);
if (status != CELIX_SUCCESS) {
- fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Failed to create bundle archives for auto start list %s", autoStart);
+ fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status,
+ "Failed to create bundle archives for auto start list %s", autoStart);
return status;
}
}
@@ -370,7 +383,8 @@ celix_status_t celix_bundleCache_createBundleArchivesCache(celix_framework_t *fw
if (autoInstall) {
status = celix_bundleCache_createBundleArchivesForSpaceSeparatedList(fw, &bndId, autoInstall, logProgress);
if (status != CELIX_SUCCESS) {
- fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Failed to create bundle archives for auto start list %s", autoInstall);
+ fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status,
+ "Failed to create bundle archives for auto install list %s", autoInstall);
return status;
}
}
diff --git a/libs/framework/src/celix_bundle_cache.h b/libs/framework/src/celix_bundle_cache.h
index 06810b54..14f5ea86 100644
--- a/libs/framework/src/celix_bundle_cache.h
+++ b/libs/framework/src/celix_bundle_cache.h
@@ -47,7 +47,7 @@ typedef struct celix_bundle_cache celix_bundle_cache_t;
* @return CELIX_SUCCESS if bundle cache is successfully created.
*/
celix_status_t
-celix_bundleCache_create(celix_framework_t* fw, celix_bundle_cache_t **out);
+celix_bundleCache_create(celix_framework_t* fw, celix_bundle_cache_t** out);
/**
* @brief Destroy the bundle cache, releasing all resources allocated in celix_bundleCache_create
@@ -56,12 +56,12 @@ celix_bundleCache_create(celix_framework_t* fw, celix_bundle_cache_t **out);
* @return Status code indication failure or success:
* - CELIX_SUCCESS when no errors are encountered.
*/
-celix_status_t celix_bundleCache_destroy(celix_bundle_cache_t *cache);
+celix_status_t celix_bundleCache_destroy(celix_bundle_cache_t* cache);
/**
- * @brief Creates a new archive for the given bundle (using the id and location). The archive is created on the supplied bundlePool.
+ * @brief Creates a new archive for the given bundle (using the id and location).
*
- * @param fw The Celix framework to create an archive in
+ * @param cache The bundle cache to create an archive in.
* @param id The id of the bundle
* @param location The location identifier of the bundle
* @param archive The archive to create
@@ -72,7 +72,7 @@ celix_status_t celix_bundleCache_destroy(celix_bundle_cache_t *cache);
* - CELIX_ENOMEM If allocating memory for <code>bundle_archive</code> failed.
*/
celix_status_t
-celix_bundleCache_createArchive(celix_framework_t *fw, long id, const char *location, bundle_archive_pt *archive);
+celix_bundleCache_createArchive(celix_bundle_cache_t* cache, long id, const char* location, bundle_archive_pt* archive);
/**
* @@brief Creates a new system archive for framework bundle.
@@ -85,7 +85,7 @@ celix_bundleCache_createArchive(celix_framework_t *fw, long id, const char *loca
* - CELIX_FILE_IO_EXCEPTION If the cache cannot be opened or read.
* - CELIX_BUNDLE_EXCEPTION If the bundle cannot be created.
*/
-celix_status_t celix_bundleCache_createSystemArchive(celix_framework_t* fw, bundle_archive_pt *archive);
+celix_status_t celix_bundleCache_createSystemArchive(celix_framework_t* fw, bundle_archive_pt* archive);
/**
* @brief Destroy the archive from the cache.
@@ -97,7 +97,7 @@ celix_status_t celix_bundleCache_createSystemArchive(celix_framework_t* fw, bund
* - CELIX_FILE_IO_EXCEPTION when root of the archive is not a directory.
* - errno when the directory cannot be deleted for other reasons, check error codes of fts_open/fts_read/remove.
*/
-celix_status_t celix_bundleCache_destroyArchive(celix_bundle_cache_t *cache, bundle_archive_pt archive);
+celix_status_t celix_bundleCache_destroyArchive(celix_bundle_cache_t* cache, bundle_archive_pt archive);
/**
* @brief Deletes the entire bundle cache.
@@ -108,25 +108,25 @@ celix_status_t celix_bundleCache_destroyArchive(celix_bundle_cache_t *cache, bu
* - CELIX_ILLEGAL_ARGUMENT If the cache is invalid
* - CELIX_FILE_IO_EXCEPTION If the cache cannot be opened or read.
*/
-celix_status_t celix_bundleCache_deleteCacheDir(celix_bundle_cache_t *cache);
+celix_status_t celix_bundleCache_deleteCacheDir(celix_bundle_cache_t* cache);
/**
* @brief Find if the there is already a bundle cache for the provided bundle zip location and if this is true
* return the bundle id for the bundle cache entry.
*
- * @param fw The framework.
+ * @param cache The cache.
* @param location The location of the bundle zip to find the id for.
* @return The bundle id or -1 if not found.
*/
-long celix_bundleCache_findBundleIdForLocation(celix_framework_t *fw, const char *location);
+long celix_bundleCache_findBundleIdForLocation(celix_bundle_cache_t* cache, const char* location);
/**
* @brief Find if the there is already a bundle cache for the provided bundle id.
- * @param fw The framework.
+ * @param cache The bundle cache.
* @param bndId The bundle id to find the bundle cache for.
* @return Whether the bundle id is already used in a bundle cache entry.
*/
-bool celix_bundleCache_isBundleIdAlreadyUsed(celix_framework_t *fw, long bndId);
+bool celix_bundleCache_isBundleIdAlreadyUsed(celix_bundle_cache_t* cache, long bndId);
/**
* Clean existing cache dir and create the bundle archives cache for all the bundles configured for starting and
@@ -141,7 +141,7 @@ bool celix_bundleCache_isBundleIdAlreadyUsed(celix_framework_t *fw, long bndId);
* @param[in] printProgress Whether report progress of bundle archive creation.
* @return Status code indication failure or success.
*/
-celix_status_t celix_bundleCache_createBundleArchivesCache(celix_framework_t *fw, bool printProgress);
+celix_status_t celix_bundleCache_createBundleArchivesCache(celix_framework_t* fw, bool printProgress);
#ifdef __cplusplus
}
diff --git a/libs/framework/src/framework.c b/libs/framework/src/framework.c
index 8e9dd886..f87c3432 100644
--- a/libs/framework/src/framework.c
+++ b/libs/framework/src/framework.c
@@ -650,10 +650,10 @@ celix_status_t celix_framework_installBundleInternal(celix_framework_t *framewor
return CELIX_SUCCESS;
}
- long alreadyExistingBndId = celix_bundleCache_findBundleIdForLocation(framework, bndLoc);
+ long alreadyExistingBndId = celix_bundleCache_findBundleIdForLocation(framework->cache, bndLoc);
long id = alreadyExistingBndId == -1 ? framework_getNextBundleId(framework) : alreadyExistingBndId;
bundle_archive_t* archive = NULL;
- status = CELIX_DO_IF(status, celix_bundleCache_createArchive(framework, id, bndLoc, &archive));
+ status = CELIX_DO_IF(status, celix_bundleCache_createArchive(framework->cache, id, bndLoc, &archive));
status = CELIX_DO_IF(status, celix_bundle_createFromArchive(framework, archive, &bundle));
if (status == CELIX_SUCCESS) {
celix_framework_bundle_entry_t *bEntry = fw_bundleEntry_create(bundle);
@@ -971,7 +971,7 @@ celix_status_t fw_removeFrameworkListener(framework_pt framework, bundle_pt bund
long framework_getNextBundleId(framework_pt framework) {
long nextId = __atomic_fetch_add(&framework->currentBundleId, 1, __ATOMIC_SEQ_CST);
- while ( celix_bundleCache_isBundleIdAlreadyUsed(framework, nextId) ||
+ while ( celix_bundleCache_isBundleIdAlreadyUsed(framework->cache, nextId) ||
celix_framework_isBundleIdAlreadyUsed(framework, nextId)) {
nextId = __atomic_fetch_add(&framework->currentBundleId, 1, __ATOMIC_SEQ_CST);
}