feat(unittests): add support for dynamic test harnesses
This patch adds support to the unittest framework to support
dynamic reconfiguration of test harnesses at run time, adding
flexibility to the tests.
It also replaces the build-time-linked test harnesses used
by the existing unit tests by dynamic ones and includes
some refactor on the slot buffer and the host test helpers to
ease the tests.
Signed-off-by: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
Change-Id: Iabe9d0982d4fb6e78424fcd24a916324c7675697
diff --git a/lib/realm/tests/CMakeLists.txt b/lib/realm/tests/CMakeLists.txt
index f8291f8..52e18cd 100644
--- a/lib/realm/tests/CMakeLists.txt
+++ b/lib/realm/tests/CMakeLists.txt
@@ -3,9 +3,13 @@
# SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
#
+target_include_directories(rmm-lib-realm
+ PRIVATE "tests")
+
# Add test functionality
rmm_build_unittest(NAME granule
TARGET rmm-lib-realm
SOURCES "tests/granule.cpp"
+ "tests/realm_test_utils.c"
"tests/test_harness.c"
ITERATIONS 10)
diff --git a/lib/realm/tests/granule.cpp b/lib/realm/tests/granule.cpp
index 823f880..5b70b2e 100644
--- a/lib/realm/tests/granule.cpp
+++ b/lib/realm/tests/granule.cpp
@@ -13,9 +13,11 @@
#include <granule.h> /* Interface to exercise */
#include <host_harness.h>
#include <host_utils.h>
+#include <realm_test_utils.h>
#include <status.h>
#include <stdlib.h>
#include <string.h>
+#include <test_harness.h>
#include <test_helpers.h>
#include <time.h>
#include <unistd.h>
@@ -125,6 +127,13 @@
memset((void *)get_granule_struct_base(), 0,
sizeof(struct granule) *
test_helpers_get_nr_granules());
+
+ /*
+ * Unregister any existing callback that might
+ * have been installed
+ */
+ (void)test_helpers_unregister_cb(CB_BUFFER_MAP);
+ (void)test_helpers_unregister_cb(CB_BUFFER_UNMAP);
}
};
@@ -1484,6 +1493,13 @@
host_util_get_granule_base()};
struct granule *granule;
int *val;
+ union test_harness_cbs cb;
+
+ /* Register harness callbacks to use by this test */
+ cb.buffer_map = test_buffer_map;
+ (void)test_helpers_register_cb(cb, CB_BUFFER_MAP);
+ cb.buffer_unmap = test_buffer_unmap;
+ (void)test_helpers_register_cb(cb, CB_BUFFER_UNMAP);
/***************************************************************
* TEST CASE 1:
diff --git a/lib/realm/tests/realm_test_utils.c b/lib/realm/tests/realm_test_utils.c
new file mode 100644
index 0000000..b752c5d
--- /dev/null
+++ b/lib/realm/tests/realm_test_utils.c
@@ -0,0 +1,47 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
+ */
+
+#include <buffer.h>
+#include <buffer_private.h>
+#include <xlat_tables.h>
+
+/*
+ * Return the PA mapped to a given slot.
+ *
+ * NOTE: This API assumes a 4KB granularity and that the architecture
+ * has a VA space of 48 bits.
+ */
+static uintptr_t slot_to_pa(enum buffer_slot slot)
+{
+ struct xlat_table_entry *entry = get_cache_entry();
+ uintptr_t va = slot_to_va(slot);
+ uint64_t *desc_ptr = xlat_get_pte_from_table(entry, va);
+ uint64_t descriptor = xlat_read_descriptor(desc_ptr);
+
+ return (uintptr_t)(descriptor & XLAT_TTE_L3_PA_MASK);
+}
+
+/*
+ * Helper function to find the slot VA to which a PA is mapped to.
+ * This function is used to validate that the slot buffer library
+ * mapped the given PA to the VA that would be expected by the
+ * aarch64 VMSA.
+ */
+uintptr_t realm_test_util_get_slot_va(uintptr_t pa)
+{
+ for (unsigned int i = 0U; i < NR_CPU_SLOTS; i++) {
+ if (pa == slot_to_pa((enum buffer_slot)i)) {
+ /*
+ * Found a slot returning the same address, get
+ * the VA for that slot (the one that would be
+ * used by the aarch64 VMSA).
+ */
+ return slot_to_va((enum buffer_slot)i);
+ }
+ }
+
+ /* No buffer slot found */
+ return (uintptr_t)NULL;
+}
diff --git a/lib/realm/tests/realm_test_utils.h b/lib/realm/tests/realm_test_utils.h
new file mode 100644
index 0000000..4507ed8
--- /dev/null
+++ b/lib/realm/tests/realm_test_utils.h
@@ -0,0 +1,13 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
+ */
+
+#ifndef REALM_TEST_UTILS_H
+#define REALM_TEST_UTILS_H
+
+#include <buffer.h>
+
+uintptr_t realm_test_util_get_slot_va(uintptr_t pa);
+
+#endif /* REALM_TEST_UTILS_H */
diff --git a/lib/realm/tests/test_harness.c b/lib/realm/tests/test_harness.c
index 1d9855b..e3795bb 100644
--- a/lib/realm/tests/test_harness.c
+++ b/lib/realm/tests/test_harness.c
@@ -3,56 +3,7 @@
* SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
*/
-#include <buffer.h>
-#include <buffer_private.h>
-#include <test_harness.h>
-
-/*
- * Get the expected VA (as per the aarch64 build) for a given slot.
- */
-static inline uintptr_t slot_to_expected_va(enum buffer_slot slot)
-{
- return (uintptr_t)(SLOT_VIRT + (GRANULE_SIZE * slot));
-}
-
-/*
- * Return the PA mapped to a given slot.
- *
- * NOTE: This API assumes a 4KB granularity and that the architecture
- * has a VA space of 48 bits.
- */
-static uintptr_t slot_to_arch_pa(enum buffer_slot slot)
-{
- struct xlat_table_entry *entry = get_cache_entry();
- uintptr_t va = slot_to_va(slot);
- uint64_t *desc_ptr = xlat_get_pte_from_table(entry, va);
- uint64_t descriptor = xlat_read_descriptor(desc_ptr);
-
- return (uintptr_t)(descriptor & XLAT_TTE_L3_PA_MASK);
-}
-
-/*
- * Helper function to find the slot VA to which a PA is mapped to.
- * This function is used to validate that the slot buffer library
- * mapped the given fake PA to the VA that would be expected by the
- * aarch64 architecture.
- */
-static uintptr_t host_pa_to_slot_va(uintptr_t pa)
-{
- for (unsigned int i = 0U; i < NR_CPU_SLOTS; i++) {
- if (pa == slot_to_arch_pa((enum buffer_slot)i)) {
- /*
- * Found a slot returning the same address, get
- * the "real" VA for that slot (the one that
- * would be used by the aarch64 architecture).
- */
- return slot_to_expected_va((enum buffer_slot)i);
- }
- }
-
- /* No buffer slot found */
- return (uintptr_t)NULL;
-}
+#include <realm_test_utils.h>
/*
* Maps addr to the requested slot buffer and returns a pointer to the
@@ -72,7 +23,7 @@
void test_buffer_unmap(void *buf)
{
- void *slot_va = (void *)host_pa_to_slot_va((uintptr_t)buf);
+ void *slot_va = (void *)realm_test_util_get_slot_va((uintptr_t)buf);
assert(slot_va != NULL);
diff --git a/lib/realm/tests/test_harness.h b/lib/realm/tests/test_harness.h
new file mode 100644
index 0000000..c725cf1
--- /dev/null
+++ b/lib/realm/tests/test_harness.h
@@ -0,0 +1,19 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
+ */
+
+#ifndef TEST_HARNESS_H
+#define TEST_HARNESS_H
+
+#include <buffer.h>
+
+/*
+ * Test specific host_harness functions which are dynamically
+ * overridden during test execution.
+ */
+
+void *test_buffer_map(enum buffer_slot slot, unsigned long addr);
+void test_buffer_unmap(void *buf);
+
+#endif /* TEST_HARNESS_H */