/* * Arm SCP/MCP Software * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ELEM_THREAD_ID 10 #define MODULE_THREAD_ID 11 struct __fwk_multi_thread_ctx *fwk_multi_thread_ctx; struct fwk_slist_node slist_node[4]; /* Mock module and element */ static struct __fwk_thread_ctx fake_thread_element_ctx; static struct fwk_element fake_element; static struct fwk_element_ctx fake_element_ctx; static struct __fwk_thread_ctx fake_thread_module_ctx; static struct fwk_module fake_module; static struct fwk_module_ctx fake_module_ctx; /* Wrapped OS functions */ osStatus_t __wrap_osKernelStart(void) { return osOK; } osStatus_t __wrap_osKernelInitialize(void) { return osOK; } /* * Indicate the number of function calls before exiting the non-returning * functions */ uint32_t __wrap_osThreadFlagsWait(uint32_t flags, uint32_t options, uint32_t timeout) { (void) flags; (void) options; (void) timeout; return flags; } uint32_t __wrap_osThreadFlagsClear(uint32_t flags) { (void)flags; return 0; } uint32_t __wrap_osThreadFlagsSet(osThreadId_t thread_id, uint32_t flags) { (void) thread_id; (void) flags; return 0; } static osThreadId_t osThreadNew_return_val; static const osThreadAttr_t *osThreadNew_param_attr; osThreadId_t __wrap_osThreadNew(osThreadFunc_t func, void *argument, const osThreadAttr_t *attr) { (void) func; (void) argument; osThreadNew_param_attr = attr; return osThreadNew_return_val; } static int fwk_interrupt_get_current_return_val; int __wrap_fwk_interrupt_get_current(void) { return fwk_interrupt_get_current_return_val; } /* Wrapped framework functions */ static unsigned int fwk_mm_calloc_return_null; static unsigned int fwk_mm_calloc_call_count; static void *fwk_mm_calloc_val; void *__wrap_fwk_mm_calloc(size_t num, size_t size) { fwk_mm_calloc_call_count++; if (fwk_mm_calloc_return_null == fwk_mm_calloc_call_count) fwk_mm_calloc_val = NULL; else fwk_mm_calloc_val = (void *)calloc(num, size); return fwk_mm_calloc_val; } int __wrap_fwk_interrupt_global_disable(void) { return 0; } int __wrap_fwk_interrupt_global_enable(void) { return 0; } static bool fwk_module_is_valid_element_id_return_val; bool __wrap_fwk_module_is_valid_element_id(fwk_id_t id) { return fwk_module_is_valid_element_id_return_val; } static bool fwk_module_is_valid_module_id_return_val; bool __wrap_fwk_module_is_valid_module_id(fwk_id_t id) { return fwk_module_is_valid_module_id_return_val; } bool __wrap_fwk_module_is_valid_entity_id(fwk_id_t id) { return false; } bool __wrap_fwk_module_is_valid_event_id(fwk_id_t id) { return false; } bool __wrap_fwk_module_is_valid_notification_id(fwk_id_t id) { return false; } struct fwk_element_ctx *__wrap_fwk_module_get_element_ctx(fwk_id_t id) { (void) id; return &fake_element_ctx; } struct fwk_module_ctx *__wrap_fwk_module_get_ctx(fwk_id_t id) { (void) id; return &fake_module_ctx; } int __wrap_fwk_module_get_state(fwk_id_t id, enum fwk_module_state *state) { (void) id; (void) state; return FWK_SUCCESS; } static int test_suite_setup(void) { fwk_multi_thread_ctx = __fwk_multi_thread_get_ctx(); return FWK_SUCCESS; } static void test_case_setup(void) { fwk_mm_calloc_return_null = UINT_MAX; fwk_mm_calloc_call_count = 0; fwk_interrupt_get_current_return_val = FWK_SUCCESS; osThreadNew_return_val = (void*)MODULE_THREAD_ID; fake_thread_element_ctx.os_thread_id = (osThreadId_t)ELEM_THREAD_ID; fake_thread_module_ctx.os_thread_id = (osThreadId_t)MODULE_THREAD_ID; fake_module_ctx = (struct fwk_module_ctx){ }; fake_module_ctx.desc = &fake_module; fake_module_ctx.thread_ctx = NULL; fake_element_ctx = (struct fwk_element_ctx){ }; fake_element_ctx.desc = &fake_element; fake_element_ctx.thread_ctx = NULL; fwk_module_is_valid_element_id_return_val = false; fwk_module_is_valid_module_id_return_val = true; } static void test_create_common_thread(void) { int result; result = __fwk_thread_init(16); assert(result == FWK_SUCCESS); } static void test_create_id_invalid(void) { int status; fwk_id_t id = FWK_ID_MODULE(0x1); /* The ID is invalid */ fwk_module_is_valid_module_id_return_val = false; status = fwk_thread_create(id); assert(status == FWK_E_PARAM); } static void test_create_not_initialized(void) { int status; fwk_id_t id = FWK_ID_MODULE(0x1); /* Thread component not initialized */ fwk_multi_thread_ctx->running = true; status = fwk_thread_create(id); assert(status == FWK_E_STATE); fwk_multi_thread_ctx->running = false; } static void test_create_thread_invalid(void) { int status; fwk_id_t id = FWK_ID_MODULE(0x1); /* module thread ctx is not null */ fake_module_ctx.thread_ctx = &fake_thread_module_ctx; status = fwk_thread_create(id); assert(status == FWK_E_STATE); } static void test_create_thread_memory_allocation_failed(void) { int status; fwk_id_t id = FWK_ID_MODULE(0x1); /* Thread memory allocation failed */ fwk_mm_calloc_return_null = 1; status = fwk_thread_create(id); assert(status == FWK_E_NOMEM); } static void test_create_thread_creation_failed(void) { int status; fwk_id_t id = FWK_ID_MODULE(0x1); /* Thread creation failed */ osThreadNew_return_val = NULL; status = fwk_thread_create(id); assert(status == FWK_E_OS); } static void test_create_element_thread(void) { int status; fwk_id_t id = FWK_ID_MODULE(0x1); /* Thread creation for an element */ fwk_module_is_valid_element_id_return_val = true; status = fwk_thread_create(id); assert(status == FWK_SUCCESS); assert(fake_element_ctx.thread_ctx == fwk_mm_calloc_val); } static void test_create_module_thread(void) { int status; fwk_id_t id = FWK_ID_MODULE(0x1); /* Thread creation for a module */ status = fwk_thread_create(id); assert(status == FWK_SUCCESS); assert(fake_module_ctx.thread_ctx == fwk_mm_calloc_val); } static const struct fwk_test_case_desc test_case_table[] = { FWK_TEST_CASE(test_create_common_thread), FWK_TEST_CASE(test_create_id_invalid), FWK_TEST_CASE(test_create_not_initialized), FWK_TEST_CASE(test_create_thread_invalid), FWK_TEST_CASE(test_create_thread_memory_allocation_failed), FWK_TEST_CASE(test_create_thread_creation_failed), FWK_TEST_CASE(test_create_element_thread), FWK_TEST_CASE(test_create_module_thread) }; struct fwk_test_suite_desc test_suite = { .name = "fwk_multi_thread_create", .test_suite_setup = test_suite_setup, .test_case_setup = test_case_setup, .test_case_count = FWK_ARRAY_SIZE(test_case_table), .test_case_table = test_case_table, };