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