Skip to content

Commit fec9649

Browse files
committed
vmh_tests: Add set of parametrized tests and test suit
Add enhanced vmh testing. Add tests for: heap creation, heap creation with config, multiple allocation tests for each heap mode. Signed-off-by: Jakub Dabek <jakub.dabek@intel.com>
1 parent 13ba1b7 commit fec9649

File tree

1 file changed

+258
-0
lines changed

1 file changed

+258
-0
lines changed

zephyr/test/vmh.c

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <errno.h>
99
#include <stdbool.h>
10+
#include <stdlib.h>
1011

1112
#include <adsp_memory_regions.h>
1213
#include <sof/boot_test.h>
@@ -17,8 +18,265 @@
1718

1819
LOG_MODULE_DECLARE(sof_boot_test, CONFIG_SOF_LOG_LEVEL);
1920

21+
/* Test creating and freeing a virtual memory heap */
22+
static void test_vmh_init_and_free_heap(int memory_region_attribute,
23+
struct vmh_heap_config *config,
24+
int core_id,
25+
bool allocating_continuously,
26+
bool expect_success)
27+
{
28+
struct vmh_heap *heap = vmh_init_heap(config, memory_region_attribute,
29+
core_id, allocating_continuously);
30+
if (expect_success) {
31+
zassert_not_null(heap,
32+
"Heap initialization expected to succeed but failed");
33+
}
34+
else
35+
zassert_is_null(heap, "Heap initialization expected to fail but succeeded");
36+
37+
if (heap) {
38+
int ret = vmh_free_heap(heap);
39+
40+
zassert_equal(ret, 0, "Failed to free heap");
41+
}
42+
}
43+
44+
/* Test for vmh_alloc and vmh_free */
45+
static void test_vmh_alloc_free_no_check(struct vmh_heap *heap,
46+
uint32_t alloc_size,
47+
bool expect_success)
48+
{
49+
void *ptr = vmh_alloc(heap, alloc_size);
50+
51+
if (expect_success)
52+
zassert_not_null(ptr, "Allocation expected to succeed but failed");
53+
else
54+
zassert_is_null(ptr, "Allocation expected to fail but succeeded");
55+
56+
if (ptr) {
57+
int ret = vmh_free(heap, ptr);
58+
59+
zassert_equal(ret, 0, "Failed to free allocated memory");
60+
}
61+
}
62+
63+
static void verify_memory_content(void *ptr, uint32_t alloc_size)
64+
{
65+
66+
/* Calculate check positions end and middle if applicable */
67+
uint8_t *end_ptr = (uint8_t *)ptr + alloc_size - sizeof(uint32_t);
68+
uint8_t *middle_ptr = (uint8_t *)ptr + (alloc_size / 2);
69+
uint8_t test_value = 0xAA;
70+
int test_write_size = 1;
71+
72+
/* Write test pattern to the allocated memory beginning middle and end */
73+
memset(ptr, test_value, test_write_size);
74+
memset(middle_ptr, test_value, test_write_size);
75+
memset(end_ptr, test_value, test_write_size);
76+
77+
/* Verify the written test pattern at all points */
78+
zassert_equal(*((uint8_t *)ptr), test_value,
79+
"Memory content verification failed at the start");
80+
zassert_equal(*end_ptr, test_value,
81+
"Memory content verification failed at the end");
82+
zassert_equal(*middle_ptr, test_value,
83+
"Memory content verification failed in the middle");
84+
}
85+
86+
/* Test function for vmh_alloc and vmh_free with memory read/write */
87+
static void test_vmh_alloc_free_check(struct vmh_heap *heap,
88+
uint32_t alloc_size,
89+
bool expect_success)
90+
{
91+
void *ptr = vmh_alloc(heap, alloc_size);
92+
93+
if (expect_success)
94+
zassert_not_null(ptr, "Allocation expected to succeed but failed");
95+
else {
96+
zassert_is_null(ptr, "Allocation expected to fail but succeeded");
97+
return;
98+
}
99+
100+
if (ptr) {
101+
verify_memory_content(ptr, alloc_size);
102+
}
103+
104+
int ret = vmh_free(heap, ptr);
105+
106+
zassert_equal(ret, 0, "Failed to free allocated memory");
107+
}
108+
109+
/* Test function for multiple allocations on the same heap with read/write */
110+
static void test_vmh_multiple_allocs(struct vmh_heap *heap, int num_allocs,
111+
uint32_t min_alloc_size,
112+
uint32_t max_alloc_size)
113+
{
114+
void *ptrs[num_allocs];
115+
uint32_t alloc_size;
116+
bool success;
117+
int ret;
118+
119+
/* Perform multiple allocations */
120+
for (int i = 0; i < num_allocs; i++) {
121+
/* Generate a random allocation size between min_alloc_size and max_alloc_size */
122+
alloc_size = min_alloc_size +
123+
k_cycle_get_32() % (max_alloc_size - min_alloc_size + 1);
124+
125+
ptrs[i] = vmh_alloc(heap, alloc_size);
126+
127+
if (!ptrs[i])
128+
LOG_INF("Test allocation failed for size: %d", alloc_size);
129+
130+
zassert_true(ptrs[i] != NULL,
131+
"Allocation of size %u expected to succeed but failed",
132+
alloc_size);
133+
134+
if (ptrs[i]) {
135+
verify_memory_content(ptrs[i], alloc_size);
136+
}
137+
}
138+
139+
for (int i = 0; i < num_allocs; i++) {
140+
if (ptrs[i]) {
141+
ret = vmh_free(heap, ptrs[i]);
142+
zassert_equal(ret, 0, "Failed to free allocated memory");
143+
}
144+
}
145+
}
146+
147+
/* Test case for multiple allocations */
148+
static void test_vmh_alloc_multiple_times(bool allocating_continuously)
149+
{
150+
struct vmh_heap *heap =
151+
vmh_init_heap(NULL, MEM_REG_ATTR_CORE_HEAP, 0, allocating_continuously);
152+
153+
zassert_not_null(heap, "Heap initialization failed");
154+
155+
/* Test multiple allocations with small sizes */
156+
test_vmh_multiple_allocs(heap, 16, 4, 8);
157+
test_vmh_multiple_allocs(heap, 64, 4, 8);
158+
test_vmh_multiple_allocs(heap, 16, 4, 1024);
159+
test_vmh_multiple_allocs(heap, 64, 4, 1024);
160+
if (allocating_continuously) {
161+
test_vmh_multiple_allocs(heap, 16, 1024, 4096);
162+
test_vmh_multiple_allocs(heap, 16, 4096, 8192);
163+
}
164+
165+
/* Clean up the heap after testing */
166+
int ret = vmh_free_heap(heap);
167+
168+
zassert_equal(ret, 0, "Failed to free heap after multiple allocations");
169+
}
170+
171+
/* Test case for vmh_alloc and vmh_free */
172+
static void test_vmh_alloc_free(bool allocating_continuously)
173+
{
174+
struct vmh_heap *heap =
175+
vmh_init_heap(NULL, MEM_REG_ATTR_CORE_HEAP, 0, allocating_continuously);
176+
177+
zassert_not_null(heap, "Heap initialization failed");
178+
179+
test_vmh_alloc_free_no_check(heap, 512, true);
180+
test_vmh_alloc_free_no_check(heap, 1024, true);
181+
test_vmh_alloc_free_no_check(heap, sizeof(int), true);
182+
test_vmh_alloc_free_no_check(heap, 0, false);
183+
184+
test_vmh_alloc_free_check(heap, 512, true);
185+
test_vmh_alloc_free_check(heap, 1024, true);
186+
test_vmh_alloc_free_check(heap, sizeof(int), true);
187+
test_vmh_alloc_free_check(heap, 0, false);
188+
189+
int ret = vmh_free_heap(heap);
190+
191+
zassert_equal(ret, 0, "Failed to free heap");
192+
193+
/* Could add tests with configs for heaps*/
194+
}
195+
196+
/* Test case for vmh_alloc and vmh_free with and without config */
197+
static void test_heap_creation(void)
198+
{
199+
test_vmh_init_and_free_heap(MEM_REG_ATTR_CORE_HEAP, NULL, 0, false, true);
200+
201+
/* Try to setup with pre defined heap config */
202+
struct vmh_heap_config config = {0};
203+
204+
config.block_bundles_table[0].block_size = 8;
205+
206+
config.block_bundles_table[0].number_of_blocks = 1024;
207+
208+
config.block_bundles_table[1].block_size = 16;
209+
210+
config.block_bundles_table[1].number_of_blocks = 512;
211+
212+
test_vmh_init_and_free_heap(MEM_REG_ATTR_CORE_HEAP, &config, 0, false, true);
213+
}
214+
215+
/* Test case for alloc/free on configured heap */
216+
static void test_alloc_on_configured_heap(bool allocating_continuously)
217+
{
218+
219+
/* Try to setup with pre defined heap config */
220+
struct vmh_heap_config config = {0};
221+
222+
config.block_bundles_table[0].block_size = 32;
223+
224+
config.block_bundles_table[0].number_of_blocks = 256;
225+
226+
/* Create continuous allocation heap for success test */
227+
struct vmh_heap *heap =
228+
vmh_init_heap(&config, MEM_REG_ATTR_CORE_HEAP, 0, allocating_continuously);
229+
230+
/* Will succeed on continuous and fail with single block alloc */
231+
test_vmh_alloc_free_check(heap, 512, allocating_continuously);
232+
233+
int ret = vmh_free_heap(heap);
234+
235+
zassert_equal(ret, 0, "Failed to free heap");
236+
}
237+
238+
/* Test cases for initializing heaps on all available regions */
239+
static void test_vmh_init_all_heaps(void)
240+
{
241+
int num_regions = CONFIG_MP_MAX_NUM_CPUS + VIRTUAL_REGION_COUNT;
242+
int i;
243+
const struct sys_mm_drv_region *virtual_memory_region =
244+
sys_mm_drv_query_memory_regions();
245+
246+
/* Test initializing all types of heaps */
247+
for (i = 0; i < num_regions; i++) {
248+
249+
/* Zeroed size symbolizes end of regions table */
250+
if (!virtual_memory_region[i].size)
251+
break;
252+
253+
struct vmh_heap *heap = vmh_init_heap(NULL, virtual_memory_region[i].attr,
254+
i, true);
255+
256+
zassert_not_null(heap, "Heap initialization expected to succeed but failed");
257+
258+
/* Test if it fails when heap already exists */
259+
test_vmh_init_and_free_heap(virtual_memory_region[i].attr, NULL, i, true,
260+
false);
261+
262+
if (heap) {
263+
int ret = vmh_free_heap(heap);
264+
265+
zassert_equal(ret, 0, "Failed to free heap");
266+
}
267+
}
268+
}
20269

21270
ZTEST(sof_boot, virtual_memory_heap)
22271
{
272+
test_heap_creation();
273+
test_vmh_init_all_heaps();
274+
test_alloc_on_configured_heap(true);
275+
test_alloc_on_configured_heap(false);
276+
test_vmh_alloc_free(true);
277+
test_vmh_alloc_free(false);
278+
test_vmh_alloc_multiple_times(true);
279+
test_vmh_alloc_multiple_times(false);
280+
23281
TEST_CHECK_RET(true, "virtual_memory_heap");
24282
}

0 commit comments

Comments
 (0)