From 8e968176aebab9c45a01fc93c4819bf14dcc6b48 Mon Sep 17 00:00:00 2001 From: PengZheng Date: Sat, 30 Mar 2024 19:04:02 +0800 Subject: [PATCH] gh-674: Add more tests for array_list. --- .../src/ArrayListErrorInjectionTestSuite.cc | 45 +++++++++++++++++-- libs/utils/gtest/src/ArrayListTestSuite.cc | 29 ++++++++++++ libs/utils/src/array_list.c | 8 ++-- libs/utils/src/version_private.h | 1 - 4 files changed, 73 insertions(+), 10 deletions(-) diff --git a/libs/utils/gtest/src/ArrayListErrorInjectionTestSuite.cc b/libs/utils/gtest/src/ArrayListErrorInjectionTestSuite.cc index 177adba9d..6f95a4a6d 100644 --- a/libs/utils/gtest/src/ArrayListErrorInjectionTestSuite.cc +++ b/libs/utils/gtest/src/ArrayListErrorInjectionTestSuite.cc @@ -39,14 +39,14 @@ class ArrayListErrorInjectionTestSuite : public ::testing::Test { TEST_F(ArrayListErrorInjectionTestSuite, CreateTest) { //Given an error is injected for calloc (used for the array struct) - celix_ei_expect_calloc(CELIX_EI_UNKNOWN_CALLER, 1, nullptr); + celix_ei_expect_calloc((void *)celix_arrayList_createWithOptions, 0, nullptr); //Then creating an array list should fail EXPECT_EQ(nullptr, celix_arrayList_create()); //And an error is logged to the celix_err EXPECT_EQ(1, celix_err_getErrorCount()); //Given an error is injected for malloc (used for the element data) - celix_ei_expect_calloc(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + celix_ei_expect_calloc((void *)celix_arrayList_createWithOptions, 0, nullptr, 2); //Then creating an array list should fail EXPECT_EQ(nullptr, celix_arrayList_create()); //And an error is logged to the celix_err @@ -57,7 +57,7 @@ TEST_F(ArrayListErrorInjectionTestSuite, CreateTest) { TEST_F(ArrayListErrorInjectionTestSuite, AddFunctionsTest) { // Given an array list with a capacity of 10 (whitebox knowledge) and with an entry than needs to be freed when // removed. - auto* list = celix_arrayList_createStringArray(); + celix_autoptr(celix_array_list_t) list = celix_arrayList_createStringArray(); //When adding 10 elements, no error is expected for (int i = 0; i < 10; ++i) { @@ -73,8 +73,29 @@ TEST_F(ArrayListErrorInjectionTestSuite, AddFunctionsTest) { EXPECT_EQ(10, celix_arrayList_size(list)); //And an error is logged to the celix_err EXPECT_EQ(1, celix_err_getErrorCount()); +} + +TEST_F(ArrayListErrorInjectionTestSuite, AddPointerTest) { + celix_array_list_create_options_t opts{}; + opts.elementType = CELIX_ARRAY_LIST_ELEMENT_TYPE_POINTER; + opts.removedCallback = [](void *, celix_array_list_entry_t) { + }; + // Given a pointer array list + celix_autoptr(celix_array_list_t) pointerList = celix_arrayList_createWithOptions(&opts); - celix_arrayList_destroy(list); + //When adding 10 elements, no error is expected + for (int i = 0; i < 10; ++i) { + EXPECT_EQ(CELIX_SUCCESS, celix_arrayList_add(pointerList, (void*)1)); + } + EXPECT_EQ(10, celix_arrayList_size(pointerList)); + + // When an error is injected for realloc + celix_ei_expect_realloc(CELIX_EI_UNKNOWN_CALLER, 1, nullptr); + // Then adding a pointer should fail + EXPECT_EQ(CELIX_ENOMEM, celix_arrayList_add(pointerList, (void*)1)); + EXPECT_EQ(10, celix_arrayList_size(pointerList)); + //And an error is logged to the celix_err + EXPECT_EQ(1, celix_err_getErrorCount()); } TEST_F(ArrayListErrorInjectionTestSuite, AddStringAndAddVersionFailureTest) { @@ -94,6 +115,22 @@ TEST_F(ArrayListErrorInjectionTestSuite, AddStringAndAddVersionFailureTest) { EXPECT_EQ(CELIX_ENOMEM, celix_arrayList_addVersion(versionList, version)); } +TEST_F(ArrayListErrorInjectionTestSuite, CopyVersionArrayFailureTest) { + // Given a version array list with 11 elements (more than max initial capacity, whitebox knowledge) + celix_autoptr(celix_array_list_t) versionList = celix_arrayList_createVersionArray(); + for (int i = 0; i < 11; ++i) { + celix_autoptr(celix_version_t) version = celix_version_create(1, 0, 0, nullptr); + celix_arrayList_addVersion(versionList, version); + } + + // When an error is injected for celix_version_copy (used in version array list copy callback (whitebox knowledge)) + celix_ei_expect_celix_version_copy((void*)celix_arrayList_copy, 1, nullptr); + // Then copying an array list should fail + EXPECT_EQ(nullptr, celix_arrayList_copy(versionList)); + // And a celix_err is expected + EXPECT_EQ(1, celix_err_getErrorCount()); +} + TEST_F(ArrayListErrorInjectionTestSuite, CopyArrayListFailureTest) { // Given a string array list with 11 elements (more than max initial capacity, whitebox knowledge) celix_autoptr(celix_array_list_t) stringList = celix_arrayList_createStringArray(); diff --git a/libs/utils/gtest/src/ArrayListTestSuite.cc b/libs/utils/gtest/src/ArrayListTestSuite.cc index 5f9aad33c..aa0a1a7e9 100644 --- a/libs/utils/gtest/src/ArrayListTestSuite.cc +++ b/libs/utils/gtest/src/ArrayListTestSuite.cc @@ -363,6 +363,9 @@ TEST_F(ArrayListTestSuite, CopyArrayTest) { EXPECT_TRUE(celix_arrayList_equals(stringList, stringListCopy)); EXPECT_TRUE(celix_arrayList_equals(versionList, versionListCopy)); EXPECT_TRUE(celix_arrayList_equals(ptrList, ptrListCopy)); + + auto* result = celix_arrayList_copy(nullptr); + EXPECT_EQ(nullptr, result); } TEST_F(ArrayListTestSuite, SimpleRemovedCallbacksForArrayListTest) { @@ -377,6 +380,32 @@ TEST_F(ArrayListTestSuite, SimpleRemovedCallbacksForArrayListTest) { celix_arrayList_destroy(list); //will call free for every entry } +TEST_F(ArrayListTestSuite, AddStringToArrayListOfUndefinedTypeTest) { + celix_array_list_create_options_t opts{}; + opts.simpleRemovedCallback = free; + auto* list = celix_arrayList_createWithOptions(&opts); + celix_arrayList_addString(list, celix_utils_strdup("value")); + celix_arrayList_addString(list, celix_utils_strdup("value")); + celix_arrayList_addString(list, celix_utils_strdup("value")); + celix_arrayList_addString(list, celix_utils_strdup("value")); + EXPECT_EQ(celix_arrayList_size(list), 4); + celix_arrayList_destroy(list); //will call free for every entry +} + +TEST_F(ArrayListTestSuite, AddVersionToArrayListOfUndefinedTypeTest) { + celix_array_list_create_options_t opts{}; + opts.simpleRemovedCallback = [](void* data) { + celix_version_destroy((celix_version_t*)data); + }; + auto* list = celix_arrayList_createWithOptions(&opts); + celix_arrayList_addVersion(list, celix_version_create(1, 3, 0, nullptr)); + celix_arrayList_addVersion(list, celix_version_create(1, 3, 0, nullptr)); + celix_arrayList_addVersion(list, celix_version_create(1, 3, 0, nullptr)); + celix_arrayList_addVersion(list, celix_version_create(1, 3, 0, nullptr)); + EXPECT_EQ(celix_arrayList_size(list), 4); + celix_arrayList_destroy(list); //will call free for every entry +} + TEST_F(ArrayListTestSuite, RemovedCallbacksForArrayListTest) { int count = 0 ; celix_array_list_create_options_t opts{}; diff --git a/libs/utils/src/array_list.c b/libs/utils/src/array_list.c index 9c580f8a8..85013da9c 100644 --- a/libs/utils/src/array_list.c +++ b/libs/utils/src/array_list.c @@ -93,11 +93,9 @@ static bool celix_arrayList_versionEquals(celix_array_list_entry_t a, celix_arra return celix_arrayList_compareVersionEntries(a, b) == 0; } -static bool celix_arrayList_equalsForElement(celix_array_list_t *list, celix_array_list_entry_t a, celix_array_list_entry_t b) { - if (list && list->equalsCallback != NULL) { - return list->equalsCallback(a, b); - } - return false; +inline static bool celix_arrayList_equalsForElement(celix_array_list_t *list, celix_array_list_entry_t a, celix_array_list_entry_t b) { + // by class invariant, equalsCallback is never NULL + return list->equalsCallback(a, b); } static celix_status_t celix_arrayList_copyStringEntry(celix_array_list_entry_t src, celix_array_list_entry_t* dst) { diff --git a/libs/utils/src/version_private.h b/libs/utils/src/version_private.h index cadd54142..78ec2daa5 100644 --- a/libs/utils/src/version_private.h +++ b/libs/utils/src/version_private.h @@ -25,7 +25,6 @@ struct celix_version { int minor; int micro; char *qualifier; - int hash; };