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 eca2f207c87c362208281219112dbe4a9570bd8d Author: PengZheng <[email protected]> AuthorDate: Sun May 28 18:25:51 2023 +0800 Delete residue archive directory in case of errors. --- .../BundleArchiveWithErrorInjectionTestSuite.cc | 59 ++++++++-- .../gtest/src/CelixBundleCacheTestSuite.cc | 2 + libs/framework/include_deprecated/bundle_archive.h | 7 +- libs/framework/src/bundle_archive.c | 128 +++++++++++---------- libs/framework/src/bundle_archive_private.h | 7 ++ 5 files changed, 132 insertions(+), 71 deletions(-) diff --git a/libs/framework/gtest/src/BundleArchiveWithErrorInjectionTestSuite.cc b/libs/framework/gtest/src/BundleArchiveWithErrorInjectionTestSuite.cc index bd8e71a9..4cccd60e 100644 --- a/libs/framework/gtest/src/BundleArchiveWithErrorInjectionTestSuite.cc +++ b/libs/framework/gtest/src/BundleArchiveWithErrorInjectionTestSuite.cc @@ -91,6 +91,14 @@ TEST_F(BundleArchiveWithErrorInjectionTestSuite, BundleArchiveCreatedFailedTest) celix_ei_expect_asprintf((void*)celix_bundleArchive_create, 0, -1); installBundleAndExpectFailure(); + teardownErrorInjectors(); + celix_ei_expect_asprintf((void*)celix_bundleArchive_create, 0, -1, 2); + installBundleAndExpectFailure(); + + teardownErrorInjectors(); + celix_ei_expect_asprintf((void*)celix_bundleArchive_create, 0, -1, 3); + installBundleAndExpectFailure(); + teardownErrorInjectors(); // Given a mocked malloc which returns NULL from a call from manifest_create celix_ei_expect_malloc((void*)manifest_create, 0, nullptr); @@ -117,22 +125,12 @@ TEST_F(BundleArchiveWithErrorInjectionTestSuite, BundleArchiveCreateCacheDirecto 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, 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, 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, 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 @@ -159,6 +157,7 @@ class CelixBundleArchiveErrorInjectionTestSuite : public ::testing::Test { fw.logger = celix_frameworkLogger_create(CELIX_LOG_LEVEL_TRACE); } ~CelixBundleArchiveErrorInjectionTestSuite() override { + celix_utils_deleteDirectory(TEST_ARCHIVE_ROOT, nullptr); celix_frameworkLogger_destroy(fw.logger); celix_properties_destroy(fw.configurationMap); } @@ -167,25 +166,63 @@ class CelixBundleArchiveErrorInjectionTestSuite : public ::testing::Test { EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_create(&fw, &fw.cache)); *cache = fw.cache; } + 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); + celix_ei_expect_celix_utils_strdup(nullptr, 0, nullptr); + celix_ei_expect_celix_utils_createDirectory(nullptr, 0, CELIX_SUCCESS); + celix_ei_expect_celix_utils_getLastModified(nullptr, 0, CELIX_SUCCESS); + celix_ei_expect_celix_utils_deleteDirectory(nullptr, 0, CELIX_SUCCESS); + celix_ei_expect_celix_utils_writeOrCreateString(nullptr, 0, nullptr); + celix_ei_expect_celix_utils_extractZipData(nullptr, 0, CELIX_SUCCESS); + } struct celix_framework fw {}; }; TEST_F(CelixBundleArchiveErrorInjectionTestSuite, ArchiveCreateErrorTest) { celix_bundle_cache_t* cache = nullptr; createCache(&cache); - bundle_archive_t* archive = nullptr; + + // archive directory creation failures not covered by other tests + celix_ei_expect_celix_utils_writeOrCreateString((void*)celix_bundleArchive_getLastModifiedInternal, 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)); + teardownErrorInjectors(); + + celix_ei_expect_celix_utils_deleteDirectory((void*)celix_bundleArchive_create, 2, CELIX_FILE_IO_EXCEPTION); + EXPECT_EQ(CELIX_FILE_IO_EXCEPTION, + 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)); + teardownErrorInjectors(); + + celix_ei_expect_celix_utils_writeOrCreateString((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)); + teardownErrorInjectors(); + + // revision creation failure 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)); + teardownErrorInjectors(); + // bundle state persistence failure 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)); + teardownErrorInjectors(); 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 index 8333d587..675ef0ff 100644 --- a/libs/framework/gtest/src/CelixBundleCacheTestSuite.cc +++ b/libs/framework/gtest/src/CelixBundleCacheTestSuite.cc @@ -51,6 +51,7 @@ 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_STREQ(SIMPLE_TEST_BUNDLE1_LOCATION, celix_bundleArchive_getLocation(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); @@ -69,6 +70,7 @@ TEST_F(CelixBundleCacheTestSuite, SystemArchiveCreateDestroyTest) { EXPECT_EQ(0, celix_bundleArchive_getId(archive)); EXPECT_EQ(CELIX_SUCCESS, bundleArchive_getArchiveRoot(archive, &archiveRoot)); EXPECT_EQ(nullptr, archiveRoot); + EXPECT_EQ(nullptr, celix_bundleArchive_getLocation(archive)); EXPECT_EQ(CELIX_SUCCESS, celix_bundleCache_destroyArchive(fw.cache, archive)); } diff --git a/libs/framework/include_deprecated/bundle_archive.h b/libs/framework/include_deprecated/bundle_archive.h index 7ea6f061..daa9b0aa 100644 --- a/libs/framework/include_deprecated/bundle_archive.h +++ b/libs/framework/include_deprecated/bundle_archive.h @@ -96,8 +96,11 @@ CELIX_FRAMEWORK_DEPRECATED_EXPORT celix_status_t bundleArchive_getPersistentStat * * @param[in] archive The bundle archive. * @param[out] lastModified The last modified time of the bundle archive. - * @return CELIX_SUCCESS if the last modified time could be retrieved, CELIX_FILE_IO_EXCEPTION if the last modified - * time could not be retrieved. Check errno for more specific error information. + * @return Status code indication failure or success: + * - CELIX_SUCCESS when no errors are encountered. + * - CELIX_FILE_IO_EXCEPTION if the last modified time could not be retrieved. + * Check errno for more specific error information.when root of the archive is not a directory. + * - CELIX_ENOMEM not enough memory for manifest file path. */ CELIX_FRAMEWORK_DEPRECATED_EXPORT celix_status_t celix_bundleArchive_getLastModified(bundle_archive_pt archive, struct timespec* lastModified); diff --git a/libs/framework/src/bundle_archive.c b/libs/framework/src/bundle_archive.c index 668d113d..d82faf8a 100644 --- a/libs/framework/src/bundle_archive.c +++ b/libs/framework/src/bundle_archive.c @@ -37,8 +37,6 @@ #include "framework_private.h" #include "linked_list_iterator.h" -celix_status_t celix_bundleArchive_getLastModifiedInternal(bundle_archive_pt archive, struct timespec *lastModified); - /** * The bundle archive which is used to store the bundle data and can be reused when a framework is restarted. * The lifecycle of a bundle archive is coupled to the lifecycle of the bundle that is created from the archive. @@ -46,18 +44,18 @@ celix_status_t celix_bundleArchive_getLastModifiedInternal(bundle_archive_pt arc * @note The bundle archive is thread safe. */ struct bundleArchive { - //initialed during creation and immutable - celix_framework_t* fw; - long id; - char *archiveRoot; - char *savedBundleStatePropertiesPath; + // initialed during creation and immutable + celix_framework_t* fw; + long id; + char* archiveRoot; + char* savedBundleStatePropertiesPath; char* storeRoot; char* resourceCacheRoot; - char* bundleSymbolicName; //read from the manifest - char* bundleVersion; //read from the manifest + char* bundleSymbolicName; // read from the manifest + char* bundleVersion; // read from the manifest - celix_thread_mutex_t lock; //protects below and saving of bundle state properties - bundle_revision_t* revision; //the current revision + celix_thread_mutex_t lock; // protects below and saving of bundle state properties + bundle_revision_t* revision; // the current revision char* location; }; @@ -82,10 +80,8 @@ static celix_status_t celix_bundleArchive_storeBundleStateProperties(bundle_arch return CELIX_SUCCESS; } -celix_status_t celix_bundleArchive_extractBundle( - bundle_archive_t* archive, - const char* revisionRoot, - const char* bundleUrl) { +static celix_status_t +celix_bundleArchive_extractBundle(bundle_archive_t* archive, const char* bundleUrl) { celix_status_t status = CELIX_SUCCESS; bool extractBundle = true; @@ -97,7 +93,6 @@ celix_status_t celix_bundleArchive_extractBundle( return status; } - //check if bundle location is newer than current revision if (status == CELIX_SUCCESS) { extractBundle = celix_framework_utils_isBundleUrlNewerThan(archive->fw, bundleUrl, &revisionMod); @@ -115,13 +110,13 @@ celix_status_t celix_bundleArchive_extractBundle( * segfaults. */ const char* error; - status = celix_utils_deleteDirectory(revisionRoot, &error); + status = celix_utils_deleteDirectory(archive->resourceCacheRoot, &error); if (status != CELIX_SUCCESS) { - fw_logCode(archive->fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Failed to remove existing bundle archive revision directory '%s': %s", revisionRoot, error); + fw_logCode(archive->fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Failed to remove existing bundle archive revision directory '%s': %s", archive->resourceCacheRoot, error); return status; } - status = celix_framework_utils_extractBundle(archive->fw, bundleUrl, revisionRoot); + status = celix_framework_utils_extractBundle(archive->fw, bundleUrl, archive->resourceCacheRoot); if (status != CELIX_SUCCESS) { fw_log(archive->fw->logger, CELIX_LOG_LEVEL_ERROR, "Failed to initialize archive. Failed to extract bundle zip to revision directory."); return status; @@ -133,7 +128,7 @@ celix_status_t celix_bundleArchive_extractBundle( * Initialize archive by creating the bundle cache directory, optionally extracting the bundle from the bundle file, * reading the bundle state properties, reading the bundle manifest and updating the bundle state properties. */ -celix_status_t celix_bundleArchive_createCacheDirectory(bundle_archive_pt archive, manifest_pt* manifestOut) { +static celix_status_t celix_bundleArchive_createCacheDirectory(bundle_archive_pt archive, manifest_pt* manifestOut) { if (celix_utils_fileExists(archive->archiveRoot)) { fw_log(archive->fw->logger, CELIX_LOG_LEVEL_TRACE, "Bundle archive root for bundle id %li already exists.", archive->id); @@ -148,11 +143,6 @@ celix_status_t celix_bundleArchive_createCacheDirectory(bundle_archive_pt archiv } //create store directory - int rc = asprintf(&archive->storeRoot, "%s/%s", archive->archiveRoot, CELIX_BUNDLE_ARCHIVE_STORE_DIRECTORY_NAME); - if (rc < 0) { - fw_log(archive->fw->logger, CELIX_LOG_LEVEL_ERROR, "Failed to initialize archive. Failed to create bundle store dir."); - return CELIX_ENOMEM; - } status = celix_utils_createDirectory(archive->storeRoot, false, &errorStr); if (status != CELIX_SUCCESS) { fw_log(archive->fw->logger, CELIX_LOG_LEVEL_ERROR, "Failed to initialize archive. Failed to create bundle store dir: %s", errorStr); @@ -160,12 +150,6 @@ celix_status_t celix_bundleArchive_createCacheDirectory(bundle_archive_pt archiv } //create bundle revision directory - rc = asprintf(&archive->resourceCacheRoot, "%s/%s", archive->archiveRoot, CELIX_BUNDLE_ARCHIVE_RESOURCE_CACHE_NAME); - if (rc < 0) { - fw_log(archive->fw->logger, CELIX_LOG_LEVEL_ERROR, "Failed to initialize archive. Failed to create bundle revision dir."); - return CELIX_ENOMEM; - } - status = celix_utils_createDirectory(archive->resourceCacheRoot, false, &errorStr); if (status != CELIX_SUCCESS) { fw_log(archive->fw->logger, CELIX_LOG_LEVEL_ERROR, "Failed to initialize archive. Failed to create bundle revision dir: %s", errorStr); @@ -173,7 +157,7 @@ celix_status_t celix_bundleArchive_createCacheDirectory(bundle_archive_pt archiv } //extract bundle zip to revision directory - status = celix_bundleArchive_extractBundle(archive, archive->resourceCacheRoot, archive->location); + status = celix_bundleArchive_extractBundle(archive, archive->location); if (status != CELIX_SUCCESS) { fw_log(archive->fw->logger, CELIX_LOG_LEVEL_ERROR, "Failed to initialize archive. Failed to extract bundle."); return status; @@ -183,6 +167,10 @@ celix_status_t celix_bundleArchive_createCacheDirectory(bundle_archive_pt archiv *manifestOut = NULL; char pathBuffer[512]; char* manifestPath = celix_utils_writeOrCreateString(pathBuffer, sizeof(pathBuffer), "%s/%s", archive->resourceCacheRoot, CELIX_BUNDLE_MANIFEST_REL_PATH); + if (manifestPath == NULL) { + fw_log(archive->fw->logger, CELIX_LOG_LEVEL_ERROR, "Failed to initialize archive. Failed to create manifest path."); + return CELIX_ENOMEM; + } status = manifest_createFromFile(manifestPath, manifestOut); celix_utils_freeStringIfNotEqual(pathBuffer, manifestPath); if (status != CELIX_SUCCESS) { @@ -229,15 +217,28 @@ celix_status_t celix_bundleArchive_create(celix_framework_t* fw, const char *arc status = CELIX_ENOMEM; } } else { - int rc; - archive->location = celix_utils_strdup(location); - archive->archiveRoot = celix_utils_strdup(archiveRoot); - 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) { - status = CELIX_ENOMEM; - } + status = CELIX_ENOMEM; + do { + archive->location = celix_utils_strdup(location); + if (archive->location == NULL) { + break; + } + archive->archiveRoot = celix_utils_strdup(archiveRoot); + if (archive->archiveRoot == NULL) { + break; + } + if (asprintf(&archive->savedBundleStatePropertiesPath, "%s/%s", archiveRoot, + CELIX_BUNDLE_ARCHIVE_STATE_PROPERTIES_FILE_NAME) < 0) { + break; + } + if (asprintf(&archive->storeRoot, "%s/%s", archive->archiveRoot, CELIX_BUNDLE_ARCHIVE_STORE_DIRECTORY_NAME) < 0) { + break; + } + if (asprintf(&archive->resourceCacheRoot, "%s/%s", archive->archiveRoot, CELIX_BUNDLE_ARCHIVE_RESOURCE_CACHE_NAME) < 0) { + break; + } + status = CELIX_SUCCESS; + } while (0); } if (status != CELIX_SUCCESS) { error = "Failed to setup archive paths."; @@ -252,7 +253,7 @@ celix_status_t celix_bundleArchive_create(celix_framework_t* fw, const char *arc } if (status != CELIX_SUCCESS) { error = "Failed to initialize archive or create manifest."; - goto init_failed; + goto dir_failed; } status = celix_bundleRevision_create(fw, archive->archiveRoot, archive->location, manifest, &archive->revision); @@ -273,6 +274,7 @@ celix_status_t celix_bundleArchive_create(celix_framework_t* fw, const char *arc return CELIX_SUCCESS; store_prop_failed: revision_failed: +dir_failed: if (!isSystemBundle) { celix_utils_deleteDirectory(archive->archiveRoot, NULL); } @@ -299,7 +301,7 @@ celix_status_t bundleArchive_destroy(bundle_archive_pt archive) { return CELIX_SUCCESS; } -celix_status_t bundleArchive_getId(bundle_archive_pt archive, long *id) { +celix_status_t bundleArchive_getId(bundle_archive_pt archive, long* id) { *id = archive->id; return CELIX_SUCCESS; } @@ -329,23 +331,26 @@ char* celix_bundleArchive_getLocation(bundle_archive_pt archive) { return result; } -celix_status_t bundleArchive_getArchiveRoot(bundle_archive_pt archive, const char **archiveRoot) { +celix_status_t bundleArchive_getArchiveRoot(bundle_archive_pt archive, const char** archiveRoot) { *archiveRoot = archive->archiveRoot; return CELIX_SUCCESS; } -celix_status_t bundleArchive_getCurrentRevisionNumber(bundle_archive_pt archive, long *revisionNumber) { - *revisionNumber = 1; //NOTE bundle revision is deprecated +//LCOV_EXCL_START +celix_status_t bundleArchive_getCurrentRevisionNumber(bundle_archive_pt archive, long* revisionNumber) { + *revisionNumber = 1; // NOTE bundle revision is deprecated return CELIX_SUCCESS; } +//LCOV_EXCL_STOP -celix_status_t bundleArchive_getCurrentRevision(bundle_archive_pt archive, bundle_revision_pt *revision) { +celix_status_t bundleArchive_getCurrentRevision(bundle_archive_pt archive, bundle_revision_pt* revision) { celixThreadMutex_lock(&archive->lock); *revision = archive->revision; celixThreadMutex_unlock(&archive->lock); return CELIX_SUCCESS; } +//LCOV_EXCL_START celix_status_t bundleArchive_getRevision(bundle_archive_pt archive, long revNr __attribute__((unused)), bundle_revision_pt *revision) { return bundleArchive_getCurrentRevision(archive, revision); } @@ -372,7 +377,7 @@ celix_status_t bundleArchive_setRefreshCount(bundle_archive_pt archive __attribu return CELIX_SUCCESS; } -celix_status_t bundleArchive_getLastModified(bundle_archive_pt archive, time_t *lastModified) { +celix_status_t bundleArchive_getLastModified(bundle_archive_pt archive, time_t* lastModified) { struct timespec mod; celix_status_t status = celix_bundleArchive_getLastModified(archive, &mod); if (status == CELIX_SUCCESS) { @@ -380,13 +385,17 @@ celix_status_t bundleArchive_getLastModified(bundle_archive_pt archive, time_t * } return status; } +//LCOV_EXCL_STOP -celix_status_t celix_bundleArchive_getLastModifiedInternal(bundle_archive_pt archive, struct timespec *lastModified) { - //precondition: archive->lock is locked +celix_status_t celix_bundleArchive_getLastModifiedInternal(bundle_archive_pt archive, struct timespec* lastModified) { + // precondition: archive->lock is locked celix_status_t status = CELIX_SUCCESS; char manifestPathBuffer[CELIX_DEFAULT_STRING_CREATE_BUFFER_SIZE]; char* manifestPath = celix_utils_writeOrCreateString(manifestPathBuffer, sizeof(manifestPathBuffer), "%s/%s", archive->resourceCacheRoot, CELIX_BUNDLE_MANIFEST_REL_PATH); - status = celix_utils_getLastModified(manifestPath, lastModified); + if (manifestPath == NULL) { + status = CELIX_ENOMEM; + } + status = CELIX_DO_IF(status, celix_utils_getLastModified(manifestPath, lastModified)); celix_utils_freeStringIfNotEqual(manifestPathBuffer, manifestPath); return status; } @@ -399,6 +408,7 @@ celix_status_t celix_bundleArchive_getLastModified(bundle_archive_pt archive, st return status; } +//LCOV_EXCL_START celix_status_t bundleArchive_setLastModified(bundle_archive_pt archive __attribute__((unused)), time_t lastModifiedTime __attribute__((unused))) { celix_status_t status = CELIX_SUCCESS; char manifestPathBuffer[CELIX_DEFAULT_STRING_CREATE_BUFFER_SIZE]; @@ -407,6 +417,7 @@ celix_status_t bundleArchive_setLastModified(bundle_archive_pt archive __attribu celix_utils_freeStringIfNotEqual(manifestPathBuffer, manifestPath); return status; } +//LCOV_EXCL_STOP celix_status_t bundleArchive_revise(bundle_archive_pt archive, const char * location __attribute__((unused)), const char *updatedBundleUrl) { celixThreadMutex_lock(&archive->lock); @@ -417,8 +428,8 @@ celix_status_t bundleArchive_revise(bundle_archive_pt archive, const char * loca updateUrl = updatedBundleUrl; } - const char *reason = NULL; - celix_status_t status = celix_bundleArchive_extractBundle(archive, archive->resourceCacheRoot, updateUrl); + const char* reason = NULL; + celix_status_t status = celix_bundleArchive_extractBundle(archive, updateUrl); if (status == CELIX_SUCCESS) { bundle_revision_t* current = archive->revision; bundle_revision_t* revised = bundleRevision_revise(current, updateUrl); @@ -445,18 +456,19 @@ revise_finished: return status; } - -celix_status_t bundleArchive_rollbackRevise(bundle_archive_pt archive, bool *rolledback) { +//LCOV_EXCL_START +celix_status_t bundleArchive_rollbackRevise(bundle_archive_pt archive, bool* rolledback) { *rolledback = true; fw_log(archive->fw->logger, CELIX_LOG_LEVEL_ERROR, "Revise rollback not supported."); return CELIX_BUNDLE_EXCEPTION; } celix_status_t bundleArchive_close(bundle_archive_pt archive) { - // close revision - // not yet needed/possible - return CELIX_SUCCESS; + // close revision + // not yet needed/possible + return CELIX_SUCCESS; } +//LCOV_EXCL_STOP celix_status_t bundleArchive_closeAndDelete(bundle_archive_pt archive) { celix_status_t status = CELIX_SUCCESS; diff --git a/libs/framework/src/bundle_archive_private.h b/libs/framework/src/bundle_archive_private.h index e8c7e229..379213ea 100644 --- a/libs/framework/src/bundle_archive_private.h +++ b/libs/framework/src/bundle_archive_private.h @@ -21,6 +21,8 @@ #ifndef BUNDLE_ARCHIVE_PRIVATE_H_ #define BUNDLE_ARCHIVE_PRIVATE_H_ +#include <time.h> + #include "bundle_archive.h" #ifdef __cplusplus @@ -73,6 +75,11 @@ const char* celix_bundleArchive_getPersistentStoreRoot(bundle_archive_t *archive */ const char* celix_bundleArchive_getCurrentRevisionRoot(bundle_archive_pt archive); +/** + * Return the last modified time of the bundle archive. + */ +celix_status_t celix_bundleArchive_getLastModifiedInternal(bundle_archive_pt archive, struct timespec* lastModified); + #ifdef __cplusplus } #endif
