mirror of
https://github.com/azure-rtos/usbx.git
synced 2025-01-28 07:03:07 +08:00
6ed7092b77
Add regression tests (auto triggered on PR, manually triggered in forked branch).
354 lines
13 KiB
C
354 lines
13 KiB
C
/* Include necessary system files. */
|
|
|
|
#include "usbx_ux_test_cdc_ecm.h"
|
|
|
|
/* Resource usage */
|
|
|
|
static ULONG set_cfg_counter;
|
|
|
|
static ULONG rsc_mem_alloc_cnt_on_set_cfg;
|
|
static ULONG rsc_sem_on_set_cfg;
|
|
static ULONG rsc_sem_get_on_set_cfg;
|
|
static ULONG rsc_mutex_on_set_cfg;
|
|
|
|
static ULONG rsc_enum_sem_usage;
|
|
static ULONG rsc_enum_sem_get_count;
|
|
static ULONG rsc_enum_mutex_usage;
|
|
static ULONG rsc_enum_mem_alloc_count;
|
|
|
|
static ULONG rsc_cdc_sem_usage;
|
|
static ULONG rsc_cdc_sem_get_count;
|
|
static ULONG rsc_cdc_mutex_usage;
|
|
static ULONG rsc_cdc_mem_alloc_count;
|
|
static ULONG rsc_cdc_mem_tx_rx_count;
|
|
|
|
static ULONG error_callback_counter;
|
|
|
|
/* Log resources usage on SetConfigure */
|
|
|
|
static UX_TEST_SETUP _SetConfigure = UX_TEST_SETUP_SetConfigure;
|
|
|
|
static VOID ux_test_hcd_entry_set_cfg(UX_TEST_ACTION *action, VOID *_params)
|
|
{
|
|
|
|
set_cfg_counter ++;
|
|
|
|
rsc_mem_alloc_cnt_on_set_cfg = ux_test_utility_sim_mem_alloc_count();
|
|
|
|
rsc_sem_on_set_cfg = ux_test_utility_sim_sem_create_count();
|
|
rsc_sem_get_on_set_cfg = ux_test_utility_sim_sem_get_count();
|
|
rsc_mutex_on_set_cfg = ux_test_utility_sim_mutex_create_count();
|
|
}
|
|
|
|
static UX_TEST_HCD_SIM_ACTION log_on_SetCfg[] = {
|
|
{ .function = UX_HCD_TRANSFER_REQUEST,
|
|
.req_setup = &_SetConfigure,
|
|
.req_action = UX_TEST_SETUP_MATCH_REQ,
|
|
.action_func = ux_test_hcd_entry_set_cfg,
|
|
.no_return = UX_TRUE
|
|
}, /* Invoke callback & continue */
|
|
{ 0 }
|
|
};
|
|
|
|
static void count_error_callback(struct UX_TEST_ACTION_STRUCT *action, VOID *params)
|
|
{
|
|
UX_TEST_ERROR_CALLBACK_PARAMS *error = (UX_TEST_ERROR_CALLBACK_PARAMS *)params;
|
|
|
|
// printf("error trap: 0x%x, 0x%x, 0x%x\n", error->system_level, error->system_context, error->error_code);
|
|
error_callback_counter ++;
|
|
}
|
|
|
|
static UX_TEST_HCD_SIM_ACTION count_on_error_trap[] = {
|
|
{ .usbx_function = UX_TEST_OVERRIDE_ERROR_CALLBACK,
|
|
.action_func = count_error_callback,
|
|
},
|
|
{ 0 }
|
|
};
|
|
|
|
static UINT sleep_break_on_error(VOID)
|
|
{
|
|
|
|
if (error_callback_counter >= 3)
|
|
return error_callback_counter;
|
|
|
|
return UX_SUCCESS;
|
|
}
|
|
|
|
static UINT sleep_break_on_host_tx_or_rx_buffer_allocated(VOID)
|
|
{
|
|
UINT buffer_count = 0;
|
|
if (cdc_ecm_host == UX_NULL)
|
|
return(UX_SUCCESS);
|
|
if (cdc_ecm_host -> ux_host_class_cdc_ecm_xmit_buffer)
|
|
buffer_count ++;
|
|
if (cdc_ecm_host -> ux_host_class_cdc_ecm_receive_buffer)
|
|
buffer_count ++;
|
|
return (buffer_count);
|
|
}
|
|
|
|
static UINT sleep_break_on_host_tx_and_rx_buffer_allocated(VOID)
|
|
{
|
|
UINT buffer_count = 0;
|
|
if (cdc_ecm_host == UX_NULL)
|
|
return(UX_SUCCESS);
|
|
if (cdc_ecm_host -> ux_host_class_cdc_ecm_xmit_buffer)
|
|
buffer_count ++;
|
|
if (cdc_ecm_host -> ux_host_class_cdc_ecm_receive_buffer)
|
|
buffer_count ++;
|
|
return ((buffer_count >=2) ? buffer_count : UX_SUCCESS);
|
|
}
|
|
|
|
/* Define what the initial system looks like. */
|
|
#ifdef CTEST
|
|
void test_application_define(void *first_unused_memory)
|
|
#else
|
|
void usbx_cdc_ecm_basic_memory_test_application_define(void *first_unused_memory)
|
|
#endif
|
|
{
|
|
|
|
/* Inform user. */
|
|
printf("Running CDC ECM Basic Memory Test................................... ");
|
|
|
|
stepinfo("\n");
|
|
|
|
/* Override error trap. */
|
|
ux_test_link_hooks_from_array(count_on_error_trap);
|
|
|
|
/* Reset testing counts. */
|
|
ux_test_utility_sim_mem_alloc_log_enable(UX_TRUE);
|
|
ux_test_utility_sim_mem_alloc_count_reset();
|
|
ux_test_utility_sim_mutex_create_count_reset();
|
|
ux_test_utility_sim_sem_create_count_reset();
|
|
ux_test_utility_sim_sem_get_count_reset();
|
|
/* Reset error generations */
|
|
ux_test_utility_sim_sem_error_generation_stop();
|
|
ux_test_utility_sim_mutex_error_generation_stop();
|
|
ux_test_utility_sim_sem_get_error_generation_stop();
|
|
|
|
ux_test_cdc_ecm_initialize(first_unused_memory);
|
|
}
|
|
|
|
static void post_init_host()
|
|
{
|
|
|
|
UINT status;
|
|
ULONG mem_free;
|
|
ULONG test_n;
|
|
|
|
|
|
/* Test disconnect. */
|
|
stepinfo(">>>>>>>>>>>>>>>>>>> Test disconnect\n");
|
|
ux_test_disconnect_slave();
|
|
ux_test_disconnect_host_wait_for_enum_completion();
|
|
|
|
/* Reset testing counts. */
|
|
ux_test_utility_sim_mem_alloc_count_reset();
|
|
ux_test_utility_sim_mutex_create_count_reset();
|
|
ux_test_utility_sim_sem_create_count_reset();
|
|
ux_test_utility_sim_sem_get_count_reset();
|
|
ux_test_hcd_sim_host_set_actions(log_on_SetCfg);
|
|
|
|
/* Save free memory usage. */
|
|
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
|
|
|
stepinfo(">>>>>>>>>>>>>>>>>>> Test connect\n");
|
|
/* Connect. */
|
|
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
|
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
|
class_cdc_ecm_get_host();
|
|
|
|
/* Log create counts for further tests. */
|
|
rsc_enum_mutex_usage = rsc_mutex_on_set_cfg;
|
|
rsc_enum_sem_usage = rsc_sem_on_set_cfg;
|
|
rsc_enum_mem_alloc_count = rsc_mem_alloc_cnt_on_set_cfg;
|
|
/* Log create counts when instances active for further tests. */
|
|
rsc_cdc_mutex_usage = ux_test_utility_sim_mutex_create_count() - rsc_enum_mutex_usage;
|
|
rsc_cdc_sem_usage = ux_test_utility_sim_sem_create_count() - rsc_enum_sem_usage;
|
|
rsc_cdc_mem_alloc_count = ux_test_utility_sim_mem_alloc_count() - rsc_enum_mem_alloc_count;
|
|
/* Some allocation does not affect enum. */
|
|
rsc_cdc_mem_tx_rx_count = 0;
|
|
if (cdc_ecm_host->ux_host_class_cdc_ecm_receive_buffer)
|
|
rsc_cdc_mem_tx_rx_count ++;
|
|
if (cdc_ecm_host->ux_host_class_cdc_ecm_xmit_buffer)
|
|
rsc_cdc_mem_tx_rx_count ++;
|
|
/* Lock log base for tests. */
|
|
ux_test_utility_sim_mem_alloc_log_lock();
|
|
|
|
stepinfo("enum mem: %ld\n", rsc_enum_mem_alloc_count);
|
|
stepinfo("cdc mem : %ld\n", rsc_cdc_mem_alloc_count);
|
|
stepinfo("mem free: %ld, %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_CACHE_SAFE] -> ux_byte_pool_available);
|
|
|
|
/* Simulate detach and attach for FS enumeration,
|
|
and check if there is memory error in normal enumeration.
|
|
*/
|
|
stepinfo(">>>>>>>>>>>>>>>>>>> Enumeration test\n");
|
|
mem_free = (~0);
|
|
for (test_n = 0; test_n < 3; test_n++)
|
|
{
|
|
stepinfo("%4ld / 2\n", test_n);
|
|
|
|
/* Disconnect. */
|
|
ux_test_dcd_sim_slave_disconnect();
|
|
ux_test_hcd_sim_host_disconnect();
|
|
|
|
/* Update memory free level (disconnect) */
|
|
if (mem_free == (~0))
|
|
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
|
else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
|
|
{
|
|
|
|
printf("ERROR #%d.%ld: Memory level different after re-enumerations %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
|
test_control_return(1);
|
|
}
|
|
|
|
/* Connect. */
|
|
error_callback_counter = 0;
|
|
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
|
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
|
|
|
/* Wait and break on error. */
|
|
ux_test_breakable_sleep(200, sleep_break_on_error);
|
|
|
|
/* Check */
|
|
if (cdc_ecm_host_from_system_change_function == UX_NULL)
|
|
{
|
|
|
|
printf("ERROR #%d.%ld: Enumeration fail\n", __LINE__, test_n);
|
|
test_control_return(1);
|
|
}
|
|
}
|
|
|
|
/* Simulate detach and attach for FS enumeration,
|
|
and test possible memory allocation error handlings.
|
|
*/
|
|
if (rsc_cdc_mem_alloc_count) stepinfo(">>>>>>>>>>>>>>>>>>> Memory errors enumeration test\n");
|
|
mem_free = (~0);
|
|
for (test_n = 0; test_n < rsc_cdc_mem_alloc_count; test_n ++)
|
|
{
|
|
|
|
stepinfo("%4ld / %4ld\n", test_n, rsc_cdc_mem_alloc_count - 1);
|
|
|
|
/* Disconnect. */
|
|
ux_test_dcd_sim_slave_disconnect();
|
|
ux_test_hcd_sim_host_disconnect();
|
|
|
|
/* Update memory free level (disconnect) */
|
|
if (mem_free == (~0))
|
|
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
|
else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
|
|
{
|
|
|
|
printf("ERROR #%d.%ld: Memory level different after re-enumerations %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
|
test_control_return(1);
|
|
}
|
|
|
|
/* Set memory error generation */
|
|
ux_test_utility_sim_mem_alloc_error_generation_start(test_n + rsc_enum_mem_alloc_count);
|
|
|
|
/* Connect. */
|
|
error_callback_counter = 0;
|
|
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
|
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
|
|
|
if (test_n >= rsc_cdc_mem_alloc_count - rsc_cdc_mem_tx_rx_count)
|
|
{
|
|
|
|
/* Wait and break on errors. */
|
|
ux_test_breakable_sleep(200, sleep_break_on_error);
|
|
}
|
|
else
|
|
{
|
|
|
|
/* Wait and break on errors. */
|
|
ux_test_breakable_sleep(200, sleep_break_on_error);
|
|
|
|
/* Check error */
|
|
if (cdc_ecm_host_from_system_change_function != UX_NULL)
|
|
{
|
|
|
|
printf("ERROR #%d.%ld: device detected when there is memory error\n", __LINE__, test_n);
|
|
test_control_return(1);
|
|
}
|
|
}
|
|
|
|
stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
|
}
|
|
ux_test_utility_sim_mem_alloc_error_generation_stop();
|
|
if (rsc_cdc_mem_alloc_count) stepinfo("\n");
|
|
|
|
/* Test device deinit. */
|
|
stepinfo(">>>>>>>>>>>>>>>>>>> Test class deinit\n");
|
|
ux_test_disconnect_slave();
|
|
ux_test_disconnect_host_wait_for_enum_completion();
|
|
ux_device_stack_class_unregister(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry);
|
|
|
|
/* Reset testing counts. */
|
|
ux_test_utility_sim_mem_alloc_count_reset();
|
|
ux_test_utility_sim_mutex_create_count_reset();
|
|
ux_test_utility_sim_sem_create_count_reset();
|
|
ux_test_utility_sim_sem_get_count_reset();
|
|
|
|
stepinfo(">>>>>>>>>>>>>>>>>>> Test class init\n");
|
|
UX_TEST_CHECK_SUCCESS(ux_device_stack_class_register(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry, 1, 0, &cdc_ecm_parameter));
|
|
|
|
/* Log create counts for further tests. */
|
|
rsc_cdc_mutex_usage = ux_test_utility_sim_mutex_create_count();
|
|
rsc_cdc_sem_usage = ux_test_utility_sim_sem_create_count();
|
|
rsc_cdc_mem_alloc_count = ux_test_utility_sim_mem_alloc_count();
|
|
|
|
/* Lock log base for tests. */
|
|
ux_test_utility_sim_mem_alloc_log_lock();
|
|
|
|
if (rsc_cdc_mem_alloc_count) stepinfo(">>>>>>>>>>>>>>>>>>> Memory errors class init test\n");
|
|
mem_free = (~0);
|
|
for (test_n = 0; test_n < rsc_cdc_mem_alloc_count; test_n ++)
|
|
{
|
|
|
|
stepinfo("%4ld / %4ld\n", test_n, rsc_cdc_mem_alloc_count - 1);
|
|
|
|
/* Deinit. */
|
|
ux_device_stack_class_unregister(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry);
|
|
|
|
/* Update memory free level (disconnect) */
|
|
if (mem_free == (~0))
|
|
mem_free = _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available;
|
|
else if (mem_free != _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available)
|
|
{
|
|
|
|
printf("ERROR #%d.%ld: Memory level different after re-init %ld <> %ld\n", __LINE__, test_n, mem_free, _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
|
test_control_return(1);
|
|
}
|
|
|
|
/* Set memory error generation */
|
|
ux_test_utility_sim_mem_alloc_error_generation_start(test_n);
|
|
|
|
/* Init. */
|
|
|
|
status = ux_device_stack_class_register(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry, 1, 0, &cdc_ecm_parameter);
|
|
|
|
/* Check error */
|
|
if (status != UX_MEMORY_INSUFFICIENT)
|
|
{
|
|
|
|
printf("ERROR #%d.%ld: code 0x%x\n", __LINE__, test_n, status);
|
|
test_control_return(1);
|
|
}
|
|
stepinfo("mem free: %ld\n", _ux_system -> ux_system_memory_byte_pool[UX_MEMORY_BYTE_POOL_REGULAR] -> ux_byte_pool_available);
|
|
}
|
|
ux_test_utility_sim_mem_alloc_error_generation_stop();
|
|
if (rsc_cdc_mem_alloc_count) stepinfo("\n");
|
|
|
|
stepinfo(">>>>>>>>>>>>>>>>>>> Test connect to avoid post post operation\n");
|
|
/* Connect. */
|
|
UX_TEST_CHECK_SUCCESS(ux_device_stack_class_register(_ux_system_slave_class_cdc_ecm_name, ux_device_class_cdc_ecm_entry, 1, 0, &cdc_ecm_parameter));
|
|
ux_test_dcd_sim_slave_connect(UX_FULL_SPEED_DEVICE);
|
|
ux_test_hcd_sim_host_connect(UX_FULL_SPEED_DEVICE);
|
|
class_cdc_ecm_get_host();
|
|
|
|
stepinfo(">>>>>>>>>>>>>>>>>>> post_init_host done\n");
|
|
}
|
|
|
|
static void post_init_device()
|
|
{
|
|
stepinfo(">>>>>>>>>>>>>>>>>>> post_init_device empty\n");
|
|
} |