Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

Commit

Permalink
Add CLI input mode to test runner (#2955)
Browse files Browse the repository at this point in the history
Add another solution ( separate from the configurable delay config added in PR #2950 ) for the problem of race condition between AWS IoT Device Tester (that runs on host machine) getting serial console access to device and the test runner executing tests on the device.

This change adds a CLI console feature to the test runner of waiting for a "start" command from the console (based on FreeRTOS+CLI library) to being execution of tests. This feature can be enabled with the AWS_TEST_RUNNER_ENABLE_CLI_INPUT config in the aws_test_runner_config.h file.
  • Loading branch information
aggarw13 committed Jan 27, 2021
1 parent 64a4605 commit 441e02e
Show file tree
Hide file tree
Showing 6 changed files with 242 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,33 @@ void FreeRTOS_CLIEnterConsoleLoop( xConsoleIO_t consoleIO,
char * pOutputBuffer,
size_t outputBufferLength );


/**
* @brief Adds incoming data from console input interface (@p pConsoleInput)
* to the input command buffer (@pCommandBuffer), and if the input command is
* complete, it checks against commands registered with FreeRTOS+CLI and calls
* the matching command's handler for processing the input command.
*
* @param[in] consoleIO The console interface object for read/write operations.
* @param[in] pConsoleInput The buffer containing the data read from the console.
* @param[in] inputSize The size of the @p pConsoleInput buffer.
* @param[in, out] pCommandBuffer The buffer which represents the complete command
* entered on the console. This buffer is incrementally filled with data from
* @p pConsoleInput on each call to this function.
* @param[in] commandBufferLength The size of the @p pCommandBuffer buffer.
* @param[in, out] pCommandBufferIndex The index till where the data has been
* populated in the @p pCommandBuffer buffer.
* @param[out] pOutputBuffer This buffer is populated with the output from
* processing a command with FreeRTOS+CLI.
* @param[in] outpuBufferLength The size of the output buffer.
*/
void FreeRTOS_CLI_ProcessInputBuffer( xConsoleIO_t consoleIO,
char * pConsoleInput,
int32_t inputSize,
char * pCommandBuffer,
size_t commandBufferLength,
size_t * pCommandBufferIndex,
char * pOutputBuffer,
size_t outpuBufferLength );

#endif /* ifndef FREERTOS_CLI_CONSOLE_H */
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,7 @@ static const char * const pcNewLine = "\r\n";
static char cInputBuffer[ cmdMAX_INPUT_BUFFER_SIZE ] = "";
static char cErrorString[ cmdMAX_ERROR_SIZE ] = "";

static uint8_t ucCommandIndex = 0;

static void processInputBuffer( xConsoleIO_t consoleIO,
int32_t inputSize,
char * pCommandBuffer,
size_t commandBufferLength,
char * pOutputBuffer,
size_t outpuBufferLength );
static size_t ucCommandIndex = 0;

void FreeRTOS_CLIEnterConsoleLoop( xConsoleIO_t consoleIO,
char * pCommandBuffer,
Expand Down Expand Up @@ -86,12 +79,14 @@ void FreeRTOS_CLIEnterConsoleLoop( xConsoleIO_t consoleIO,
/* Echo back. */
consoleIO.write( cInputBuffer, bytesRead );

processInputBuffer( consoleIO,
bytesRead,
pCommandBuffer,
commandBufferLength,
pOutputBuffer,
outputBufferLength );
FreeRTOS_CLI_ProcessInputBuffer( consoleIO,
cInputBuffer,
bytesRead,
pCommandBuffer,
commandBufferLength,
&ucCommandIndex,
pOutputBuffer,
outputBufferLength );

/* Reset input buffer for next iteration. */
memset( cInputBuffer, 0x00, cmdMAX_INPUT_BUFFER_SIZE );
Expand All @@ -107,12 +102,14 @@ void FreeRTOS_CLIEnterConsoleLoop( xConsoleIO_t consoleIO,
}
}

static void processInputBuffer( xConsoleIO_t consoleIO,
int32_t inputSize,
char * pCommandBuffer,
size_t commandBufferLength,
char * pOutputBuffer,
size_t outpuBufferLength )
void FreeRTOS_CLI_ProcessInputBuffer( xConsoleIO_t consoleIO,
char * cInputBuffer,
int32_t inputSize,
char * pCommandBuffer,
size_t commandBufferLength,
size_t * pCommandBufferIndex,
char * pOutputBuffer,
size_t outpuBufferLength )
{
BaseType_t xReturned;
uint8_t i;
Expand All @@ -128,20 +125,20 @@ static void processInputBuffer( xConsoleIO_t consoleIO,
* passed to the command interpreter. */
if( ( cRxedChar >= ' ' ) && ( cRxedChar <= '~' ) )
{
if( ucCommandIndex < ( commandBufferLength - 1UL ) )
if( *pCommandBufferIndex < ( commandBufferLength - 1UL ) )
{
pCommandBuffer[ ucCommandIndex ] = cRxedChar;
ucCommandIndex++;
pCommandBuffer[ ucCommandIndex ] = '\0';
pCommandBuffer[ *pCommandBufferIndex ] = cRxedChar;
*pCommandBufferIndex = *pCommandBufferIndex + 1UL;
pCommandBuffer[ *pCommandBufferIndex ] = '\0';
}
}
else if( ( cRxedChar == '\b' ) || ( cRxedChar == cmdASCII_DEL ) )
{
/* Backspace was pressed. Erase the last character in the string - if any. */
if( ucCommandIndex > 0 )
if( *pCommandBufferIndex > 0 )
{
ucCommandIndex--;
pCommandBuffer[ ucCommandIndex ] = '\0';
*pCommandBufferIndex = *pCommandBufferIndex - 1UL;
pCommandBuffer[ *pCommandBufferIndex ] = '\0';
}
}
/* Was it the end of the line? */
Expand Down Expand Up @@ -178,7 +175,7 @@ static void processInputBuffer( xConsoleIO_t consoleIO,
* sent. Clear the command index to receive a new command.
* Remember the command that was just processed first in case it is
* to be processed again. */
ucCommandIndex = 0;
*pCommandBufferIndex = 0;

consoleIO.write( pcEndOfOutputMessage, strlen( pcEndOfOutputMessage ) );
}
Expand Down
13 changes: 12 additions & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ afr_module_sources(
)
afr_module_include_dirs(
${AFR_CURRENT_MODULE}
INTERFACE "${inc_dir}"
INTERFACE
"${inc_dir}"
)
afr_module_dependencies(
${AFR_CURRENT_MODULE}
Expand All @@ -40,6 +41,16 @@ afr_module_dependencies(
AFR::common
3rdparty::unity
)

if(TARGET AFR::common_io::mcu_port)
afr_module_dependencies(
${AFR_CURRENT_MODULE}
INTERFACE
AFR::freertos_cli_plus_uart
AFR::common_io
)
endif()

if(TARGET AFR::pkcs11_implementation::mcu_port)
afr_module_dependencies(
${AFR_CURRENT_MODULE}
Expand Down
157 changes: 138 additions & 19 deletions tests/common/aws_test_runner.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@
/* Application version info. */
#include "aws_application_version.h"

/* Include files for UART based FreeRTOS+CLI support of test runner.
* Note: This adds a dependency on Common IO for UART communication .*/
#if defined( AWS_TEST_RUNNER_ENABLE_CLI_INPUT ) && ( AWS_TEST_RUNNER_ENABLE_CLI_INPUT == 1 )
#include <string.h>
#include "FreeRTOS_CLI.h"
#include "FreeRTOS_CLI_UART.h"
#include "iot_uart.h"
#endif

/**
* Default value of delay period before the execution of tests on device.
*/
Expand All @@ -67,7 +76,7 @@ unsigned int xHeapAfter;
* do not change the signature of it. You could, however, add or remove
* RUN_TEST_GROUP statements.
*/
static void RunTests( void )
static void RunTestSuites( void )
{
/* Tests can be disabled in aws_test_runner_config.h */

Expand Down Expand Up @@ -265,25 +274,9 @@ static void RunTests( void )
RUN_TEST_GROUP( deviceShadow_Integration );
#endif
}
/*-----------------------------------------------------------*/

void TEST_RUNNER_RunTests_task( void * pvParameters )
void RunTestsWrapper()
{
/* Disable unused parameter warning. */
( void ) pvParameters;

/* Initialize unity. */
UnityFixture.Verbose = 1;
UnityFixture.GroupFilter = 0;
UnityFixture.NameFilter = testrunnerTEST_FILTER;
UnityFixture.RepeatCount = 1;

/* Add sufficient delay before starting tests on device to allow
* device to be available as serial port connection to the host machine
* OS.
* The serial console is used by host machine to view device logs. */
vTaskDelay( pdMS_TO_TICKS( AWS_TEST_RUNNER_DELAY_MS ) );

UNITY_BEGIN();

/* Give the print buffer time to empty */
Expand All @@ -293,7 +286,7 @@ void TEST_RUNNER_RunTests_task( void * pvParameters )
xHeapBefore = xPortGetFreeHeapSize();
#endif

RunTests();
RunTestSuites();

#if ( testrunnerFULL_MEMORYLEAK_ENABLED == 1 )

Expand All @@ -313,6 +306,132 @@ void TEST_RUNNER_RunTests_task( void * pvParameters )

/* Currently disabled. Will be enabled after cleanup. */
UNITY_END();
}

/*-----------------------------------------------------------*/
#if defined( AWS_TEST_RUNNER_ENABLE_CLI_INPUT ) && ( AWS_TEST_RUNNER_ENABLE_CLI_INPUT == 1 )

/* Global flag that represents whether a "start" command is received
* on the serial console. */
static BaseType_t xReceivedCommand = pdFALSE;

/**
* @brief The command handler for the "start" command recognized by the
* serial console of the FreeRTOS test runner. On receiving the command,
* the test runner begins executing tests on the device.
*
* @return Returns pdFALSE to indicate completion of execution of tests.
*/
static BaseType_t prvRunTestsCommand( int8_t * pcWriteBuffer,
size_t xWriteBufferLen,
const int8_t * pcCommandString )
{
( void ) pcWriteBuffer;
( void ) xWriteBufferLen;
( void ) pcCommandString;

/* Set flag to indicate reception of command from serial console to start */
/* executing tests. */
xReceivedCommand = pdTRUE;

RunTestsWrapper();

return pdFALSE;
}

/* Definition of a FreeRTOS+CLI command to instruct the test runner start executing commands.
* The command takes no parameters. */
static const CLI_Command_Definition_t xStartCommand =
{
"start",
"start : Instructs test runner to start executing tests on the board.",
prvRunTestsCommand, /* The handler for the command. */
0 /* Zero number of parameters. */
};

/* Size of the buffer fot storing input command from serial console. */
#define cmdMAX_INPUT_SIZE 20

/* Size of buffer for storing output string for the serial console of test runner. */
#define cmdMAX_OUTPUT_SIZE 100

void prvTestRunnerConsole()
{
int32_t bytesRead;
int8_t serialInputChar;

static const char * const pcWelcomeMessage =
"Welcome to the Test Runner console.\r\n[Type the \"start\" command to beging executing tests]\r\n>";

/* Register the "start" command that will allow user to signal from the serial console
* about when to start execution of tests by the test runner. */
FreeRTOS_CLIRegisterCommand( &xStartCommand );

/* Print welcome message on serial console to indicate prompt for entering command. */
uartConsoleIO.write( pcWelcomeMessage, strlen( pcWelcomeMessage ) );

/* The input and output buffers are declared static to keep them off the stack. */
static int8_t pOutputBuffer[ cmdMAX_OUTPUT_SIZE ], pInputBuffer[ cmdMAX_INPUT_SIZE ], pErrorBuffer[ 30 ];
BaseType_t xErrorEncountered = pdFALSE;

while( ( xReceivedCommand == pdFALSE ) && ( xErrorEncountered == pdFALSE ) )
{
static size_t inputBufferIndex = 0;

/* Read characters to input buffer. */
bytesRead = uartConsoleIO.read( &serialInputChar, 1 );

if( bytesRead > 0 )
{
/* Echo back to the console. */
uartConsoleIO.write( &serialInputChar, bytesRead );

FreeRTOS_CLI_ProcessInputBuffer( uartConsoleIO,
&serialInputChar,
bytesRead,
pInputBuffer,
sizeof( pInputBuffer ),
&inputBufferIndex,
pOutputBuffer,
sizeof( pOutputBuffer ) );
}
else
{
snprintf( pErrorBuffer,
sizeof( pErrorBuffer ),
"Read from serial console failed. Error=%d\n",
( int ) bytesRead );
uartConsoleIO.write( pErrorBuffer, strlen( pErrorBuffer ) );

xErrorEncountered = pdTRUE;
}
}
}
#endif /* if defined( AWS_TEST_RUNNER_ENABLE_CLI_INPUT ) && ( AWS_TEST_RUNNER_ENABLE_CLI_INPUT == 1 ) */

void TEST_RUNNER_RunTests_task( void * pvParameters )
{
/* Disable unused parameter warning. */
( void ) pvParameters;

/* Initialize unity. */
UnityFixture.Verbose = 1;
UnityFixture.GroupFilter = 0;
UnityFixture.NameFilter = testrunnerTEST_FILTER;
UnityFixture.RepeatCount = 1;

#if defined( AWS_TEST_RUNNER_ENABLE_CLI_INPUT ) && ( AWS_TEST_RUNNER_ENABLE_CLI_INPUT == 1 )
prvTestRunnerConsole();
#else

/* Add sufficient delay before starting tests on device to allow
* device to be available as serial port connection to the host machine
* OS.
* The serial console is used by host machine to view device logs. */
vTaskDelay( pdMS_TO_TICKS( AWS_TEST_RUNNER_DELAY_MS ) );

RunTestsWrapper();
#endif

#ifdef CODE_COVERAGE
exit( 0 );
Expand Down
28 changes: 28 additions & 0 deletions vendors/espressif/boards/esp32/aws_tests/application_code/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
/* Test includes */
#include "aws_test_runner.h"

#include "iot_uart.h"
#include "driver/uart.h"

/* AWS library includes. */
#include "iot_system_init.h"
#include "iot_logging_task.h"
Expand Down Expand Up @@ -141,6 +144,28 @@ static void prvMiscInitialization( void );

/*-----------------------------------------------------------*/

IotUARTHandle_t xConsoleUart;

static void iot_uart_init( void )
{
IotUARTConfig_t xUartConfig;
int32_t status = IOT_UART_SUCCESS;

xConsoleUart = iot_uart_open( UART_NUM_0 );
configASSERT( xConsoleUart );

status = iot_uart_ioctl( xConsoleUart, eUartGetConfig, &xUartConfig );
configASSERT( status == IOT_UART_SUCCESS );

xUartConfig.ulBaudrate = 115200;
xUartConfig.xParity = eUartParityNone;
xUartConfig.xStopbits = eUartStopBitsOne;
xUartConfig.ucFlowControl = true;

status = iot_uart_ioctl( xConsoleUart, eUartSetConfig, &xUartConfig );
configASSERT( status == IOT_UART_SUCCESS );
}

/**
* @brief Application runtime entry point.
*/
Expand Down Expand Up @@ -198,6 +223,9 @@ int app_main( void )

static void prvMiscInitialization( void )
{
/* Initialize UART. */
iot_uart_init();

/* Initialize NVS */
esp_err_t ret = nvs_flash_init();

Expand Down
Loading

0 comments on commit 441e02e

Please sign in to comment.