Testing object_pool
Add unit tests for object_pool functions. It need a C wrapper because
the macros for creating pool do not work when compiling in C++. The
declaration and initialization order of structure members must be the
same in C++ while this is not a requirement in C.
Change-Id: Id06bcd39cabfcbb57584c8ef7f8a118e3226c3c2
Signed-off-by: Imre Kis <imre.kis@arm.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bcfb234..3ad62d2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2019, Arm Limited. All rights reserved.
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -112,3 +112,4 @@
include_directories(${CMAKE_CURRENT_LIST_DIR}/include)
include(tests/lib/libc/test_libc.cmake)
+include(tests/lib/object_pool/test_object_pool.cmake)
diff --git a/tests/lib/object_pool/object_pool_allocator_wrapper.c b/tests/lib/object_pool/object_pool_allocator_wrapper.c
new file mode 100644
index 0000000..1a7fc6d
--- /dev/null
+++ b/tests/lib/object_pool/object_pool_allocator_wrapper.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "object_pool_allocator_wrapper.h"
+#include "lib/object_pool.h"
+#include <string.h>
+
+uint32_t array[POOL_SIZE];
+
+void object_pool_allocate(struct object_pool *pool) {
+ OBJECT_POOL_ARRAY(local_pool, array);
+ memcpy(pool, &local_pool, sizeof(*pool));
+}
diff --git a/tests/lib/object_pool/object_pool_allocator_wrapper.h b/tests/lib/object_pool/object_pool_allocator_wrapper.h
new file mode 100644
index 0000000..e6953e7
--- /dev/null
+++ b/tests/lib/object_pool/object_pool_allocator_wrapper.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "lib/object_pool.h"
+
+#define POOL_SIZE (16)
+extern uint32_t array[POOL_SIZE];
+void object_pool_allocate(struct object_pool *pool);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tests/lib/object_pool/test_object_pool.cmake b/tests/lib/object_pool/test_object_pool.cmake
new file mode 100644
index 0000000..d3ef9a5
--- /dev/null
+++ b/tests/lib/object_pool/test_object_pool.cmake
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include(UnitTest)
+
+unit_test_add_suite(
+ NAME object_pool
+ SOURCES
+ ${CMAKE_CURRENT_LIST_DIR}/test_object_pool.cpp
+ ${CMAKE_CURRENT_LIST_DIR}/object_pool_allocator_wrapper.c
+ ${TF_A_UNIT_TESTS_PATH}/mocks/common/debug.cpp
+ INCLUDE_DIRECTORIES
+ ${TF_A_UNIT_TESTS_PATH}/mocks/include/
+ ${TF_A_UNIT_TESTS_PATH}/mocks/include/lib/libc/
+ ${TF_A_PATH}/include
+ COMPILE_DEFINITIONS
+ LOG_LEVEL=50
+)
diff --git a/tests/lib/object_pool/test_object_pool.cpp b/tests/lib/object_pool/test_object_pool.cpp
new file mode 100644
index 0000000..603fc94
--- /dev/null
+++ b/tests/lib/object_pool/test_object_pool.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+extern "C" {
+#include "lib/object_pool.h"
+}
+#include "object_pool_allocator_wrapper.h"
+#include "common/mock_debug.h"
+#include "CppUTest/TestHarness.h"
+#include "CppUTestExt/MockSupport.h"
+#include <string.h>
+
+#define POOL_TEST_VALUE0 (0x01234567)
+#define POOL_TEST_VALUE1 (0xf0123456)
+
+TEST_GROUP(object_pool) {
+ TEST_SETUP() {
+ memset(array, 0x00, sizeof(array));
+ object_pool_allocate(&pool); // Invoking C wrapper
+ }
+
+ TEST_TEARDOWN() {
+ mock().checkExpectations();
+ mock().clear();
+ }
+
+ void check_remaining_fields(size_t start) {
+ for (size_t i = start; i < POOL_SIZE; i++) {
+ UNSIGNED_LONGS_EQUAL(0, array[i]);
+ }
+ }
+
+ struct object_pool pool = {0};
+};
+
+TEST(object_pool, allocate_one) {
+ uint32_t *first = (uint32_t *)pool_alloc(&pool);
+ *first = POOL_TEST_VALUE0;
+
+ UNSIGNED_LONGS_EQUAL(POOL_TEST_VALUE0, array[0]);
+ check_remaining_fields(1);
+}
+
+TEST(object_pool, allocate_two) {
+ uint32_t *first = (uint32_t *)pool_alloc(&pool);
+ *first = POOL_TEST_VALUE0;
+
+ uint32_t *second = (uint32_t *)pool_alloc(&pool);
+ *second = POOL_TEST_VALUE1;
+
+ UNSIGNED_LONGS_EQUAL(POOL_TEST_VALUE0, array[0]);
+ UNSIGNED_LONGS_EQUAL(POOL_TEST_VALUE1, array[1]);
+ check_remaining_fields(2);
+}
+
+TEST(object_pool, allocate_two_at_once) {
+ uint32_t *items = (uint32_t *)pool_alloc_n(&pool, 2);
+ items[0] = POOL_TEST_VALUE0;
+ items[1] = POOL_TEST_VALUE1;
+
+ UNSIGNED_LONGS_EQUAL(POOL_TEST_VALUE0, array[0]);
+ UNSIGNED_LONGS_EQUAL(POOL_TEST_VALUE1, array[1]);
+ check_remaining_fields(2);
+}
+
+TEST(object_pool, allocate_one_then_overflow) {
+ panic_environment_t env;
+
+ uint32_t *first = (uint32_t*) pool_alloc(&pool);
+ *first = POOL_TEST_VALUE0;
+
+ if (SETUP_PANIC_ENVIRONMENT(env)) {
+ expect_tf_log(
+ "Cannot allocate 16 objects out of pool (15 objects left).\n");
+ pool_alloc_n(&pool, POOL_SIZE);
+ }
+}
+
+TEST(object_pool, overflow) {
+ panic_environment_t env;
+
+ if (SETUP_PANIC_ENVIRONMENT(env)) {
+ expect_tf_log("Cannot allocate 17 objects out of pool (16 objects left).\n");
+ pool_alloc_n(&pool, POOL_SIZE + 1);
+ }
+}