-
Notifications
You must be signed in to change notification settings - Fork 321
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
vmh_tests: Add set of parametrized tests and test suit
Add enhanced vmh testing. Signed-off-by: Jakub Dabek <[email protected]>
- Loading branch information
1 parent
608af3d
commit 09dd76e
Showing
1 changed file
with
255 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,13 @@ | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
/* | ||
* Copyright(c) 2023 Intel Corporation. All rights reserved. | ||
* | ||
* Author: Guennadi Liakhovetski <[email protected]> | ||
*/ | ||
* Copyright(c) 2023 Intel Corporation. All rights reserved. | ||
* | ||
* Author: Guennadi Liakhovetski <[email protected]> | ||
*/ | ||
|
||
#include <errno.h> | ||
#include <stdbool.h> | ||
#include <stdlib.h> | ||
|
||
#include <adsp_memory_regions.h> | ||
#include <sof/boot_test.h> | ||
|
@@ -17,8 +18,258 @@ | |
|
||
LOG_MODULE_DECLARE(sof_boot_test, CONFIG_SOF_LOG_LEVEL); | ||
|
||
/* Test creating and freeing a virtual memory heap */ | ||
static void test_vmh_init_and_free_heap(int memory_region_attribute, | ||
struct vmh_heap_config *config, | ||
int core_id, | ||
bool allocating_continuously, | ||
bool expect_success) | ||
{ | ||
struct vmh_heap *heap = vmh_init_heap(config, memory_region_attribute, | ||
core_id, allocating_continuously); | ||
if (expect_success) { | ||
zassert_not_null(heap, | ||
"Heap initialization expected to succeed but failed"); | ||
} | ||
else | ||
zassert_is_null(heap, "Heap initialization expected to fail but succeeded"); | ||
|
||
if (heap) { | ||
int ret = vmh_free_heap(heap); | ||
|
||
zassert_equal(ret, 0, "Failed to free heap"); | ||
} | ||
} | ||
|
||
/* Test for vmh_alloc and vmh_free */ | ||
static void test_vmh_alloc_free_no_check(struct vmh_heap *heap, | ||
uint32_t alloc_size, | ||
bool expect_success) | ||
{ | ||
void *ptr = vmh_alloc(heap, alloc_size); | ||
|
||
if (expect_success) | ||
zassert_not_null(ptr, "Allocation expected to succeed but failed"); | ||
else | ||
zassert_is_null(ptr, "Allocation expected to fail but succeeded"); | ||
|
||
if (ptr) { | ||
int ret = vmh_free(heap, ptr); | ||
|
||
zassert_equal(ret, 0, "Failed to free allocated memory"); | ||
} | ||
} | ||
|
||
/* Test function for vmh_alloc and vmh_free with memory read/write */ | ||
static void test_vmh_alloc_free_check(struct vmh_heap *heap, | ||
uint32_t alloc_size, | ||
bool expect_success) | ||
{ | ||
void *ptr = vmh_alloc(heap, alloc_size); | ||
|
||
if (expect_success) | ||
zassert_not_null(ptr, "Allocation expected to succeed but failed"); | ||
else { | ||
zassert_is_null(ptr, "Allocation expected to fail but succeeded"); | ||
return; | ||
} | ||
|
||
if (ptr) { | ||
/* Write test pattern to the allocated memory and verify it */ | ||
memset(ptr, 0xAA, alloc_size); | ||
|
||
uint8_t start_val = *((uint8_t *)ptr); | ||
|
||
zassert_equal(start_val, 0xAA, | ||
"Memory content verification failed at the start"); | ||
|
||
uint8_t end_val = *((uint8_t *)ptr + alloc_size - 1); | ||
|
||
zassert_equal(end_val, 0xAA, | ||
"Memory content verification failed at the end"); | ||
|
||
if (alloc_size > 2) { | ||
uint32_t middle_pos = alloc_size / 2; | ||
uint8_t middle_val = *((uint8_t *)ptr + middle_pos); | ||
|
||
zassert_equal(middle_val, 0xAA, | ||
"Memory content verification failed in the middle"); | ||
} | ||
|
||
int ret = vmh_free(heap, ptr); | ||
|
||
zassert_equal(ret, 0, "Failed to free allocated memory"); | ||
} | ||
} | ||
|
||
/* Test function for multiple allocations on the same heap with read/write */ | ||
static void test_vmh_multiple_allocs(struct vmh_heap *heap, int num_allocs, | ||
uint32_t min_alloc_size, | ||
uint32_t max_alloc_size) | ||
{ | ||
void *ptrs[num_allocs]; | ||
uint32_t alloc_size; | ||
bool success; | ||
int ret; | ||
|
||
/* Perform multiple allocations */ | ||
for (int i = 0; i < num_allocs; i++) { | ||
/* Generate a random allocation size between min_alloc_size and max_alloc_size */ | ||
alloc_size = min_alloc_size + | ||
k_cycle_get_32() % (max_alloc_size - min_alloc_size + 1); | ||
|
||
ptrs[i] = vmh_alloc(heap, alloc_size); | ||
|
||
zassert_true(ptrs[i] != NULL, | ||
"Allocation of size %u expected to succeed but failed", | ||
alloc_size); | ||
|
||
if (ptrs[i] != NULL) { | ||
LOG_INF("Test allocation size: %d", alloc_size); | ||
|
||
memset(ptrs[i], 0xAA, alloc_size); | ||
|
||
|
||
uint8_t *byte_ptr = (uint8_t *)ptrs[i]; | ||
|
||
for (uint32_t j = 0; j < alloc_size; j++) { | ||
zassert_equal(byte_ptr[j], 0xAA, | ||
"Memory content verification failed at position %u", j); | ||
} | ||
} | ||
} | ||
|
||
for (int i = 0; i < num_allocs; i++) { | ||
if (ptrs[i]) { | ||
ret = vmh_free(heap, ptrs[i]); | ||
zassert_equal(ret, 0, "Failed to free allocated memory"); | ||
} | ||
} | ||
} | ||
|
||
/* Test case for multiple allocations */ | ||
static void test_vmh_alloc_multiple_times(bool allocating_continuously) | ||
{ | ||
struct vmh_heap *heap = | ||
vmh_init_heap(NULL, MEM_REG_ATTR_CORE_HEAP, 0, allocating_continuously); | ||
|
||
zassert_not_null(heap, "Heap initialization failed"); | ||
|
||
/* Test multiple allocations with small sizes */ | ||
test_vmh_multiple_allocs(heap, 64, 4, 8); | ||
test_vmh_multiple_allocs(heap, 64, 4, 8); | ||
test_vmh_multiple_allocs(heap, 64, 4, 8); | ||
test_vmh_multiple_allocs(heap, 16, 4, 1024); | ||
test_vmh_multiple_allocs(heap, 16, 4, 1024); | ||
test_vmh_multiple_allocs(heap, 64, 1024, 4096); | ||
test_vmh_multiple_allocs(heap, 64, 4096, 8192); | ||
test_vmh_multiple_allocs(heap, 16, 1024, 4096); | ||
test_vmh_multiple_allocs(heap, 16, 4096, 8192); | ||
|
||
/* Clean up the heap after testing */ | ||
int ret = vmh_free_heap(heap); | ||
|
||
zassert_equal(ret, 0, "Failed to free heap after multiple allocations"); | ||
} | ||
|
||
/* Test case for vmh_alloc and vmh_free */ | ||
static void test_vmh_alloc_free(bool allocating_continuously) | ||
{ | ||
struct vmh_heap *heap = | ||
vmh_init_heap(NULL, MEM_REG_ATTR_CORE_HEAP, 0, allocating_continuously); | ||
|
||
zassert_not_null(heap, "Heap initialization failed"); | ||
|
||
test_vmh_alloc_free_no_check(heap, 512, true); | ||
test_vmh_alloc_free_no_check(heap, 2048, true); | ||
test_vmh_alloc_free_no_check(heap, sizeof(int), false); | ||
test_vmh_alloc_free_no_check(heap, 0, false); | ||
|
||
test_vmh_alloc_free_check(heap, 512, true); | ||
test_vmh_alloc_free_check(heap, 2048, true); | ||
test_vmh_alloc_free_check(heap, sizeof(int), false); | ||
test_vmh_alloc_free_check(heap, 0, false); | ||
|
||
int ret = vmh_free_heap(heap); | ||
|
||
zassert_equal(ret, 0, "Failed to free heap"); | ||
|
||
/* Could add tests with configs for heaps*/ | ||
} | ||
|
||
/* Test case for vmh_alloc and vmh_free with and without config */ | ||
static void test_heap_creation(void) | ||
{ | ||
test_vmh_init_and_free_heap(MEM_REG_ATTR_CORE_HEAP, NULL, 0, false, true); | ||
|
||
/* Try to setup with pre defined heap config */ | ||
struct vmh_heap_config config; | ||
|
||
config.block_bundles_table[0].block_size = 4; | ||
|
||
config.block_bundles_table[0].number_of_blocks = 80; | ||
|
||
config.block_bundles_table[1].block_size = 4; | ||
|
||
config.block_bundles_table[1].number_of_blocks = 80; | ||
|
||
test_vmh_init_and_free_heap(MEM_REG_ATTR_CORE_HEAP, &config, 0, false, true); | ||
} | ||
|
||
/* Test case for alloc/free on configured heap */ | ||
static void test_alloc_on_configured_heap(bool allocating_continuously) | ||
{ | ||
|
||
/* Try to setup with pre defined heap config */ | ||
struct vmh_heap_config config; | ||
|
||
config.block_bundles_table[0].block_size = 20; | ||
|
||
config.block_bundles_table[0].number_of_blocks = 80; | ||
|
||
/* Create continuous allocation heap for success test */ | ||
struct vmh_heap *heap = | ||
vmh_init_heap(NULL, MEM_REG_ATTR_CORE_HEAP, 0, allocating_continuously); | ||
|
||
/* Will succeed on continuous and fail with single block alloc */ | ||
test_vmh_alloc_free_check(heap, 512, allocating_continuously); | ||
|
||
int ret = vmh_free_heap(heap); | ||
|
||
zassert_equal(ret, 0, "Failed to free heap"); | ||
} | ||
|
||
/* Test cases for initializing heaps on all available regions */ | ||
static void test_vmh_init_all_heaps(void) | ||
{ | ||
int num_regions = CONFIG_MP_MAX_NUM_CPUS + VIRTUAL_REGION_COUNT; | ||
int i; | ||
const struct sys_mm_drv_region *virtual_memory_region = | ||
sys_mm_drv_query_memory_regions(); | ||
|
||
/* Test initializing all types of heaps */ | ||
for (i = 0; i < num_regions; i++) { | ||
|
||
/* Test without continuous allocation */ | ||
test_vmh_init_and_free_heap(virtual_memory_region[i].attr, NULL, 0, false, | ||
true); | ||
|
||
/* Test if it fails when heap already exists */ | ||
test_vmh_init_and_free_heap(virtual_memory_region[i].attr, NULL, 0, true, | ||
false); | ||
} | ||
} | ||
|
||
ZTEST(sof_boot, virtual_memory_heap) | ||
{ | ||
test_heap_creation(); | ||
test_vmh_init_all_heaps(); | ||
test_alloc_on_configured_heap(true); | ||
test_alloc_on_configured_heap(false); | ||
test_vmh_alloc_free(true); | ||
test_vmh_alloc_free(false); | ||
test_vmh_alloc_multiple_times(true); | ||
test_vmh_alloc_multiple_times(false); | ||
|
||
TEST_CHECK_RET(true, "virtual_memory_heap"); | ||
} |