This is an automated email from the ASF dual-hosted git repository.
pnoltes pushed a commit to branch feature/674-add-element-type-to-array-list
in repository https://gitbox.apache.org/repos/asf/celix.git
The following commit(s) were added to
refs/heads/feature/674-add-element-type-to-array-list by this push:
new 5097e483 #674 Add add/assign nullptr test for array list
5097e483 is described below
commit 5097e4831f20dbe3c947c0fb327327a1ad3cd3e3
Author: Pepijn Noltes <[email protected]>
AuthorDate: Wed Feb 7 19:25:38 2024 +0100
#674 Add add/assign nullptr test for array list
---
.../gtest/src/ArrayListErrorInjectionTestSuite.cc | 26 +++++++-
libs/utils/gtest/src/ArrayListTestSuite.cc | 64 ++++++++++++++++++++
libs/utils/include/celix_array_list.h | 43 +++++++++++++-
libs/utils/src/array_list.c | 69 +++++++++++-----------
4 files changed, 162 insertions(+), 40 deletions(-)
diff --git a/libs/utils/gtest/src/ArrayListErrorInjectionTestSuite.cc
b/libs/utils/gtest/src/ArrayListErrorInjectionTestSuite.cc
index 309d54d0..f808d3af 100644
--- a/libs/utils/gtest/src/ArrayListErrorInjectionTestSuite.cc
+++ b/libs/utils/gtest/src/ArrayListErrorInjectionTestSuite.cc
@@ -20,7 +20,6 @@
#include <gtest/gtest.h>
#include "celix_array_list.h"
-#include "celix_array_list_ei.h"
#include "celix_err.h"
#include "celix_utils_ei.h"
#include "celix_version_ei.h"
@@ -34,10 +33,28 @@ public:
celix_ei_expect_calloc(nullptr, 0, nullptr);
celix_ei_expect_celix_utils_strdup(nullptr, 0, nullptr);
celix_ei_expect_celix_version_copy(nullptr, 0, nullptr);
+ celix_err_resetErrors();
}
};
-TEST_F(ArrayListErrorInjectionTestSuite, TestAddFunctions) {
+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);
+ //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_malloc(CELIX_EI_UNKNOWN_CALLER, 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(2, celix_err_getErrorCount());
+}
+
+
+TEST_F(ArrayListErrorInjectionTestSuite, AddFunctionsTest) {
//Given an array list with a capacity of 10 (whitebox knowledge)
auto* list = celix_arrayList_create();
@@ -53,6 +70,8 @@ TEST_F(ArrayListErrorInjectionTestSuite, TestAddFunctions) {
//Then adding an element should fail
EXPECT_EQ(CELIX_ENOMEM, celix_arrayList_addInt(list, 10));
EXPECT_EQ(10, celix_arrayList_size(list));
+ //And an error is logged to the celix_err
+ EXPECT_EQ(1, celix_err_getErrorCount());
celix_arrayList_destroy(list);
}
@@ -70,7 +89,8 @@ TEST_F(ArrayListErrorInjectionTestSuite,
AddStringAndAddVersionFailureTest) {
// When an error is injected for celix_version_copy
celix_ei_expect_celix_version_copy((void*)celix_arrayList_addVersion, 0,
nullptr);
// Then adding a version should fail
- EXPECT_EQ(CELIX_ENOMEM, celix_arrayList_addVersion(versionList, NULL));
+ celix_autoptr(celix_version_t) version =
celix_version_createVersionFromString("1.0.0");
+ EXPECT_EQ(CELIX_ENOMEM, celix_arrayList_addVersion(versionList, version));
}
TEST_F(ArrayListErrorInjectionTestSuite, CopyArrayListFailureTest) {
diff --git a/libs/utils/gtest/src/ArrayListTestSuite.cc
b/libs/utils/gtest/src/ArrayListTestSuite.cc
index 0bc61c26..e820f714 100644
--- a/libs/utils/gtest/src/ArrayListTestSuite.cc
+++ b/libs/utils/gtest/src/ArrayListTestSuite.cc
@@ -528,3 +528,67 @@ TEST_F(ArrayListTestSuite, AutoCleanupTest) {
celix_autoptr(celix_array_list_t) list = celix_arrayList_create();
EXPECT_NE(nullptr, list);
}
+
+TEST_F(ArrayListTestSuite, AddNullTest) {
+ // Given an undefined type, string, string ref and version list
+ celix_autoptr(celix_array_list_t) list = celix_arrayList_create();
+ celix_autoptr(celix_array_list_t) stringList =
celix_arrayList_createStringArray();
+ celix_autoptr(celix_array_list_t) stringRefList =
celix_arrayList_createStringRefArray();
+ celix_autoptr(celix_array_list_t) versionList =
celix_arrayList_createVersionArray();
+
+ // When adding a null value to the lists
+ celix_arrayList_add(list, nullptr);
+ celix_arrayList_addString(stringList, nullptr);
+ celix_arrayList_addString(stringRefList, nullptr);
+ celix_arrayList_addVersion(versionList, nullptr);
+
+ // Then the lists contain the null value
+ EXPECT_EQ(1, celix_arrayList_size(list));
+ EXPECT_EQ(nullptr, celix_arrayList_get(list, 0));
+ EXPECT_EQ(1, celix_arrayList_size(stringList));
+ EXPECT_EQ(nullptr, celix_arrayList_getString(stringList, 0));
+ EXPECT_EQ(1, celix_arrayList_size(stringRefList));
+ EXPECT_EQ(nullptr, celix_arrayList_getString(stringRefList, 0));
+ EXPECT_EQ(1, celix_arrayList_size(versionList));
+ EXPECT_EQ(nullptr, celix_arrayList_getVersion(versionList, 0));
+
+ // When copying the lists
+ celix_autoptr(celix_array_list_t) listCopy = celix_arrayList_copy(list);
+ celix_autoptr(celix_array_list_t) stringListCopy =
celix_arrayList_copy(stringList);
+ celix_autoptr(celix_array_list_t) stringRefListCopy =
celix_arrayList_copy(stringRefList);
+ celix_autoptr(celix_array_list_t) versionListCopy =
celix_arrayList_copy(versionList);
+
+ // Then the copied lists contain the null value
+ EXPECT_EQ(1, celix_arrayList_size(listCopy));
+ EXPECT_EQ(nullptr, celix_arrayList_get(listCopy, 0));
+ EXPECT_EQ(1, celix_arrayList_size(stringListCopy));
+ EXPECT_EQ(nullptr, celix_arrayList_getString(stringListCopy, 0));
+ EXPECT_EQ(1, celix_arrayList_size(stringRefListCopy));
+ EXPECT_EQ(nullptr, celix_arrayList_getString(stringRefListCopy, 0));
+ EXPECT_EQ(1, celix_arrayList_size(versionListCopy));
+ EXPECT_EQ(nullptr, celix_arrayList_getVersion(versionListCopy, 0));
+}
+
+TEST_F(ArrayListTestSuite, AssignNullTest) {
+ // Given a string and version list
+ celix_autoptr(celix_array_list_t) stringList =
celix_arrayList_createStringArray();
+ celix_autoptr(celix_array_list_t) versionList =
celix_arrayList_createVersionArray();
+
+ // When assigning a null value to the lists
+ celix_arrayList_assignString(stringList, nullptr);
+ celix_arrayList_assignVersion(versionList, nullptr);
+
+ // Then the lists contain the null value
+ EXPECT_EQ(1, celix_arrayList_size(stringList));
+ EXPECT_EQ(nullptr, celix_arrayList_getString(stringList, 0));
+ EXPECT_EQ(1, celix_arrayList_size(versionList));
+ EXPECT_EQ(nullptr, celix_arrayList_getVersion(versionList, 0));
+
+ // When copying the lists
+ celix_autoptr(celix_array_list_t) stringListCopy =
celix_arrayList_copy(stringList);
+ celix_autoptr(celix_array_list_t) versionListCopy =
celix_arrayList_copy(versionList);
+
+ // Then the copied lists contain the null value
+ EXPECT_EQ(1, celix_arrayList_size(stringListCopy));
+ EXPECT_EQ(nullptr, celix_arrayList_getString(stringListCopy, 0));
+}
diff --git a/libs/utils/include/celix_array_list.h
b/libs/utils/include/celix_array_list.h
index 716aa194..a35d87a6 100644
--- a/libs/utils/include/celix_array_list.h
+++ b/libs/utils/include/celix_array_list.h
@@ -177,16 +177,20 @@ typedef struct celix_array_list_create_options {
*
* The remove, equals and compare callback will be NULL.
*
- * @deprecated Use celix_arrayList_createWithOptions instead.
+ * @return A new empty array list or NULL if the array list could not be
created. If NULL is returned an error message
+ * is logged to celix_err.
*/
CELIX_UTILS_DEPRECATED_EXPORT
-celix_array_list_t* celix_arrayList_create() __attribute__((deprecated("use
create typed array list instead")));
+celix_array_list_t* celix_arrayList_create();
/**
* @brief Creates a new empty array list with a pointer element type where the
array list is not the owner of the
* pointers.
*
* The remove, equals and compare callback will be NULL.
+ *
+ * @return A new empty array list or NULL if the array list could not be
created. If NULL is returned an error message
+ * is logged to celix_err.
*/
CELIX_UTILS_EXPORT
celix_array_list_t* celix_arrayList_createPointerArray();
@@ -196,6 +200,9 @@ celix_array_list_t* celix_arrayList_createPointerArray();
*
* The remove callback will be configured to free the string, and equals and
compare callback will be configured for
* string comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be
created. If NULL is returned an error message
+ * is logged to celix_err.
*/
CELIX_UTILS_EXPORT
celix_array_list_t* celix_arrayList_createStringArray();
@@ -206,6 +213,9 @@ celix_array_list_t* celix_arrayList_createStringArray();
*
* The remove callback will be configured to NULL, and equals and compare
callback will be configured for
* string comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be
created. If NULL is returned an error message
+ * is logged to celix_err.
*/
CELIX_UTILS_EXPORT
celix_array_list_t* celix_arrayList_createStringRefArray();
@@ -215,6 +225,9 @@ celix_array_list_t* celix_arrayList_createStringRefArray();
*
* The remove callback will be configured to NULL, and equals and compare
callback will be configured for
* integer comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be
created. If NULL is returned an error message
+ * is logged to celix_err.
*/
CELIX_UTILS_EXPORT
celix_array_list_t* celix_arrayList_createIntArray();
@@ -224,6 +237,9 @@ celix_array_list_t* celix_arrayList_createIntArray();
*
* The remove callback will be configured to NULL, and equals and compare
callback will be configured for
* integer comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be
created. If NULL is returned an error message
+ * is logged to celix_err.
*/
CELIX_UTILS_EXPORT
celix_array_list_t* celix_arrayList_createLongArray();
@@ -233,6 +249,9 @@ celix_array_list_t* celix_arrayList_createLongArray();
*
* The remove callback will be configured to NULL, and equals and compare
callback will be configured for
* unsigned integer comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be
created. If NULL is returned an error message
+ * is logged to celix_err.
*/
CELIX_UTILS_EXPORT
celix_array_list_t* celix_arrayList_createUIntArray();
@@ -242,6 +261,9 @@ celix_array_list_t* celix_arrayList_createUIntArray();
*
* The remove callback will be configured to NULL, and equals and compare
callback will be configured for
* unsigned integer comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be
created. If NULL is returned an error message
+ * is logged to celix_err.
*/
CELIX_UTILS_EXPORT
celix_array_list_t* celix_arrayList_createULongArray();
@@ -251,6 +273,9 @@ celix_array_list_t* celix_arrayList_createULongArray();
*
* The remove callback will be configured to NULL, and equals and compare
callback will be configured for
* float comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be
created. If NULL is returned an error message
+ * is logged to celix_err.
*/
CELIX_UTILS_EXPORT
celix_array_list_t* celix_arrayList_createFloatArray();
@@ -260,6 +285,9 @@ celix_array_list_t* celix_arrayList_createFloatArray();
*
* The remove callback will be configured to NULL, and equals and compare
callback will be configured for
* double comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be
created. If NULL is returned an error message
+ * is logged to celix_err.
*/
CELIX_UTILS_EXPORT
celix_array_list_t* celix_arrayList_createDoubleArray();
@@ -269,6 +297,9 @@ celix_array_list_t* celix_arrayList_createDoubleArray();
*
* The remove callback will be configured to NULL, and equals and compare
callback will be configured for
* boolean comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be
created. If NULL is returned an error message
+ * is logged to celix_err.
*/
CELIX_UTILS_EXPORT
celix_array_list_t* celix_arrayList_createBoolArray();
@@ -278,6 +309,9 @@ celix_array_list_t* celix_arrayList_createBoolArray();
*
* The remove callback will be configured to NULL, and equals and compare
callback will be configured for
* unsigned integer comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be
created. If NULL is returned an error message
+ * is logged to celix_err.
*/
CELIX_UTILS_EXPORT
celix_array_list_t* celix_arrayList_createSizeArray();
@@ -287,6 +321,9 @@ celix_array_list_t* celix_arrayList_createSizeArray();
*
* The remove callback will be configured to free a celix version, and equals
and compare callback will be configured
* for celix version comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be
created. If NULL is returned an error message
+ * is logged to celix_err.
*/
CELIX_UTILS_EXPORT
celix_array_list_t* celix_arrayList_createVersionArray();
@@ -299,6 +336,8 @@ celix_array_list_t* celix_arrayList_createVersionArray();
* The provided callbacks in the options will override the default callbacks.
*
* @param opts The create options, only used during the creation of the array
list.
+ * @return A new empty array list or NULL if the array list could not be
created. If NULL is returned an error message
+ * is logged to celix_err.
*/
CELIX_UTILS_EXPORT
celix_array_list_t* celix_arrayList_createWithOptions(const
celix_array_list_create_options_t* opts);
diff --git a/libs/utils/src/array_list.c b/libs/utils/src/array_list.c
index d35f40df..094a313c 100644
--- a/libs/utils/src/array_list.c
+++ b/libs/utils/src/array_list.c
@@ -158,23 +158,20 @@ static void
celix_arrayList_callRemovedCallback(celix_array_list_t *list, int in
}
static celix_status_t celix_arrayList_ensureCapacity(celix_array_list_t* list,
int capacity) {
- celix_status_t status = CELIX_SUCCESS;
celix_array_list_entry_t *newList;
list->modCount++;
size_t oldCapacity = list->capacity;
if (capacity > oldCapacity) {
size_t newCapacity = (oldCapacity * 3) / 2 + 1;
- if (newCapacity < capacity) {
- newCapacity = capacity;
- }
newList = realloc(list->elementData, sizeof(celix_array_list_entry_t)
* newCapacity);
- if (newList != NULL) {
- list->capacity = newCapacity;
- list->elementData = newList;
+ if (!newList) {
+ celix_err_push("Failed to reallocate memory for elementData");
+ return CELIX_ENOMEM;
}
- status = newList == NULL ? CELIX_ENOMEM : CELIX_SUCCESS;
+ list->capacity = newCapacity;
+ list->elementData = newList;
}
- return status;
+ return CELIX_SUCCESS;
}
static void celix_arrayList_setTypeSpecificCallbacks(celix_array_list_t* list)
{
@@ -238,31 +235,34 @@ static void
celix_arrayList_setTypeSpecificCallbacks(celix_array_list_t* list) {
celix_array_list_t* celix_arrayList_createWithOptions(const
celix_array_list_create_options_t* opts) {
celix_autofree celix_array_list_t *list = calloc(1, sizeof(*list));
- if (list) {
- list->capacity = 10;
- list->elementData = malloc(sizeof(celix_array_list_entry_t) *
list->capacity);
- if (!list->elementData) {
- celix_err_push("Failed to allocate memory for elementData");
- return NULL;
- }
+ if (!list) {
+ celix_err_push("Failed to allocate memory for list");
+ return NULL;
+ }
- list->elementType = opts->elementType;
- celix_arrayList_setTypeSpecificCallbacks(list);
+ list->capacity = 10;
+ list->elementData = malloc(sizeof(celix_array_list_entry_t) *
list->capacity);
+ if (!list->elementData) {
+ celix_err_push("Failed to allocate memory for elementData");
+ return NULL;
+ }
- //if opts contains callbacks, use them and override the default ones
- if (opts->simpleRemovedCallback) {
- list->simpleRemovedCallback = opts->simpleRemovedCallback;
- }
- if (opts->removedCallback) {
- list->removedCallback = opts->removedCallback;
- list->removedCallbackData = opts->removedCallbackData;
- }
- if (opts->equalsCallback) {
- list->equalsCallback = opts->equalsCallback;
- }
- if (opts->compareCallback) {
- list->compareCallback = opts->compareCallback;
- }
+ list->elementType = opts->elementType;
+ celix_arrayList_setTypeSpecificCallbacks(list);
+
+ //if opts contains callbacks, use them and override the default ones
+ if (opts->simpleRemovedCallback) {
+ list->simpleRemovedCallback = opts->simpleRemovedCallback;
+ }
+ if (opts->removedCallback) {
+ list->removedCallback = opts->removedCallback;
+ list->removedCallbackData = opts->removedCallbackData;
+ }
+ if (opts->equalsCallback) {
+ list->equalsCallback = opts->equalsCallback;
+ }
+ if (opts->compareCallback) {
+ list->compareCallback = opts->compareCallback;
}
return celix_steal_ptr(list);
}
@@ -439,7 +439,7 @@ celix_status_t
celix_arrayList_addString(celix_array_list_t* list, const char* v
list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
- if (list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING) {
+ if (list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING && val) {
entry.stringVal = celix_utils_strdup(val);
if (entry.stringVal == NULL) {
return CELIX_ENOMEM;
@@ -535,7 +535,7 @@ celix_status_t
celix_arrayList_addVersion(celix_array_list_t* list, const celix_
list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
celix_array_list_entry_t entry;
memset(&entry, 0, sizeof(entry));
- if (list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION) {
+ if (list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION && value) {
entry.versionVal = celix_version_copy(value);
if (entry.versionVal == NULL) {
return CELIX_ENOMEM;
@@ -739,7 +739,6 @@ celix_array_list_t* celix_arrayList_copy(const
celix_array_list_t* list) {
opts.simpleRemovedCallback = list->simpleRemovedCallback;
celix_autoptr(celix_array_list_t) copy =
celix_arrayList_createWithOptions(&opts);
if (!copy) {
- celix_err_push("Failed to create copy list. Out of memory.");
return NULL;
}