From f03c9e53a1f10e1038da830b35b5f631cbbc3c1d Mon Sep 17 00:00:00 2001 From: "Mohamed Ali Khalifi (AE/PJ-SW4)" Date: Thu, 12 Mar 2020 16:28:30 +0100 Subject: [PATCH 1/7] Add test executor and support code Co-authored-by: ChiefGokhlayehBosch Signed-off-by: ChiefGokhlayehBosch --- CMakeLists.txt | 29 +- .../config/core/essentials/Kiso_BSPConfig.h | 4 + .../NucleoF767/bsp/include/BSP_NucleoF767.h | 1 + boards/NucleoF767/bsp/source/bsp_api_button.c | 1 - .../bsp/source/bsp_api_genericuart.c | 230 ++++++++++++++ boards/NucleoF767/bsp/source/bsp_api_testif.c | 45 +-- boards/NucleoF767/bsp/source/protected/gpio.h | 4 + .../core/essentials/Kiso_BSPConfig.h | 1 + cmake/KisoLibsConfig.cmake | 1 - .../test/integration/CMakeLists.txt | 30 ++ core/essentials/test/integration/readme.md | 7 + .../test/integration/source/TestEntry.c | 68 +++++ .../test/integration/source/TestSuiteUart.c | 245 +++++++++++++++ .../test/integration/source/TestSuiteUart.h | 55 ++++ .../test/integration/specs/I2C_Test_Spec.md | 283 ++++++++++++++++++ .../test/integration/specs/SPI_Test_Spec.md | 207 +++++++++++++ .../test/integration/specs/UART_Test_Spec.md | 212 +++++++++++++ .../test/integration/test-protocol.txt | 0 testing/integration/readme.md | 8 + testing/integration/test-auxiliary/readme.md | 3 + .../integration/test-coordinator/readme.md | 3 + .../integration/test-executor/CMakeLists.txt | 24 ++ testing/integration/test-executor/readme.md | 3 + .../testapp/config/utils/Kiso_UtilsConfig.h | 107 +++++++ .../test-executor/testapp/source/AppModules.h | 17 ++ .../test-executor/testapp/source/BSP_Proxy.h | 53 ++++ .../test-executor/testapp/source/main.c | 260 ++++++++++++++++ testing/integration/test-scheduler/readme.md | 3 + 28 files changed, 1874 insertions(+), 30 deletions(-) create mode 100644 boards/NucleoF767/bsp/source/bsp_api_genericuart.c create mode 100644 core/essentials/test/integration/CMakeLists.txt create mode 100644 core/essentials/test/integration/readme.md create mode 100644 core/essentials/test/integration/source/TestEntry.c create mode 100644 core/essentials/test/integration/source/TestSuiteUart.c create mode 100644 core/essentials/test/integration/source/TestSuiteUart.h create mode 100644 core/essentials/test/integration/specs/I2C_Test_Spec.md create mode 100644 core/essentials/test/integration/specs/SPI_Test_Spec.md create mode 100644 core/essentials/test/integration/specs/UART_Test_Spec.md create mode 100644 core/essentials/test/integration/test-protocol.txt create mode 100644 testing/integration/readme.md create mode 100644 testing/integration/test-auxiliary/readme.md create mode 100644 testing/integration/test-coordinator/readme.md create mode 100644 testing/integration/test-executor/CMakeLists.txt create mode 100644 testing/integration/test-executor/readme.md create mode 100644 testing/integration/test-executor/testapp/config/utils/Kiso_UtilsConfig.h create mode 100644 testing/integration/test-executor/testapp/source/AppModules.h create mode 100644 testing/integration/test-executor/testapp/source/BSP_Proxy.h create mode 100644 testing/integration/test-executor/testapp/source/main.c create mode 100644 testing/integration/test-scheduler/readme.md diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ce1a276..c5f5ec78 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,7 @@ option(ENABLE_FORMAT_CHECKS "Run format checks during configuration stage and ge option(SKIP_FORMAT_REPORTS "Skip generation of format XML reports in build directory" ON) option(ENABLE_STATIC_CHECKS "Configure a build tree for static code analysis" OFF) option(ENABLE_COVERAGE "Build unit tests with coverage information to use with GCOV and LCOV" ON) +option(ENABLE_INTEGRATION_TESTING "Build for integration tests application" OFF) ## Include config file if it exists include(kiso_defaults.cmake OPTIONAL) @@ -17,14 +18,16 @@ if (NOT DEFINED CMAKE_TOOLCHAIN_FILE AND NOT ${ENABLE_TESTING}) include(cmake/ArmToolchain.cmake) endif() -message("------------- KISO CONFIG -------------") -message("Building Kiso tests: ${ENABLE_TESTING}") -message(" ... with coverage: ${ENABLE_COVERAGE}") -message("Kiso Board Path: ${KISO_BOARD_PATH}") -message("Kiso OS: ${KISO_OS_LIB}") -message("Kiso Application Path: ${KISO_APPLICATION_PATH}") -message("Project Config Path: ${PROJECT_CONFIG_PATH}") -message("------------- KISO CONFIG -------------") +message("---------------------------------- KISO CONFIG ----------------------------------") +message("Building Kiso tests: ${ENABLE_TESTING}") +message(" ... with coverage: ${ENABLE_COVERAGE}") +message("Building Kiso integration tests: ${ENABLE_INTEGRATION_TESTING}") +message(" ... with entry in: ${KISO_INTEGRATION_TEST_NAME}") +message("Kiso Board Path: ${KISO_BOARD_PATH}") +message("Kiso OS: ${KISO_OS_LIB}") +message("Kiso Application Path: ${KISO_APPLICATION_PATH}") +message("Project Config Path: ${PROJECT_CONFIG_PATH}") +message("---------------------------------- KISO CONFIG ----------------------------------") project (Kiso C) @@ -89,7 +92,12 @@ if(${ENABLE_STATIC_CHECKS}) endif() ## Add application code -add_subdirectory(${KISO_APPLICATION_PATH} ${CMAKE_CURRENT_BINARY_DIR}/applications/${KISO_APPLICATION_NAME}) +if(${ENABLE_INTEGRATION_TESTING}) + add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/testing/integration/test-executor) + add_subdirectory(${KISO_INTEGRATION_TEST_NAME}/test/integration) +else(${ENABLE_INTEGRATION_TESTING}) + add_subdirectory(${KISO_APPLICATION_PATH} ${CMAKE_CURRENT_BINARY_DIR}/applications/${KISO_APPLICATION_NAME}) +endif(${ENABLE_INTEGRATION_TESTING}) include(KisoLibsConfig) @@ -98,6 +106,9 @@ include(KisoLibsConfig) add_subdirectory(core/essentials) add_subdirectory(core/utils) add_subdirectory(core/connectivity/cellular) +if(${ENABLE_INTEGRATION_TESTING}) + add_subdirectory(core/testing) +endif(${ENABLE_INTEGRATION_TESTING}) ## Add thirdparty libs add_subdirectory(thirdparty) diff --git a/boards/NucleoF767/bsp/config/core/essentials/Kiso_BSPConfig.h b/boards/NucleoF767/bsp/config/core/essentials/Kiso_BSPConfig.h index 52c59475..49616eb1 100644 --- a/boards/NucleoF767/bsp/config/core/essentials/Kiso_BSPConfig.h +++ b/boards/NucleoF767/bsp/config/core/essentials/Kiso_BSPConfig.h @@ -48,6 +48,10 @@ #define KISO_FEATURE_BSP_BUTTON 1 #endif +#ifndef KISO_FEATURE_BSP_GENERIC_UART +#define KISO_FEATURE_BSP_GENERIC_UART 1 +#endif + #ifndef KISO_FEATURE_BSP_CELLULAR_SARAR4N4 #define KISO_FEATURE_BSP_CELLULAR_SARAR4N4 0 #endif diff --git a/boards/NucleoF767/bsp/include/BSP_NucleoF767.h b/boards/NucleoF767/bsp/include/BSP_NucleoF767.h index 5486b4a6..188e2bb8 100644 --- a/boards/NucleoF767/bsp/include/BSP_NucleoF767.h +++ b/boards/NucleoF767/bsp/include/BSP_NucleoF767.h @@ -38,6 +38,7 @@ enum BSP_NUCLEOF767y_Modules_E MODULE_BSP_API_BOARD, MODULE_BSP_API_LED, MODULE_BSP_API_TEST_IF, + MODULE_BSP_API_GENERICUART, MODULE_BSP_TIME, MODULE_BSP_BUTTON, }; diff --git a/boards/NucleoF767/bsp/source/bsp_api_button.c b/boards/NucleoF767/bsp/source/bsp_api_button.c index 631a6f00..708e679e 100644 --- a/boards/NucleoF767/bsp/source/bsp_api_button.c +++ b/boards/NucleoF767/bsp/source/bsp_api_button.c @@ -28,7 +28,6 @@ /*---------------------- LOCAL FUNCTIONS DECLARATION ----------------------------------------------------------------*/ void EXTI15_10_IRQHandler(void); -void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin); /*---------------------- VARIABLES DECLARATION ----------------------------------------------------------------------*/ diff --git a/boards/NucleoF767/bsp/source/bsp_api_genericuart.c b/boards/NucleoF767/bsp/source/bsp_api_genericuart.c new file mode 100644 index 00000000..ec27839f --- /dev/null +++ b/boards/NucleoF767/bsp/source/bsp_api_genericuart.c @@ -0,0 +1,230 @@ +/******************************************************************************** +* Copyright (c) 2010-2020 Robert Bosch GmbH +* +* This program and the accompanying materials are made available under the +* terms of the Eclipse Public License 2.0 which is available at +* http://www.eclipse.org/legal/epl-2.0. +* +* SPDX-License-Identifier: EPL-2.0 +* +* Contributors: +* Robert Bosch GmbH - initial contribution +* +********************************************************************************/ + +#include "Kiso_BSP_GenericUart.h" + +#if KISO_FEATURE_BSP_GENERIC_UART + +#include "Kiso_Basics.h" +#include "Kiso_Retcode.h" +#include "stm32/stm32f7/Kiso_MCU_STM32F7_UART_Handle.h" +#include "Kiso_HAL_Delay.h" +#include "BSP_NucleoF767.h" +#include "protected/gpio.h" + +/*---------------------- MACROS DEFINITION --------------------------------------------------------------------------*/ + +#undef KISO_MODULE_ID +#define KISO_MODULE_ID MODULE_BSP_API_GENERICUART + +#define UART_INT_PRIORITY UINT32_C(10) +#define UART_SUBPRIORITY UINT32_C(1) + +/*---------------------- LOCAL FUNCTIONS DECLARATION ----------------------------------------------------------------*/ + +void USART2_IRQHandler(void); + +/*---------------------- VARIABLES DECLARATION ----------------------------------------------------------------------*/ + +static uint8_t bspState = (uint8_t)BSP_STATE_INIT; /**< BSP State of the cellular module */ + +/** + * Static structure storing the UART handle for Test Interface + */ +static struct MCU_UART_S uartCtrlStruct = + { + .TxMode = KISO_HAL_TRANSFER_MODE_INTERRUPT, + .RxMode = KISO_HAL_TRANSFER_MODE_INTERRUPT, + .Datarate = 115200U, + .huart.Instance = USART2, + .huart.Init.BaudRate = 115200U, + .huart.Init.WordLength = UART_WORDLENGTH_8B, + .huart.Init.StopBits = UART_STOPBITS_1, + .huart.Init.Parity = UART_PARITY_NONE, + .huart.Init.Mode = UART_MODE_TX_RX, + .huart.Init.HwFlowCtl = UART_HWCONTROL_NONE, + .huart.Init.OverSampling = UART_OVERSAMPLING_16, + .huart.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE, + .huart.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT, +}; +/*---------------------- EXPOSED FUNCTIONS IMPLEMENTATION -----------------------------------------------------------*/ + +/** + * See API interface for function documentation + * @retval RETCODE_OK in case of success. + * @retval RETCODE_INCONSISTENT_STATE in case the module is not in a state to allow connecting. + */ +Retcode_T BSP_GenericUart_Connect(uint32_t id) +{ + KISO_UNUSED(id); + Retcode_T retcode = RETCODE_OK; + + if (!(bspState & (uint8_t)BSP_STATE_TO_CONNECTED)) + { + retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_INCONSISTENT_STATE); + } + if (RETCODE_OK == retcode) + { + /* IOSV bit MUST be set to access GPIO port G[2:15] */ + __HAL_RCC_PWR_CLK_ENABLE(); + __HAL_RCC_LPTIM1_CLK_ENABLE(); + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* UART RX/TX GPIO pin configuration */ + GPIO_OpenClockGate(GPIO_PORT_D, PIND_USART2_TX | PIND_USART2_RX); + + GPIO_InitStruct.Pin = PIND_USART2_TX | PIND_USART2_RX; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF7_USART2; + + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + bspState = (uint8_t)BSP_STATE_CONNECTED; + } + return retcode; +} + +/** + * See API interface for function documentation + * @retval RETCODE_OK in case of success. + * @retval RETCODE_INCONSISTENT_STATE in case the module is not in a state to allow enabling. + */ +Retcode_T BSP_GenericUart_Enable(uint32_t id) +{ + KISO_UNUSED(id); + Retcode_T retcode = RETCODE_OK; + + if (!(bspState & (uint8_t)BSP_STATE_TO_ENABLED)) + { + retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_INCONSISTENT_STATE); + } + if (RETCODE_OK == retcode) + { + __HAL_RCC_USART2_CLK_ENABLE(); + __HAL_RCC_USART2_FORCE_RESET(); + __HAL_RCC_USART2_RELEASE_RESET(); + __GPIOD_CLK_ENABLE(); + /* Configure the UART resource */ + if (HAL_OK != HAL_UART_Init(&uartCtrlStruct.huart)) + { + retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_BSP_UART_INIT_FAILED); + } + } + if (RETCODE_OK == retcode) + { + NVIC_ClearPendingIRQ(USART2_IRQn); + HAL_NVIC_SetPriority(USART2_IRQn, UART_INT_PRIORITY, UART_SUBPRIORITY); + HAL_NVIC_EnableIRQ(USART2_IRQn); + + bspState = (uint8_t)BSP_STATE_ENABLED; + } + return retcode; +} + +/** + * See API interface for function documentation + * @retval RETCODE_OK in case of success. + * @retval RETCODE_INCONSISTENT_STATE in case the module is not in a state to allow disabling. + */ +Retcode_T BSP_GenericUart_Disable(uint32_t id) +{ + KISO_UNUSED(id); + Retcode_T retcode = RETCODE_OK; + + if (!(bspState & (uint8_t)BSP_STATE_TO_DISABLED)) + { + retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_INCONSISTENT_STATE); + } + if (RETCODE_OK == retcode) + { + /* Disable interrupts and deactivate UART peripheral */ + HAL_NVIC_DisableIRQ(USART2_IRQn); + /* Clear the pending interrupt */ + HAL_NVIC_ClearPendingIRQ(USART2_IRQn); + + if (HAL_OK != HAL_UART_DeInit(&uartCtrlStruct.huart)) + { + retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_BSP_UART_DEINIT_FAILED); + } + } + if (RETCODE_OK == retcode) + { + __USART2_CLK_DISABLE(); + bspState = (uint8_t)BSP_STATE_DISABLED; + } + return retcode; +} + +/** + * See API interface for function documentation + * @retval RETCODE_OK in case of success. + * @retval RETCODE_INCONSISTENT_STATE in case the module is not in a state to allow disconnecting. + */ +Retcode_T BSP_GenericUart_Disconnect(uint32_t id) +{ + KISO_UNUSED(id); + Retcode_T retcode = RETCODE_OK; + if (!(bspState & (uint8_t)BSP_STATE_TO_DISCONNECTED)) + { + retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_INCONSISTENT_STATE); + } + if (RETCODE_OK == retcode) + { + HAL_GPIO_DeInit(GPIOD, PIND_USART2_TX | PIND_USART2_RX); + GPIO_CloseClockGate(GPIO_PORT_D, PIND_USART2_TX | PIND_USART2_RX); + } + if (RETCODE_OK == retcode) + { + bspState = (uint8_t)BSP_STATE_DISCONNECTED; + } + return retcode; +} + +/** + * See API interface for function documentation + * @return A pointer to the UART control structure + */ +HWHandle_T BSP_GenericUart_GetHandle(uint32_t id) +{ + KISO_UNUSED(id); + return (HWHandle_T)&uartCtrlStruct; +} + +/** + * This function is not in use. + */ +Retcode_T BSP_GenericUart_UserControl(uint32_t control, void *param) +{ + KISO_UNUSED(control); + KISO_UNUSED(param); + + return RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_NOT_SUPPORTED); +} + +/*---------------------- LOCAL FUNCTIONS IMPLEMENTATION -------------------------------------------------------------*/ + +/** + * Interrupt Service Routine handling USART2 IRQ. Forwards call to MCU Layer for handling. + */ +void USART2_IRQHandler(void) +{ + if (uartCtrlStruct.IrqCallback) + { + uartCtrlStruct.IrqCallback((UART_T)&uartCtrlStruct); + } +} +#endif /* KISO_FEATURE_BSP_TEST_INTERFACE */ diff --git a/boards/NucleoF767/bsp/source/bsp_api_testif.c b/boards/NucleoF767/bsp/source/bsp_api_testif.c index 1b4bd875..324f55fc 100644 --- a/boards/NucleoF767/bsp/source/bsp_api_testif.c +++ b/boards/NucleoF767/bsp/source/bsp_api_testif.c @@ -1,5 +1,5 @@ /******************************************************************************** -* Copyright (c) 2010-2019 Robert Bosch GmbH +* Copyright (c) 2010-2020 Robert Bosch GmbH * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -16,6 +16,7 @@ #if KISO_FEATURE_BSP_TEST_INTERFACE +#include "Kiso_Basics.h" #include "stm32/stm32f7/Kiso_MCU_STM32F7_UART_Handle.h" #include "Kiso_HAL_Delay.h" #include "BSP_NucleoF767.h" @@ -27,10 +28,7 @@ #define KISO_MODULE_ID MODULE_BSP_API_TEST_IF #define TESTIF_UART_INT_PRIORITY UINT32_C(10) -#define TESTIF_UART_SUBPRIORITY UINT32_C(0) - -#define PINB_DBG_TX GPIO_PIN_8 -#define PINB_DBG_RX GPIO_PIN_9 +#define TESTIF_UART_SUBPRIORITY UINT32_C(1) /*---------------------- LOCAL FUNCTIONS DECLARATION ----------------------------------------------------------------*/ @@ -77,16 +75,22 @@ Retcode_T BSP_TestInterface_Connect(void) } if (RETCODE_OK == retcode) { - GPIO_InitTypeDef BSP_GPIOInitStruct = {0}; + /* IOSV bit MUST be set to access GPIO port G[2:15] */ + __HAL_RCC_PWR_CLK_ENABLE(); + __HAL_RCC_LPTIM1_CLK_ENABLE(); + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + + /* UART RX/TX GPIO pin configuration */ + GPIO_OpenClockGate(GPIO_PORT_D, PIND_USART3_TX | PIND_USART3_RX); - GPIO_OpenClockGate(GPIO_PORT_D, PINB_DBG_TX | PINB_DBG_RX); - /* Configure RX TX as alternate function push pull */ - BSP_GPIOInitStruct.Pin = PINB_DBG_TX | PINB_DBG_RX; - BSP_GPIOInitStruct.Mode = GPIO_MODE_AF_PP; - BSP_GPIOInitStruct.Pull = GPIO_NOPULL; - BSP_GPIOInitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - BSP_GPIOInitStruct.Alternate = GPIO_AF7_USART3; - HAL_GPIO_Init(GPIOD, &BSP_GPIOInitStruct); + GPIO_InitStruct.Pin = PIND_USART3_TX | PIND_USART3_RX; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF7_USART3; + + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); bspState = (uint8_t)BSP_STATE_CONNECTED; } @@ -108,11 +112,10 @@ Retcode_T BSP_TestInterface_Enable(void) } if (RETCODE_OK == retcode) { - /* Enable the UART clock */ __HAL_RCC_USART3_CLK_ENABLE(); __HAL_RCC_USART3_FORCE_RESET(); __HAL_RCC_USART3_RELEASE_RESET(); - + __GPIOD_CLK_ENABLE(); /* Configure the UART resource */ if (HAL_OK != HAL_UART_Init(&testIf_UARTStruct.huart)) { @@ -121,6 +124,7 @@ Retcode_T BSP_TestInterface_Enable(void) } if (RETCODE_OK == retcode) { + NVIC_ClearPendingIRQ(USART3_IRQn); HAL_NVIC_SetPriority(USART3_IRQn, TESTIF_UART_INT_PRIORITY, TESTIF_UART_SUBPRIORITY); HAL_NVIC_EnableIRQ(USART3_IRQn); @@ -146,6 +150,9 @@ Retcode_T BSP_TestInterface_Disable(void) { /* Disable interrupts and deactivate UART peripheral */ HAL_NVIC_DisableIRQ(USART3_IRQn); + /* Clear the pending interrupt */ + HAL_NVIC_ClearPendingIRQ(USART3_IRQn); + if (HAL_OK != HAL_UART_DeInit(&testIf_UARTStruct.huart)) { retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_BSP_UART_DEINIT_FAILED); @@ -173,8 +180,8 @@ Retcode_T BSP_TestInterface_Disconnect(void) } if (RETCODE_OK == retcode) { - HAL_GPIO_DeInit(GPIOD, PINB_DBG_TX | PINB_DBG_RX); - GPIO_CloseClockGate(GPIO_PORT_D, PINB_DBG_TX | PINB_DBG_RX); + HAL_GPIO_DeInit(GPIOD, PIND_USART3_TX | PIND_USART3_RX); + GPIO_CloseClockGate(GPIO_PORT_D, PIND_USART3_TX | PIND_USART3_RX); } if (RETCODE_OK == retcode) { @@ -206,7 +213,7 @@ Retcode_T BSP_TestInterface_Control(uint32_t command, void *arg) /*---------------------- LOCAL FUNCTIONS IMPLEMENTATION -------------------------------------------------------------*/ /** - * Interrupt Service Routine handling USART1 IRQ. Forwards call to MCU Layer for handling. + * Interrupt Service Routine handling USART3 IRQ. Forwards call to MCU Layer for handling. */ void USART3_IRQHandler(void) { diff --git a/boards/NucleoF767/bsp/source/protected/gpio.h b/boards/NucleoF767/bsp/source/protected/gpio.h index ba6217ce..8d6de803 100644 --- a/boards/NucleoF767/bsp/source/protected/gpio.h +++ b/boards/NucleoF767/bsp/source/protected/gpio.h @@ -35,6 +35,10 @@ #define PINB_LED_G GPIO_PIN_0 #define PINB_LED_B GPIO_PIN_7 #define PINC_USR_BUTTON GPIO_PIN_13 +#define PIND_USART2_TX GPIO_PIN_5 +#define PIND_USART2_RX GPIO_PIN_6 +#define PIND_USART3_TX GPIO_PIN_8 +#define PIND_USART3_RX GPIO_PIN_9 /*---------------------- EXPORTED TYPES ------------------------------------------------------------------------------*/ /** diff --git a/ci/testing_config/core/essentials/Kiso_BSPConfig.h b/ci/testing_config/core/essentials/Kiso_BSPConfig.h index c740d18e..be489aa2 100644 --- a/ci/testing_config/core/essentials/Kiso_BSPConfig.h +++ b/ci/testing_config/core/essentials/Kiso_BSPConfig.h @@ -42,6 +42,7 @@ /* BSP Features */ #define KISO_FEATURE_BSP_LED 1 #define KISO_FEATURE_BSP_BUTTON 1 +#define KISO_FEATURE_BSP_GENERIC_UART 1 #define KISO_FEATURE_BSP_CELLULAR_SARAR4N4 1 #define KISO_FEATURE_BSP_GNSS_MAXM8 1 #define KISO_FEATURE_BSP_BMA280 1 diff --git a/cmake/KisoLibsConfig.cmake b/cmake/KisoLibsConfig.cmake index cba4be35..fe23baff 100644 --- a/cmake/KisoLibsConfig.cmake +++ b/cmake/KisoLibsConfig.cmake @@ -72,7 +72,6 @@ if(NOT KISO_STATIC_CONFIG) configure_file(${ABS_BOARD_CONFIG_PATH}/${HEADER} ${DEST} COPYONLY) endforeach(HEADER ${BOARD_CONF_FILES}) - # Copy app-specific config files in intermediary directory # APP_CONFIG_PATH is not required - only act if present if(NOT APP_CONFIG_PATH) message(STATUS "APP_CONFIG_PATH not set to a valid path. Not using application-specific configuration.") diff --git a/core/essentials/test/integration/CMakeLists.txt b/core/essentials/test/integration/CMakeLists.txt new file mode 100644 index 00000000..81e8d939 --- /dev/null +++ b/core/essentials/test/integration/CMakeLists.txt @@ -0,0 +1,30 @@ +cmake_minimum_required(VERSION 3.6) + +project ("Essentials integration test entry" C ASM) + +# the checks will be executed as it would be on the desired compile step +if(${ENABLE_STATIC_CHECKS}) + set(CMAKE_C_CLANG_TIDY ${CLANG_TIDY} --extra-arg=--target=arm-none-eabi --extra-arg=-mthumb --extra-arg=--sysroot=${CMAKE_SYSROOT} -checks=-*,readability-*,clang-analyzer-*,-clang-analyzer-cplusplus*) + set(CMAKE_CXX_CLANG_TIDY ${CLANG_TIDY} --extra-arg=--target=arm-none-eabi --extra-arg=--sysroot=${CMAKE_SYSROOT} -checks=-*,readability-*,clang-analyzer-*,-clang-analyzer-cplusplus*) +endif() + +## Only compilable for a target +if(${CMAKE_CROSSCOMPILING}) + file(GLOB TEST_ENTRY_SOURCES + source/*.c + ) + add_library(testentry STATIC ${TEST_ENTRY_SOURCES}) + + target_include_directories(testentry + PRIVATE + source + ) + # List of additional libs from board_config.cmake + target_link_libraries(testentry testing essentials ${KISO_BOARD_LIBS}) +endif(${CMAKE_CROSSCOMPILING}) + +# Include the tests for this module +if(${CMAKE_TESTING_ENABLED}) + #add_subdirectory(testentry/test) +endif() + diff --git a/core/essentials/test/integration/readme.md b/core/essentials/test/integration/readme.md new file mode 100644 index 00000000..38315cda --- /dev/null +++ b/core/essentials/test/integration/readme.md @@ -0,0 +1,7 @@ +# Integration Test Framework + +It is composed by the following packages: +* Test-scheduler: Called in the continious integration. Define where the tests should be run. +* Test-coordinator: Coordiante the build and execution of the tests. +* Test-auxiliaries: List of elements that supports more complex tests (example: communication tests between a cloud service and a device) +* Test-executor: Software that will be flashed on the device under test. \ No newline at end of file diff --git a/core/essentials/test/integration/source/TestEntry.c b/core/essentials/test/integration/source/TestEntry.c new file mode 100644 index 00000000..974a9580 --- /dev/null +++ b/core/essentials/test/integration/source/TestEntry.c @@ -0,0 +1,68 @@ +/********************************************************************************************************************** + * Copyright (c) 2010#2019 Robert Bosch GmbH + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl#2.0. + * + * SPDX#License#Identifier: EPL#2.0 + * + * Contributors: + * Robert Bosch GmbH # initial contribution + * + **********************************************************************************************************************/ + +/** + * @file + * + * @brief + * Implements the following functionalities specified in template.h + */ +/*###################### INCLUDED HEADERS ############################################################################*/ +#include "Kiso_Testing.h" +#include "TestSuiteUart.h" + +/*###################### MACROS DEFINITION ###########################################################################*/ +#undef KISO_MODULE_ID +#define KISO_MODULE_ID KISO_MODULE_ID_TEST_ENTRY + +#define TEST_ENTRY_ID 1 +/*###################### LOCAL_TYPES DEFINITION ######################################################################*/ + +/*###################### LOCAL FUNCTIONS DECLARATION #################################################################*/ + +Retcode_T TestEntry_Initialize(void *param1, uint32_t param2); +static Retcode_T TestEntry_Setup(CCMsg_T *ccmsg); +static Retcode_T TestEntry_Teardown(CCMsg_T *ccmsg); + +/*###################### VARIABLES DECLARATION #######################################################################*/ + +/*###################### EXPOSED FUNCTIONS IMPLEMENTATION ############################################################*/ + +/*###################### LOCAL FUNCTIONS IMPLEMENTATION ##############################################################*/ + +Retcode_T TestEntry_Initialize(void *param1, uint32_t param2) +{ + KISO_UNUSED(param1); + KISO_UNUSED(param2); + + Retcode_T retcode = RETCODE_OK; + retcode = Tests_Initialize(TEST_ENTRY_ID, TestEntry_Setup, TestEntry_Teardown); + if (RETCODE_OK == retcode) + { + retcode = TestSuiteUart_Initialize((uint8_t)1); + } + return retcode; +} + +static Retcode_T TestEntry_Setup(CCMsg_T *ccmsg) +{ + KISO_UNUSED(ccmsg); + return RETCODE_OK; +} + +static Retcode_T TestEntry_Teardown(CCMsg_T *ccmsg) +{ + KISO_UNUSED(ccmsg); + return RETCODE_OK; +} \ No newline at end of file diff --git a/core/essentials/test/integration/source/TestSuiteUart.c b/core/essentials/test/integration/source/TestSuiteUart.c new file mode 100644 index 00000000..78019fb9 --- /dev/null +++ b/core/essentials/test/integration/source/TestSuiteUart.c @@ -0,0 +1,245 @@ +/********************************************************************************************************************** + * Copyright (c) 2010#2019 Robert Bosch GmbH + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl#2.0. + * + * SPDX#License#Identifier: EPL#2.0 + * + * Contributors: + * Robert Bosch GmbH # initial contribution + * + **********************************************************************************************************************/ + +/** + * @file + * + * @brief + * Implements test cases for uart comminication verification + */ +/*###################### INCLUDED HEADERS ############################################################################*/ +#include "Kiso_Testing.h" +#include "Kiso_CmdProcessor.h" +#include "Kiso_MCU_UART.h" +#include "Kiso_BSP_GenericUart.h" +#include "TestSuiteUART.h" +#include +#include "FreeRTOS.h" +#include "semphr.h" +/*###################### MACROS DEFINITION ###########################################################################*/ +#undef KISO_MODULE_ID +#define KISO_MODULE_ID 0 + +#define UART_BUFFER_LEN 5 +#define DATA_TRANSFER_TIMEOUT_MS UINT32_C(1000) +#define UART_DEVICE UINT32_C(1) + +/*###################### LOCAL_TYPES DEFINITION ######################################################################*/ +enum TestSuiteUart_TestCases_E +{ + TEST_CASE_FUNCTIONAL_TEST_ID = 1 +}; +/*###################### LOCAL FUNCTIONS DECLARATION #################################################################*/ + +static Retcode_T TestCase_FctTest_Setup(CCMsg_T *ccmsg); +static void TestCase_FctTest_Run(CCMsg_T *ccmsg); +static Retcode_T TestCase_FctTest_Teardown(CCMsg_T *ccmsg); +static void UartISRCallback(UART_T uart, struct MCU_UART_Event_S event); + +/*###################### VARIABLES DECLARATION #######################################################################*/ + +/*###################### EXPOSED FUNCTIONS IMPLEMENTATION ############################################################*/ + +/*###################### LOCAL FUNCTIONS IMPLEMENTATION ##############################################################*/ + +static UART_T UartHdl = 0; +static xSemaphoreHandle UartLock = 0; + +Retcode_T TestSuiteUart_Initialize(uint8_t sId) +{ + Retcode_T retcode = RETCODE_OK; + + retcode = Tests_RegisterTestSuite(sId, TestCase_FctTest_Setup, TestCase_FctTest_Teardown); + + if (RETCODE_OK == retcode) + { + retcode = Tests_RegisterTestCase(sId, TEST_CASE_FUNCTIONAL_TEST_ID, TestCase_FctTest_Setup, TestCase_FctTest_Run, TestCase_FctTest_TearDown); + } + return retcode; +} + +/** + * @brief Performs the setup operation of the functional test of uart in interrupt mode + * @details This function initializes the uart interface in interrupt mode and creates the necessary + * synchronisation ressources. + */ +static Retcode_T TestCase_FctTest_Setup(CCMsg_T *ccmsg) +{ + KISO_UNUSED(ccmsg); + Retcode_T retcode = RETCODE_OK; + + UartHdl = (UART_T)BSP_GenericUart_GetHandle(UART_DEVICE); + if (NULL == UartHdl) + { + retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_NULL_POINTER); + } + if (RETCODE_OK == retcode) + { + UartLock = xSemaphoreCreateBinary(); + if (NULL == UartLock) + { + return RETCODE(RETCODE_SEVERITY_FATAL, RETCODE_SEMAPHORE_ERROR); + } + } + if (RETCODE_OK == retcode) + { + retcode = BSP_GenericUart_Connect(UART_DEVICE); + } + if (RETCODE_OK == retcode) + { + retcode = MCU_UART_Initialize(UartHdl, UartISRCallback); + } + if (RETCODE_OK == retcode) + { + retcode = BSP_GenericUart_Enable(UART_DEVICE); + } + return retcode; +} + +/** + * @brief Deinitializes the uart interface + */ +static Retcode_T TestCase_FctTest_Teardown(CCMsg_T *ccmsg) +{ + KISO_UNUSED(ccmsg); + Retcode_T retcode; + + retcode = MCU_UART_Deinitialize(UartHdl); + if (RETCODE_OK == retcode) + { + retcode = BSP_GenericUart_Disable(UART_DEVICE); + } + if (RETCODE_OK == retcode) + { + retcode = BSP_GenericUart_Disconnect(UART_DEVICE); + } + if (RETCODE_OK == retcode) + { + vSemaphoreDelete(UartLock); + } + return retcode; +} + +/** + * This Test will put the uart receiver into receive mode and send data via the transmitter the data will be + * looped back to the receiver at hardware level (e.g. wiring TX line to RX line) + * the test will succede if the transmit operation succeeded and if the received data matches the transmitted data + */ +static void TestCase_FctTest_Run(CCMsg_T *ccmsg) +{ + KISO_UNUSED(ccmsg); + + Retcode_T retcode; + uint8_t dataOut[UART_BUFFER_LEN]; + uint8_t dataIn[UART_BUFFER_LEN] = {0}; + char msg[30] = "SUCCESS"; + + for (uint8_t i = 0; i < UART_BUFFER_LEN; i++) + { + dataOut[i] = i; + } + + retcode = MCU_UART_Receive(UartHdl, dataIn, UART_BUFFER_LEN); + + if (RETCODE_OK == retcode) + { + retcode = MCU_UART_Send(UartHdl, dataOut, UART_BUFFER_LEN); + } + if (RETCODE_OK == retcode) + { + if (pdTRUE != xSemaphoreTake(UartLock, DATA_TRANSFER_TIMEOUT_MS)) + { + retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_SEMAPHORE_ERROR); + strcpy(msg, "FAIL"); + } + } + if (RETCODE_OK == retcode) + { + for (uint8_t i = 0; i < UART_BUFFER_LEN; i++) + { + if (dataIn[i] != dataOut[i]) + { + retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_UNEXPECTED_BEHAVIOR); + strcpy(msg, "FAIL"); + } + } + } + Tests_SendReport(Retcode_GetCode(retcode), msg); +} + +static void UartISRCallback(UART_T uart, struct MCU_UART_Event_S event) +{ + KISO_UNUSED(uart); + Retcode_T Rc = RETCODE_OK; + + if (UINT8_C(1) == event.TxComplete) + { + + if (RETCODE_OK == Rc) + { + BaseType_t higherPriorityTaskWoken = pdFALSE; + + if (NULL != UartLock) + { + if (pdTRUE == xSemaphoreGiveFromISR(UartLock, &higherPriorityTaskWoken)) + { + portYIELD_FROM_ISR(higherPriorityTaskWoken); + } + else + { + /* ignore... semaphore has already been given */ + } + } + else + { + Rc = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_NULL_POINTER); + } + } + } + + if (UINT8_C(1) == event.RxComplete) + { + + if (RETCODE_OK == Rc) + { + BaseType_t higherPriorityTaskWoken = pdFALSE; + + if (NULL != UartLock) + { + if (pdTRUE == xSemaphoreGiveFromISR(UartLock, &higherPriorityTaskWoken)) + { + portYIELD_FROM_ISR(higherPriorityTaskWoken); + } + else + { + /* ignore... semaphore has already been given */ + } + } + else + { + Rc = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_NULL_POINTER); + } + } + } + + if (UINT8_C(1) == event.TxError) + { + Rc = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_FAILURE); + } + + if (RETCODE_OK != Rc) + { + Retcode_RaiseErrorFromIsr(Rc); + } +} diff --git a/core/essentials/test/integration/source/TestSuiteUart.h b/core/essentials/test/integration/source/TestSuiteUart.h new file mode 100644 index 00000000..4319f201 --- /dev/null +++ b/core/essentials/test/integration/source/TestSuiteUart.h @@ -0,0 +1,55 @@ +/********************************************************************************************************************** + * Copyright (c) 2010#2019 Robert Bosch GmbH + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl#2.0. + * + * SPDX#License#Identifier: EPL#2.0 + * + * Contributors: + * Robert Bosch GmbH # initial contribution + * + **********************************************************************************************************************/ + +/** + * @file + * @defgroup + * @ingroup + * @{ + * + * @brief Provides an API for the following functionality + * + */ +#ifndef TESTSUITE_UART_H_ +#define TESTSUITE_UART_H_ + +/*###################### INCLUDED HEADERS ############################################################################*/ + +/*###################### MACROS DEFINITION ###########################################################################*/ + +/*###################### TYPE DEFINITIONS ############################################################################*/ + +enum TestSuiteUart_Retcodes_E +{ + TESTSUITE_SETUP_TRIGGERED_SEVERAL_TIMES = RETCODE_FIRST_CUSTOM_CODE, + TESTSUITE_RUN_TRIGGERED_SEVERAL_TIMES, + TestSuite_Teardown_TRIGGERED_SEVERAL_TIMES, +}; + +/*###################### EXPORTED FUNCTIONS PROTOTYPES ###############################################################*/ + +/** + * @brief Initializes the uart test suite + * @details This function will register the uart test suites in the Testing module TestSuites register and will + * also register for execution all the test cases belonging to this test suite + * @param id is the identifier to be given to the test suite it will be used in the communication protocol between + * the test executor and the test controller @see todo: add link to docu + */ +Retcode_T TestSuiteUart_Initialize(uint8_t id); + +/*###################### GLOBAL VARIABLES ###########################################################################*/ + +/** @} */ + +#endif /* TESTSUITE_UART_H_ */ diff --git a/core/essentials/test/integration/specs/I2C_Test_Spec.md b/core/essentials/test/integration/specs/I2C_Test_Spec.md new file mode 100644 index 00000000..2b5a1d83 --- /dev/null +++ b/core/essentials/test/integration/specs/I2C_Test_Spec.md @@ -0,0 +1,283 @@ +# Test Entry 3: "Essentials" + +## Test Suite 3.3: I2C_Selfcontained_Test +### Description + +* Purpose + + Test the I2C transfer functionality + +* Test participants: + - Device under Test (DUT): Stm32 - Bike Sensor Board (BSE) + - Test Coordinator: PC + +### Test Setup +The test setup consists of the test coordinator and 1 test participant + +* Test Coordinator (on PC) +* The DUT is connected to the PC via UART which is the Test Coordination Channel. The embedded C testling code is flashed onto the DUT. +* The DUT is connected to a 12 V power source. +* For this selfcontained test, no external wires are necessary and only BSE-internal Sensors are polled via I2C. + +On the BSE testling, the initialization sequence setups the I2C Clock and the I2C GPIOs: + +* I2C SCL line: GPIO_PIN_14, Bank GPIOG, mode GPIO_PULLUP, GPIO_SPEED_LOW +* I2C SDA line: GPIO_PIN_13, Bank GPIOG, mode GPIO_PULLUP, GPIO_SPEED_LOW +* Alternative function: GPIO_AF4_I2C1 +* I2C Clock: PCLK1 +* enable GPIO bank G clock +* power up GPIO bank G (PWR_CR2_IOSV register) +* IRQs I2Cx_ER_IRQn and I2Cx_EV_IRQn are enabled + +### Teardown + +No special teardown + +### Test Cases + +#### TC 3.3.1 TestCase_I2C_initialize +##### Setup +No separate Test Case Setup required + +##### Run +1. For all present I2C Interfaces: BCDS_I2C1, BCDS_I2C2 + + * Call API: I2C_getVersion(), expect version + * Call API: I2C_getCapabilities(), expect only "address10bit" capability. + * Call API: I2C_initialize(), expect RETCODE_OK + * Call API: I2C_powerControl(PERIPHERALS_POWER_STATE_FULL), expect RETCODE_OK + * Call API: I2C_powerControl(PERIPHERALS_POWER_STATE_OFF), expect RETCODE_OK + * Call API: I2C_powerControl(PERIPHERALS_POWER_STATE_FULL), expect RETCODE_OK + * Call API: I2C_control(BCDS_I2C_BUS_SPEED,BCDS_I2C_BUS_SPEED_STANDARD), expect RETCODE_OK + * Call API: I2C_control(BCDS_I2C_BUS_SPEED,BCDS_I2C_BUS_SPEED_FAST), expect RETCODE_OK + * Call API: I2C_control(BCDS_I2C_BUS_SPEED,BCDS_I2C_BUS_SPEED_FAST_PLUS), expect RETCODE_OK + * Call API: I2C_control(BCDS_I2C_BUS_SPEED,BCDS_I2C_OWN_ADDRESS,0x42), expect RETCODE_OK + * Call API: I2C_getStatus(), expect only flag "Initialized" + * Call API: I2C_uninitialize(), expect RETCODE_OK + +2. If all as expected, return Success. + +##### TearDown +No separate Test Case Tear Down required + +#### TC 3.3.2 TestCase_I2C_master_BMI160 + +On the BSE boardThe inertial measurement unit BMI160 is visible via BCDS_I2C1 on address 0x68. +To read a register, the register ID is first written via I2C to BMI160. +Maximum supported clock frequency is 1000khz, i.e., BCDS_I2C_BUS_SPEED_FAST_PLUS. + +##### Setup +Call API: I2C_initialize(), expect RETCODE_OK + +##### Run +1. Transmit 1 byte value 0 to BMI160 to access the CHIPID register: + + * Call API: I2C_masterTransmit(BCDS_I2C1 ,0x68, 0, 1, 0); + * Expect RETCODE_OK; + * Expect "TransferDone" Callback. +2. Read 1 byte CHIPID value from BMI160: + + * Call API: I2C_masterReceive(BCDS_I2C1 ,0x68, &chipid, 1, 0); + * Expect RETCODE_OK; + * Expect "TransferDone" Callback. + * Expect CHIPID to be ( 0b11010001 = 0xD1 ) +3. Transmit 1 byte value 0x04 to BMI160 to access the DATA registers: + + * Call API: I2C_masterTransmit(BCDS_I2C1 ,0x68, 0x04, 1, 0); + * Expect RETCODE_OK; + * Expect "TransferDone" Callback. +4. Read 20 byte DATA register values from BMI160: + + * Call API: I2C_masterReceive(BCDS_I2C1 ,0x68, datareg, 20, 0); + * Expect RETCODE_OK; + * Expect "TransferDone" Callback. + * Expect at least one DATA registers values to contain values different from 0 +5. If all as expected, return Success. + +##### TearDown +Call API: I2C_uninitialize(), expect RETCODE_OK + +## Test Suite 3.4: I2C_Arduino_Test +### Description + +1. Purpose: + + * Test the I2C transfer functionality with an Arduino counterpart that allows precise master AND slave communication tests. + +2. Test participants: + + * Test Coordinator: PC + * Device under Test (DUT): Stm32 - Bike Sensor Board (BSE) + * Arduino Due - the arduino code is contained in the Peripherals/test/integration/Testling/Tests/testSuiteI2c/Arduino_I2C_final_Testing_Code folder. + +### Setup +The test setup consists of the test coordinator and 2 test participants + +1. Test Coordinator (on PC) +2. The DUT is connected to the PC via UART which is the Test Coordination Channel. The embedded C testling code is flashed onto the DUT. +3. The DUT is connected to a 12 V power source. +4. The Arduino is connected to the PC via UART to flash and power the Arduino board. +5. The Arduino testling code is flashed onto the Arduino. +6. The I2C bus I2C1 of the BSE board is led out and connected to the Arduino Due board such that: + + * BSE-PG14/C6 SCL line is connected to Arduino GPIO pin 21 + * BSE-PG13/C7 SDA line is connected to Arduino GPIO pin 20 + * a common ground line between the BSE board and the Arduino board is connected + +On the BSE testling, the initialization sequence setups the I2C Clock and the I2C GPIOs: + +7. I2C SCL line: GPIO_PIN_14, Bank GPIOG, mode GPIO_PULLUP, GPIO_SPEED_LOW +8. I2C SDA line: GPIO_PIN_13, Bank GPIOG, mode GPIO_PULLUP, GPIO_SPEED_LOW +9. Alternative function: GPIO_AF4_I2C1 +10. I2C Clock: PCLK1 +11. Enable GPIO bank G clock +12. Power up GPIO bank G (PWR_CR2_IOSV register) +13. IRQs I2Cx_ER_IRQn and I2Cx_EV_IRQn are enabled + +### Teardown +No special teardown + +### Test Cases + +#### TC 3.4.1 TestCase_I2C_master + +The arduino wire library has a maximum i2c buffer size of 32 bytes - so larger data streams cannot be tested. + +##### Setup +1. Call API: I2C_initialize(), expect RETCODE_OK +2. Send testcase ID (1) to arduino and expect acknowledge byte (1) + + * Call API: I2C_masterTransmit(BCDS_I2C1, ARDUINO_I2C_ADDRESS, 1, 1, 0); + * Call API: I2C_masterRecieve (BCDS_I2C1, ARDUINO_I2C_ADDRESS, &arduinoAcknowledges, 1, 0); + * Expect arduinoAcknowledges == 1 +3. Call API: I2C_uninitialize(), expect RETCODE_OK +4. Call API: I2C_initialize(), expect RETCODE_OK + +##### Run +1. In Master mode send 1 byte to Arduino and receive it back: + + * Call API: I2C_masterTransmit(BCDS_I2C1, ARDUINO_I2C_ADDRESS, TESTBYTE, 1, 0); + * Expect RETCODE_OK; + * Expect "TransferDone" Callback. + * Call API: I2C_masterReceive(BCDS_I2C1, ARDUINO_I2C_ADDRESS, &receiveBuffer, 1, 0); + * Expect RETCODE_OK; + * Expect "TransferDone" Callback. + * Verify (receiveBuffer == TESTBYTE) +2. In Master mode send 32 bytes to Arduino and receive them back + + * uint8_t TEST32BYTES[] = {42, 43, ..., 73 }; + * Call API: I2C_masterTransmit(BCDS_I2C1, ARDUINO_I2C_ADDRESS, TEST32BYTES, 32, 0); + * Expect RETCODE_OK; + * Expect "TransferDone" Callback. +3. Call API: I2C_masterReceive(BCDS_I2C1, ARDUINO_I2C_ADDRESS, receiveBuffer32, 32, 0); + + * Expect RETCODE_OK; + * Expect "TransferDone" Callback. +4. Verify (receiveBuffer32 identical to TEST32BYTES) +5. Return Success. + +##### TearDown +Call API: I2C_uninitialize(), expect RETCODE_OK + +#### TC 3.4.2 TestCase_I2C_slave_woCallback + +##### Setup +1. Call API: I2C_initialize(), expect RETCODE_OK +2. Send testcase ID (2) to arduino and expect acknowledge byte (1) + + * Byte to call API: I2C_masterTransmit(BCDS_I2C1, ARDUINO_I2C_ADDRESS, 2, 1, 0); + * Byte to call API: I2C_masterRecieve (BCDS_I2C1, ARDUINO_I2C_ADDRESS, &arduinoAcknowledges, 1, 0); + * Expect arduinoAcknowledges == 1 +3. Call API: I2C_uninitialize(), expect RETCODE_OK +4. Call API: I2C_initialize(), expect RETCODE_OK +5. Set own slave address to 0x42 + +##### Run + +1. In Slave mode, wait for Arduino to request 1 byte, then wait until Arduino sends it back + + * Call API: I2C_slaveTransmit(BCDS_I2C1, TESTBYTE, 1); + * expect RETCODE_OK; + * expect "TransferDone" Callback. + * Call API: I2C_slaveReceive(BCDS_I2C1, &receiveBuffer, 1); + * expect RETCODE_OK; + * expect "TransferDone" Callback. + * Verify (receiveBuffer == TESTBYTE) +2. In Slave mode send 32 bytes to Arduino and receive them back + + * uint8_t TEST32BYTES[] = {42, 43, ..., 73 }; + * Call API: I2C_slaveTransmit(BCDS_I2C1, ARDUINO_I2C_ADDRESS, TEST32BYTES, 32); + * expect RETCODE_OK; + * expect "TransferDone" Callback. + * Call API: I2C_slaveReceive(BCDS_I2C1, ARDUINO_I2C_ADDRESS, receiveBuffer32, 32); + * expect RETCODE_OK; + * expect "TransferDone" Callback. + * Verify (receiveBuffer32 identical to TEST32BYTES) +3. Return Success. + +##### TearDown + +Call API: I2C_uninitialize(), expect RETCODE_OK + +#### TC 3.4.3 TestCase_I2C_slave_callbackDriven + +##### Setup +1. Call API: I2C_initialize(), expect RETCODE_OK +2. Send testcase ID (3) to arduino and expect acknowledge byte (1) + + * Call API: I2C_masterTransmit(BCDS_I2C1, ARDUINO_I2C_ADDRESS, 3, 1, 0); + * Call API: I2C_masterRecieve (BCDS_I2C1, ARDUINO_I2C_ADDRESS, &arduinoAcknowledges, 1, 0); + * Expect arduinoAcknowledges == 1 +3. Call API: I2C_uninitialize(), expect RETCODE_OK + +##### Run +1. Define uint8_t TEST32BYTES[] = {42, 43, ..., 73 }; +2. Call API: I2C_initialize(), expect RETCODE_OK +3. Set own slave address to 0x42 +4. Register new callback event handler that: + + * Answers a SlaveTransmit request with: I2C_slaveTransmit(BCDS_I2C1, TEST32BYTES, 32); + * expect RETCODE_OK; + * Answers a SlaveReceive request with: I2C_slaveReceive(BCDS_I2C1, receiveBuffer32, 32); + * expect RETCODE_OK; + * Updates 4-state-variable from waitForSlaveTransmit(0) to waitForSlaveReceive(1) to done(2) or alternatively error(3) +5. Wait with timeout until 4-state-variable goes through the states + + * WaitForSlaveTransmit(0) + * WaitForSlaveReceive(1) + * Done(2) +6. Make sure error(3) is not reached or return error-report. +7. When state done(2) is reached, verify (receiveBuffer32 identical to TEST32BYTES) +8. Return Success. + +##### TearDown + +Call API: I2C_uninitialize(), expect RETCODE_OK + +#### TC 3.4.4 TestCase_I2C_higherSpeeds + +##### Setup +1. Call API: I2C_initialize(), expect RETCODE_OK +2. Send testcase ID (4) to arduino and expect acknowledge byte (1) + + * Call API: I2C_masterTransmit(BCDS_I2C1, ARDUINO_I2C_ADDRESS, 4, 1, 0); + * Call API: I2C_masterRecieve (BCDS_I2C1, ARDUINO_I2C_ADDRESS, &arduinoAcknowledges, 1, 0); + * Expect arduinoAcknowledges == 1 +3. Call API: I2C_uninitialize(), expect RETCODE_OK +4. Call API: I2C_initialize(), expect RETCODE_OK + +##### Run +1. uint8_t TEST32BYTES[] = {42, 43, ..., 73 }; +2. Set the bus speeds [Standard Speed (100kHz), Fast Speed (400kHz), Fast+ Speed (1MHz)] try: + + * In Master mode send 32 bytes to Arduino and receive them back + * call API: I2C_masterTransmit(BCDS_I2C1, ARDUINO_I2C_ADDRESS, TEST32BYTES, 32, 0); + * expect RETCODE_OK; + * expect "TransferDone" Callback. + * Call API: I2C_masterReceive(BCDS_I2C1, ARDUINO_I2C_ADDRESS, receiveBuffer32, 32, 0); + * expect RETCODE_OK; + * expect "TransferDone" Callback. + * Verify (receiveBuffer32 identical to TEST32BYTES) +3. Return Success. + +##### TearDown +Call API: I2C_uninitialize(), expect RETCODE_OK diff --git a/core/essentials/test/integration/specs/SPI_Test_Spec.md b/core/essentials/test/integration/specs/SPI_Test_Spec.md new file mode 100644 index 00000000..0542dfdb --- /dev/null +++ b/core/essentials/test/integration/specs/SPI_Test_Spec.md @@ -0,0 +1,207 @@ +Integration Test Specification for SPI + +# Test Suite 2: "Test Specification of SPI" + +## Description + +* Purpose + * Test the Peripheral SPI functionality +* Test participants which are involved + * Test participant :- BSE +* Test environment and setup + * BSE device be connected to the PC via USB Cable. + * A PC has a test coordinator. +* Setup for Flashing-Manual. + * SPI IntegrationTestApp binary file into BSE device + * once the flashing is done + * It automatically reset the device and IntegrationTestApps Boots-up + +## Setup +The test setup consists of the test coordinator and 2 test participants: + +* test coordinator (on PC) +* The test device BSE with the embedded C test participant + +The test device is connected to the test coordinator on the PC via UART as a Test Coordination Channel. + + +### Parameters +No special parameters + +## Teardown +* Deinitialize the SPI Port with SPI_deinitialize. + +## Test Suite 1.2: Non initialized - error test +### Description +* Test the SPI error cases for non initialized case + +### Setup +* No required separate Test Suite Setup for this example. + +### Teardown +* Not required separate Test Suite Tear Down for this example. + +### Test Cases + +#### TC 1.1.1 TestCase_SPI_Control_Error_unitialized +* Test case Setup + * Deinitialize the SPI. +* Test Case Run + * Parameter passed: valid handle, valid control, valid argument + * Run SPI_Control API +* Expected return value from the API: RETCODE_FAILURE +* Test case Tear Down + * Not required separate Test Case Tear Down for this example. + +#### TC 1.1.2 TestCase_SPI_Send_Error_unitialized +* Test case Setup + * Deinitialize the SPI. +* Test Case Run + * Parameter passed: valid handle, valid sendValue, valid bufferSize + * Run SPI_Send API +* Expected return value from the API: RETCODE_FAILURE +* Test case Tear Down + * Not required separate Test Case Tear Down for this example. + +#### TC 1.1.3 TestCase_SPI_Receive_Error_unitialized +* Test case Setup + * Deinitialize the SPI. +* Test Case Run + * Parameter passed: valid handle, valid receiveValue, valid bufferSize + * Run SPI_Receive API +* Expected return value from the API: RETCODE_FAILURE +* Test case Tear Down + * No required separate Test Case Tear Down for this example. + +#### TC 1.1.4 TestCase_SPI_Transfer_Error_unitialized +* Test case Setup + * Deinitialize the SPI. +* Test Case Run + * Parameter passed: valid handle, valid sendValue, valid receiveValue, valid bufferSize + * Run SPI_Transfer API +* Expected return value from the API: RETCODE_FAILURE +* Test case Tear Down + * No required separate Test Case Tear Down for this example. + +################################################################################################################################## + + +#### TC 1.1.5 TestCase_SPI_Send_Error_invalidPort +* Test case Setup + * Initialize the SPI Port. +* Test Case Run + * Parameter passed: invalid port, valid sendValue, valid bufferSize + * Run SPI_Send API +* Expected return value from the API: RETCODE_FAILURE +* Test case Tear Down + * No required separate Test Case Tear Down for this example. + +#### TC 1.1.6 TestCase_SPI_Send_Error_invalidSendValue +* Test case Setup + * Initialize the SPI Port. +* Test Case Run + * Parameter passed: valid port, invalid sendValue, valid bufferSize + * Run SPI_Send API +* Expected return value from the API: RETCODE_FAILURE +* Test case Tear Down + * Not required separate Test Case Tear Down for this example. + +#### TC 1.2.3 TestCase_SPI_Send_Error_invalidBufferSize +* Test case Setup + * Initialize the SPI Port. +* Test Case Run + * Parameter passed: valid port, valid sendValue, invalid bufferSize + * Run SPI_Send API +* Expected return value from the API: RETCODE_FAILURE +* Test case Tear Down + * Not required separate Test Case Tear Down for this example. + +#### TC 1.2.4 TestCase_SPI_Receive_Error_invalidPort +* Test case Setup + * Initialize the SPI Port. +* Test Case Run + * Parameter passed: invalid port, valid receiveValue, valid bufferSize + * Run SPI_Receive API +* Expected return value from the API: RETCODE_FAILURE +* Test case Tear Down + * Not required separate Test Case Tear Down for this example. + +#### TC 1.2.5 TestCase_SPI_Receive_Error_invalidReceiveValue +* Test case Setup + * Initialize the SPI Port. +* Test Case Run + * Parameter passed: valid port, invalid receiveValue, valid bufferSize + * Run SPI_Receive API +* Expected return value from the API: RETCODE_FAILURE +* Test case Tear Down + * Not required separate Test Case Tear Down for this example. + +#### TC 1.2.6 TestCase_SPI_Receive_Error_invalidReceiveValue +* Test case Setup + * Initialize the SPI Port. +* Test Case Run + * Parameter passed: valid port, invalid receiveValue, valid bufferSize + * Run SPI_Receive API +* Expected return value from the API: RETCODE_FAILURE +* Test case Tear Down + * Not required separate Test Case Tear Down for this example. + +#### TC 1.2.7 TestCase_SPI_Transfer_Error_invalidPort +* Test case Setup + * Initialize the SPI Port. +* Test Case Run + * Parameter passed: invalid port, valid sendValue, valid receiveValue, valid bufferSize + * Run SPI_Receive API +* Expected return value from the API: RETCODE_FAILURE +* Test case Tear Down + * Not required separate Test Case Tear Down for this example. + +#### TC 1.2.8 TestCase_SPI_Transfer_Error_invalidSendValue +* Test case Setup + * Initialize the SPI Port. +* Test Case Run + * Parameter passed: valid port, invalid sendValue, valid receiveValue, valid bufferSize + * Run SPI_Receive API +* Expected return value from the API: RETCODE_FAILURE +* Test case Tear Down + * Not required separate Test Case Tear Down for this example. + +#### TC 1.2.9 TestCase_SPI_Transfer_Error_invalidReceiveValue +* Test case Setup + * Initialize the SPI Port. +* Test Case Run + * Parameter passed: valid port, valid sendValue, invalid receiveValue, valid bufferSize + * Run SPI_Receive API +* Expected return value from the API: RETCODE_FAILURE +* Test case Tear Down + * Not required separate Test Case Tear Down for this example. + +#### TC 1.2.10 TestCase_SPI_Transfer_Error_invalidBufferSize +* Test case Setup + * Initialize the SPI Port. +* Test Case Run + * Parameter passed: valid port, valid sendValue, valid receiveValue, invalid bufferSize + * Run SPI_Receive API +* Expected return value from the API: RETCODE_FAILURE +* Test case Tear Down + * Not required separate Test Case Tear Down for this example. + + #### TC 1.2.11 TestCase_SPI_Control_Error_invalidParameter +* Test case Setup + * Initialize the SPI Port. +* Test Case Run + * Parameter passed: valid handle, invalid control, invalid argument + * Run SPI_Control API + * Expected return value from the API: RETCODE_NOT_SUPPORTED +* Test case Tear Down + * Not required separate Test Case Tear Down for this example. + +################################################################################################################################## + +## Test Suite 1.3: functional tests +### Description +* Currently it is not possible to have functional SPI tests, because there is neither implemented bus +partner for testing nor a possibility to test the GPIO pins. Instead, the (positive tests) +functionality will be tested by testing the external flash which is connected via SPI. +That means, if flash is working, SPI is working too. But that also means, if flash does not work, +its unclear if the error is in the flash driver or in the SPI driver. diff --git a/core/essentials/test/integration/specs/UART_Test_Spec.md b/core/essentials/test/integration/specs/UART_Test_Spec.md new file mode 100644 index 00000000..818e8a36 --- /dev/null +++ b/core/essentials/test/integration/specs/UART_Test_Spec.md @@ -0,0 +1,212 @@ +# Test Entry 3: "Essentials" +## Test Suite 3.1: UART +### Description +* This suite aims at testing the basic functionality of the UART APIs + +### Setup +The test setup consists of the test coordinator and 1 test participant + +* Test Coordinator (on PC) +* The DUT is connected to the PC via UART which is the Test Coordination Channel. The embedded C testling code is flashed onto the DUT. + +### TearDown + +No special teardown + +### Test Cases + +#### TC 3.1.1:TestCase_Uart_getStatus +##### Setup +No special setup + +##### Run +1. Invoke the Uart_getStatus API +2. Expected return value from the API: HAL_UART_STATE_READY + +##### TearDown +No special teardown + +#### TC 3.1.2:TestCase_Uart_getVersion +##### Setup +No special setup + +##### Run +1. Invoke the Uart_getVersion API +2. API should return the version number of the UART + +##### TearDown +No special teardown + +#### TC 3.1.3:TestCase_Uart_getCapabilities +##### Setup +No special setup + +##### Run +1. Invoke the Uart_getCapabilities API +2. API should return the capabilities supported by the UART + +##### TearDown +No special teardown + + +#### TC 3.1.4:TestCase_Uart_initialize +##### Setup +1. Invoke the Uart_control API with the following parameters, + + * BCDS_Uart1 + * BCDS_UART_MODE_ASYNCHRONOUS | BCDS_UART_DATA_BITS_8 | BCDS_UART_PARITY_NONE | BCDS_UART_STOP_BITS_1 | BCDS_UART_FLOW_CONTROL_NONE + * 115200 (Baud rate) +2. Expected return value from the API: RETCODE_SUCCESS + +##### Run +1. Invoke the Uart_initialize API +2. Expected return value from the API: RETCODE_SUCCESS + +##### TearDown +1. Invoke the Uart_uninitialize API +2. Expected return value from the API: RETCODE_SUCCESS + +#### TC 3.1.5:TestCase_Uart_control +##### Setup +No special setup + +##### Run +1. Invoke the Uart_control API with the following parameters, + + * BCDS_Uart1 + * BCDS_UART_MODE_ASYNCHRONOUS | BCDS_UART_DATA_BITS_8 | BCDS_UART_PARITY_NONE | BCDS_UART_STOP_BITS_1 + * 115200 (Baud rate) +2. Expected return value from the API: RETCODE_SUCCESS + +##### TearDown +No special teardown + + +#### TC 3.1.6:TestCase_Uart_send +##### Setup +1. Invoke the Uart_control API with the following parameters, + + * BCDS_Uart1 + * BCDS_UART_MODE_ASYNCHRONOUS | BCDS_UART_DATA_BITS_8 | BCDS_UART_PARITY_NONE | BCDS_UART_STOP_BITS_1 | BCDS_UART_FLOW_CONTROL_NONE + * 115200 (Baud rate) +2. Expected return value from the API: RETCODE_SUCCESS +3. Invoke the Uart_initialize API +4. Expected return value from the API: RETCODE_SUCCESS + +##### Run +1. Invoke the Uart_send API and send the data "BikeSensor" +2. Expected return value from the API: RETCODE_SUCCESS + +##### TearDown +1. Invoke the Uart_uninitialize API +2. Expected return value from the API: RETCODE_SUCCESS + +#### TC 3.1.7:TestCase_Uart_receive +##### Setup +1. Invoke the Uart_control API with the following parameters, + + * BCDS_Uart1 + * BCDS_UART_MODE_ASYNCHRONOUS | BCDS_UART_DATA_BITS_8 | BCDS_UART_PARITY_NONE | BCDS_UART_STOP_BITS_1 + * 115200 (Baud rate) +2. Expected return value from the API: RETCODE_SUCCESS +3. Invoke the Uart_initialize API +4. Expected return value from the API: RETCODE_SUCCESS + +##### Run +1. Invoke the Uart_receive API +2. Expected return value from the API: RETCODE_FAILURE + +/* @todo: Expectation is a failure because no device is sending data to the DUT UART. Beaglebone has to be integrated for validating this test case */ + +##### TearDown +1. Invoke the Uart_uninitialize API +2. Expected return value from the API: RETCODE_SUCCESS + + +#### TC 3.1.8:TestCase_Uart_uninitialize +##### Setup +1. Invoke the Uart_control API with the following parameters + + * BCDS_Uart1 + * BCDS_UART_MODE_ASYNCHRONOUS | BCDS_UART_DATA_BITS_9 | BCDS_UART_PARITY_NONE | BCDS_UART_STOP_BITS_1 + * 9600 (Baud rate) +2. Expected return value from the API: RETCODE_SUCCESS +3. Invoke the Uart_initialize API +4. Expected return value from the API: RETCODE_SUCCESS + +##### Run +1. Invoke the Uart_uninitialize API +2. Expected return value from the API: RETCODE_SUCCESS + +##### TearDown +No special teardown + +#### TC 3.1.9:TestCase_Uart_powerControl_full +##### Setup +No special setup + +##### Run +1. Invoke the Uart_powerControl API with the following parameter + + * PERIPHERALS_POWER_STATE_FULL +2. Expected return value from the API: RETCODE_SUCCESS + +##### TearDown +No special teardown + +#### TC 3.1.10:TestCase_Uart_powerControl_low +##### Setup +No special setup + +##### Run +1. Invoke the Uart_powerControl API with the following parameter + + * PERIPHERALS_POWER_STATE_LOW +2. Expected return value from the API: RETCODE_FAILURE + +##### TearDown +No special teardown + +#### TC 3.1.11:Testcase_Uart_initialize_without_control +##### Setup +No special setup + +##### Run +1. Invoke the Uart_initialize API +2. Expected return value from the API:RETCODE_SUCCESS + +##### TearDown +1. Invoke the Uart_uninitialize API +2. Expected return value from the API: RETCODE_SUCCESS + +#### TC 3.1.12:Testcase_Uart_send_without_initialize +##### Setup +1. Invoke the Uart_control API with the following parameters, + + * BCDS_Uart1 + * BCDS_UART_MODE_ASYNCHRONOUS | BCDS_UART_DATA_BITS_8 | BCDS_UART_PARITY_NONE | BCDS_UART_STOP_BITS_1 | BCDS_UART_FLOW_CONTROL_NONE + * 115200 (Baud rate) +2. Expected return value from the API: RETCODE_SUCCESS + +##### Run +1. Invoke the Uart_send API and send the data "Integration testing" +2. Expected return value from the API: RETCODE_FAILURE + +##### TearDown +No special teardown + +#### TC 3.1.13:Testcase_Uart_receive_without_initialize +##### Setup +1. Invoke the Uart_control API with the following parameters, + + * BCDS_Uart1 + * BCDS_UART_MODE_ASYNCHRONOUS | BCDS_UART_DATA_BITS_8 | BCDS_UART_PARITY_NONE | BCDS_UART_STOP_BITS_1 | BCDS_UART_FLOW_CONTROL_NONE + * 115200 (Baud rate) +2. Expected return value from the API: RETCODE_SUCCESS + +##### Run +1. Invoke the Uart_receive API +2. Expected return value from the API: RETCODE_FAILURE + +##### TearDown +No special teardown \ No newline at end of file diff --git a/core/essentials/test/integration/test-protocol.txt b/core/essentials/test/integration/test-protocol.txt new file mode 100644 index 00000000..e69de29b diff --git a/testing/integration/readme.md b/testing/integration/readme.md new file mode 100644 index 00000000..127ae9a8 --- /dev/null +++ b/testing/integration/readme.md @@ -0,0 +1,8 @@ +# Integration Test Framework + +It is composed of the following packages: + +* Test-scheduler: Called in continuous integration. Defines where the tests should be run. +* Test-coordinator: Coordinate the build and execution of tests. +* Test-auxiliaries: List of elements that support more complex tests (example: communication tests between a cloud service and a device) +* Test-executor: Software that will be flashed on the device under test. diff --git a/testing/integration/test-auxiliary/readme.md b/testing/integration/test-auxiliary/readme.md new file mode 100644 index 00000000..a4822685 --- /dev/null +++ b/testing/integration/test-auxiliary/readme.md @@ -0,0 +1,3 @@ +# Test Auxiliary + +Contains different entities that will support the device under test to execute and verify the tests. diff --git a/testing/integration/test-coordinator/readme.md b/testing/integration/test-coordinator/readme.md new file mode 100644 index 00000000..7171acbf --- /dev/null +++ b/testing/integration/test-coordinator/readme.md @@ -0,0 +1,3 @@ +# Test Coordinator + +TBD diff --git a/testing/integration/test-executor/CMakeLists.txt b/testing/integration/test-executor/CMakeLists.txt new file mode 100644 index 00000000..04476bca --- /dev/null +++ b/testing/integration/test-executor/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.6) + +project("Kiso Integration Test Executor" C) + +if(${CMAKE_CROSSCOMPILING}) + set(APP_CONFIG_PATH ${CMAKE_CURRENT_LIST_DIR}/testapp/config PARENT_SCOPE) + + add_executable(TestExecutor + testapp/source/main.c + ) + + target_include_directories(TestExecutor PRIVATE source) + target_link_libraries(TestExecutor bsp essentials testing utils testentry ${KISO_OS_LIB} ${KISO_BOARD_LIBS}) + target_compile_definitions(TestExecutor PRIVATE ${KISO_BOARD_NAME}) + + add_custom_target(TestExecutor.bin ALL + COMMAND ${CMAKE_OBJCOPY} -O binary -R .usrpg $ ${CMAKE_CURRENT_BINARY_DIR}/TestExecutor.bin + COMMENT "Creating flashable binary ${CMAKE_CURRENT_BINARY_DIR}/TestExecutor.bin" + ) + add_dependencies(TestExecutor.bin TestExecutor) + + include(FlashTarget) + CREATE_FLASH_TARGET_JLINK(TestExecutor) +endif() diff --git a/testing/integration/test-executor/readme.md b/testing/integration/test-executor/readme.md new file mode 100644 index 00000000..ecb20e73 --- /dev/null +++ b/testing/integration/test-executor/readme.md @@ -0,0 +1,3 @@ +# Test Executor + +Embedded application linked with integration test fixtures and flashed onto the device under test. diff --git a/testing/integration/test-executor/testapp/config/utils/Kiso_UtilsConfig.h b/testing/integration/test-executor/testapp/config/utils/Kiso_UtilsConfig.h new file mode 100644 index 00000000..9c134ee5 --- /dev/null +++ b/testing/integration/test-executor/testapp/config/utils/Kiso_UtilsConfig.h @@ -0,0 +1,107 @@ +/******************************************************************************** +* Copyright (c) 2010-2019 Robert Bosch GmbH +* +* This program and the accompanying materials are made available under the +* terms of the Eclipse Public License 2.0 which is available at +* http://www.eclipse.org/legal/epl-2.0. +* +* SPDX-License-Identifier: EPL-2.0 +* +* Contributors: +* Robert Bosch GmbH - initial contribution +* +********************************************************************************/ + +/** + * @file + * @brief Utils config header. + * + * @details + * Provides configuration interface for the Utils components. + */ + +#ifndef KISO_UTILSCONFIG_H_ +#define KISO_UTILSCONFIG_H_ + +// clang-format off + +#ifndef KISO_FEATURE_CMDLINEDEBUGGER +/** @brief Enable (1) or disable (0) the CmdLineDebugger feature. */ +#define KISO_FEATURE_CMDLINEDEBUGGER 1 +#endif + +#ifndef KISO_FEATURE_CMDPROCESSOR +/** @brief Enable (1) or disable (0) the CmdProcessor feature. */ +#define KISO_FEATURE_CMDPROCESSOR 1 +#endif + +#ifndef KISO_FEATURE_CRC +/** @brief Enable (1) or disable (0) the Crc feature. */ +#define KISO_FEATURE_CRC 1 +#endif + +#ifndef KISO_FEATURE_EVENTHUB +/** @brief Enable (1) or disable (0) the EventHub feature. */ +#define KISO_FEATURE_EVENTHUB 1 +#endif + +#ifndef KISO_FEATURE_GUARDEDTASK +/** @brief Enable (1) or disable (0) the GuardedTask feature. */ +#define KISO_FEATURE_GUARDEDTASK 1 +#endif + +#ifndef KISO_FEATURE_ERRORLOGGER +/** @brief Enable (1) or disable (0) the ErrorLogger feature. */ +#define KISO_FEATURE_ERRORLOGGER 1 +#endif + +#ifndef KISO_FEATURE_LOGGING +/** @brief Enable (1) or disable (0) the Logging feature. */ +#define KISO_FEATURE_LOGGING 1 +#endif + +#ifndef KISO_FEATURE_RINGBUFFER +/** @brief Enable (1) or disable (0) the RingBuffer feature. */ +#define KISO_FEATURE_RINGBUFFER 1 +#endif + +#ifndef KISO_FEATURE_SLEEPCONTROL +/** @brief Enable (1) or disable (0) the SleepControl feature. */ +#define KISO_FEATURE_SLEEPCONTROL 0 +#endif + +#ifndef KISO_FEATURE_TASKMONITOR +/** @brief Enable (1) or disable (0) the TaskMonitor feature. */ +#define KISO_FEATURE_TASKMONITOR 1 +#endif + +#if KISO_FEATURE_TASKMONITOR + #ifndef KISO_TASKMONITOR_MAX_TASKS + /** @brief Maximum number of TaskMonitor tickets to reserve for the system. */ + #define KISO_TASKMONITOR_MAX_TASKS 10 + #endif +#endif /* if KISO_FEATURE_TASKMONITOR */ + +#ifndef KISO_FEATURE_UARTTRANSCEIVER +/** @brief Enable (1) or disable (0) the UartTransceiver feature. */ +#define KISO_FEATURE_UARTTRANSCEIVER 1 +#endif + +#ifndef KISO_FEATURE_I2CTRANSCEIVER +/** @brief Enable (1) or disable (0) the I2CTransceiver feature. */ +#define KISO_FEATURE_I2CTRANSCEIVER 1 +#endif + +#ifndef KISO_FEATURE_XPROTOCOL +/** @brief Enable (1) or disable (0) the XProtocol feature. */ +#define KISO_FEATURE_XPROTOCOL 1 +#endif + +#ifndef KISO_FEATURE_PIPEANDFILTER +/** @brief Enable (1) or disable (0) the pipe & filter pattern feature. */ +#define KISO_FEATURE_PIPEANDFILTER 1 +#endif + +// clang-format on + +#endif /* KISO_UTILSCONFIG_H_ */ diff --git a/testing/integration/test-executor/testapp/source/AppModules.h b/testing/integration/test-executor/testapp/source/AppModules.h new file mode 100644 index 00000000..cbd2681a --- /dev/null +++ b/testing/integration/test-executor/testapp/source/AppModules.h @@ -0,0 +1,17 @@ + +#ifndef APPMODULES_H_ +#define APPMODULES_H_ + +/** + * @brief Enumerates application modules which are reporting error codes according to RETCODE specification. + * @info usage: + * #undef KISO_APP_MODULE_ID + * #define KISO_APP_MODULE_ID APP_MODULE_ID_xxx + */ +enum App_ModuleID_E +{ + APP_MODULE_ID_MAIN = 1, + /* Define next module ID here and assign a value to it! */ +}; + +#endif diff --git a/testing/integration/test-executor/testapp/source/BSP_Proxy.h b/testing/integration/test-executor/testapp/source/BSP_Proxy.h new file mode 100644 index 00000000..08994ffc --- /dev/null +++ b/testing/integration/test-executor/testapp/source/BSP_Proxy.h @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2010-2020 Robert Bosch GmbH + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Robert Bosch GmbH - initial contribution + * + ******************************************************************************/ + +/** + * @file + * @defgroup + * @ingroup + * @{ + * + * @brief Provides conversion from the bsp board interface to the testapp + * expected interface. + */ + +#if defined(CommonGateway) +#include "BSP_CommonGateway.h" +#elif defined(NucleoF767) +#include "BSP_NucleoF767.h" +#endif + +#if defined(CommonGateway) + +#define TEST_BOARD_LED_ALL COMMONGATEWAY_LED_ALL +#define TEST_BOARD_LED_PASS COMMONGATEWAY_LED_GREEN_ID +#define TEST_BOARD_LED_FAIL COMMONGATEWAY_LED_BLUE_ID +#define TEST_BOARD_LED_PANIC COMMONGATEWAY_LED_RED_ID +#define TEST_BOARD_LED_COMMAND_ON COMMONGATEWAY_LED_COMMAND_ON +#define TEST_BOARD_LED_COMMAND_OFF COMMONGATEWAY_LED_COMMAND_OFF +#define TEST_BOARD_LED_COMMAND_TOGGLE COMMONGATEWAY_LED_COMMAND_TOGGLE + +#elif defined(NucleoF767) + +#define TEST_BOARD_LED_ALL NUCLEOF767_LED_ALL +#define TEST_BOARD_LED_PASS NUCLEOF767_LED_GREEN_ID +#define TEST_BOARD_LED_FAIL NUCLEOF767_LED_BLUE_ID +#define TEST_BOARD_LED_PANIC NUCLEOF767_LED_RED_ID +#define TEST_BOARD_LED_COMMAND_ON NUCLEOF767_LED_COMMAND_ON +#define TEST_BOARD_LED_COMMAND_OFF NUCLEOF767_LED_COMMAND_OFF +#define TEST_BOARD_LED_COMMAND_TOGGLE NUCLEOF767_LED_COMMAND_TOGGLE + +#endif + +/** @} */ diff --git a/testing/integration/test-executor/testapp/source/main.c b/testing/integration/test-executor/testapp/source/main.c new file mode 100644 index 00000000..acad8f35 --- /dev/null +++ b/testing/integration/test-executor/testapp/source/main.c @@ -0,0 +1,260 @@ +/******************************************************************************* +* Copyright (c) 2010-2020 Robert Bosch GmbH +* +* This program and the accompanying materials are made available under the +* terms of the Eclipse Public License 2.0 which is available at +* http://www.eclipse.org/legal/epl-2.0. +* +* SPDX-License-Identifier: EPL-2.0 +* +* Contributors: +* Robert Bosch GmbH - initial contribution +* +*******************************************************************************/ + +/** + * @brief This file implements the #main() of the test executor software. After + * initializing the test board and starting the OS scheduler, it shall call the + * function in the feature integration tests responsible for initializing and + * starting the tests (e.g. #TestEntry_Initialize() under + * core/essentials/test/integration/source/TestEntry.c) + * + * @file + */ + +#include "AppModules.h" +#include "BSP_Proxy.h" +#include "Kiso_Retcode.h" +#include "Kiso_BSP_LED.h" +#include "Kiso_BSP_Board.h" +#include "Kiso_Basics.h" +#include "Kiso_CmdProcessor.h" +#include "FreeRTOS.h" +#include "task.h" +#include + +#undef KISO_MODULE_ID +#define KISO_MODULE_ID KISO_APP_MODULE_MAIN + +#define TASK_PRIO_MAIN_CMD_PROCESSOR (UINT32_C(1)) +#define TASK_STACK_SIZE_MAIN_CMD_PROCESSOR (UINT16_C(700)) +#define TASK_Q_LEN_MAIN_CMD_PROCESSOR (UINT32_C(10)) + +extern void xPortSysTickHandler(void); /*link-time function to be provided by the freertos library */ +extern Retcode_T TestEntry_Initialize(void *param1, uint32_t param2); /* link-time function to be provided by the library implementing the feature integration tests*/ + +static Retcode_T systemStartup(void); +static void systemInit(void *param1, uint32_t param2); +static void ErrorHandler(Retcode_T error, bool isfromIsr); +static void assertIndicationMapping(const unsigned long line, const unsigned char *const file); +static void SysTickPreCallback(void); + +#if configSUPPORT_STATIC_ALLOCATION +void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, + StackType_t **ppxIdleTaskStackBuffer, + uint32_t *pulIdleTaskStackSize); +#endif +#if configSUPPORT_STATIC_ALLOCATION && configUSE_TIMERS +void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, + StackType_t **ppxTimerTaskStackBuffer, + uint32_t *pulTimerTaskStackSize); +#endif + +static CmdProcessor_T MainCmdProcessor; + +int main(void) +{ + /* Mapping Default Error Handling function */ + Retcode_T retcode = Retcode_Initialize(ErrorHandler); + +#ifndef NDEBUG + if (RETCODE_OK == retcode) + { + retcode = Assert_Initialize(assertIndicationMapping); + } +#endif /*NDEBUG*/ + if (RETCODE_OK == retcode) + { + retcode = systemStartup(); + } + if (RETCODE_OK == retcode) + { + retcode = CmdProcessor_Initialize(&MainCmdProcessor, + (char *)"MainCmdProcessor", + TASK_PRIO_MAIN_CMD_PROCESSOR, + TASK_STACK_SIZE_MAIN_CMD_PROCESSOR, + TASK_Q_LEN_MAIN_CMD_PROCESSOR); + } + if (RETCODE_OK == retcode) + { + /* Here we enqueue the application initialization into the command + * processor, such that the initialization function will be invoked + * once the RTOS scheduler is started below. + */ + retcode = CmdProcessor_Enqueue(&MainCmdProcessor, + systemInit, + &MainCmdProcessor, + UINT32_C(0)); + } + + if (RETCODE_OK != retcode) + { + printf("System Startup failed"); + assert(false); + } + /* start scheduler */ + vTaskStartScheduler(); +} + +/** + * @brief Starts the system up. + * @details This function will execute before the scheduler starts and it is + * intended to make the target board ready for operation. + * @return Returns RETCODE_OK in case of success, error code otherwise. + */ +Retcode_T systemStartup(void) +{ + Retcode_T retcode = RETCODE_OK; + uint32_t param1 = 0; + void *param2 = NULL; + + /* Initialize the callbacks for the system tick */ + BSP_Board_OSTickInitialize(SysTickPreCallback, NULL); + retcode = BSP_Board_Initialize(param1, param2); + if (RETCODE_OK == retcode) + { + retcode = BSP_LED_Connect(); + } + if (RETCODE_OK == retcode) + { + retcode = BSP_LED_Enable(TEST_BOARD_LED_ALL); + } + if (RETCODE_OK == retcode) + { + retcode = BSP_LED_Switch(TEST_BOARD_LED_ALL, TEST_BOARD_LED_COMMAND_ON); + } + return retcode; +} + +void systemInit(void *param1, uint32_t param2) +{ + KISO_UNUSED(param1); + KISO_UNUSED(param2); + Retcode_T retcode = TestEntry_Initialize(NULL, 0U); + if (RETCODE_OK != retcode) + { + Retcode_RaiseError(retcode); + } +} + +/** + * @brief Error handler function. + * @details This function is called when Retcode_RaiseError() function is + * invoked, it is used to report the error to the user. + * @param[in] error Error code raised. + * @param[in] isfromIsr if true then the ErrorHandler is being executed from an + * ISR context and not all the services are available. + */ +void ErrorHandler(Retcode_T error, bool isfromIsr) +{ + if (!isfromIsr) + { + /** \todo: ERROR HANDLING SHOULD BE DONE FOR THE ERRORS RAISED FROM PLATFORM */ + uint32_t PackageID = Retcode_GetPackage(error); + uint32_t ErrorCode = Retcode_GetCode(error); + uint32_t ModuleID = Retcode_GetModuleId(error); + Retcode_Severity_T SeverityCode = Retcode_GetSeverity(error); + + if (RETCODE_SEVERITY_FATAL == SeverityCode) + { + printf("Fatal Error:[%u] from Module:[%u] in Package:[%u]\r\n", + (unsigned int)ErrorCode, + (unsigned int)ModuleID, + (unsigned int)PackageID); + } + else if (RETCODE_SEVERITY_ERROR == SeverityCode) + { + printf("Severe Error:[%u] from Module:[%u] in Package:[%u]\r\n", + (unsigned int)ErrorCode, + (unsigned int)ModuleID, + (unsigned int)PackageID); + } + BSP_LED_Switch(TEST_BOARD_LED_ALL, TEST_BOARD_LED_COMMAND_OFF); + BSP_LED_Switch(TEST_BOARD_LED_PANIC, TEST_BOARD_LED_COMMAND_ON); + } + else + { + + BSP_LED_Switch(TEST_BOARD_LED_ALL, TEST_BOARD_LED_COMMAND_OFF); + BSP_LED_Switch(TEST_BOARD_LED_PANIC, TEST_BOARD_LED_COMMAND_ON); + } +} + +#ifndef NDEBUG +/** + * @brief This API is called when function enters an assert + * @param[in] line line number where asserted. + * @param[in] file file name which is asserted. + */ +void assertIndicationMapping(const unsigned long line, const unsigned char *const file) +{ + (void)BSP_LED_Switch(TEST_BOARD_LED_ALL, TEST_BOARD_LED_COMMAND_ON); + printf("asserted at Filename %s , line no %ld \n\r", file, line); +} +#endif /* NDEBUG */ + +/** + * @brief This function is a hook from FreeRTOS to systick. + * @details This function is called when ever the Systick IRQ is hit. This is a + * temporary implementation where the #SysTick_Handler() is not directly mapped + * to #xPortSysTickHandler(). Instead it is only called if the scheduler has + * started. + */ +static void SysTickPreCallback(void) +{ + if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) + { + xPortSysTickHandler(); + } +} + +#if configSUPPORT_STATIC_ALLOCATION + +static StaticTask_t xIdleTaskTCBBuffer; +static StackType_t xIdleStack[IDLE_TASK_SIZE]; + +/** + * @brief If static allocation is supported then the application must provide + * the following callback function + * @details Enables the application to optionally provide the memory that will + * be used by the idle task as the task's stack and TCB. + */ +void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, + StackType_t **ppxIdleTaskStackBuffer, + uint32_t *pulIdleTaskStackSize) +{ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer; + *ppxIdleTaskStackBuffer = &xIdleStack[0]; + *pulIdleTaskStackSize = IDLE_TASK_SIZE; +} +#endif + +#if configSUPPORT_STATIC_ALLOCATION && configUSE_TIMERS +static StaticTask_t xTimerTaskTCBBuffer; +static StackType_t xTimerStack[configTIMER_TASK_STACK_DEPTH]; + +/** + * @brief If static allocation and timers are supported then the application + * must provide the following callback function + * @details Enables the application to optionally provide the memory that will + * be used by the timer task as the task's stack and TCB. + */ +void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, + StackType_t **ppxTimerTaskStackBuffer, + uint32_t *pulTimerTaskStackSize) +{ + *ppxTimerTaskTCBBuffer = &xTimerTaskTCBBuffer; + *ppxTimerTaskStackBuffer = &xTimerStack[0]; + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; +} +#endif diff --git a/testing/integration/test-scheduler/readme.md b/testing/integration/test-scheduler/readme.md new file mode 100644 index 00000000..d049eab1 --- /dev/null +++ b/testing/integration/test-scheduler/readme.md @@ -0,0 +1,3 @@ +# Test Scheduler + +Schedules which tests should be executed where. Represents the link to the continuous integration setup on Jenkins. From acc8d0cb585376fd820db952d392de95544db4e9 Mon Sep 17 00:00:00 2001 From: "Mohamed Ali Khalifi (AE/PJ-SW4)" Date: Tue, 11 Feb 2020 10:27:30 +0100 Subject: [PATCH 2/7] Add testing to core Co-authored-by: ChiefGokhlayehBosch Signed-off-by: ChiefGokhlayehBosch --- core/essentials/test/integration/readme.md | 12 +- .../test/integration/source/TestSuiteUart.c | 40 +- .../test/integration/source/TestSuiteUart.h | 28 +- .../test/integration/specs/I2C_Test_Spec.md | 283 -------------- .../test/integration/specs/SPI_Test_Spec.md | 207 ---------- .../test/integration/specs/UART_Test_Spec.md | 218 ++--------- core/testing/CMakeLists.txt | 40 ++ core/testing/include/Kiso_Testing.h | 192 +++++++++ core/testing/include/Kiso_Testing_Config.h | 54 +++ core/testing/source/CChannel.c | 312 +++++++++++++++ core/testing/source/Serial.c | 219 +++++++++++ core/testing/source/SerialMsgTransceiver.c | 258 +++++++++++++ core/testing/source/TestRegistry.c | 339 ++++++++++++++++ core/testing/source/TestRunner.c | 363 ++++++++++++++++++ core/testing/source/Testing.c | 74 ++++ core/testing/source/protected/CChannel.h | 162 ++++++++ .../testing/source/protected/SerialCChannel.h | 77 ++++ .../source/protected/SerialMsgTransceiver.h | 58 +++ core/testing/source/protected/TestRegistry.h | 197 ++++++++++ core/testing/source/protected/TestRunner.h | 62 +++ 20 files changed, 2465 insertions(+), 730 deletions(-) delete mode 100644 core/essentials/test/integration/specs/I2C_Test_Spec.md delete mode 100644 core/essentials/test/integration/specs/SPI_Test_Spec.md create mode 100644 core/testing/CMakeLists.txt create mode 100644 core/testing/include/Kiso_Testing.h create mode 100644 core/testing/include/Kiso_Testing_Config.h create mode 100644 core/testing/source/CChannel.c create mode 100644 core/testing/source/Serial.c create mode 100644 core/testing/source/SerialMsgTransceiver.c create mode 100644 core/testing/source/TestRegistry.c create mode 100644 core/testing/source/TestRunner.c create mode 100644 core/testing/source/Testing.c create mode 100644 core/testing/source/protected/CChannel.h create mode 100644 core/testing/source/protected/SerialCChannel.h create mode 100644 core/testing/source/protected/SerialMsgTransceiver.h create mode 100644 core/testing/source/protected/TestRegistry.h create mode 100644 core/testing/source/protected/TestRunner.h diff --git a/core/essentials/test/integration/readme.md b/core/essentials/test/integration/readme.md index 38315cda..aa2d943b 100644 --- a/core/essentials/test/integration/readme.md +++ b/core/essentials/test/integration/readme.md @@ -1,7 +1,7 @@ -# Integration Test Framework +# Integration Tests: Essentials -It is composed by the following packages: -* Test-scheduler: Called in the continious integration. Define where the tests should be run. -* Test-coordinator: Coordiante the build and execution of the tests. -* Test-auxiliaries: List of elements that supports more complex tests (example: communication tests between a cloud service and a device) -* Test-executor: Software that will be flashed on the device under test. \ No newline at end of file +This is the integration test package for Essentials. It contains integration test suites for: + +* UART - testing sending and receiving data over standard UART. + +Check `TestEntry.c` to see which integration test suites are loaded. diff --git a/core/essentials/test/integration/source/TestSuiteUart.c b/core/essentials/test/integration/source/TestSuiteUart.c index 78019fb9..2ea102f4 100644 --- a/core/essentials/test/integration/source/TestSuiteUart.c +++ b/core/essentials/test/integration/source/TestSuiteUart.c @@ -1,16 +1,16 @@ -/********************************************************************************************************************** - * Copyright (c) 2010#2019 Robert Bosch GmbH +/******************************************************************************* + * Copyright (c) 2010-2020 Robert Bosch GmbH * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl#2.0. + * http://www.eclipse.org/legal/epl-2.0. * - * SPDX#License#Identifier: EPL#2.0 + * SPDX-License-Identifier: EPL-2.0 * * Contributors: - * Robert Bosch GmbH # initial contribution + * Robert Bosch GmbH - initial contribution * - **********************************************************************************************************************/ + ******************************************************************************/ /** * @file @@ -18,41 +18,33 @@ * @brief * Implements test cases for uart comminication verification */ -/*###################### INCLUDED HEADERS ############################################################################*/ +#include "TestSuiteUart.h" +#include "Kiso_Basics.h" #include "Kiso_Testing.h" #include "Kiso_CmdProcessor.h" #include "Kiso_MCU_UART.h" #include "Kiso_BSP_GenericUart.h" -#include "TestSuiteUART.h" -#include #include "FreeRTOS.h" #include "semphr.h" -/*###################### MACROS DEFINITION ###########################################################################*/ + #undef KISO_MODULE_ID #define KISO_MODULE_ID 0 -#define UART_BUFFER_LEN 5 +#define UART_BUFFER_LEN (5) #define DATA_TRANSFER_TIMEOUT_MS UINT32_C(1000) #define UART_DEVICE UINT32_C(1) +#define MSG_BUFFER_SIZE (32) -/*###################### LOCAL_TYPES DEFINITION ######################################################################*/ enum TestSuiteUart_TestCases_E { TEST_CASE_FUNCTIONAL_TEST_ID = 1 }; -/*###################### LOCAL FUNCTIONS DECLARATION #################################################################*/ static Retcode_T TestCase_FctTest_Setup(CCMsg_T *ccmsg); static void TestCase_FctTest_Run(CCMsg_T *ccmsg); static Retcode_T TestCase_FctTest_Teardown(CCMsg_T *ccmsg); static void UartISRCallback(UART_T uart, struct MCU_UART_Event_S event); -/*###################### VARIABLES DECLARATION #######################################################################*/ - -/*###################### EXPOSED FUNCTIONS IMPLEMENTATION ############################################################*/ - -/*###################### LOCAL FUNCTIONS IMPLEMENTATION ##############################################################*/ - static UART_T UartHdl = 0; static xSemaphoreHandle UartLock = 0; @@ -64,14 +56,14 @@ Retcode_T TestSuiteUart_Initialize(uint8_t sId) if (RETCODE_OK == retcode) { - retcode = Tests_RegisterTestCase(sId, TEST_CASE_FUNCTIONAL_TEST_ID, TestCase_FctTest_Setup, TestCase_FctTest_Run, TestCase_FctTest_TearDown); + retcode = Tests_RegisterTestCase(sId, TEST_CASE_FUNCTIONAL_TEST_ID, TestCase_FctTest_Setup, TestCase_FctTest_Run, TestCase_FctTest_Teardown); } return retcode; } /** - * @brief Performs the setup operation of the functional test of uart in interrupt mode - * @details This function initializes the uart interface in interrupt mode and creates the necessary + * @brief Performs the setup operation of the functional test of uart in interrupt mode + * @details This function initializes the uart interface in interrupt mode and creates the necessary * synchronisation ressources. */ static Retcode_T TestCase_FctTest_Setup(CCMsg_T *ccmsg) @@ -132,7 +124,7 @@ static Retcode_T TestCase_FctTest_Teardown(CCMsg_T *ccmsg) } /** - * This Test will put the uart receiver into receive mode and send data via the transmitter the data will be + * This Test will put the uart receiver into receive mode and send data via the transmitter the data will be * looped back to the receiver at hardware level (e.g. wiring TX line to RX line) * the test will succede if the transmit operation succeeded and if the received data matches the transmitted data */ @@ -143,7 +135,7 @@ static void TestCase_FctTest_Run(CCMsg_T *ccmsg) Retcode_T retcode; uint8_t dataOut[UART_BUFFER_LEN]; uint8_t dataIn[UART_BUFFER_LEN] = {0}; - char msg[30] = "SUCCESS"; + char msg[MSG_BUFFER_SIZE] = "SUCCESS"; for (uint8_t i = 0; i < UART_BUFFER_LEN; i++) { diff --git a/core/essentials/test/integration/source/TestSuiteUart.h b/core/essentials/test/integration/source/TestSuiteUart.h index 4319f201..f170590e 100644 --- a/core/essentials/test/integration/source/TestSuiteUart.h +++ b/core/essentials/test/integration/source/TestSuiteUart.h @@ -1,16 +1,16 @@ -/********************************************************************************************************************** - * Copyright (c) 2010#2019 Robert Bosch GmbH +/******************************************************************************* + * Copyright (c) 2010-2020 Robert Bosch GmbH * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl#2.0. + * http://www.eclipse.org/legal/epl-2.0. * - * SPDX#License#Identifier: EPL#2.0 + * SPDX-License-Identifier: EPL-2.0 * * Contributors: - * Robert Bosch GmbH # initial contribution + * Robert Bosch GmbH - initial contribution * - **********************************************************************************************************************/ + ******************************************************************************/ /** * @file @@ -19,16 +19,12 @@ * @{ * * @brief Provides an API for the following functionality - * + * */ #ifndef TESTSUITE_UART_H_ #define TESTSUITE_UART_H_ -/*###################### INCLUDED HEADERS ############################################################################*/ - -/*###################### MACROS DEFINITION ###########################################################################*/ - -/*###################### TYPE DEFINITIONS ############################################################################*/ +#include "Kiso_Retcode.h" enum TestSuiteUart_Retcodes_E { @@ -37,19 +33,15 @@ enum TestSuiteUart_Retcodes_E TestSuite_Teardown_TRIGGERED_SEVERAL_TIMES, }; -/*###################### EXPORTED FUNCTIONS PROTOTYPES ###############################################################*/ - /** * @brief Initializes the uart test suite - * @details This function will register the uart test suites in the Testing module TestSuites register and will - * also register for execution all the test cases belonging to this test suite + * @details This function will register the uart test suites in the Testing module TestSuites register and will + * also register for execution all the test cases belonging to this test suite * @param id is the identifier to be given to the test suite it will be used in the communication protocol between * the test executor and the test controller @see todo: add link to docu */ Retcode_T TestSuiteUart_Initialize(uint8_t id); -/*###################### GLOBAL VARIABLES ###########################################################################*/ - /** @} */ #endif /* TESTSUITE_UART_H_ */ diff --git a/core/essentials/test/integration/specs/I2C_Test_Spec.md b/core/essentials/test/integration/specs/I2C_Test_Spec.md deleted file mode 100644 index 2b5a1d83..00000000 --- a/core/essentials/test/integration/specs/I2C_Test_Spec.md +++ /dev/null @@ -1,283 +0,0 @@ -# Test Entry 3: "Essentials" - -## Test Suite 3.3: I2C_Selfcontained_Test -### Description - -* Purpose - + Test the I2C transfer functionality - -* Test participants: - - Device under Test (DUT): Stm32 - Bike Sensor Board (BSE) - - Test Coordinator: PC - -### Test Setup -The test setup consists of the test coordinator and 1 test participant - -* Test Coordinator (on PC) -* The DUT is connected to the PC via UART which is the Test Coordination Channel. The embedded C testling code is flashed onto the DUT. -* The DUT is connected to a 12 V power source. -* For this selfcontained test, no external wires are necessary and only BSE-internal Sensors are polled via I2C. - -On the BSE testling, the initialization sequence setups the I2C Clock and the I2C GPIOs: - -* I2C SCL line: GPIO_PIN_14, Bank GPIOG, mode GPIO_PULLUP, GPIO_SPEED_LOW -* I2C SDA line: GPIO_PIN_13, Bank GPIOG, mode GPIO_PULLUP, GPIO_SPEED_LOW -* Alternative function: GPIO_AF4_I2C1 -* I2C Clock: PCLK1 -* enable GPIO bank G clock -* power up GPIO bank G (PWR_CR2_IOSV register) -* IRQs I2Cx_ER_IRQn and I2Cx_EV_IRQn are enabled - -### Teardown - -No special teardown - -### Test Cases - -#### TC 3.3.1 TestCase_I2C_initialize -##### Setup -No separate Test Case Setup required - -##### Run -1. For all present I2C Interfaces: BCDS_I2C1, BCDS_I2C2 - - * Call API: I2C_getVersion(), expect version - * Call API: I2C_getCapabilities(), expect only "address10bit" capability. - * Call API: I2C_initialize(), expect RETCODE_OK - * Call API: I2C_powerControl(PERIPHERALS_POWER_STATE_FULL), expect RETCODE_OK - * Call API: I2C_powerControl(PERIPHERALS_POWER_STATE_OFF), expect RETCODE_OK - * Call API: I2C_powerControl(PERIPHERALS_POWER_STATE_FULL), expect RETCODE_OK - * Call API: I2C_control(BCDS_I2C_BUS_SPEED,BCDS_I2C_BUS_SPEED_STANDARD), expect RETCODE_OK - * Call API: I2C_control(BCDS_I2C_BUS_SPEED,BCDS_I2C_BUS_SPEED_FAST), expect RETCODE_OK - * Call API: I2C_control(BCDS_I2C_BUS_SPEED,BCDS_I2C_BUS_SPEED_FAST_PLUS), expect RETCODE_OK - * Call API: I2C_control(BCDS_I2C_BUS_SPEED,BCDS_I2C_OWN_ADDRESS,0x42), expect RETCODE_OK - * Call API: I2C_getStatus(), expect only flag "Initialized" - * Call API: I2C_uninitialize(), expect RETCODE_OK - -2. If all as expected, return Success. - -##### TearDown -No separate Test Case Tear Down required - -#### TC 3.3.2 TestCase_I2C_master_BMI160 - -On the BSE boardThe inertial measurement unit BMI160 is visible via BCDS_I2C1 on address 0x68. -To read a register, the register ID is first written via I2C to BMI160. -Maximum supported clock frequency is 1000khz, i.e., BCDS_I2C_BUS_SPEED_FAST_PLUS. - -##### Setup -Call API: I2C_initialize(), expect RETCODE_OK - -##### Run -1. Transmit 1 byte value 0 to BMI160 to access the CHIPID register: - - * Call API: I2C_masterTransmit(BCDS_I2C1 ,0x68, 0, 1, 0); - * Expect RETCODE_OK; - * Expect "TransferDone" Callback. -2. Read 1 byte CHIPID value from BMI160: - - * Call API: I2C_masterReceive(BCDS_I2C1 ,0x68, &chipid, 1, 0); - * Expect RETCODE_OK; - * Expect "TransferDone" Callback. - * Expect CHIPID to be ( 0b11010001 = 0xD1 ) -3. Transmit 1 byte value 0x04 to BMI160 to access the DATA registers: - - * Call API: I2C_masterTransmit(BCDS_I2C1 ,0x68, 0x04, 1, 0); - * Expect RETCODE_OK; - * Expect "TransferDone" Callback. -4. Read 20 byte DATA register values from BMI160: - - * Call API: I2C_masterReceive(BCDS_I2C1 ,0x68, datareg, 20, 0); - * Expect RETCODE_OK; - * Expect "TransferDone" Callback. - * Expect at least one DATA registers values to contain values different from 0 -5. If all as expected, return Success. - -##### TearDown -Call API: I2C_uninitialize(), expect RETCODE_OK - -## Test Suite 3.4: I2C_Arduino_Test -### Description - -1. Purpose: - - * Test the I2C transfer functionality with an Arduino counterpart that allows precise master AND slave communication tests. - -2. Test participants: - - * Test Coordinator: PC - * Device under Test (DUT): Stm32 - Bike Sensor Board (BSE) - * Arduino Due - the arduino code is contained in the Peripherals/test/integration/Testling/Tests/testSuiteI2c/Arduino_I2C_final_Testing_Code folder. - -### Setup -The test setup consists of the test coordinator and 2 test participants - -1. Test Coordinator (on PC) -2. The DUT is connected to the PC via UART which is the Test Coordination Channel. The embedded C testling code is flashed onto the DUT. -3. The DUT is connected to a 12 V power source. -4. The Arduino is connected to the PC via UART to flash and power the Arduino board. -5. The Arduino testling code is flashed onto the Arduino. -6. The I2C bus I2C1 of the BSE board is led out and connected to the Arduino Due board such that: - - * BSE-PG14/C6 SCL line is connected to Arduino GPIO pin 21 - * BSE-PG13/C7 SDA line is connected to Arduino GPIO pin 20 - * a common ground line between the BSE board and the Arduino board is connected - -On the BSE testling, the initialization sequence setups the I2C Clock and the I2C GPIOs: - -7. I2C SCL line: GPIO_PIN_14, Bank GPIOG, mode GPIO_PULLUP, GPIO_SPEED_LOW -8. I2C SDA line: GPIO_PIN_13, Bank GPIOG, mode GPIO_PULLUP, GPIO_SPEED_LOW -9. Alternative function: GPIO_AF4_I2C1 -10. I2C Clock: PCLK1 -11. Enable GPIO bank G clock -12. Power up GPIO bank G (PWR_CR2_IOSV register) -13. IRQs I2Cx_ER_IRQn and I2Cx_EV_IRQn are enabled - -### Teardown -No special teardown - -### Test Cases - -#### TC 3.4.1 TestCase_I2C_master - -The arduino wire library has a maximum i2c buffer size of 32 bytes - so larger data streams cannot be tested. - -##### Setup -1. Call API: I2C_initialize(), expect RETCODE_OK -2. Send testcase ID (1) to arduino and expect acknowledge byte (1) - - * Call API: I2C_masterTransmit(BCDS_I2C1, ARDUINO_I2C_ADDRESS, 1, 1, 0); - * Call API: I2C_masterRecieve (BCDS_I2C1, ARDUINO_I2C_ADDRESS, &arduinoAcknowledges, 1, 0); - * Expect arduinoAcknowledges == 1 -3. Call API: I2C_uninitialize(), expect RETCODE_OK -4. Call API: I2C_initialize(), expect RETCODE_OK - -##### Run -1. In Master mode send 1 byte to Arduino and receive it back: - - * Call API: I2C_masterTransmit(BCDS_I2C1, ARDUINO_I2C_ADDRESS, TESTBYTE, 1, 0); - * Expect RETCODE_OK; - * Expect "TransferDone" Callback. - * Call API: I2C_masterReceive(BCDS_I2C1, ARDUINO_I2C_ADDRESS, &receiveBuffer, 1, 0); - * Expect RETCODE_OK; - * Expect "TransferDone" Callback. - * Verify (receiveBuffer == TESTBYTE) -2. In Master mode send 32 bytes to Arduino and receive them back - - * uint8_t TEST32BYTES[] = {42, 43, ..., 73 }; - * Call API: I2C_masterTransmit(BCDS_I2C1, ARDUINO_I2C_ADDRESS, TEST32BYTES, 32, 0); - * Expect RETCODE_OK; - * Expect "TransferDone" Callback. -3. Call API: I2C_masterReceive(BCDS_I2C1, ARDUINO_I2C_ADDRESS, receiveBuffer32, 32, 0); - - * Expect RETCODE_OK; - * Expect "TransferDone" Callback. -4. Verify (receiveBuffer32 identical to TEST32BYTES) -5. Return Success. - -##### TearDown -Call API: I2C_uninitialize(), expect RETCODE_OK - -#### TC 3.4.2 TestCase_I2C_slave_woCallback - -##### Setup -1. Call API: I2C_initialize(), expect RETCODE_OK -2. Send testcase ID (2) to arduino and expect acknowledge byte (1) - - * Byte to call API: I2C_masterTransmit(BCDS_I2C1, ARDUINO_I2C_ADDRESS, 2, 1, 0); - * Byte to call API: I2C_masterRecieve (BCDS_I2C1, ARDUINO_I2C_ADDRESS, &arduinoAcknowledges, 1, 0); - * Expect arduinoAcknowledges == 1 -3. Call API: I2C_uninitialize(), expect RETCODE_OK -4. Call API: I2C_initialize(), expect RETCODE_OK -5. Set own slave address to 0x42 - -##### Run - -1. In Slave mode, wait for Arduino to request 1 byte, then wait until Arduino sends it back - - * Call API: I2C_slaveTransmit(BCDS_I2C1, TESTBYTE, 1); - * expect RETCODE_OK; - * expect "TransferDone" Callback. - * Call API: I2C_slaveReceive(BCDS_I2C1, &receiveBuffer, 1); - * expect RETCODE_OK; - * expect "TransferDone" Callback. - * Verify (receiveBuffer == TESTBYTE) -2. In Slave mode send 32 bytes to Arduino and receive them back - - * uint8_t TEST32BYTES[] = {42, 43, ..., 73 }; - * Call API: I2C_slaveTransmit(BCDS_I2C1, ARDUINO_I2C_ADDRESS, TEST32BYTES, 32); - * expect RETCODE_OK; - * expect "TransferDone" Callback. - * Call API: I2C_slaveReceive(BCDS_I2C1, ARDUINO_I2C_ADDRESS, receiveBuffer32, 32); - * expect RETCODE_OK; - * expect "TransferDone" Callback. - * Verify (receiveBuffer32 identical to TEST32BYTES) -3. Return Success. - -##### TearDown - -Call API: I2C_uninitialize(), expect RETCODE_OK - -#### TC 3.4.3 TestCase_I2C_slave_callbackDriven - -##### Setup -1. Call API: I2C_initialize(), expect RETCODE_OK -2. Send testcase ID (3) to arduino and expect acknowledge byte (1) - - * Call API: I2C_masterTransmit(BCDS_I2C1, ARDUINO_I2C_ADDRESS, 3, 1, 0); - * Call API: I2C_masterRecieve (BCDS_I2C1, ARDUINO_I2C_ADDRESS, &arduinoAcknowledges, 1, 0); - * Expect arduinoAcknowledges == 1 -3. Call API: I2C_uninitialize(), expect RETCODE_OK - -##### Run -1. Define uint8_t TEST32BYTES[] = {42, 43, ..., 73 }; -2. Call API: I2C_initialize(), expect RETCODE_OK -3. Set own slave address to 0x42 -4. Register new callback event handler that: - - * Answers a SlaveTransmit request with: I2C_slaveTransmit(BCDS_I2C1, TEST32BYTES, 32); - * expect RETCODE_OK; - * Answers a SlaveReceive request with: I2C_slaveReceive(BCDS_I2C1, receiveBuffer32, 32); - * expect RETCODE_OK; - * Updates 4-state-variable from waitForSlaveTransmit(0) to waitForSlaveReceive(1) to done(2) or alternatively error(3) -5. Wait with timeout until 4-state-variable goes through the states - - * WaitForSlaveTransmit(0) - * WaitForSlaveReceive(1) - * Done(2) -6. Make sure error(3) is not reached or return error-report. -7. When state done(2) is reached, verify (receiveBuffer32 identical to TEST32BYTES) -8. Return Success. - -##### TearDown - -Call API: I2C_uninitialize(), expect RETCODE_OK - -#### TC 3.4.4 TestCase_I2C_higherSpeeds - -##### Setup -1. Call API: I2C_initialize(), expect RETCODE_OK -2. Send testcase ID (4) to arduino and expect acknowledge byte (1) - - * Call API: I2C_masterTransmit(BCDS_I2C1, ARDUINO_I2C_ADDRESS, 4, 1, 0); - * Call API: I2C_masterRecieve (BCDS_I2C1, ARDUINO_I2C_ADDRESS, &arduinoAcknowledges, 1, 0); - * Expect arduinoAcknowledges == 1 -3. Call API: I2C_uninitialize(), expect RETCODE_OK -4. Call API: I2C_initialize(), expect RETCODE_OK - -##### Run -1. uint8_t TEST32BYTES[] = {42, 43, ..., 73 }; -2. Set the bus speeds [Standard Speed (100kHz), Fast Speed (400kHz), Fast+ Speed (1MHz)] try: - - * In Master mode send 32 bytes to Arduino and receive them back - * call API: I2C_masterTransmit(BCDS_I2C1, ARDUINO_I2C_ADDRESS, TEST32BYTES, 32, 0); - * expect RETCODE_OK; - * expect "TransferDone" Callback. - * Call API: I2C_masterReceive(BCDS_I2C1, ARDUINO_I2C_ADDRESS, receiveBuffer32, 32, 0); - * expect RETCODE_OK; - * expect "TransferDone" Callback. - * Verify (receiveBuffer32 identical to TEST32BYTES) -3. Return Success. - -##### TearDown -Call API: I2C_uninitialize(), expect RETCODE_OK diff --git a/core/essentials/test/integration/specs/SPI_Test_Spec.md b/core/essentials/test/integration/specs/SPI_Test_Spec.md deleted file mode 100644 index 0542dfdb..00000000 --- a/core/essentials/test/integration/specs/SPI_Test_Spec.md +++ /dev/null @@ -1,207 +0,0 @@ -Integration Test Specification for SPI - -# Test Suite 2: "Test Specification of SPI" - -## Description - -* Purpose - * Test the Peripheral SPI functionality -* Test participants which are involved - * Test participant :- BSE -* Test environment and setup - * BSE device be connected to the PC via USB Cable. - * A PC has a test coordinator. -* Setup for Flashing-Manual. - * SPI IntegrationTestApp binary file into BSE device - * once the flashing is done - * It automatically reset the device and IntegrationTestApps Boots-up - -## Setup -The test setup consists of the test coordinator and 2 test participants: - -* test coordinator (on PC) -* The test device BSE with the embedded C test participant - -The test device is connected to the test coordinator on the PC via UART as a Test Coordination Channel. - - -### Parameters -No special parameters - -## Teardown -* Deinitialize the SPI Port with SPI_deinitialize. - -## Test Suite 1.2: Non initialized - error test -### Description -* Test the SPI error cases for non initialized case - -### Setup -* No required separate Test Suite Setup for this example. - -### Teardown -* Not required separate Test Suite Tear Down for this example. - -### Test Cases - -#### TC 1.1.1 TestCase_SPI_Control_Error_unitialized -* Test case Setup - * Deinitialize the SPI. -* Test Case Run - * Parameter passed: valid handle, valid control, valid argument - * Run SPI_Control API -* Expected return value from the API: RETCODE_FAILURE -* Test case Tear Down - * Not required separate Test Case Tear Down for this example. - -#### TC 1.1.2 TestCase_SPI_Send_Error_unitialized -* Test case Setup - * Deinitialize the SPI. -* Test Case Run - * Parameter passed: valid handle, valid sendValue, valid bufferSize - * Run SPI_Send API -* Expected return value from the API: RETCODE_FAILURE -* Test case Tear Down - * Not required separate Test Case Tear Down for this example. - -#### TC 1.1.3 TestCase_SPI_Receive_Error_unitialized -* Test case Setup - * Deinitialize the SPI. -* Test Case Run - * Parameter passed: valid handle, valid receiveValue, valid bufferSize - * Run SPI_Receive API -* Expected return value from the API: RETCODE_FAILURE -* Test case Tear Down - * No required separate Test Case Tear Down for this example. - -#### TC 1.1.4 TestCase_SPI_Transfer_Error_unitialized -* Test case Setup - * Deinitialize the SPI. -* Test Case Run - * Parameter passed: valid handle, valid sendValue, valid receiveValue, valid bufferSize - * Run SPI_Transfer API -* Expected return value from the API: RETCODE_FAILURE -* Test case Tear Down - * No required separate Test Case Tear Down for this example. - -################################################################################################################################## - - -#### TC 1.1.5 TestCase_SPI_Send_Error_invalidPort -* Test case Setup - * Initialize the SPI Port. -* Test Case Run - * Parameter passed: invalid port, valid sendValue, valid bufferSize - * Run SPI_Send API -* Expected return value from the API: RETCODE_FAILURE -* Test case Tear Down - * No required separate Test Case Tear Down for this example. - -#### TC 1.1.6 TestCase_SPI_Send_Error_invalidSendValue -* Test case Setup - * Initialize the SPI Port. -* Test Case Run - * Parameter passed: valid port, invalid sendValue, valid bufferSize - * Run SPI_Send API -* Expected return value from the API: RETCODE_FAILURE -* Test case Tear Down - * Not required separate Test Case Tear Down for this example. - -#### TC 1.2.3 TestCase_SPI_Send_Error_invalidBufferSize -* Test case Setup - * Initialize the SPI Port. -* Test Case Run - * Parameter passed: valid port, valid sendValue, invalid bufferSize - * Run SPI_Send API -* Expected return value from the API: RETCODE_FAILURE -* Test case Tear Down - * Not required separate Test Case Tear Down for this example. - -#### TC 1.2.4 TestCase_SPI_Receive_Error_invalidPort -* Test case Setup - * Initialize the SPI Port. -* Test Case Run - * Parameter passed: invalid port, valid receiveValue, valid bufferSize - * Run SPI_Receive API -* Expected return value from the API: RETCODE_FAILURE -* Test case Tear Down - * Not required separate Test Case Tear Down for this example. - -#### TC 1.2.5 TestCase_SPI_Receive_Error_invalidReceiveValue -* Test case Setup - * Initialize the SPI Port. -* Test Case Run - * Parameter passed: valid port, invalid receiveValue, valid bufferSize - * Run SPI_Receive API -* Expected return value from the API: RETCODE_FAILURE -* Test case Tear Down - * Not required separate Test Case Tear Down for this example. - -#### TC 1.2.6 TestCase_SPI_Receive_Error_invalidReceiveValue -* Test case Setup - * Initialize the SPI Port. -* Test Case Run - * Parameter passed: valid port, invalid receiveValue, valid bufferSize - * Run SPI_Receive API -* Expected return value from the API: RETCODE_FAILURE -* Test case Tear Down - * Not required separate Test Case Tear Down for this example. - -#### TC 1.2.7 TestCase_SPI_Transfer_Error_invalidPort -* Test case Setup - * Initialize the SPI Port. -* Test Case Run - * Parameter passed: invalid port, valid sendValue, valid receiveValue, valid bufferSize - * Run SPI_Receive API -* Expected return value from the API: RETCODE_FAILURE -* Test case Tear Down - * Not required separate Test Case Tear Down for this example. - -#### TC 1.2.8 TestCase_SPI_Transfer_Error_invalidSendValue -* Test case Setup - * Initialize the SPI Port. -* Test Case Run - * Parameter passed: valid port, invalid sendValue, valid receiveValue, valid bufferSize - * Run SPI_Receive API -* Expected return value from the API: RETCODE_FAILURE -* Test case Tear Down - * Not required separate Test Case Tear Down for this example. - -#### TC 1.2.9 TestCase_SPI_Transfer_Error_invalidReceiveValue -* Test case Setup - * Initialize the SPI Port. -* Test Case Run - * Parameter passed: valid port, valid sendValue, invalid receiveValue, valid bufferSize - * Run SPI_Receive API -* Expected return value from the API: RETCODE_FAILURE -* Test case Tear Down - * Not required separate Test Case Tear Down for this example. - -#### TC 1.2.10 TestCase_SPI_Transfer_Error_invalidBufferSize -* Test case Setup - * Initialize the SPI Port. -* Test Case Run - * Parameter passed: valid port, valid sendValue, valid receiveValue, invalid bufferSize - * Run SPI_Receive API -* Expected return value from the API: RETCODE_FAILURE -* Test case Tear Down - * Not required separate Test Case Tear Down for this example. - - #### TC 1.2.11 TestCase_SPI_Control_Error_invalidParameter -* Test case Setup - * Initialize the SPI Port. -* Test Case Run - * Parameter passed: valid handle, invalid control, invalid argument - * Run SPI_Control API - * Expected return value from the API: RETCODE_NOT_SUPPORTED -* Test case Tear Down - * Not required separate Test Case Tear Down for this example. - -################################################################################################################################## - -## Test Suite 1.3: functional tests -### Description -* Currently it is not possible to have functional SPI tests, because there is neither implemented bus -partner for testing nor a possibility to test the GPIO pins. Instead, the (positive tests) -functionality will be tested by testing the external flash which is connected via SPI. -That means, if flash is working, SPI is working too. But that also means, if flash does not work, -its unclear if the error is in the flash driver or in the SPI driver. diff --git a/core/essentials/test/integration/specs/UART_Test_Spec.md b/core/essentials/test/integration/specs/UART_Test_Spec.md index 818e8a36..b2762d3a 100644 --- a/core/essentials/test/integration/specs/UART_Test_Spec.md +++ b/core/essentials/test/integration/specs/UART_Test_Spec.md @@ -1,212 +1,46 @@ -# Test Entry 3: "Essentials" -## Test Suite 3.1: UART +# Test Entry 1: Essentials + +## Test Suite 1.1: UART + ### Description -* This suite aims at testing the basic functionality of the UART APIs + +This suite aims at testing the basic functionality of the MCU UART APIs. ### Setup -The test setup consists of the test coordinator and 1 test participant + +The test setup consists of the test coordinator and one (1) test participant. * Test Coordinator (on PC) * The DUT is connected to the PC via UART which is the Test Coordination Channel. The embedded C testling code is flashed onto the DUT. -### TearDown +### Teardown No special teardown ### Test Cases -#### TC 3.1.1:TestCase_Uart_getStatus -##### Setup -No special setup - -##### Run -1. Invoke the Uart_getStatus API -2. Expected return value from the API: HAL_UART_STATE_READY - -##### TearDown -No special teardown - -#### TC 3.1.2:TestCase_Uart_getVersion -##### Setup -No special setup - -##### Run -1. Invoke the Uart_getVersion API -2. API should return the version number of the UART - -##### TearDown -No special teardown - -#### TC 3.1.3:TestCase_Uart_getCapabilities -##### Setup -No special setup - -##### Run -1. Invoke the Uart_getCapabilities API -2. API should return the capabilities supported by the UART - -##### TearDown -No special teardown - - -#### TC 3.1.4:TestCase_Uart_initialize -##### Setup -1. Invoke the Uart_control API with the following parameters, - - * BCDS_Uart1 - * BCDS_UART_MODE_ASYNCHRONOUS | BCDS_UART_DATA_BITS_8 | BCDS_UART_PARITY_NONE | BCDS_UART_STOP_BITS_1 | BCDS_UART_FLOW_CONTROL_NONE - * 115200 (Baud rate) -2. Expected return value from the API: RETCODE_SUCCESS - -##### Run -1. Invoke the Uart_initialize API -2. Expected return value from the API: RETCODE_SUCCESS - -##### TearDown -1. Invoke the Uart_uninitialize API -2. Expected return value from the API: RETCODE_SUCCESS - -#### TC 3.1.5:TestCase_Uart_control -##### Setup -No special setup - -##### Run -1. Invoke the Uart_control API with the following parameters, - - * BCDS_Uart1 - * BCDS_UART_MODE_ASYNCHRONOUS | BCDS_UART_DATA_BITS_8 | BCDS_UART_PARITY_NONE | BCDS_UART_STOP_BITS_1 - * 115200 (Baud rate) -2. Expected return value from the API: RETCODE_SUCCESS - -##### TearDown -No special teardown - - -#### TC 3.1.6:TestCase_Uart_send -##### Setup -1. Invoke the Uart_control API with the following parameters, - - * BCDS_Uart1 - * BCDS_UART_MODE_ASYNCHRONOUS | BCDS_UART_DATA_BITS_8 | BCDS_UART_PARITY_NONE | BCDS_UART_STOP_BITS_1 | BCDS_UART_FLOW_CONTROL_NONE - * 115200 (Baud rate) -2. Expected return value from the API: RETCODE_SUCCESS -3. Invoke the Uart_initialize API -4. Expected return value from the API: RETCODE_SUCCESS - -##### Run -1. Invoke the Uart_send API and send the data "BikeSensor" -2. Expected return value from the API: RETCODE_SUCCESS - -##### TearDown -1. Invoke the Uart_uninitialize API -2. Expected return value from the API: RETCODE_SUCCESS +#### TC 1.1.1: Functional Test -#### TC 3.1.7:TestCase_Uart_receive ##### Setup -1. Invoke the Uart_control API with the following parameters, - * BCDS_Uart1 - * BCDS_UART_MODE_ASYNCHRONOUS | BCDS_UART_DATA_BITS_8 | BCDS_UART_PARITY_NONE | BCDS_UART_STOP_BITS_1 - * 115200 (Baud rate) -2. Expected return value from the API: RETCODE_SUCCESS -3. Invoke the Uart_initialize API -4. Expected return value from the API: RETCODE_SUCCESS +1. Get device handle of BSP initialized generic UART + * UART must be configured in loopback mode, echoing any data sent out +2. Allocate OS signal semaphore used as signal from IRQ +3. Connect the generic UART BSP +4. Initialize UART MCU with UART handle +5. Enable generic UART BSP ##### Run -1. Invoke the Uart_receive API -2. Expected return value from the API: RETCODE_FAILURE -/* @todo: Expectation is a failure because no device is sending data to the DUT UART. Beaglebone has to be integrated for validating this test case */ +1. Initiate UART receive process +2. Start send process dummy data of a few bytes size +3. Wait for send to completed + * Maximum timeout depends on baud-rate and data length +4. Expect to receive echo -##### TearDown -1. Invoke the Uart_uninitialize API -2. Expected return value from the API: RETCODE_SUCCESS - - -#### TC 3.1.8:TestCase_Uart_uninitialize -##### Setup -1. Invoke the Uart_control API with the following parameters - - * BCDS_Uart1 - * BCDS_UART_MODE_ASYNCHRONOUS | BCDS_UART_DATA_BITS_9 | BCDS_UART_PARITY_NONE | BCDS_UART_STOP_BITS_1 - * 9600 (Baud rate) -2. Expected return value from the API: RETCODE_SUCCESS -3. Invoke the Uart_initialize API -4. Expected return value from the API: RETCODE_SUCCESS - -##### Run -1. Invoke the Uart_uninitialize API -2. Expected return value from the API: RETCODE_SUCCESS - -##### TearDown -No special teardown - -#### TC 3.1.9:TestCase_Uart_powerControl_full -##### Setup -No special setup - -##### Run -1. Invoke the Uart_powerControl API with the following parameter - - * PERIPHERALS_POWER_STATE_FULL -2. Expected return value from the API: RETCODE_SUCCESS - -##### TearDown -No special teardown - -#### TC 3.1.10:TestCase_Uart_powerControl_low -##### Setup -No special setup - -##### Run -1. Invoke the Uart_powerControl API with the following parameter - - * PERIPHERALS_POWER_STATE_LOW -2. Expected return value from the API: RETCODE_FAILURE - -##### TearDown -No special teardown - -#### TC 3.1.11:Testcase_Uart_initialize_without_control -##### Setup -No special setup - -##### Run -1. Invoke the Uart_initialize API -2. Expected return value from the API:RETCODE_SUCCESS - -##### TearDown -1. Invoke the Uart_uninitialize API -2. Expected return value from the API: RETCODE_SUCCESS - -#### TC 3.1.12:Testcase_Uart_send_without_initialize -##### Setup -1. Invoke the Uart_control API with the following parameters, - - * BCDS_Uart1 - * BCDS_UART_MODE_ASYNCHRONOUS | BCDS_UART_DATA_BITS_8 | BCDS_UART_PARITY_NONE | BCDS_UART_STOP_BITS_1 | BCDS_UART_FLOW_CONTROL_NONE - * 115200 (Baud rate) -2. Expected return value from the API: RETCODE_SUCCESS - -##### Run -1. Invoke the Uart_send API and send the data "Integration testing" -2. Expected return value from the API: RETCODE_FAILURE - -##### TearDown -No special teardown - -#### TC 3.1.13:Testcase_Uart_receive_without_initialize -##### Setup -1. Invoke the Uart_control API with the following parameters, - - * BCDS_Uart1 - * BCDS_UART_MODE_ASYNCHRONOUS | BCDS_UART_DATA_BITS_8 | BCDS_UART_PARITY_NONE | BCDS_UART_STOP_BITS_1 | BCDS_UART_FLOW_CONTROL_NONE - * 115200 (Baud rate) -2. Expected return value from the API: RETCODE_SUCCESS - -##### Run -1. Invoke the Uart_receive API -2. Expected return value from the API: RETCODE_FAILURE +##### Teardown -##### TearDown -No special teardown \ No newline at end of file +1. Deinitialize UART MCU, deactivating IRQs +2. Disable generic UART BSP +3. Disconnect generic UART BSP +4. Free OS signal semaphore diff --git a/core/testing/CMakeLists.txt b/core/testing/CMakeLists.txt new file mode 100644 index 00000000..eb7afcb4 --- /dev/null +++ b/core/testing/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.6) + +project ("Kiso Testing" C) + +## Interface library +add_library(testing_int INTERFACE) +target_include_directories(testing_int +INTERFACE + include +) +target_link_libraries(testing_int INTERFACE essentials_int) + +## Enable static code analysis +# the checks will be executed as it would be on the desired compile step +if(${ENABLE_STATIC_CHECKS}) + set(CMAKE_C_CLANG_TIDY ${CLANG_TIDY} --extra-arg=--target=arm-none-eabi --extra-arg=--sysroot=${CMAKE_SYSROOT}) + set(CMAKE_CXX_CLANG_TIDY ${CLANG_TIDY} --extra-arg=--target=arm-none-eabi --extra-arg=--sysroot=${CMAKE_SYSROOT}) +endif() + +## Make sure we are only compiling them with the proper toolchain +if(${CMAKE_CROSSCOMPILING}) + + file(GLOB TESTING_SOURCES + ./source/*.c + ) + add_library(testing STATIC EXCLUDE_FROM_ALL ${TESTING_SOURCES}) + target_include_directories(testing + PUBLIC + include + PRIVATE + source/protected + ) + target_link_libraries(testing testing_int essentials utils ${KISO_OS_LIB}) + +endif(${CMAKE_CROSSCOMPILING}) + +## Add tests +if(${CMAKE_TESTING_ENABLED}) + #add_subdirectory(test) +endif() diff --git a/core/testing/include/Kiso_Testing.h b/core/testing/include/Kiso_Testing.h new file mode 100644 index 00000000..64080452 --- /dev/null +++ b/core/testing/include/Kiso_Testing.h @@ -0,0 +1,192 @@ +/********************************************************************************************************************** + * Copyright (c) 2010#2019 Robert Bosch GmbH + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl#2.0. + * + * SPDX#License#Identifier: EPL#2.0 + * + * Contributors: + * Robert Bosch GmbH # initial contribution + * + **********************************************************************************************************************/ + +/** + * @file + * @defgroup + * @ingroup + * @{ + * + * @brief This module manages the integration testing protocol and communication between the device under test + and the test coordinator + * + */ + +#ifndef KISO_TESTING_H_ +#define KISO_TESTING_H_ + +/*###################### INCLUDED HEADERS ############################################################################*/ + +#include "Kiso_Basics.h" +#include "Kiso_Retcode.h" +#include "Kiso_Assert.h" +#include "Kiso_Testing_Config.h" + +/*###################### MACROS DEFINITION ###########################################################################*/ + +/*###################### TYPE DEFINITIONS ############################################################################*/ +/** + * @brief Enumerates the internal units in the Kiso_Testing library which could return Retcode conform error + * codes. In case of error, one can refer to this enumeration to identify which source file has issued + * it. +*/ +enum KISO_TESTING_Modules_E +{ + KISO_MODULE_ID_TESTING = 1, + KISO_MODULE_ID_TESTING_TESTREGISTRY, /**< KISO_TESTS_MODULE_ID_TESTREGISTRY */ + KISO_MODULE_ID_TESTING_CCHANNEL, /**< KISO_TESTS_MODULE_ID_CCHANNEL */ + KISO_MODULE_ID_TESTING_SERIALMSGTRANSCEIVER, /**< KISO_TESTS_MODULE_ID_SERIALMSGTRANSCEIVER */ + KISO_MODULE_ID_TESTING_TESTRUNNER, /**< KISO_TESTS_MODULE_ID_TESTRUNNER */ + KISO_MODULE_ID_TESTING_SERIAL, /**< KISO_TESTS_MODULE_ID_SERIAL */ + KISO_MODULE_ID_TESTING_TESTENTRY, +}; + +/** + * @brief Enumerates the special return codes that could be returned from the different units in the + * Kiso_Testing library. +*/ +enum KISO_TESTING_Retcodes_E +{ + RETCODE_TESTING_SUITE_ALREADY_REGISTERED = RETCODE_FIRST_CUSTOM_CODE, + RETCODE_TESTING_CASE_ALREADY_REGISTERED, + RETCODE_TESTING_CCHANNEL_INITIALISATION_FAILED, + RETCODE_TESTING_INCOMPLETE_MESSAGE_RECEIVED, + RETCODE_TESTING_CRC_MISMATCH, + RETCODE_TESTING_VERSION_MISMATCH, + RETCODE_TESTING_TLVELEMENT_NOT_FOUND, + RETCODE_TESTING_REPORT_TIMEOUT, + RETCODE_TESTING_CCHANNEL_NOT_SPECIFIED, +}; + +/** + * @brief Enumerates the types of messages exchanged between the Test_Executor and the Test_Controller + */ +enum CCMsg_MessageType_E +{ + CCMSG_TYPE_COMMAND, + CCMSG_TYPE_REPORT, + CCMSG_TYPE_ACK, +}; + +/** + * @brief Encapsulates the elements composing the message header. + */ +typedef struct MessageHeader_S +{ + uint8_t messageInfo; /**< version is 2 bits, message type is 2 bits and the remaining 4 bits are reserved */ + uint8_t messageToken; + uint8_t messageType; + uint8_t errorCode; + uint8_t testEntry; + uint8_t testSuite; + uint8_t testCase; + uint8_t payloadLength; +} MsgHdr_T; + +/** + * @brief Encapsulates the elements composing a TLV object(type, length and value) + */ +typedef struct TlvElement_S +{ + uint8_t type; + uint8_t length; + char *value; +} TlvElt_T; + +/** + * @brief Encapsulates the elements composing a message.. + */ +typedef struct CCMsg_S +{ + MsgHdr_T header; /**< Header of the message */ + uint8_t payload[TEST_MAX_PAYLOAD_LENGTH]; + TlvElt_T tlvArray[CCHANNEL_MAX_NUMBER_OF_TLV_ELEMENTS]; /**< Parsed TLV array (from receive buffer) */ + uint8_t payloadIndex; + uint8_t tlvArrayIndex; + uint8_t numberOfTlvElements; /**< Number of TLV elements for the message */ + uint8_t rebootCounter; + bool isFree : 1; /**< This bit indicates whether the received message is processed by test runner or not */ +} CCMsg_T; + +/** + * @brief Defines a prototype type for the setup functions of the test suites and test cases. + */ +typedef Retcode_T (*SetupFct_T)(CCMsg_T *ccmsg); + +/** + * @brief Defines a prototype type for the tear down functions of the test suites and test cases. + */ +typedef Retcode_T (*TearDownFct_T)(CCMsg_T *ccmsg); + +/** + * @brief Sefines a prototype type for the run functions of the test cases. + */ +typedef void (*RunFct_T)(CCMsg_T *ccmsg); + +/*###################### EXPORTED FUNCTIONS PROTOTYPES ###############################################################*/ + +/** + * @brief Initializes the Testing Framework. + * @details this + * @param[in] eId Id of the Test Entry + * @return RETCODE_OK if initialized successfully error code otherwise + */ +Retcode_T Tests_Initialize(uint8_t eId, SetupFct_T setup, TearDownFct_T teardown); + +/** + * @brief Registers a Test Suite + * @details todo mak explain what the function does currently + * @param[in] sId The identifier of the TestSuite to register + * @param[in] setup A reference to the setup function of the TestSuite + * @param[in] teardown A reference to the tear down function of the TestSuite + * @note setup and tear down functions pointers can be null if nothing has to be done. + * @return RETCODE_OK in case of success, error code otherwise. + */ +Retcode_T Tests_RegisterTestSuite(uint8_t sId, SetupFct_T setup, TearDownFct_T teardown); + +/** + * @brief Registers a Test Case + * @details todo mak explain what the function does + * @param[in] sId identifier of the Test Suite the test to register + * @param[in] cId identifier of the Test Case to register + * @param[in] setup A reference to the setup function of the Test Suite + * @param[in] run A reference to the run function of the Test Suite + * @param[in] teardown A reference to the tear down function of the Test Suite + * @note setup and tear down functions pointers can be null if nothing has to be done. + * @return RETCODE_OK in case of success, error code otherwise. + */ +Retcode_T Tests_RegisterTestCase(uint8_t sId, uint8_t cId, SetupFct_T setup, RunFct_T run, TearDownFct_T teardown); + +/** + * @brief Sends a result of a test case execution. + * @details todo mak explain what the function does + * @param[in] result The test result code (0: success / otherwise: failure) + * @param[in] reason A 0-terminating string stating a reason. It can be NULL, if no reason should be sent. + */ +void Tests_SendReport(uint8_t result, char *reason); + +/** + * @brief Gets a tlv element using the type of the tlvElement input + * @details todo mak explain what the function does + * @param[in] ccmsg A reference to the message in which to look for the element + * @param[in,out] tlvElement A reference to where to store the element if found. + * tlvElement->type is used as input to find the element's value + * @return RETCODE_OK in case of success, error code otherwise. + * todo mak: make explicit the type search. interface is hiding information. + */ +Retcode_T Tests_GetTlvElement(CCMsg_T *ccmsg, TlvElt_T *tlvElement); + +#endif /* KISO_TESTING_H_ */ + +/** @} */ diff --git a/core/testing/include/Kiso_Testing_Config.h b/core/testing/include/Kiso_Testing_Config.h new file mode 100644 index 00000000..8e91d272 --- /dev/null +++ b/core/testing/include/Kiso_Testing_Config.h @@ -0,0 +1,54 @@ +/*----------------------------------------------------------------------------*/ +/* + * Copyright (C) Bosch Connected Devices and Solutions GmbH. + * All Rights Reserved. Confidential. + * + * Distribution only to people who need to know this information in + * order to do their job.(Need-to-know principle). + * Distribution to persons outside the company, only if these persons + * signed a non-disclosure agreement. + * Electronic transmission, e.g. via electronic mail, must be made in + * encrypted form. + */ +/*----------------------------------------------------------------------------*/ + +/** + * @file Add a brief description here. + * + * Put here the documentation of this header file. Explain the interface exposed + * by this header, e.g. what is the purpose of use, how to use it, etc. + */ + +#ifndef KISO_TESTING_CONFIG_H +#define KISO_TESTING_CONFIG_H + +#ifndef TEST_RUNNER_TASK_PRIO +#define TEST_RUNNER_TASK_PRIO 2 +#endif + +#ifndef TEST_RUNNER_TASK_STACK_DEPTH +#define TEST_RUNNER_TASK_STACK_DEPTH 1024 +#endif + +#ifndef TEST_RUNNER_QUEUE_SIZE +#define TEST_RUNNER_QUEUE_SIZE 5U +#endif + +#ifndef TEST_MAX_NUMBER_OF_TEST_SUITES +#define TEST_MAX_NUMBER_OF_TEST_SUITES 16 +#endif + +/** Macros defining the maximum number of Test Cases per Test Suite */ +#ifndef TEST_MAX_NUMBER_OF_TEST_CASES_PER_TEST_SUITE +#define TEST_MAX_NUMBER_OF_TEST_CASES_PER_TEST_SUITE 16 +#endif + +#ifndef CCHANNEL_MAX_NUMBER_OF_TLV_ELEMENTS +#define CCHANNEL_MAX_NUMBER_OF_TLV_ELEMENTS 2 +#endif + +#ifndef TEST_MAX_PAYLOAD_LENGTH +#define TEST_MAX_PAYLOAD_LENGTH 248U +#endif + +#endif /* KISO_TESTING_CONFIG_H */ diff --git a/core/testing/source/CChannel.c b/core/testing/source/CChannel.c new file mode 100644 index 00000000..ba864be6 --- /dev/null +++ b/core/testing/source/CChannel.c @@ -0,0 +1,312 @@ +/******************************************************************************* + * Copyright (c) 2010-2020 Robert Bosch GmbH + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Robert Bosch GmbH - initial contribution + * + ******************************************************************************/ + +/** + * @file + * + * @brief + * This module is responsible for the transmission and reception of data through + * the communication medium, which can be UART / UDP / BLE and so on. + */ + +#include "Kiso_Testing.h" +#include "CChannel.h" +#include "TestRunner.h" +#include "SerialCChannel.h" +#include "SerialMsgTransceiver.h" + +#undef KISO_MODULE_ID +#define KISO_MODULE_ID KISO_MODULE_ID_TESTING_CCHANNEL + +#define MAX_NUMBER_OF_INCOMING_MESSAGE 2 + +#define CCHANNEL_TLV_TYPE_REASON 112 + +#define CCHANNEL_REPORT_TYPE 110 + +#define CCHANNEL_NUM_OF_SEND_RETRIES 4 + +#define MSG_INIT_OK ("CCHANNEL INIT OK\r\n") + +static CCMsg_T *allocCCMessage(void); +static Retcode_T sendMessage(CCMsg_T *ccmsg); +static void parseTlvElements(CCMsg_T *ccmsg); +static void freeAllCCMsg(void); + +static CCMsg_T msgPool[MAX_NUMBER_OF_INCOMING_MESSAGE]; +static CCMsg_T ackMessage; +static CCMsg_T reportMessage; + +Retcode_T CChannel_Initialize(void) +{ + freeAllCCMsg(); + Retcode_T retcode = Serial_Initialize(); + + if (RETCODE_OK == retcode) + { + char msg[sizeof(MSG_INIT_OK)] = MSG_INIT_OK; + retcode = Serial_Send((void *)msg, strlen(msg)); + } + return retcode; +} + +Retcode_T CChannel_Deinitialize(void) +{ + return Serial_Deinitialize(); +} + +void CChannel_FreeCCMsg(CCMsg_T *ccmsg) +{ + (void)memset(ccmsg, 0, sizeof(CCMsg_T)); + + ccmsg->isFree = true; +} + +void CChannel_ReceiveEventHandler(uint8_t *buffer, uint8_t length) +{ + if (CCMSG_VERSION != ((buffer[0] & CCMSG_VERSION_MASK) >> CCMSG_VERSION_SHIFT)) + { + //if the framework version does not match we just ignore this message + return; + } + + CCMsg_T *ccmsg = allocCCMessage(); + + if (NULL == ccmsg) + { + Retcode_RaiseError(RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_OUT_OF_RESOURCES)); + return; + } + + (void)memcpy(ccmsg, buffer, length); + + parseTlvElements(ccmsg); + + TestRunner_ProcessMessage(ccmsg); +} + +void CChannel_PrepareAck(CCMsg_T *ccmsg) +{ + (void)memset(&ackMessage, 0, sizeof(CCMsg_T)); + + (void)memcpy(&ackMessage, ccmsg, CCHANNEL_HEADER_LENGTH); + + ackMessage.header.messageInfo = CCMSG_CREATE_TYPE(CCHANNEL_MSG_TYPE_ACK); + ackMessage.header.payloadLength = 0; +} + +Retcode_T CChannel_SendAck(uint8_t result) +{ + ackMessage.header.errorCode = result; + + assert(ackMessage.header.messageInfo == CCMSG_CREATE_TYPE(CCHANNEL_MSG_TYPE_ACK)); + assert(ackMessage.header.payloadLength == 0); + + return sendMessage(&ackMessage); +} + +Retcode_T CChannel_ResendAck(void) +{ + return sendMessage(&ackMessage); +} + +void CChannel_PrepareReport(CCMsg_T *ccmsg) +{ + (void)memset(&reportMessage, 0, sizeof(CCMsg_T)); + + (void)memcpy(&reportMessage, ccmsg, CCHANNEL_HEADER_LENGTH); + + reportMessage.header.messageType = CCHANNEL_REPORT_TYPE; + reportMessage.header.messageInfo = CCMSG_CREATE_TYPE(CCHANNEL_MSG_TYPE_REPORT); + reportMessage.header.payloadLength = 0; +} + +Retcode_T CChannel_SendReport(uint8_t result, char *reason) +{ + Retcode_T retcode = RETCODE_OK; + + reportMessage.header.errorCode = result; + + assert(reportMessage.header.payloadLength == 0); + + if (NULL != reason) + { + TlvElt_T reasonTlv; + reasonTlv.type = CCHANNEL_TLV_TYPE_REASON; + reasonTlv.length = strlen(reason); + reasonTlv.value = reason; + + retcode = CChannel_AddTlvElement(&reportMessage, &reasonTlv); + + if ((strlen(reason) + 2) != reportMessage.header.payloadLength) + { + return RETCODE(RETCODE_SEVERITY_WARNING, (uint32_t)RETCODE_UNEXPECTED_BEHAVIOR); + } + } + + assert(reportMessage.header.messageInfo == CCMSG_CREATE_TYPE(CCHANNEL_MSG_TYPE_REPORT)); + + if (RETCODE_OK == retcode) + { + retcode = sendMessage(&reportMessage); + } + + return retcode; +} + +Retcode_T CChannel_ResendReport(void) +{ + Retcode_T retcode = RETCODE_OK; + + retcode = sendMessage(&reportMessage); + + return retcode; +} + +bool CChannel_DoesAckMatchReport(CCMsg_T *ccack) +{ + bool result = true; + MsgHdr_T msgHdr = reportMessage.header; + MsgHdr_T ackHdr = ccack->header; + + if ((ackHdr.messageToken != msgHdr.messageToken) || (ackHdr.testEntry != msgHdr.testEntry) || (ackHdr.testSuite != msgHdr.testSuite) || (ackHdr.testCase != msgHdr.testCase)) + { + result = false; + } + + return result; +} + +Retcode_T CChannel_GetTlvElement(CCMsg_T *ccmsg, TlvElt_T *tlvElement) +{ + if ((NULL == ccmsg) || (NULL == tlvElement)) + { + return RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_INVALID_PARAM); + } + else + { + for (uint32_t i = 0; i < ccmsg->numberOfTlvElements; i++) + { + if (tlvElement->type == ccmsg->tlvArray[i].type) + { + if (NULL == ccmsg->tlvArray[i].value) + { + return RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_NULL_POINTER); + } + + tlvElement->value = ccmsg->tlvArray[i].value; + tlvElement->length = ccmsg->tlvArray[i].length; + return RETCODE_OK; + } + } + } + return RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_TESTING_TLVELEMENT_NOT_FOUND); +} + +Retcode_T CChannel_AddTlvElement(CCMsg_T *ccmsg, TlvElt_T *tlvElement) +{ + if ((NULL == ccmsg) || (NULL == tlvElement) || (NULL == tlvElement->value)) + { + return (RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t)RETCODE_NULL_POINTER)); + } + else + { + + if (CCHANNEL_MAX_NUMBER_OF_TLV_ELEMENTS == ccmsg->numberOfTlvElements) + { + //we allow only 20 TLV elements in a message + return RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t)RETCODE_OUT_OF_RESOURCES); + } + + if (CCHANNEL_PAYLOAD_MAX_SIZE <= (ccmsg->payloadIndex + 2 + tlvElement->length)) + { + //we allow only 248 as the maximum paylaod size + return RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t)RETCODE_OUT_OF_RESOURCES); + } + + TlvElt_T *currentTlvElement = &ccmsg->tlvArray[ccmsg->numberOfTlvElements]; + + currentTlvElement->type = tlvElement->type; + ccmsg->payload[ccmsg->payloadIndex++] = tlvElement->type; + currentTlvElement->length = tlvElement->length; + ccmsg->payload[ccmsg->payloadIndex++] = tlvElement->length; + + currentTlvElement->value = (char *)&(ccmsg->payload[ccmsg->payloadIndex]); + (void)memcpy(&ccmsg->payload[ccmsg->payloadIndex], tlvElement->value, tlvElement->length); + + ccmsg->payloadIndex += tlvElement->length; + + ccmsg->header.payloadLength += tlvElement->length + 2; + ccmsg->numberOfTlvElements++; + + return RETCODE_OK; + } +} + +static CCMsg_T *allocCCMessage(void) +{ + CCMsg_T *ccmsg = NULL; + + for (uint8_t i = 0; i < MAX_NUMBER_OF_INCOMING_MESSAGE; i++) + { + if (msgPool[i].isFree) + { + ccmsg = &msgPool[i]; + ccmsg->isFree = false; + break; + } + } + + return ccmsg; +} + +static Retcode_T sendMessage(CCMsg_T *ccmsg) +{ + Retcode_T retcode = RETCODE_OK; + uint32_t retries = CCHANNEL_NUM_OF_SEND_RETRIES; + do + { + retcode = SerialMsgTransceiver_Send((uint8_t *)ccmsg, CCHANNEL_HEADER_LENGTH + ccmsg->header.payloadLength); + retries--; + } while (retries > 0 && RETCODE_OK != retcode); + + return retcode; +} + +static void parseTlvElements(CCMsg_T *ccmsg) +{ + for (uint8_t i = 0; i < ccmsg->header.payloadLength;) + { + if (ccmsg->numberOfTlvElements == CCHANNEL_MAX_NUMBER_OF_TLV_ELEMENTS) + { + return; + } + + ccmsg->tlvArray[ccmsg->numberOfTlvElements].type = ccmsg->payload[i++]; + ccmsg->tlvArray[ccmsg->numberOfTlvElements].length = ccmsg->payload[i++]; + ccmsg->tlvArray[ccmsg->numberOfTlvElements].value = (char *)&(ccmsg->payload[i]); + i += ccmsg->tlvArray[ccmsg->numberOfTlvElements].length; + ccmsg->numberOfTlvElements++; + } +} + +static void freeAllCCMsg(void) +{ + (void)memset(msgPool, 0, sizeof(msgPool)); + + for (uint32_t i = 0; i < MAX_NUMBER_OF_INCOMING_MESSAGE; i++) + { + msgPool[i].isFree = true; + } +} diff --git a/core/testing/source/Serial.c b/core/testing/source/Serial.c new file mode 100644 index 00000000..d399bfba --- /dev/null +++ b/core/testing/source/Serial.c @@ -0,0 +1,219 @@ +/********************************************************************************************************************** + * Copyright (c) 2010#2019 Robert Bosch GmbH + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl#2.0. + * + * SPDX#License#Identifier: EPL#2.0 + * + * Contributors: + * Robert Bosch GmbH # initial contribution + * + **********************************************************************************************************************/ + +/** + * @file + * + * @brief + * todo add brief description Implements the following functionalities specified in template.h + */ +/*###################### INCLUDED HEADERS ###########################################################################*/ + +#include "Kiso_Testing.h" +#include "Kiso_Testing_Config.h" +#include "Kiso_BSP_TestInterface.h" +#include "Kiso_MCU_UART.h" +#include "Kiso_GuardedTask.h" +#include "Kiso_RingBuffer.h" +#include "FreeRTOS.h" +#include "semphr.h" +#include "SerialMsgTransceiver.h" +#include "SerialCChannel.h" + +/*###################### MACROS DEFINITION ##########################################################################*/ +#undef KISO_MODULE_ID +#define KISO_MODULE_ID KISO_MODULE_ID_TESTING_SERIAL + +#define WAIT_TIME_FOR_SINGLE_UART_TRANSMISSION UINT32_C(500) + +#define MAX_BUFFER_SIZE UINT16_C(300) + +#ifndef SERIAL_TASK_PRIO +#define SERIAL_TASK_PRIO (1UL) +#endif /* SERiAL_TASK_PRIO */ + +#ifndef SERIAL_TASK_STACK_DEPTH +#define SERIAL_TASK_STACK_DEPTH (128UL) +#endif /* SERIAL_TASK_STACK_DEPTH */ + +/*###################### LOCAL_TYPES DEFINITION #####################################################################*/ + +/*###################### LOCAL FUNCTIONS DECLARATION ################################################################*/ + +static void uartEventsCallbackFunc(UART_T uart, struct MCU_UART_Event_S event); + +/*###################### VARIABLES DECLARATION ######################################################################*/ + +static GuardedTask_T serialGuardedTask; +volatile uint32_t serialReceivedCnt = 0; +static SemaphoreHandle_t TransmitDataSemaphoreHandle = NULL; +static RingBuffer_T serialRingBuffer; +static uint8_t serialBuffer[MAX_BUFFER_SIZE]; +static uint8_t RxBuffer; +static UART_T TestInterfaceUart; +#ifndef NDEBUG +volatile uint32_t TestUartErrorCount = 0; /* number of errors post mortem */ +#endif /* NDEBUG */ + +/*###################### EXPOSED FUNCTIONS IMPLEMENTATION ###########################################################*/ + +/* The description is defined at function declaration */ +Retcode_T Serial_Initialize(void) +{ + Retcode_T rc = RETCODE_OK; + + rc = BSP_TestInterface_Connect(); + if (RETCODE_OK == rc) + { + TestInterfaceUart = (UART_T)BSP_TestInterface_GetUARTHandle(); + if (NULL == TestInterfaceUart) + { + rc = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_NULL_POINTER); + } + } + + if (RETCODE_OK == rc) + { + rc = MCU_UART_Initialize(TestInterfaceUart, uartEventsCallbackFunc); + } + + if (RETCODE_OK == rc) + { + rc = BSP_TestInterface_Enable(); + } + + if (RETCODE_OK == rc) + { + rc = GuardedTask_Initialize(&serialGuardedTask, SerialMsgTransceiver_Receive, "SERIAL_TASK", SERIAL_TASK_PRIO, SERIAL_TASK_STACK_DEPTH); + } + + if (RETCODE_OK == rc) + { + TransmitDataSemaphoreHandle = xSemaphoreCreateBinary(); + if (NULL == TransmitDataSemaphoreHandle) + { + rc = RETCODE(RETCODE_SEVERITY_WARNING, (uint32_t)RETCODE_OUT_OF_RESOURCES); + } + } + + if (RETCODE_OK == rc) + { + RingBuffer_Initialize(&serialRingBuffer, serialBuffer, MAX_BUFFER_SIZE); + } + + if (RETCODE_OK == rc) + { + /* start the receive process, this will enable UART interrupts and trigger a callback on receive */ + rc = MCU_UART_Receive(TestInterfaceUart, &RxBuffer, 1UL); + } + + return (rc); +} + +Retcode_T Serial_Deinitialize(void) +{ + Retcode_T rc = MCU_UART_Deinitialize(TestInterfaceUart); + if (RETCODE_OK == rc) + { + rc = BSP_TestInterface_Disable(); + } + + if (RETCODE_OK == rc) + { + rc = BSP_TestInterface_Disconnect(); + } + + if (RETCODE_OK == rc) + { + rc = GuardedTask_Deinitialize(&serialGuardedTask); + } + return rc; +} + +Retcode_T Serial_Send(void *data, uint32_t len) +{ + Retcode_T retCode; + retCode = MCU_UART_Send(TestInterfaceUart, (uint8_t *)data, len); + + if (RETCODE_OK == retCode) + { + /* Waiting here for the transmit complete event */ + if (pdTRUE != xSemaphoreTake(TransmitDataSemaphoreHandle, (WAIT_TIME_FOR_SINGLE_UART_TRANSMISSION / portTICK_RATE_MS))) + { + retCode = RETCODE(RETCODE_SEVERITY_WARNING, (uint32_t)RETCODE_SEMAPHORE_ERROR); + } + } + + return (retCode); +} + +Retcode_T Serial_Receive(void *data, uint32_t len) +{ + uint32_t numberOfReadBytes = 0; + Retcode_T retcode = RETCODE_OK; + + numberOfReadBytes = RingBuffer_Read(&serialRingBuffer, (uint8_t *)data, len); + + if (numberOfReadBytes != len) + { + retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_UNEXPECTED_BEHAVIOR); + } + + return retcode; +} + +/*###################### LOCAL FUNCTIONS IMPLEMENTATION #############################################################*/ + +static void uartEventsCallbackFunc(UART_T uart, struct MCU_UART_Event_S event) +{ + KISO_UNUSED(uart); /* not used in One-Byte-Mode */ + + Retcode_T retcode = RETCODE_OK; + + /* Signal the guarded task to indicate that the receive is complete */ + if (event.RxComplete) + { + serialReceivedCnt++; + + if (1UL == RingBuffer_Write(&serialRingBuffer, (uint8_t *)&RxBuffer, 1UL)) + { + (void)GuardedTask_SignalFromIsr(&serialGuardedTask); + } + } + else if (event.TxComplete) + { + portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; + + if (pdTRUE == xSemaphoreGiveFromISR(TransmitDataSemaphoreHandle, &xHigherPriorityTaskWoken)) + { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + else + { + /* ignore... semaphore has already been given */ + } + } + else if (event.RxError) + { + retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_FAILURE); + } + else if (event.TxError) + { + retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_FAILURE); + } + if (RETCODE_OK != retcode) + { + Retcode_RaiseErrorFromIsr(retcode); + } +} \ No newline at end of file diff --git a/core/testing/source/SerialMsgTransceiver.c b/core/testing/source/SerialMsgTransceiver.c new file mode 100644 index 00000000..147b7fce --- /dev/null +++ b/core/testing/source/SerialMsgTransceiver.c @@ -0,0 +1,258 @@ +/******************************************************************************* + * Copyright (c) 2010-2020 Robert Bosch GmbH + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Robert Bosch GmbH - initial contribution + * + ******************************************************************************/ + +/** + * @file + * + * @brief + * Implements the following functionalities specified in template.h + */ +#include "Kiso_Testing.h" +#include "SerialMsgTransceiver.h" +#include "SerialCChannel.h" +#include "CChannel.h" +#include "Kiso_GuardedTask.h" +#include + +#undef KISO_MODULE_ID +#define KISO_MODULE_ID KISO_MODULE_ID_TESTING_SERIALMSGTRANSCEIVER + +#define PAYLOAD_LENGTH_INDEX 7 +#define RECEIVE_BUFFER_SIZE 256 + +#define START 0xC0 +#define ESC 0xDB +#define ESC_START 0xDC +#define ESC_ESC 0xDD + +#define CRC_DEFAULT UINT8_C(0) +#define CRC_BIT_SHIFT_4 UINT16_C(4) /** 4 bit shifting for CRC calculation */ +#define CRC_BIT_SHIFT_5 UINT16_C(5) /** 5 bit shifting for CRC calculation */ +#define CRC_BIT_SHIFT_8 UINT16_C(8) /** 8 bit shifting for CRC calculation */ +#define CRC_BIT_SHIFT_12 UINT16_C(12) /** 12 bit shifting for CRC calculation */ +#define CRC_INIT_VALUE UINT16_C(0) /** Default Initialize value for flag */ +#define CRC_BYTE_MASK UINT16_C(0xFF) + +enum Receiver_State_E +{ + WAITING_FOR_START, + RECEIVING_HEADER, + RECEIVING_PAYLOAD, + RECEIVED_DONE +}; + +static uint16_t calculateCRC(const void *buffer, uint8_t length); + +static uint8_t receiveBuffer[RECEIVE_BUFFER_SIZE]; +static uint32_t serialConsumedCnt = 0; /* number of characters received */ +static uint32_t msgCnt = 0; /* diagnostic: number of messages received */ +static uint32_t msgOK = 0; /* diagnostic: number of messages received */ +static uint32_t msgNOK = 0; /* diagnostic: number of messages received */ + +Retcode_T SerialMsgTransceiver_Send(uint8_t *message, uint8_t length) +{ + Retcode_T ReturnValue; + uint8_t sendBuffer[length * 2]; //todo variable length array dangerous + uint8_t j = 0; + + uint16_t crc = calculateCRC(message, length); + + sendBuffer[j++] = START; + + if (((crc >> CHAR_BIT) & 0xFF) == START) + { + sendBuffer[j++] = ESC; + sendBuffer[j++] = ESC_START; + } + else if (((crc >> CHAR_BIT) & 0xFF) == ESC) + { + sendBuffer[j++] = ESC; + sendBuffer[j++] = ESC_ESC; + } + else + { + sendBuffer[j++] = (crc >> CHAR_BIT) & 0xFF; + } + + if ((crc & 0xFF) == START) + { + sendBuffer[j++] = ESC; + sendBuffer[j++] = ESC_START; + } + else if ((crc & 0xFF & 0xFF) == ESC) + { + sendBuffer[j++] = ESC; + sendBuffer[j++] = ESC_ESC; + } + else + { + sendBuffer[j++] = crc & 0xFF; + } + + for (uint32_t i = 0; i < length; i++) + { + if (message[i] == START) + { + sendBuffer[j++] = ESC; + sendBuffer[j++] = ESC_START; + } + else if (message[i] == ESC) + { + sendBuffer[j++] = ESC; + sendBuffer[j++] = ESC_ESC; + } + else + { + sendBuffer[j++] = message[i]; + } + } + + ReturnValue = Serial_Send(sendBuffer, j); + + return (ReturnValue); +} + +//@todo dei9bue: verify total length, limited to 256! what to do if exceeded? +/* The description is defined at function declaration */ +void SerialMsgTransceiver_Receive(void) +{ + static uint8_t receivingState = WAITING_FOR_START; + static uint8_t receivedByte; + static uint8_t nReceivedByte = 0; + static uint8_t payloadLength = 0; + static bool receivedEsc = false; + static uint8_t testCnt = 0; + + /* The serialReceivedCnt is incremented with every received byte in the ISR + The difference betweeb the serialReceivedCnt and serialConsumedCnt repflects the number of bytes available in the buffer + We consume characters while the difference is > 0 + There is no need to check overflows since both numbers are of uint32_t and the result will always state the difference. + */ + while ((serialReceivedCnt - serialConsumedCnt) > 0) + { + if (RETCODE_OK != Serial_Receive((uint8_t *)&receivedByte, UINT32_C(1))) + { + Retcode_RaiseError(RETCODE(RETCODE_SEVERITY_WARNING, RETCODE_FAILURE)); + return; + } + serialConsumedCnt++; + + if (WAITING_FOR_START == receivingState) + { + if (START == receivedByte) + { + nReceivedByte = 0; + (void)memset(receiveBuffer, 0, sizeof(receiveBuffer)); + receivingState = RECEIVING_HEADER; + } + } + else + { + if (START == receivedByte) + { + Retcode_RaiseError(RETCODE(RETCODE_SEVERITY_WARNING, RETCODE_TESTING_INCOMPLETE_MESSAGE_RECEIVED)); + nReceivedByte = 0; + (void)memset(receiveBuffer, 0, sizeof(receiveBuffer)); + msgNOK++; + receivingState = RECEIVING_HEADER; + } + else if (receivedEsc) + { + receivedEsc = false; + if (ESC_START == receivedByte) + { + receiveBuffer[nReceivedByte++] = START; + } + else if (ESC_ESC == receivedByte) + { + receiveBuffer[nReceivedByte++] = ESC; + } + else + { + // error should not happen + Retcode_RaiseError(RETCODE(RETCODE_SEVERITY_WARNING, RETCODE_INCONSITENT_STATE)); + receivingState = WAITING_FOR_START; + } + } + else if (ESC == receivedByte) + { + receivedEsc = true; + } + else + { + receiveBuffer[nReceivedByte++] = receivedByte; + } + + if (RECEIVING_HEADER == receivingState) + { + if (CCHANNEL_HEADER_LENGTH + 2 == nReceivedByte) + { + payloadLength = receiveBuffer[PAYLOAD_LENGTH_INDEX + 2]; + + if (0 == payloadLength) + { + receivingState = RECEIVED_DONE; + } + else + { + receivingState = RECEIVING_PAYLOAD; + } + } + } + else if (RECEIVING_PAYLOAD == receivingState) + { + if (payloadLength + CCHANNEL_HEADER_LENGTH + 2 == nReceivedByte) + { + receivingState = RECEIVED_DONE; + } + } + } + } + + if (RECEIVED_DONE == receivingState) + { + uint16_t calculatedCRC = calculateCRC(&receiveBuffer[2], CCHANNEL_HEADER_LENGTH + payloadLength); + uint16_t expectedCRC = ((receiveBuffer[0] & CRC_BYTE_MASK) << CHAR_BIT) + (receiveBuffer[1] & CRC_BYTE_MASK); + + msgCnt++; + if (calculatedCRC == expectedCRC) + { + CChannel_ReceiveEventHandler(&receiveBuffer[2], CCHANNEL_HEADER_LENGTH + payloadLength); + receivingState = WAITING_FOR_START; + msgOK++; + } + else + { + Retcode_RaiseError(RETCODE(RETCODE_SEVERITY_WARNING, RETCODE_TESTING_CRC_MISMATCH)); + receivingState = WAITING_FOR_START; + msgNOK++; + } + testCnt++; + } +} + +static uint16_t calculateCRC(const void *buffer, uint8_t length) +{ + uint16_t crc = CRC_DEFAULT; + + for (uint8_t i = 0; i < length; i++) + { + crc = (crc >> (CRC_BIT_SHIFT_8)) | (crc << (CRC_BIT_SHIFT_8)); + crc ^= ((const uint8_t *)buffer)[i]; + crc ^= (crc & (CRC_BYTE_MASK)) >> (CRC_BIT_SHIFT_4); + crc ^= crc << (CRC_BIT_SHIFT_12); + crc ^= (crc & (CRC_BYTE_MASK)) << (CRC_BIT_SHIFT_5); + } + return crc; +} diff --git a/core/testing/source/TestRegistry.c b/core/testing/source/TestRegistry.c new file mode 100644 index 00000000..71a32c60 --- /dev/null +++ b/core/testing/source/TestRegistry.c @@ -0,0 +1,339 @@ +/********************************************************************************************************************** + * Copyright (c) 2010#2019 Robert Bosch GmbH + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl#2.0. + * + * SPDX#License#Identifier: EPL#2.0 + * + * Contributors: + * Robert Bosch GmbH # initial contribution + * + **********************************************************************************************************************/ + +/** + * @file + * + * @brief + */ +/*###################### INCLUDED HEADERS ############################################################################*/ + +#include "Kiso_Testing.h" +#include "TestRegistry.h" + +/*###################### MACROS DEFINITION ###########################################################################*/ + +#undef KISO_MODULE_ID +#define KISO_MODULE_ID KISO_MODULE_ID_TESTING_TESTREGISTRY + +/*###################### LOCAL_TYPES DEFINITION ######################################################################*/ + +/*###################### LOCAL FUNCTIONS DECLARATION #################################################################*/ + +static TstSte_T *lookupTestSuite(uint8_t sId); +static TstCse_T *lookupTestCase(TstSte_T *testSuite, uint8_t cId); + +/*###################### VARIABLES DECLARATION #######################################################################*/ + +static TstEnt_T testEntry; + +/*###################### EXPOSED FUNCTIONS IMPLEMENTATION ############################################################*/ + +/* @see TestRegistry.h for function description */ +void TestRegistry_Initialize(uint8_t eId, SetupFct_T setup, TearDownFct_T teardown) +{ + (void)memset(&testEntry, 0, sizeof(TstEnt_T)); + + testEntry.id = eId; + testEntry.setup = setup; + testEntry.teardown = teardown; +} + +/* @see TestRegistry.h for function description */ +Retcode_T TestRegistry_RegisterTestSuite(uint8_t sId, SetupFct_T setup, TearDownFct_T teardown) +{ + if (TEST_MAX_NUMBER_OF_TEST_SUITES <= testEntry.numTestSuites) + { + return RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t)RETCODE_OUT_OF_RESOURCES); + } + + TstSte_T *suite = lookupTestSuite(sId); + + if (NULL != suite) + { + /* The test suite with the given ID is already registered */ + return RETCODE(RETCODE_SEVERITY_WARNING, (uint32_t)RETCODE_TESTING_SUITE_ALREADY_REGISTERED); + } + + suite = &testEntry.testSuites[testEntry.numTestSuites]; + testEntry.numTestSuites++; + + suite->id = sId; + suite->setup = setup; + suite->teardown = teardown; + + return RETCODE_OK; +} + +/* @see TestRegistry.h for function description */ +Retcode_T TestRegistry_RegisterTestCase(uint8_t sId, uint8_t cId, SetupFct_T setup, RunFct_T run, TearDownFct_T teardown) +{ + if (NULL == run) + { + return RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t)RETCODE_INVALID_PARAM); + } + + TstSte_T *suite = lookupTestSuite(sId); + + if (NULL == suite) + { + /* The suite is not found */ + return RETCODE(RETCODE_SEVERITY_WARNING, (uint32_t)RETCODE_INVALID_PARAM); + } + + if (TEST_MAX_NUMBER_OF_TEST_CASES_PER_TEST_SUITE <= suite->numTestCases) + { + return RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t)RETCODE_OUT_OF_RESOURCES); + } + + TstCse_T *testCase = lookupTestCase(suite, cId); + + if (NULL != testCase) + { + /* A test case with the given ID is already registered */ + return RETCODE(RETCODE_SEVERITY_WARNING, (uint32_t)RETCODE_TESTING_CASE_ALREADY_REGISTERED); + } + + testCase = &suite->testCases[suite->numTestCases]; + suite->numTestCases++; + + testCase->id = cId; + testCase->setup = setup; + testCase->run = run; + testCase->teardown = teardown; + + return RETCODE_OK; +} + +/* @see TestRegistry.h for function description */ +TstEnt_T *TestRegistry_LookupTestEntry(uint8_t eId) +{ + TstEnt_T *theTestEntry = NULL; + + if (eId == testEntry.id) + { + theTestEntry = &testEntry; + } + + return theTestEntry; +} + +/* @see TestRegistry.h for function description */ +TstSte_T *TestRegistry_LookupTestSuite(uint8_t eId, uint8_t sId) +{ + TstSte_T *testSuite = NULL; + + if (eId == testEntry.id) + { + testSuite = lookupTestSuite(sId); + } + + return testSuite; +} + +/* @see TestRegistry.h for function description */ +TstCse_T *TestRegistry_LookupTestCase(uint8_t eId, uint8_t sId, uint8_t cId) +{ + TstSte_T *testSuite = TestRegistry_LookupTestSuite(eId, sId); + TstCse_T *testCase = NULL; + + if (NULL != testSuite) + { + testCase = lookupTestCase(testSuite, cId); + } + + return testCase; +} + +/* @see TestRegistry.h for function description */ +Retcode_T TestEntry_Setup(TstEnt_T *theTestEntry, CCMsg_T *ccmsg) +{ + + Retcode_T retcode = RETCODE_OK; + if ((NULL == theTestEntry) || (NULL == ccmsg)) + { + /* The suite is not found */ + retcode = RETCODE(RETCODE_SEVERITY_WARNING, (uint32_t)RETCODE_NULL_POINTER); + return (retcode); + } + + /* If test section setup pointer are null, it means that there is nothing to be done and that we can just send an + Acknowledgement with status OK.*/ + if (NULL != theTestEntry->setup) + { + retcode = theTestEntry->setup(ccmsg); + } + return retcode; +} + +/* @see TestRegistry.h for function description */ +Retcode_T TestEntry_Teardown(TstEnt_T *theTestEntry, CCMsg_T *ccmsg) +{ + + Retcode_T retcode = RETCODE_OK; + + if ((NULL == theTestEntry) || (NULL == ccmsg)) + { + /* The suite is not found */ + retcode = RETCODE(RETCODE_SEVERITY_WARNING, (uint32_t)RETCODE_NULL_POINTER); + return (retcode); + } + + /* + If test section teardown pointer are null, it means that there is nothing to be done and that we can just send an + Acknowledgement with status OK.*/ + if (NULL != theTestEntry->teardown) + { + retcode = theTestEntry->teardown(ccmsg); + } + return retcode; +} + +/* @see TestRegistry.h for function description */ +Retcode_T TestSuite_Setup(TstSte_T *testSuite, CCMsg_T *ccmsg) +{ + + Retcode_T retcode = RETCODE_OK; + + if ((NULL == testSuite) || (NULL == ccmsg)) + { + /* The suite is not found */ + retcode = RETCODE(RETCODE_SEVERITY_WARNING, (uint32_t)RETCODE_NULL_POINTER); + return (retcode); + } + /* If test suite setup pointer are null, it means that there is nothing to be done and that we can just send an + Acknowledgement with status OK.*/ + if (NULL != testSuite->setup) + { + retcode = testSuite->setup(ccmsg); + } + + return retcode; +} + +/* @see TestRegistry.h for function description */ +Retcode_T TestSuite_Teardown(TstSte_T *testSuite, CCMsg_T *ccmsg) +{ + Retcode_T retcode = RETCODE_OK; + if ((NULL == testSuite) || (NULL == ccmsg)) + { + /* The suite is not found */ + retcode = RETCODE(RETCODE_SEVERITY_WARNING, (uint32_t)RETCODE_NULL_POINTER); + return (retcode); + } + /* If test suite teardown pointer are null, it means that there is nothing to be done and that we can just send an + Acknowledgement with status OK.*/ + if (NULL != testSuite->teardown) + { + retcode = testSuite->teardown(ccmsg); + } + + return retcode; +} + +/* @see TestRegistry.h for function description */ +Retcode_T TestCase_Setup(TstCse_T *testCase, CCMsg_T *ccmsg) +{ + + Retcode_T retcode = RETCODE_OK; + + if ((NULL == testCase) || (NULL == ccmsg)) + { + /* The suite is not found */ + retcode = RETCODE(RETCODE_SEVERITY_WARNING, (uint32_t)RETCODE_NULL_POINTER); + return (retcode); + } + if (NULL != testCase->setup) + { + retcode = testCase->setup(ccmsg); + } + + return retcode; +} + +/* @see TestRegistry.h for function description */ +void TestCase_Run(TstCse_T *testCase, CCMsg_T *ccmsg) +{ + + if ((NULL == testCase) || (NULL == ccmsg) || (NULL == testCase->run)) + { + Retcode_RaiseError(RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t)RETCODE_NULL_POINTER)); + } + else + { + testCase->run(ccmsg); + } +} + +/* @see TestRegistry.h for function description */ +Retcode_T TestCase_Teardown(TstCse_T *testCase, CCMsg_T *ccmsg) +{ + + Retcode_T retcode = RETCODE_OK; + + if ((NULL == testCase) || (NULL == ccmsg)) + { + /* The suite is not found */ + retcode = RETCODE(RETCODE_SEVERITY_WARNING, (uint32_t)RETCODE_NULL_POINTER); + } + else + { + if (NULL != testCase->teardown) + { + retcode = testCase->teardown(ccmsg); + } + } + + return retcode; +} + +/*###################### LOCAL FUNCTIONS IMPLEMENTATION ##############################################################*/ + +/** + * @brief finds a test suite by suite Id in the test suites registry. +*/ +static TstSte_T *lookupTestSuite(uint8_t sId) +{ + TstSte_T *testSuite = NULL; + + for (uint32_t i = 0; i < testEntry.numTestSuites; i++) + { + if (sId == testEntry.testSuites[i].id) + { + testSuite = &testEntry.testSuites[i]; + break; + } + } + + return testSuite; +} + +/** + * @brief finds a test case by case Id in the test cases registry of the referenced test suite . +*/ +static TstCse_T *lookupTestCase(TstSte_T *testSuite, uint8_t cId) +{ + TstCse_T *testCase = NULL; + + for (uint32_t i = 0; i < testSuite->numTestCases; i++) + { + if (cId == testSuite->testCases[i].id) + { + testCase = &testSuite->testCases[i]; + break; + } + } + + return testCase; +} diff --git a/core/testing/source/TestRunner.c b/core/testing/source/TestRunner.c new file mode 100644 index 00000000..fe09b301 --- /dev/null +++ b/core/testing/source/TestRunner.c @@ -0,0 +1,363 @@ +/******************************************************************************* + * Copyright (c) 2010-2020 Robert Bosch GmbH + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Robert Bosch GmbH - initial contribution + * + ******************************************************************************/ + +/** + * @file + * + * @brief + * The TestRunner dispatches the commands to the test sections and test suites and processes the acknowledgments + * received from the test controller. + */ +#include "Kiso_Testing.h" +#include "TestRunner.h" +#include "Kiso_CmdProcessor.h" +#include "CChannel.h" +#include "TestRegistry.h" +#include "FreeRTOS.h" +#include "timers.h" + +#undef KISO_MODULE_ID +#define KISO_MODULE_ID KISO_MODULE_ID_TESTING_TESTRUNNER + +#define TEST_ENTRY_SETUP 1 +#define TEST_SUITE_SETUP 2 +#define TEST_CASE_SETUP 3 +#define TEST_CASE_RUN 13 +#define TEST_ENTRY_TEARDOWN 21 +#define TEST_SUITE_TEARDOWN 22 +#define TEST_CASE_TEARDOWN 23 + +#define RUNNER_TIME_TO_WAIT_FOR_ACK_MS (UINT8_C(3000)) + +/** Structure containing the handler for the Test Runner */ +struct TestRunner_S +{ + uint8_t id; /**< Message token corresponding to the message type */ + uint8_t numberOfRetries; + CmdProcessor_T cmdProcessor; + TimerHandle_t timer; + uint8_t lastReceivedMessageToken; + bool waitingForAck; +}; + +static void dispatcher(CCMsg_T *ccmsg, uint32_t unusedParameter); +static void processAck(CCMsg_T *ccmsg); +static void processCommand(CCMsg_T *ccmsg); +static void ackTimerCallbackFunction(TimerHandle_t timer); +static bool isMsgAnAck(CCMsg_T *ccmsg); +static bool isMsgACommand(CCMsg_T *ccmsg); + +static struct TestRunner_S testRunner; + +/* @see TestRunner.h for function description */ +Retcode_T TestRunner_Initialize(void) +{ + Retcode_T retcode = RETCODE_OK; + testRunner.id = 0U; + + retcode = CmdProcessor_Initialize(&testRunner.cmdProcessor, + "Test Runner", + TEST_RUNNER_TASK_PRIO, + TEST_RUNNER_TASK_STACK_DEPTH, + TEST_RUNNER_QUEUE_SIZE); + + if (RETCODE_OK == retcode) + { + testRunner.timer = xTimerCreate((const char *const) "Test Runner Timer", + RUNNER_TIME_TO_WAIT_FOR_ACK_MS, + pdFALSE, + NULL, + ackTimerCallbackFunction); + if (NULL == testRunner.timer) + { + retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_OUT_OF_RESOURCES); + } + } + if (RETCODE_OK == retcode) + { + retcode = CChannel_Initialize(); + } + return retcode; +} + +/* @see TestRunner.h for function description */ +void TestRunner_ProcessMessage(CCMsg_T *ccmsg) +{ + Retcode_T retcode = CmdProcessor_Enqueue(&testRunner.cmdProcessor, + (CmdProcessor_Func_T)dispatcher, + ccmsg, + 0); + + if (RETCODE_OK != retcode) + { + Retcode_RaiseError(retcode); + } +} + +/* @see TestRunner.h for function description */ +void TestRunner_SendReport(uint8_t result, char *reason) +{ + Retcode_T retcode = RETCODE_OK; + + retcode = CChannel_SendReport(result, reason); + + if (RETCODE_OK == retcode) + { + if (pdFAIL == xTimerStart(testRunner.timer, RUNNER_TIME_TO_WAIT_FOR_ACK_MS)) + { + Retcode_RaiseError(RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_OUT_OF_RESOURCES)); + } + testRunner.numberOfRetries = 3; + testRunner.waitingForAck = true; + } + else + { + Retcode_RaiseError(retcode); + } +} + +static void dispatcher(CCMsg_T *ccmsg, uint32_t unusedParameter) +{ + KISO_UNUSED(unusedParameter); + + if (isMsgAnAck(ccmsg)) + { + processAck(ccmsg); + } + else if (isMsgACommand(ccmsg)) + { + processCommand(ccmsg); + } + else + { + //@todo handle the fact that the type is not supported + // CChannel_PrepareAck(ccmsg); + // CChannel_SendAck(RETCODE_OK); + } + + CChannel_FreeCCMsg(ccmsg); +} + +static void processAck(CCMsg_T *ccmsg) +{ + if (CChannel_DoesAckMatchReport(ccmsg)) + { + + if (pdFAIL == xTimerStop(testRunner.timer, 0)) + { + //@todo raise some error? + } + + testRunner.waitingForAck = false; + testRunner.numberOfRetries = 0; + } + else + { + //@todo do we just ignore it? or raise an error? + } +} + +static void processCommand(CCMsg_T *ccmsg) +{ + Retcode_T retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_FAILURE); + + if (testRunner.waitingForAck) + { + /** + * this means the Test Coordinator did receive the Report but the ack was lost + * so we can just stop the timer and continue + */ + if (true != xTimerStop(testRunner.timer, 0)) + { + //@todo raise some error? + } + testRunner.waitingForAck = false; + testRunner.numberOfRetries = 0; + } + if (testRunner.lastReceivedMessageToken == ccmsg->header.messageToken) + { + /** + * if we receive again a command, we shouldn't do the associated action + * we should however resend the ack. + */ + retcode = CChannel_ResendAck(); + + if (RETCODE_OK != retcode) + { + Retcode_RaiseError(retcode); + } + return; + } + + uint8_t result = RETCODE_OK; + + TstEnt_T *testEntry = TestRegistry_LookupTestEntry(ccmsg->header.testEntry); + TstSte_T *testSuite = TestRegistry_LookupTestSuite(ccmsg->header.testEntry, ccmsg->header.testSuite); + TstCse_T *testCase = TestRegistry_LookupTestCase(ccmsg->header.testEntry, + ccmsg->header.testSuite, ccmsg->header.testCase); + + testRunner.lastReceivedMessageToken = ccmsg->header.messageToken; + + CChannel_PrepareAck(ccmsg); + + switch (ccmsg->header.messageType) + { + case TEST_ENTRY_SETUP: + if (NULL != testEntry) + { + retcode = TestEntry_Setup(testEntry, ccmsg); + } + else + { + /* @todo: The error code in Retcode_T occupies 16 bits. But, the argument type passed to CChannel_SendAck() is uint8_t. + * The test coordination protocol has an error code of 8 bits. This is a problem, as we would end up in overflow + * and due to the unsigned nature of the variable, we would wrap around. This needs to be fixed. */ + result = (uint8_t)RETCODE_INVALID_PARAM; + } + break; + case TEST_SUITE_SETUP: + if (NULL != testSuite) + { + retcode = TestSuite_Setup(testSuite, ccmsg); + } + else + { + result = (uint8_t)RETCODE_INVALID_PARAM; + } + break; + case TEST_CASE_SETUP: + if (NULL != testCase) + { + retcode = TestCase_Setup(testCase, ccmsg); + } + else + { + result = (uint8_t)RETCODE_INVALID_PARAM; + } + break; + case TEST_CASE_RUN: + if (NULL != testCase) + { + retcode = CChannel_SendAck(RETCODE_OK); + + if (RETCODE_OK != retcode) + { + Retcode_RaiseError(retcode); + } + else + { + CChannel_PrepareReport(ccmsg); + + TestCase_Run(testCase, ccmsg); + } + return; + } + else + { + result = (uint8_t)RETCODE_INVALID_PARAM; + } + break; + case TEST_ENTRY_TEARDOWN: + if (NULL != testEntry) + { + retcode = TestEntry_Teardown(testEntry, ccmsg); + } + else + { + result = (uint8_t)RETCODE_INVALID_PARAM; + } + break; + case TEST_SUITE_TEARDOWN: + if (NULL != testSuite) + { + retcode = TestSuite_Teardown(testSuite, ccmsg); + } + else + { + result = (uint8_t)RETCODE_INVALID_PARAM; + } + break; + case TEST_CASE_TEARDOWN: + if (NULL != testCase) + { + retcode = TestCase_Teardown(testCase, ccmsg); + } + else + { + result = (uint8_t)RETCODE_INVALID_PARAM; + } + break; + default: + result = (uint8_t)RETCODE_INVALID_PARAM; + break; + } + + if ((uint8_t)RETCODE_INVALID_PARAM != result) + { + result = Retcode_GetCode(retcode); + } + + retcode = CChannel_SendAck(result); + + if (RETCODE_OK != retcode) + { + Retcode_RaiseError(retcode); + } +} + +static void ackTimerCallbackFunction(TimerHandle_t timer) +{ + KISO_UNUSED(timer); + Retcode_T retcode = RETCODE_OK; + + if (testRunner.numberOfRetries > 0) + { + testRunner.numberOfRetries--; + + retcode = CChannel_ResendReport(); + + if (RETCODE_OK == retcode) + { + if (true != xTimerStart(testRunner.timer, RUNNER_TIME_TO_WAIT_FOR_ACK_MS)) + { + Retcode_RaiseError(RETCODE(RETCODE_SEVERITY_ERROR, (uint32_t)RETCODE_OUT_OF_RESOURCES)); + } + } + else + { + Retcode_RaiseError(retcode); + } + } + else + { + testRunner.waitingForAck = false; + Retcode_RaiseError(RETCODE(RETCODE_SEVERITY_WARNING, RETCODE_TESTING_REPORT_TIMEOUT)); + } +} + +/** + * @brief checks the type of the message and returns true if it is an acknowledgement message. + */ +static bool isMsgAnAck(CCMsg_T *ccmsg) +{ + return CCMSG_GET_TYPE(ccmsg) == CCHANNEL_MSG_TYPE_ACK; +} + +/** + * @brief checks the type of the message and returns true if it is a command message. + */ +static bool isMsgACommand(CCMsg_T *ccmsg) +{ + return CCMSG_GET_TYPE(ccmsg) == CCHANNEL_MSG_TYPE_COMMAND; +} diff --git a/core/testing/source/Testing.c b/core/testing/source/Testing.c new file mode 100644 index 00000000..37f0503a --- /dev/null +++ b/core/testing/source/Testing.c @@ -0,0 +1,74 @@ + +/********************************************************************************************************************** + * Copyright (c) 2010#2019 Robert Bosch GmbH + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl#2.0. + * + * SPDX#License#Identifier: EPL#2.0 + * + * Contributors: + * Robert Bosch GmbH # initial contribution + * + **********************************************************************************************************************/ + +/** + * @file + * + * @brief + * This file implements the promised API functions in Kiso_Testing.h with help of the components TestRunner TestRegistry + * and CChannel. + */ +/*###################### INCLUDED HEADERS ############################################################################*/ + +#include "Kiso_Testing.h" +#include "TestRegistry.h" +#include "TestRunner.h" +#include "CChannel.h" + +/*###################### MACROS DEFINITION ###########################################################################*/ + +#undef KISO_MODULE_ID +#define KISO_MODULE_ID KISO_MODULE_ID_TESTING + +/*###################### LOCAL_TYPES DEFINITION ######################################################################*/ + +/*###################### LOCAL FUNCTIONS DECLARATION #################################################################*/ + +/*###################### VARIABLES DECLARATION #######################################################################*/ + +/*###################### EXPOSED FUNCTIONS IMPLEMENTATION ############################################################*/ + +/* @see Kiso_Testing.h for function description */ +Retcode_T Tests_Initialize(uint8_t eId, SetupFct_T setup, TearDownFct_T teardown) +{ + TestRegistry_Initialize(eId, setup, teardown); + return TestRunner_Initialize(); +} + +/* @see Kiso_Testing.h for function description */ +Retcode_T Tests_RegisterTestSuite(uint8_t sId, SetupFct_T setup, TearDownFct_T teardown) +{ + return TestRegistry_RegisterTestSuite(sId, setup, teardown); +} + +/* @see Kiso_Testing.h for function description */ +Retcode_T Tests_RegisterTestCase(uint8_t sId, uint8_t cId, SetupFct_T setup, RunFct_T run, TearDownFct_T teardown) +{ + return TestRegistry_RegisterTestCase(sId, cId, setup, run, teardown); +} + +/* @see Kiso_Testing.h for function description */ +void Tests_SendReport(uint8_t result, char *reason) +{ + TestRunner_SendReport(result, reason); +} + +/* @see Kiso_Testing.h for function description */ +Retcode_T Tests_GetTlvElement(CCMsg_T *ccmsg, TlvElt_T *tlvElement) +{ + return CChannel_GetTlvElement(ccmsg, tlvElement); +} + +/*###################### LOCAL FUNCTIONS IMPLEMENTATION ##############################################################*/ \ No newline at end of file diff --git a/core/testing/source/protected/CChannel.h b/core/testing/source/protected/CChannel.h new file mode 100644 index 00000000..506ebb13 --- /dev/null +++ b/core/testing/source/protected/CChannel.h @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright (c) 2010-2020 Robert Bosch GmbH + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Robert Bosch GmbH - initial contribution + * + ******************************************************************************/ + +/** + * @file + * @defgroup + * @ingroup + * @{ + * + * @brief communication channel handling APIs. + * @details + * This file is part of the test executor software component in the integration testing framework. it provides + * internally used API functions managing the communication protocol between the test executor and the test controller. + * + */ + +#ifndef KISO_CCHANNEL_H_ +#define KISO_CCHANNEL_H_ + +#include "Kiso_Testing.h" + +#define CCMSG_VERSION 1 + +#define CCMSG_TYPE_MASK 0x30 +#define CCMSG_VERSION_MASK 0xC0 +#define CCMSG_VERSION_SHIFT (6) + +#define CCMSG_GET_VERSION(ccmsg) (((ccmsg->header.messageInfo & CCMSG_VERSION_MASK) >> 6) & 0x03) +#define CCMSG_GET_TYPE(ccmsg) (((ccmsg->header.messageInfo & CCMSG_TYPE_MASK) >> 4) & 0x03) + +#define CCMSG_CREATE_TYPE(type) ((((type << 4) & 0x30) + ((CCMSG_VERSION << 6) & CCMSG_VERSION_MASK)) & 0xFF) + +#define CCHANNEL_MSG_TYPE_COMMAND 0 +#define CCHANNEL_MSG_TYPE_REPORT 1 +#define CCHANNEL_MSG_TYPE_ACK 2 + +#define CCHANNEL_MESSAGE_MAX_LENGTH 256 +#define CCHANNEL_HEADER_LENGTH 8 +#define CCHANNEL_PAYLOAD_MAX_SIZE CCHANNEL_MESSAGE_MAX_LENGTH - CCHANNEL_HEADER_LENGTH + +#define NO_REBOOT 0 + +/** + * @brief Initializes the CChannel + * + * @return RETCODE_OK in case of success error code otherwise. + */ +Retcode_T CChannel_Initialize(void); + +/** + * @brief Frees the message after having been processed + * + * @param[in] ccmsg The reference to the message to free + */ +void CChannel_FreeCCMsg(CCMsg_T *ccmsg); + +/** + * @brief Prepares the Ack corresponding to the message + * + * @param[in] ccmsg The reference to the message we are preparing the ack for + */ +void CChannel_PrepareAck(CCMsg_T *ccmsg); + +/** + * @brief Sends the ack previously prepared + * + * @param[in] result error code to set in the ack before sending it + * + * @retcode RETCODE_OK (=0) on success. Any other value means a failure + */ +Retcode_T CChannel_SendAck(uint8_t result); + +/** + * @brief Resends the last ack. This is used in case we receive twice the same command + * + * @return RETCODE_OK on success. Any other value means a failure + */ +Retcode_T CChannel_ResendAck(void); + +/** + * @brief Prepares the report corresponding to the message + * + * @param[in] ccmsg The message we are preparing the report for + */ +void CChannel_PrepareReport(CCMsg_T *ccmsg); + +/** + * @brief Sends a Report. Function to be called within the run function implementation + * + * @param[in] result The test result code (0: success / otherwise: failure) + * @param[in] reason 0-terminating string stating a reason. It can be NULL, if no reason should be sent. + * + * @reurn RETCODE_OK on success. Any other value means a failure + */ +Retcode_T CChannel_SendReport(uint8_t result, char *reason); + +/** + * @brief Resends the last report. This is used in case we did not receive an ack for our report + * + * @return RETCODE_OK on success. Any other value means a failure + */ +Retcode_T CChannel_ResendReport(void); + +/** + * @brief Gets a tlv element using the type of the tlvElement input + * + * @param[in] ccmsg - message in which to look for the element + * @param[in, out] tlvElement - to store the element if found + * tlvElement->type used as input to find the element's value + * + * @return RETCODE_OK if found the TLV element, error code otherwise. + */ +Retcode_T CChannel_GetTlvElement(CCMsg_T *ccmsg, TlvElt_T *tlvElement); + +/** + * @brief Checks if the ack we received corresponds to the report we just sent + * + * @param[in] ccack ack message we received + * + * @return true if match, false if no match + */ +bool CChannel_DoesAckMatchReport(CCMsg_T *ccack); + +/** + * @brief Stops the CChannel + * + * @return RETCODE_OK on success. Any other value means a failure + */ +Retcode_T CChannel_Deinitialize(void); + +/** + * @brief Method triggered when a new message in received + * + * @param[in] buffer pointer to the message as a raw buffer + * @param[in] length length of the received message + */ +void CChannel_ReceiveEventHandler(uint8_t *buffer, uint8_t length); + +/** + * @brief Adds the tlv Element to the message + * + * @param[in] ccmsg Message to add the element to + * @param[in] tlvElement TLV element to add + * + * @return RETCODE_OK if successful error code otherwise + */ +Retcode_T CChannel_AddTlvElement(CCMsg_T *ccmsg, TlvElt_T *tlvElement); + +/*###################### GLOBAL VARIABLES ###########################################################################*/ + +#endif /* KISO_CCHANNEL_H_ */ diff --git a/core/testing/source/protected/SerialCChannel.h b/core/testing/source/protected/SerialCChannel.h new file mode 100644 index 00000000..88e1b0eb --- /dev/null +++ b/core/testing/source/protected/SerialCChannel.h @@ -0,0 +1,77 @@ +/********************************************************************************************************************** + * Copyright (c) 2010#2019 Robert Bosch GmbH + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl#2.0. + * + * SPDX#License#Identifier: EPL#2.0 + * + * Contributors: + * Robert Bosch GmbH # initial contribution + * + **********************************************************************************************************************/ + +/** + * @file + * @defgroup + * @ingroup + * @{ + * + * @brief Serial Communication Channel Interface + * @details This header provides APIs to control uart communication line if this one is used as a communication + * channel between the Test executor and the test controller. + */ + +#ifndef SERIALCCHANNEL_H_ +#define SERIALCCHANNEL_H_ + +/*###################### INCLUDED HEADERS ############################################################################*/ + +#include "Kiso_Retcode.h" + +/*###################### MACROS DEFINITION ###########################################################################*/ + +/*###################### TYPE DEFINITIONS ############################################################################*/ + +/*###################### EXPORTED FUNCTIONS PROTOTYPES ###############################################################*/ + +/** + * @brief Initializes the serial interface + * + * @return RETCODE_OK if Initialized successfully error code otherwise. + */ +Retcode_T Serial_Initialize(void); + +/** + * @brief Deinitializes the serial interface + * + * @return RETCODE_OK if Deinitialized successfully error code otherwise. + */ +Retcode_T Serial_Deinitialize(void); + +/** + * @brief Receives data from the serial interface + * + * @param[in] data: A pointer to a data buffer. + * @param[in] len: Number of bytes to be received. + * + * @return RETCODE_OK if Receive successful error code otherwise. + */ +Retcode_T Serial_Receive(void *data, uint32_t len); + +/** + * @brief Sends data to the serial interface + * + * @param[in] data: A pointer to a data buffer. + * @param[in] len: Number of bytes to be sent. + * + * @return RETCODE_OK if Send successful error code otherwise + */ +Retcode_T Serial_Send(void *data, uint32_t len); + +/*###################### GLOBAL VARIABLES ###########################################################################*/ + +extern volatile uint32_t serialReceivedCnt; + +#endif /* SERIALCCHANNEL_H_ */ diff --git a/core/testing/source/protected/SerialMsgTransceiver.h b/core/testing/source/protected/SerialMsgTransceiver.h new file mode 100644 index 00000000..f1901bbe --- /dev/null +++ b/core/testing/source/protected/SerialMsgTransceiver.h @@ -0,0 +1,58 @@ +/********************************************************************************************************************** + * Copyright (c) 2010#2019 Robert Bosch GmbH + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl#2.0. + * + * SPDX#License#Identifier: EPL#2.0 + * + * Contributors: + * Robert Bosch GmbH # initial contribution + * + **********************************************************************************************************************/ + +/** + * @file + * @defgroup + * @ingroup + * @{ + * + * @brief Provides APIs for sending and receiving over serial line + * + */ + +#ifndef SERIALMSGTRANSCEIVER_H_ +#define SERIALMSGTRANSCEIVER_H_ + +/*###################### INCLUDED HEADERS ############################################################################*/ + +#include "Kiso_Retcode.h" + +/*###################### MACROS DEFINITION ###########################################################################*/ + +/*###################### TYPE DEFINITIONS ############################################################################*/ + +/*###################### EXPORTED FUNCTIONS PROTOTYPES ###############################################################*/ + +/** + * @brief Receive a message parses it and forwards it to CChannel for further processing + */ +void SerialMsgTransceiver_Receive(void); + +/** + * @brief Sends a message through the serial interface. + * @details This can be also used for building and sending the messages via other interfaces + * + * @param[in] message A reference to the message buffer to be sent. + * @param[in] length The Length of the message to be sent. + * + * @retval RETCODE_OK if the message transmitted successfully, error code otherwise. + */ +Retcode_T SerialMsgTransceiver_Send(uint8_t *message, uint8_t length); + +#endif /* SERIALMSGTRANSCEIVER_H_ */ + +/*###################### GLOBAL VARIABLES ###########################################################################*/ + +/** @} */ diff --git a/core/testing/source/protected/TestRegistry.h b/core/testing/source/protected/TestRegistry.h new file mode 100644 index 00000000..bf07f5d5 --- /dev/null +++ b/core/testing/source/protected/TestRegistry.h @@ -0,0 +1,197 @@ +/********************************************************************************************************************** + * Copyright (c) 2010#2019 Robert Bosch GmbH + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl#2.0. + * + * SPDX#License#Identifier: EPL#2.0 + * + * Contributors: + * Robert Bosch GmbH # initial contribution + * + **********************************************************************************************************************/ + +/** + * @file + * @defgroup + * @ingroup + * @{ + * + * @brief todo mak write brief here + * + */ + +#ifndef TESTREGISTRY_H_ +#define TESTREGISTRY_H_ + +/*###################### INCLUDED HEADERS ############################################################################*/ + +#include "Kiso_Testing.h" + +/*###################### MACROS DEFINITION ###########################################################################*/ + +#ifndef TEST_MAX_NUMBER_OF_TEST_CASES_PER_TEST_SUITE +#warning "config TEST_MAX_NUMBER_OF_TEST_CASES_PER_TEST_SUITE not set. The software will build with default value 1" +#define TEST_MAX_NUMBER_OF_TEST_CASES_PER_TEST_SUITE 1 +#endif +/*###################### TYPE DEFINITIONS ############################################################################*/ + +/** + * @brief Structure for the test case which contains the function pointers for setup, run and tear down. + */ +typedef struct TestCase_S +{ + uint8_t id; + SetupFct_T setup; + RunFct_T run; + TearDownFct_T teardown; +} TstCse_T, TstCse_T; + +/** + * @brief Structure for the test suite which contains the function pointers for setup and tear down. + * It also contains the test case structure with the number of test cases. + */ +typedef struct TestSuite_S +{ + uint8_t id; + uint8_t numTestCases; + SetupFct_T setup; + TearDownFct_T teardown; + TstCse_T testCases[TEST_MAX_NUMBER_OF_TEST_CASES_PER_TEST_SUITE]; +} TstSte_T; + +typedef struct TestEntry_S +{ + uint8_t id; + uint8_t numTestSuites; + SetupFct_T setup; + TearDownFct_T teardown; + TstSte_T testSuites[TEST_MAX_NUMBER_OF_TEST_SUITES]; +} TstEnt_T, TstEnt_T; + +/*###################### EXPORTED FUNCTIONS PROTOTYPES ###############################################################*/ + +/** + * @brief Initializes the Test Registry. + * @details This function Initializes the Test Registry by filling it with the Test Entry, Test Suites and Test Case arrays. + * @param[in] eId The Identifier of the Test Entry + * @param[in] setup A reference to the setup function of the Test Entry. + * @param[in] teardown A reference to the tear down function of the Test Entry. + * @note setup and tear down functions pointers can be null if nothing has to be done. + */ +void TestRegistry_Initialize(uint8_t eId, SetupFct_T setup, TearDownFct_T teardown); + +/** + * @brief Registers a Test Suite + * @param[in] sId The Identifier of the Test Suite to register + * @param[in] setup A reference to the setup function of the Test Suite + * @param[in] teardown A reference to the tear down function of the Test Suite + * @note setup and tear down functions pointers can be null if nothing has to be done. + * @return RETCODE_OK if the Test Suite registered successfully. + * @return RETCODE_OUT_OF_RESOURCES if Maximum number of Test Suites reached. + * @return RETCODE_TESTING_SUITE_ALREADY_REGISTERED if a test suite with this Id has already been registered. + */ +Retcode_T TestRegistry_RegisterTestSuite(uint8_t sId, SetupFct_T setup, TearDownFct_T teardown); + +/** + * @brief Registers a Test Case + * @param[in] sId Id of the Test Suite of the test to register + * @param[in] cId Id of the Test Case to register + * @param[in] setup A reference to the setup function of the Test Suite + * @param[in] run A reference to the run function of the Test Suite + * @param[in] teardown function pointer to the tear down function of the Test Suite + * @note setup and tear down functions pointers can be null if nothing has to be done. + * @note run method MUST NOT be NULL! + * @return RETCODE_OK The Test Case registered successfully + * @return RETCODE_INVALID_PARAM No Test Suite with the given Id has been found + * @return RETCODE_OUT_OF_RESOURCES Maximum number of Test Cases reached + * @return RETCODE_TESTING_CASE_ALREADY_REGISTERED A Test Case with this Id has already been registered + */ +Retcode_T TestRegistry_RegisterTestCase(uint8_t sId, uint8_t cId, SetupFct_T setup, RunFct_T run, TearDownFct_T teardown); + +/** + * @brief Looks up for a Test Entry by Id + * @param[in] eId Id of the Test Entry to look for. + * @return Reference to the Test Entry on SUCCESS NULL if not found + */ +TstEnt_T *TestRegistry_LookupTestEntry(uint8_t eId); + +/** + * @brief Looks up for a Test Suite + * + * @param[in] eId The identifier of the Test Suite the test to register + * @param[in] sId The identifier of the Test Suite the test to register + * @return Test Suite pointer on SUCCESS NULL if not found. + */ +TstSte_T *TestRegistry_LookupTestSuite(uint8_t eId, uint8_t sId); + +/** + * @brief Looks up for a Test Case + * + * @param[in] eId The identifier of the test entry register to look from + * @param[in] sId The identifier of the test suite register to look from + * @param[in] cId Id of the Test Case to look for. + * @return Test Case pointer on SUCCESS, NULL if not found + */ +TstCse_T *TestRegistry_LookupTestCase(uint8_t eId, uint8_t sId, uint8_t cId); + +/** + * @brief Calls the setup function of the Test Entry + * @param[in] testEntry Test Entry which setup function should be called + * @param[in] ccmsg Message to pass to the Test Entry setup function. + * @return Retcode of the Setup function to use for the Acknowledgment message + */ +Retcode_T TestEntry_Setup(TstEnt_T *testEntry, CCMsg_T *ccmsg); + +/** + * @brief Calls the teardown function of the Test Entry + * @param[in] testEntry Test Entry which teardown function should be called + * @param[in] ccmsg Message to pass to the Test Entry teardown function. + * @return Retcode of the Teardown function to use for the Acknowledgment message. + */ +Retcode_T TestEntry_Teardown(TstEnt_T *testEntry, CCMsg_T *ccmsg); + +/** + * @brief Calls the setup function of the Test Suite + * @param[in] testSuite Test Suite which setup function should be called + * @param[in] ccmsg Message to pass to the Test Suite setup function. * + * @return Retcode of the setup function to use for the Acknowledgment message + */ +Retcode_T TestSuite_Setup(TstSte_T *testSuite, CCMsg_T *ccmsg); + +/** + * @brief Calls the teardown function of the Test Suite + * @param[in] testSuite Test Suite which teardown function should be called + * @param[in] ccmsg Message to pass to the Test Suite teardown function. + * @return Retcode of the Teardown function to use for the Acknowledgment message + */ +Retcode_T TestSuite_Teardown(TstSte_T *testSuite, CCMsg_T *ccmsg); + +/** + * @brief Calls the setup function of the Test Case + * @param[in] testCase Test Case which setup function should be called + * @param[in] ccmsg Message to pass to the Test Case setup function. + * @return Retcode of the setup function to use for the Acknowledgment message + */ +Retcode_T TestCase_Setup(TstCse_T *testCase, CCMsg_T *ccmsg); + +/** + * @brief Calls the run function of the Test Case + * @param[in] testCase Test Case which run function should be called + * @param[in] ccmsg Message to pass to the Test Case run function. + */ +void TestCase_Run(TstCse_T *testCase, CCMsg_T *ccmsg); + +/** + * @brief Calls the teardown function of the Test Case + * + * @param[in] testCase Test Case which teardown function should be called + * @param[in] ccmsg Message to pass to the Test Case teardown function. + * @return Retcode of the Teardown function to use for the Acknowledgment message + */ +Retcode_T TestCase_Teardown(TstCse_T *testCase, CCMsg_T *ccmsg); + +/*###################### GLOBAL VARIABLES ###########################################################################*/ + +#endif /* TESTREGISTRY_H_ */ diff --git a/core/testing/source/protected/TestRunner.h b/core/testing/source/protected/TestRunner.h new file mode 100644 index 00000000..5b0ec3e1 --- /dev/null +++ b/core/testing/source/protected/TestRunner.h @@ -0,0 +1,62 @@ +/********************************************************************************************************************** + * Copyright (c) 2010#2019 Robert Bosch GmbH + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl#2.0. + * + * SPDX#License#Identifier: EPL#2.0 + * + * Contributors: + * Robert Bosch GmbH # initial contribution + * + **********************************************************************************************************************/ + +/** + * @file + * @defgroup + * @ingroup + * @{ + * + * @brief todo mak provide description of the module. + * + */ + +#ifndef TESTRUNNER_H_ +#define TESTRUNNER_H_ + +/*###################### INCLUDED HEADERS ############################################################################*/ + +#include "Kiso_Testing.h" +#include "Kiso_Retcode.h" + +/*###################### MACROS DEFINITION ###########################################################################*/ + +/*###################### TYPE DEFINITIONS ############################################################################*/ + +/*###################### EXPORTED FUNCTIONS PROTOTYPES ###############################################################*/ + +/** + * @brief Initializes the Test Runner + * @retval RETCODE_OK in case of success, error code otherwise. + */ +Retcode_T TestRunner_Initialize(void); + +/** + * @brief Processes an incoming message + * @param[in] ccmsg incoming message to process + */ +void TestRunner_ProcessMessage(CCMsg_T *ccmsg); + +/** + * @brief Sends a Report. + * + * @param[in] result test result code (0: success / otherwise: failure) + * @param[in] reason 0-terminating string stating a reason. It can be NULL, if no reason should be sent. + */ +void TestRunner_SendReport(uint8_t result, char *reason); + +/*###################### GLOBAL VARIABLES ###########################################################################*/ + +#endif /* TESTRUNNER_H_ */ +/** @} */ From 78c9941f1c7d38c3b4f1e27790ac892c40c6aed4 Mon Sep 17 00:00:00 2001 From: ChiefGokhlayehBosch Date: Mon, 7 Sep 2020 16:48:53 +0200 Subject: [PATCH 3/7] Neaten up core/testing code Signed-off-by: ChiefGokhlayehBosch --- .../test/integration/source/TestEntry.c | 25 ++++----------- core/testing/source/Serial.c | 27 ++++------------ core/testing/source/SerialMsgTransceiver.c | 16 +++++----- core/testing/source/TestRegistry.c | 32 ++++++------------- core/testing/source/Testing.c | 27 ++++------------ core/testing/source/protected/CChannel.h | 2 -- .../testing/source/protected/SerialCChannel.h | 24 ++++---------- .../source/protected/SerialMsgTransceiver.h | 24 ++++---------- core/testing/source/protected/TestRegistry.h | 25 +++++---------- core/testing/source/protected/TestRunner.h | 26 +++++---------- 10 files changed, 67 insertions(+), 161 deletions(-) diff --git a/core/essentials/test/integration/source/TestEntry.c b/core/essentials/test/integration/source/TestEntry.c index 974a9580..7954f9a5 100644 --- a/core/essentials/test/integration/source/TestEntry.c +++ b/core/essentials/test/integration/source/TestEntry.c @@ -1,16 +1,16 @@ -/********************************************************************************************************************** - * Copyright (c) 2010#2019 Robert Bosch GmbH +/******************************************************************************* + * Copyright (c) 2010-2020 Robert Bosch GmbH * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl#2.0. + * http://www.eclipse.org/legal/epl-2.0. * - * SPDX#License#Identifier: EPL#2.0 + * SPDX-License-Identifier: EPL-2.0 * * Contributors: - * Robert Bosch GmbH # initial contribution + * Robert Bosch GmbH - initial contribution * - **********************************************************************************************************************/ + ******************************************************************************/ /** * @file @@ -18,29 +18,18 @@ * @brief * Implements the following functionalities specified in template.h */ -/*###################### INCLUDED HEADERS ############################################################################*/ #include "Kiso_Testing.h" #include "TestSuiteUart.h" -/*###################### MACROS DEFINITION ###########################################################################*/ #undef KISO_MODULE_ID #define KISO_MODULE_ID KISO_MODULE_ID_TEST_ENTRY #define TEST_ENTRY_ID 1 -/*###################### LOCAL_TYPES DEFINITION ######################################################################*/ - -/*###################### LOCAL FUNCTIONS DECLARATION #################################################################*/ Retcode_T TestEntry_Initialize(void *param1, uint32_t param2); static Retcode_T TestEntry_Setup(CCMsg_T *ccmsg); static Retcode_T TestEntry_Teardown(CCMsg_T *ccmsg); -/*###################### VARIABLES DECLARATION #######################################################################*/ - -/*###################### EXPOSED FUNCTIONS IMPLEMENTATION ############################################################*/ - -/*###################### LOCAL FUNCTIONS IMPLEMENTATION ##############################################################*/ - Retcode_T TestEntry_Initialize(void *param1, uint32_t param2) { KISO_UNUSED(param1); @@ -65,4 +54,4 @@ static Retcode_T TestEntry_Teardown(CCMsg_T *ccmsg) { KISO_UNUSED(ccmsg); return RETCODE_OK; -} \ No newline at end of file +} diff --git a/core/testing/source/Serial.c b/core/testing/source/Serial.c index d399bfba..cf742c6b 100644 --- a/core/testing/source/Serial.c +++ b/core/testing/source/Serial.c @@ -1,16 +1,16 @@ -/********************************************************************************************************************** - * Copyright (c) 2010#2019 Robert Bosch GmbH +/******************************************************************************* + * Copyright (c) 2010-2020 Robert Bosch GmbH * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl#2.0. + * http://www.eclipse.org/legal/epl-2.0. * - * SPDX#License#Identifier: EPL#2.0 + * SPDX-License-Identifier: EPL-2.0 * * Contributors: - * Robert Bosch GmbH # initial contribution + * Robert Bosch GmbH - initial contribution * - **********************************************************************************************************************/ + ******************************************************************************/ /** * @file @@ -18,8 +18,6 @@ * @brief * todo add brief description Implements the following functionalities specified in template.h */ -/*###################### INCLUDED HEADERS ###########################################################################*/ - #include "Kiso_Testing.h" #include "Kiso_Testing_Config.h" #include "Kiso_BSP_TestInterface.h" @@ -31,7 +29,6 @@ #include "SerialMsgTransceiver.h" #include "SerialCChannel.h" -/*###################### MACROS DEFINITION ##########################################################################*/ #undef KISO_MODULE_ID #define KISO_MODULE_ID KISO_MODULE_ID_TESTING_SERIAL @@ -47,14 +44,8 @@ #define SERIAL_TASK_STACK_DEPTH (128UL) #endif /* SERIAL_TASK_STACK_DEPTH */ -/*###################### LOCAL_TYPES DEFINITION #####################################################################*/ - -/*###################### LOCAL FUNCTIONS DECLARATION ################################################################*/ - static void uartEventsCallbackFunc(UART_T uart, struct MCU_UART_Event_S event); -/*###################### VARIABLES DECLARATION ######################################################################*/ - static GuardedTask_T serialGuardedTask; volatile uint32_t serialReceivedCnt = 0; static SemaphoreHandle_t TransmitDataSemaphoreHandle = NULL; @@ -66,8 +57,6 @@ static UART_T TestInterfaceUart; volatile uint32_t TestUartErrorCount = 0; /* number of errors post mortem */ #endif /* NDEBUG */ -/*###################### EXPOSED FUNCTIONS IMPLEMENTATION ###########################################################*/ - /* The description is defined at function declaration */ Retcode_T Serial_Initialize(void) { @@ -173,8 +162,6 @@ Retcode_T Serial_Receive(void *data, uint32_t len) return retcode; } -/*###################### LOCAL FUNCTIONS IMPLEMENTATION #############################################################*/ - static void uartEventsCallbackFunc(UART_T uart, struct MCU_UART_Event_S event) { KISO_UNUSED(uart); /* not used in One-Byte-Mode */ @@ -216,4 +203,4 @@ static void uartEventsCallbackFunc(UART_T uart, struct MCU_UART_Event_S event) { Retcode_RaiseErrorFromIsr(retcode); } -} \ No newline at end of file +} diff --git a/core/testing/source/SerialMsgTransceiver.c b/core/testing/source/SerialMsgTransceiver.c index 147b7fce..dbf5e887 100644 --- a/core/testing/source/SerialMsgTransceiver.c +++ b/core/testing/source/SerialMsgTransceiver.c @@ -70,34 +70,34 @@ Retcode_T SerialMsgTransceiver_Send(uint8_t *message, uint8_t length) sendBuffer[j++] = START; - if (((crc >> CHAR_BIT) & 0xFF) == START) + if (((crc >> CHAR_BIT) & CRC_BYTE_MASK) == START) { sendBuffer[j++] = ESC; sendBuffer[j++] = ESC_START; } - else if (((crc >> CHAR_BIT) & 0xFF) == ESC) + else if (((crc >> CHAR_BIT) & CRC_BYTE_MASK) == ESC) { sendBuffer[j++] = ESC; sendBuffer[j++] = ESC_ESC; } else { - sendBuffer[j++] = (crc >> CHAR_BIT) & 0xFF; + sendBuffer[j++] = (crc >> CHAR_BIT) & CRC_BYTE_MASK; } - if ((crc & 0xFF) == START) + if ((crc & CRC_BYTE_MASK) == START) { sendBuffer[j++] = ESC; sendBuffer[j++] = ESC_START; } - else if ((crc & 0xFF & 0xFF) == ESC) + else if ((crc & CRC_BYTE_MASK) == ESC) { sendBuffer[j++] = ESC; sendBuffer[j++] = ESC_ESC; } else { - sendBuffer[j++] = crc & 0xFF; + sendBuffer[j++] = crc & CRC_BYTE_MASK; } for (uint32_t i = 0; i < length; i++) @@ -123,8 +123,8 @@ Retcode_T SerialMsgTransceiver_Send(uint8_t *message, uint8_t length) return (ReturnValue); } -//@todo dei9bue: verify total length, limited to 256! what to do if exceeded? -/* The description is defined at function declaration */ +/** @todo Verify total length, limited to 256! what to do if exceeded? + * The description is defined at function declaration */ void SerialMsgTransceiver_Receive(void) { static uint8_t receivingState = WAITING_FOR_START; diff --git a/core/testing/source/TestRegistry.c b/core/testing/source/TestRegistry.c index 71a32c60..e774bd7b 100644 --- a/core/testing/source/TestRegistry.c +++ b/core/testing/source/TestRegistry.c @@ -1,45 +1,33 @@ -/********************************************************************************************************************** - * Copyright (c) 2010#2019 Robert Bosch GmbH +/******************************************************************************* + * Copyright (c) 2010-2020 Robert Bosch GmbH * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl#2.0. + * http://www.eclipse.org/legal/epl-2.0. * - * SPDX#License#Identifier: EPL#2.0 + * SPDX-License-Identifier: EPL-2.0 * * Contributors: - * Robert Bosch GmbH # initial contribution + * Robert Bosch GmbH - initial contribution * - **********************************************************************************************************************/ + ******************************************************************************/ /** * @file * * @brief */ -/*###################### INCLUDED HEADERS ############################################################################*/ - #include "Kiso_Testing.h" #include "TestRegistry.h" -/*###################### MACROS DEFINITION ###########################################################################*/ - #undef KISO_MODULE_ID #define KISO_MODULE_ID KISO_MODULE_ID_TESTING_TESTREGISTRY -/*###################### LOCAL_TYPES DEFINITION ######################################################################*/ - -/*###################### LOCAL FUNCTIONS DECLARATION #################################################################*/ - static TstSte_T *lookupTestSuite(uint8_t sId); static TstCse_T *lookupTestCase(TstSte_T *testSuite, uint8_t cId); -/*###################### VARIABLES DECLARATION #######################################################################*/ - static TstEnt_T testEntry; -/*###################### EXPOSED FUNCTIONS IMPLEMENTATION ############################################################*/ - /* @see TestRegistry.h for function description */ void TestRegistry_Initialize(uint8_t eId, SetupFct_T setup, TearDownFct_T teardown) { @@ -168,7 +156,7 @@ Retcode_T TestEntry_Setup(TstEnt_T *theTestEntry, CCMsg_T *ccmsg) return (retcode); } - /* If test section setup pointer are null, it means that there is nothing to be done and that we can just send an + /* If test section setup pointer are null, it means that there is nothing to be done and that we can just send an Acknowledgement with status OK.*/ if (NULL != theTestEntry->setup) { @@ -212,7 +200,7 @@ Retcode_T TestSuite_Setup(TstSte_T *testSuite, CCMsg_T *ccmsg) retcode = RETCODE(RETCODE_SEVERITY_WARNING, (uint32_t)RETCODE_NULL_POINTER); return (retcode); } - /* If test suite setup pointer are null, it means that there is nothing to be done and that we can just send an + /* If test suite setup pointer are null, it means that there is nothing to be done and that we can just send an Acknowledgement with status OK.*/ if (NULL != testSuite->setup) { @@ -232,7 +220,7 @@ Retcode_T TestSuite_Teardown(TstSte_T *testSuite, CCMsg_T *ccmsg) retcode = RETCODE(RETCODE_SEVERITY_WARNING, (uint32_t)RETCODE_NULL_POINTER); return (retcode); } - /* If test suite teardown pointer are null, it means that there is nothing to be done and that we can just send an + /* If test suite teardown pointer are null, it means that there is nothing to be done and that we can just send an Acknowledgement with status OK.*/ if (NULL != testSuite->teardown) { @@ -298,8 +286,6 @@ Retcode_T TestCase_Teardown(TstCse_T *testCase, CCMsg_T *ccmsg) return retcode; } -/*###################### LOCAL FUNCTIONS IMPLEMENTATION ##############################################################*/ - /** * @brief finds a test suite by suite Id in the test suites registry. */ diff --git a/core/testing/source/Testing.c b/core/testing/source/Testing.c index 37f0503a..969e0043 100644 --- a/core/testing/source/Testing.c +++ b/core/testing/source/Testing.c @@ -1,17 +1,16 @@ - -/********************************************************************************************************************** - * Copyright (c) 2010#2019 Robert Bosch GmbH +/******************************************************************************* + * Copyright (c) 2010-2020 Robert Bosch GmbH * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl#2.0. + * http://www.eclipse.org/legal/epl-2.0. * - * SPDX#License#Identifier: EPL#2.0 + * SPDX-License-Identifier: EPL-2.0 * * Contributors: - * Robert Bosch GmbH # initial contribution + * Robert Bosch GmbH - initial contribution * - **********************************************************************************************************************/ + ******************************************************************************/ /** * @file @@ -20,26 +19,14 @@ * This file implements the promised API functions in Kiso_Testing.h with help of the components TestRunner TestRegistry * and CChannel. */ -/*###################### INCLUDED HEADERS ############################################################################*/ - #include "Kiso_Testing.h" #include "TestRegistry.h" #include "TestRunner.h" #include "CChannel.h" -/*###################### MACROS DEFINITION ###########################################################################*/ - #undef KISO_MODULE_ID #define KISO_MODULE_ID KISO_MODULE_ID_TESTING -/*###################### LOCAL_TYPES DEFINITION ######################################################################*/ - -/*###################### LOCAL FUNCTIONS DECLARATION #################################################################*/ - -/*###################### VARIABLES DECLARATION #######################################################################*/ - -/*###################### EXPOSED FUNCTIONS IMPLEMENTATION ############################################################*/ - /* @see Kiso_Testing.h for function description */ Retcode_T Tests_Initialize(uint8_t eId, SetupFct_T setup, TearDownFct_T teardown) { @@ -70,5 +57,3 @@ Retcode_T Tests_GetTlvElement(CCMsg_T *ccmsg, TlvElt_T *tlvElement) { return CChannel_GetTlvElement(ccmsg, tlvElement); } - -/*###################### LOCAL FUNCTIONS IMPLEMENTATION ##############################################################*/ \ No newline at end of file diff --git a/core/testing/source/protected/CChannel.h b/core/testing/source/protected/CChannel.h index 506ebb13..6cf75d09 100644 --- a/core/testing/source/protected/CChannel.h +++ b/core/testing/source/protected/CChannel.h @@ -157,6 +157,4 @@ void CChannel_ReceiveEventHandler(uint8_t *buffer, uint8_t length); */ Retcode_T CChannel_AddTlvElement(CCMsg_T *ccmsg, TlvElt_T *tlvElement); -/*###################### GLOBAL VARIABLES ###########################################################################*/ - #endif /* KISO_CCHANNEL_H_ */ diff --git a/core/testing/source/protected/SerialCChannel.h b/core/testing/source/protected/SerialCChannel.h index 88e1b0eb..f4746e44 100644 --- a/core/testing/source/protected/SerialCChannel.h +++ b/core/testing/source/protected/SerialCChannel.h @@ -1,16 +1,16 @@ -/********************************************************************************************************************** - * Copyright (c) 2010#2019 Robert Bosch GmbH +/******************************************************************************* + * Copyright (c) 2010-2020 Robert Bosch GmbH * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl#2.0. + * http://www.eclipse.org/legal/epl-2.0. * - * SPDX#License#Identifier: EPL#2.0 + * SPDX-License-Identifier: EPL-2.0 * * Contributors: - * Robert Bosch GmbH # initial contribution + * Robert Bosch GmbH - initial contribution * - **********************************************************************************************************************/ + ******************************************************************************/ /** * @file @@ -19,23 +19,15 @@ * @{ * * @brief Serial Communication Channel Interface - * @details This header provides APIs to control uart communication line if this one is used as a communication + * @details This header provides APIs to control uart communication line if this one is used as a communication * channel between the Test executor and the test controller. */ #ifndef SERIALCCHANNEL_H_ #define SERIALCCHANNEL_H_ -/*###################### INCLUDED HEADERS ############################################################################*/ - #include "Kiso_Retcode.h" -/*###################### MACROS DEFINITION ###########################################################################*/ - -/*###################### TYPE DEFINITIONS ############################################################################*/ - -/*###################### EXPORTED FUNCTIONS PROTOTYPES ###############################################################*/ - /** * @brief Initializes the serial interface * @@ -70,8 +62,6 @@ Retcode_T Serial_Receive(void *data, uint32_t len); */ Retcode_T Serial_Send(void *data, uint32_t len); -/*###################### GLOBAL VARIABLES ###########################################################################*/ - extern volatile uint32_t serialReceivedCnt; #endif /* SERIALCCHANNEL_H_ */ diff --git a/core/testing/source/protected/SerialMsgTransceiver.h b/core/testing/source/protected/SerialMsgTransceiver.h index f1901bbe..9aa5fe8c 100644 --- a/core/testing/source/protected/SerialMsgTransceiver.h +++ b/core/testing/source/protected/SerialMsgTransceiver.h @@ -1,16 +1,16 @@ -/********************************************************************************************************************** - * Copyright (c) 2010#2019 Robert Bosch GmbH +/******************************************************************************* + * Copyright (c) 2010-2020 Robert Bosch GmbH * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl#2.0. + * http://www.eclipse.org/legal/epl-2.0. * - * SPDX#License#Identifier: EPL#2.0 + * SPDX-License-Identifier: EPL-2.0 * * Contributors: - * Robert Bosch GmbH # initial contribution + * Robert Bosch GmbH - initial contribution * - **********************************************************************************************************************/ + ******************************************************************************/ /** * @file @@ -19,22 +19,14 @@ * @{ * * @brief Provides APIs for sending and receiving over serial line - * + * */ #ifndef SERIALMSGTRANSCEIVER_H_ #define SERIALMSGTRANSCEIVER_H_ -/*###################### INCLUDED HEADERS ############################################################################*/ - #include "Kiso_Retcode.h" -/*###################### MACROS DEFINITION ###########################################################################*/ - -/*###################### TYPE DEFINITIONS ############################################################################*/ - -/*###################### EXPORTED FUNCTIONS PROTOTYPES ###############################################################*/ - /** * @brief Receive a message parses it and forwards it to CChannel for further processing */ @@ -53,6 +45,4 @@ Retcode_T SerialMsgTransceiver_Send(uint8_t *message, uint8_t length); #endif /* SERIALMSGTRANSCEIVER_H_ */ -/*###################### GLOBAL VARIABLES ###########################################################################*/ - /** @} */ diff --git a/core/testing/source/protected/TestRegistry.h b/core/testing/source/protected/TestRegistry.h index bf07f5d5..ed6def61 100644 --- a/core/testing/source/protected/TestRegistry.h +++ b/core/testing/source/protected/TestRegistry.h @@ -1,16 +1,16 @@ -/********************************************************************************************************************** - * Copyright (c) 2010#2019 Robert Bosch GmbH +/******************************************************************************* + * Copyright (c) 2010-2020 Robert Bosch GmbH * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl#2.0. + * http://www.eclipse.org/legal/epl-2.0. * - * SPDX#License#Identifier: EPL#2.0 + * SPDX-License-Identifier: EPL-2.0 * * Contributors: - * Robert Bosch GmbH # initial contribution + * Robert Bosch GmbH - initial contribution * - **********************************************************************************************************************/ + ******************************************************************************/ /** * @file @@ -19,23 +19,18 @@ * @{ * * @brief todo mak write brief here - * + * */ #ifndef TESTREGISTRY_H_ #define TESTREGISTRY_H_ -/*###################### INCLUDED HEADERS ############################################################################*/ - #include "Kiso_Testing.h" -/*###################### MACROS DEFINITION ###########################################################################*/ - #ifndef TEST_MAX_NUMBER_OF_TEST_CASES_PER_TEST_SUITE #warning "config TEST_MAX_NUMBER_OF_TEST_CASES_PER_TEST_SUITE not set. The software will build with default value 1" #define TEST_MAX_NUMBER_OF_TEST_CASES_PER_TEST_SUITE 1 #endif -/*###################### TYPE DEFINITIONS ############################################################################*/ /** * @brief Structure for the test case which contains the function pointers for setup, run and tear down. @@ -70,9 +65,7 @@ typedef struct TestEntry_S TstSte_T testSuites[TEST_MAX_NUMBER_OF_TEST_SUITES]; } TstEnt_T, TstEnt_T; -/*###################### EXPORTED FUNCTIONS PROTOTYPES ###############################################################*/ - -/** +/** * @brief Initializes the Test Registry. * @details This function Initializes the Test Registry by filling it with the Test Entry, Test Suites and Test Case arrays. * @param[in] eId The Identifier of the Test Entry @@ -192,6 +185,4 @@ void TestCase_Run(TstCse_T *testCase, CCMsg_T *ccmsg); */ Retcode_T TestCase_Teardown(TstCse_T *testCase, CCMsg_T *ccmsg); -/*###################### GLOBAL VARIABLES ###########################################################################*/ - #endif /* TESTREGISTRY_H_ */ diff --git a/core/testing/source/protected/TestRunner.h b/core/testing/source/protected/TestRunner.h index 5b0ec3e1..32544f38 100644 --- a/core/testing/source/protected/TestRunner.h +++ b/core/testing/source/protected/TestRunner.h @@ -1,16 +1,16 @@ -/********************************************************************************************************************** - * Copyright (c) 2010#2019 Robert Bosch GmbH +/******************************************************************************* + * Copyright (c) 2010-2020 Robert Bosch GmbH * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl#2.0. + * http://www.eclipse.org/legal/epl-2.0. * - * SPDX#License#Identifier: EPL#2.0 + * SPDX-License-Identifier: EPL-2.0 * * Contributors: - * Robert Bosch GmbH # initial contribution + * Robert Bosch GmbH - initial contribution * - **********************************************************************************************************************/ + ******************************************************************************/ /** * @file @@ -19,30 +19,22 @@ * @{ * * @brief todo mak provide description of the module. - * + * */ #ifndef TESTRUNNER_H_ #define TESTRUNNER_H_ -/*###################### INCLUDED HEADERS ############################################################################*/ - #include "Kiso_Testing.h" #include "Kiso_Retcode.h" -/*###################### MACROS DEFINITION ###########################################################################*/ - -/*###################### TYPE DEFINITIONS ############################################################################*/ - -/*###################### EXPORTED FUNCTIONS PROTOTYPES ###############################################################*/ - /** * @brief Initializes the Test Runner * @retval RETCODE_OK in case of success, error code otherwise. */ Retcode_T TestRunner_Initialize(void); -/** +/** * @brief Processes an incoming message * @param[in] ccmsg incoming message to process */ @@ -56,7 +48,5 @@ void TestRunner_ProcessMessage(CCMsg_T *ccmsg); */ void TestRunner_SendReport(uint8_t result, char *reason); -/*###################### GLOBAL VARIABLES ###########################################################################*/ - #endif /* TESTRUNNER_H_ */ /** @} */ From b596844a56e931f748690578fba59d92b9ef271c Mon Sep 17 00:00:00 2001 From: ChiefGokhlayehBosch Date: Mon, 7 Sep 2020 17:37:31 +0200 Subject: [PATCH 4/7] Properly await echo in UART integration test Signed-off-by: ChiefGokhlayehBosch --- .../test/integration/source/TestSuiteUart.c | 67 ++++++++++++++----- .../test/integration/specs/UART_Test_Spec.md | 4 +- 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/core/essentials/test/integration/source/TestSuiteUart.c b/core/essentials/test/integration/source/TestSuiteUart.c index 2ea102f4..26f57c9b 100644 --- a/core/essentials/test/integration/source/TestSuiteUart.c +++ b/core/essentials/test/integration/source/TestSuiteUart.c @@ -31,7 +31,7 @@ #define KISO_MODULE_ID 0 #define UART_BUFFER_LEN (5) -#define DATA_TRANSFER_TIMEOUT_MS UINT32_C(1000) +#define DATA_TRANSFER_TIMEOUT_MS UINT32_C(200) #define UART_DEVICE UINT32_C(1) #define MSG_BUFFER_SIZE (32) @@ -46,7 +46,8 @@ static Retcode_T TestCase_FctTest_Teardown(CCMsg_T *ccmsg); static void UartISRCallback(UART_T uart, struct MCU_UART_Event_S event); static UART_T UartHdl = 0; -static xSemaphoreHandle UartLock = 0; +static xSemaphoreHandle TxSignal = 0; +static xSemaphoreHandle RxSignal = 0; Retcode_T TestSuiteUart_Initialize(uint8_t sId) { @@ -78,8 +79,16 @@ static Retcode_T TestCase_FctTest_Setup(CCMsg_T *ccmsg) } if (RETCODE_OK == retcode) { - UartLock = xSemaphoreCreateBinary(); - if (NULL == UartLock) + TxSignal = xSemaphoreCreateBinary(); + if (NULL == TxSignal) + { + return RETCODE(RETCODE_SEVERITY_FATAL, RETCODE_SEMAPHORE_ERROR); + } + } + if (RETCODE_OK == retcode) + { + RxSignal = xSemaphoreCreateBinary(); + if (NULL == RxSignal) { return RETCODE(RETCODE_SEVERITY_FATAL, RETCODE_SEMAPHORE_ERROR); } @@ -118,7 +127,11 @@ static Retcode_T TestCase_FctTest_Teardown(CCMsg_T *ccmsg) } if (RETCODE_OK == retcode) { - vSemaphoreDelete(UartLock); + vSemaphoreDelete(TxSignal); + } + if (RETCODE_OK == retcode) + { + vSemaphoreDelete(RxSignal); } return retcode; } @@ -150,22 +163,46 @@ static void TestCase_FctTest_Run(CCMsg_T *ccmsg) } if (RETCODE_OK == retcode) { - if (pdTRUE != xSemaphoreTake(UartLock, DATA_TRANSFER_TIMEOUT_MS)) + if (pdTRUE != xSemaphoreTake(TxSignal, DATA_TRANSFER_TIMEOUT_MS)) { retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_SEMAPHORE_ERROR); strcpy(msg, "FAIL"); } } + if (RETCODE_OK == retcode) { - for (uint8_t i = 0; i < UART_BUFFER_LEN; i++) + if (pdTRUE == xSemaphoreTake(RxSignal, DATA_TRANSFER_TIMEOUT_MS)) { - if (dataIn[i] != dataOut[i]) + uint8_t tries = 1; + // we received something... now wait till we receive EVERYTHING. + while (pdTRUE == xSemaphoreTake(RxSignal, DATA_TRANSFER_TIMEOUT_MS)) { - retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_UNEXPECTED_BEHAVIOR); - strcpy(msg, "FAIL"); + /* Semaphore should signal at most UART_BUFFER_LEN times (also + * counting the first semaphore signal above) */ + tries++; + if (tries > UART_BUFFER_LEN) + { + retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_UNEXPECTED_BEHAVIOR); + strcpy(msg, "FAIL"); + break; + } + } + + for (uint8_t i = 0; RETCODE_OK == retcode && i < UART_BUFFER_LEN; i++) + { + if (dataIn[i] != dataOut[i]) + { + retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_UNEXPECTED_BEHAVIOR); + strcpy(msg, "FAIL"); + } } } + else + { + retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_SEMAPHORE_ERROR); + strcpy(msg, "FAIL"); + } } Tests_SendReport(Retcode_GetCode(retcode), msg); } @@ -177,14 +214,13 @@ static void UartISRCallback(UART_T uart, struct MCU_UART_Event_S event) if (UINT8_C(1) == event.TxComplete) { - if (RETCODE_OK == Rc) { BaseType_t higherPriorityTaskWoken = pdFALSE; - if (NULL != UartLock) + if (NULL != TxSignal) { - if (pdTRUE == xSemaphoreGiveFromISR(UartLock, &higherPriorityTaskWoken)) + if (pdTRUE == xSemaphoreGiveFromISR(TxSignal, &higherPriorityTaskWoken)) { portYIELD_FROM_ISR(higherPriorityTaskWoken); } @@ -202,14 +238,13 @@ static void UartISRCallback(UART_T uart, struct MCU_UART_Event_S event) if (UINT8_C(1) == event.RxComplete) { - if (RETCODE_OK == Rc) { BaseType_t higherPriorityTaskWoken = pdFALSE; - if (NULL != UartLock) + if (NULL != RxSignal) { - if (pdTRUE == xSemaphoreGiveFromISR(UartLock, &higherPriorityTaskWoken)) + if (pdTRUE == xSemaphoreGiveFromISR(RxSignal, &higherPriorityTaskWoken)) { portYIELD_FROM_ISR(higherPriorityTaskWoken); } diff --git a/core/essentials/test/integration/specs/UART_Test_Spec.md b/core/essentials/test/integration/specs/UART_Test_Spec.md index b2762d3a..9538501b 100644 --- a/core/essentials/test/integration/specs/UART_Test_Spec.md +++ b/core/essentials/test/integration/specs/UART_Test_Spec.md @@ -25,7 +25,7 @@ No special teardown 1. Get device handle of BSP initialized generic UART * UART must be configured in loopback mode, echoing any data sent out -2. Allocate OS signal semaphore used as signal from IRQ +2. Allocate OS signal semaphores used as signal from IRQ 3. Connect the generic UART BSP 4. Initialize UART MCU with UART handle 5. Enable generic UART BSP @@ -43,4 +43,4 @@ No special teardown 1. Deinitialize UART MCU, deactivating IRQs 2. Disable generic UART BSP 3. Disconnect generic UART BSP -4. Free OS signal semaphore +4. Free OS signal semaphores From 160794b49b8b3e0a6a51e581cc5870c0102d005e Mon Sep 17 00:00:00 2001 From: ChiefGokhlayehBosch Date: Mon, 7 Sep 2020 18:04:17 +0200 Subject: [PATCH 5/7] Build essentials integration test in CI/CD Signed-off-by: ChiefGokhlayehBosch --- Jenkinsfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 0d54d4d6..c41c907c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -85,7 +85,9 @@ pipeline { script { - echo "run integration-tests placeholder" + echo "build integration-tests" + sh 'cmake . -Bbuilddir-integration -G"Ninja" -DENABLE_INTEGRATION_TESTING=1 -DKISO_INTEGRATION_TEST_NAME="core/essentials" -DKISO_BOARD_NAME="NucleoF767"' + sh 'cmake --build builddir-integration' } } } From 7b56b181093d6056e78e50b7c3f904e9ba49ebb2 Mon Sep 17 00:00:00 2001 From: ChiefGokhlayehBosch Date: Tue, 8 Sep 2020 14:23:11 +0200 Subject: [PATCH 6/7] Change KISO_INTEGRATION_TEST_NAME to ...ENTRY_PATH Signed-off-by: ChiefGokhlayehBosch --- CMakeLists.txt | 4 ++-- Jenkinsfile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c5f5ec78..f369aadb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ message("---------------------------------- KISO CONFIG ------------------------ message("Building Kiso tests: ${ENABLE_TESTING}") message(" ... with coverage: ${ENABLE_COVERAGE}") message("Building Kiso integration tests: ${ENABLE_INTEGRATION_TESTING}") -message(" ... with entry in: ${KISO_INTEGRATION_TEST_NAME}") +message(" ... with entry in: ${KISO_INTEGRATION_TEST_ENTRY_PATH}") message("Kiso Board Path: ${KISO_BOARD_PATH}") message("Kiso OS: ${KISO_OS_LIB}") message("Kiso Application Path: ${KISO_APPLICATION_PATH}") @@ -94,7 +94,7 @@ endif() ## Add application code if(${ENABLE_INTEGRATION_TESTING}) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/testing/integration/test-executor) - add_subdirectory(${KISO_INTEGRATION_TEST_NAME}/test/integration) + add_subdirectory(${KISO_INTEGRATION_TEST_ENTRY_PATH}) else(${ENABLE_INTEGRATION_TESTING}) add_subdirectory(${KISO_APPLICATION_PATH} ${CMAKE_CURRENT_BINARY_DIR}/applications/${KISO_APPLICATION_NAME}) endif(${ENABLE_INTEGRATION_TESTING}) diff --git a/Jenkinsfile b/Jenkinsfile index c41c907c..b48c8d07 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -86,7 +86,7 @@ pipeline script { echo "build integration-tests" - sh 'cmake . -Bbuilddir-integration -G"Ninja" -DENABLE_INTEGRATION_TESTING=1 -DKISO_INTEGRATION_TEST_NAME="core/essentials" -DKISO_BOARD_NAME="NucleoF767"' + sh 'cmake . -Bbuilddir-integration -G"Ninja" -DENABLE_INTEGRATION_TESTING=1 -DKISO_INTEGRATION_TEST_ENTRY_PATH="core/essentials/test/integration" -DKISO_BOARD_NAME="NucleoF767"' sh 'cmake --build builddir-integration' } } From f08f23750f41e55367726706b86bf93196e2cf8b Mon Sep 17 00:00:00 2001 From: ChiefGokhlayehBosch Date: Tue, 8 Sep 2020 14:40:28 +0200 Subject: [PATCH 7/7] Add documentation about integration test framework Signed-off-by: ChiefGokhlayehBosch --- .../content/Concepts/integration_testing.md | 42 ++++++++++++++++++ .../content/images/integration_test.png | Bin 0 -> 28951 bytes .../content/images/integration_test.puml | 35 +++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 docs/website/content/Concepts/integration_testing.md create mode 100644 docs/website/content/images/integration_test.png create mode 100644 docs/website/content/images/integration_test.puml diff --git a/docs/website/content/Concepts/integration_testing.md b/docs/website/content/Concepts/integration_testing.md new file mode 100644 index 00000000..fb95982a --- /dev/null +++ b/docs/website/content/Concepts/integration_testing.md @@ -0,0 +1,42 @@ +--- +title: "Integration Testing Guide" +weight: 2 +--- + +## Definition + +Integration testing is a form of software testing which combines multiple (sub-)modules of a system into one test environment and verifies the compatibility between the selected system subset. + +## Realization + +In Kiso, integration testing is done **on-target**. This is realized through a special test-app which is flashed onto reference or user hardware and listens to the instructions of a test-coordinator (usually a host PC connected via UART, USB, CAN, or the like). Looking at the hierarchy top-to-bottom (see diagram below), the Kiso integration test framework consists of: + +* Test-App - Flashable/Bootable binary for reference and/or user hardware. + * Test-Executor - Application component of the test-app. Handles basic hardware initialization and connects with test-coordinator. + * Test-Entry - Linkable static library usually declared on a package-level (such as Essentials, Cellular, Utils, etc.), combining different test-suites into a single entity. + * Test-Suite - Collection of test-cases that share a common setup and teardown sequence. Can also be used as logical separation of test-cases. + * Test-Case - Individual test to verify one specific aspect of the (sub-)system. Comprised of setup, run and teardown. +* Test-Coordinator - Python based coordinator application running on a host PC. It communicates with the test-executor running on the device-under-test and decides which test-suites/-cases are to be executed. The python framework is realized as `pykiso` and is available as own executable python module. + +![integration test framework](/images/integration_test.png) + +All Kiso packages share a common test-executor, each package also defines one test-entry. Each test-executor/-entry pair compiles into a standalone binary which can be flashed onto hardware. Users can declare their own test-entries and link them with the provided test-executor, that way users can profit form the existing test framework to run integration tests of user written drivers or applications. + +Test-Entry, test-suite and test-case contain optional hooks for setup and teardown work. + +## Test-App Build System + +As with any target binary in Kiso, building is handled by the CMake toolchain. Two special workspace settings need to be provided during workspace configuration to build a integration test app, targeted towards a specific hardware: + +* `ENABLE_INTEGRATION_TESTING = ON` - Marks this workspace as targeted towards building a integration test app. Note that with this option set, `KISO_APPLICATION_NAME` will be ignored, meaning no user application will be built. +* `KISO_INTEGRATION_TEST_ENTRY_PATH = "path/to/test-entry"` - Path to directory containing a `CMakeLists.txt` used to build the `testentry` static-library. This library will be linked with the test-executor to create the test-app. The `CMakeLists.txt` must declare a static-library target called `testentry`, containing source-files for any test-suites that shall be part of the final test-app. + +The static-library target `testentry` can be created as follows: + +```cmake +add_library(testentry STATIC source/test_suite1.c source/test_suite2.c ...) +# List of additional libs needed +target_link_libraries(testentry testing essentials ${KISO_BOARD_LIBS}) +``` + +Please have a look at the existing CMake build files to get a better idea of what to include in your `CMakeLists.txt`. Test-Entry build files are usually located at `core//test/integration/` diff --git a/docs/website/content/images/integration_test.png b/docs/website/content/images/integration_test.png new file mode 100644 index 0000000000000000000000000000000000000000..027d78080a55b8b4c04dbc19b9b5a82c3b3cccc4 GIT binary patch literal 28951 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 LQ>j4F;>rI2WHyep literal 0 HcmV?d00001 diff --git a/docs/website/content/images/integration_test.puml b/docs/website/content/images/integration_test.puml new file mode 100644 index 00000000..d458dc59 --- /dev/null +++ b/docs/website/content/images/integration_test.puml @@ -0,0 +1,35 @@ +@startuml + +title Integration Test Framework + +package "Test App" { + component "Test Executor" as testexecutor + package "Kiso Package (e.g. Essentials) or User App" { + component "Test Entriy" as testentry + component "Test Suite 1" as testsuite1 + component "Test Suite 2" as testsuite2 + component "Test Suite ..." as testsuitecont + component "Test Case 1.1" as testcase11 + component "Test Case 1.2" as testcase12 + component "Test Case 2.1" as testcase21 + component "Test Case 2.2" as testcase22 + component "Test Case 2.3" as testcase23 + component "Test Case ..." as testcasecont + } +} + +testexecutor -> testentry : links with + +testentry --> testsuite1 : contains +testentry --> testsuite2 : contains +testentry --> testsuitecont : contains +testsuite1 --> testcase11 : contains +testsuite1 --> testcase12 : contains +testsuite2 --> testcase21 : contains +testsuite2 --> testcase22 : contains +testsuite2 --> testcase23 : contains +testsuitecont --> testcasecont : contains + +footer © Robert Bosch GmbH 2010-2020 | Licensed under EPL-2.0 + +@enduml