diff --git a/libraries/aws/ota-for-aws-iot-embedded-sdk b/libraries/aws/ota-for-aws-iot-embedded-sdk index 2bfa3038e1..f33fdb0fb0 160000 --- a/libraries/aws/ota-for-aws-iot-embedded-sdk +++ b/libraries/aws/ota-for-aws-iot-embedded-sdk @@ -1 +1 @@ -Subproject commit 2bfa3038e1d437b92f3b93a1308cf9a6ee7261ea +Subproject commit f33fdb0fb0416561ccee70beaabc7663711177a2 diff --git a/platform/lexicon.txt b/platform/lexicon.txt index ded26cf631..0ebf43d6c8 100644 --- a/platform/lexicon.txt +++ b/platform/lexicon.txt @@ -12,6 +12,7 @@ basedefs bio bitmasking blocksize +blocksize bool bootable bootloader @@ -27,6 +28,7 @@ cert cmock com config +config connectsuccessindex const couldn @@ -122,26 +124,45 @@ ota otafile otaimagestateaborted otaimagestateaccepted -otaimagestaterejected -otaimagestatetesting otaimagestateinvalid otaimagestatependingcommit otaimagestaterejected +otaimagestaterejected +otaimagestatetesting otaimagestateunknown otalastimagestate +otapal_closefile +otapalabortfailed +otapalactivatefailed +otapalbadimagestate +otapalbadsignercert +otapalbootinfocreatefailed +otapalbufferinsufficient +otapalcommitfailed +otapalcwdfailed +otapalfileabort +otapalfileclose +otapalfilegensuccess otapalimagestateinvalid otapalimagestatependingcommit otapalimagestateunknown otapalimagestatevalid otapalnullfilecontext +otapalnullfilecontext +otapaloutofmemory otapaloutofmemory otapalrejectfailed +otapalrejectfailed otapalrxfilecreatefailed +otapalrxfilecreatefailed +otapalrxfiletoolarge otapalrxfiletoolarge otapalsignaturecheckfailed +otapalsignaturecheckfailed +otapalsuccess otapalsuccess otapaluninitialized -otapal_closefile +otapaluninitialized paddrinfo palpnprotos param @@ -151,9 +172,11 @@ pcdata pcertfilepath pclientcertpath pdata +pdata pem pfile pfilecontext +pfilecontext pfilepath pformat phostname @@ -199,7 +222,6 @@ sizeof sleeptimems sni snihostname -snprintf sockaddr sockets_invalid_parameter socketstatus @@ -239,23 +261,3 @@ variadic vtaskdelay writesize www -blocksize -config -otapalsuccess -otapaluninitialized -otapaloutofmemory -otapalnullfilecontext -otapalsignaturecheckfailed -otapalrxfilecreatefailed -otapalrxfiletoolarge -otapalbootinfocreatefailed -otapalbadsignercert -otapalbadimagestate -otapalabortfailed -otapalrejectfailed -otapalcommitfailed -otapalactivatefailed -otapalfileabort -otapalfileclose -pdata -pfilecontext diff --git a/platform/posix/ota_pal/source/include/ota_pal_posix.h b/platform/posix/ota_pal/source/include/ota_pal_posix.h index 44bb706ff4..239f8c511d 100644 --- a/platform/posix/ota_pal/source/include/ota_pal_posix.h +++ b/platform/posix/ota_pal/source/include/ota_pal_posix.h @@ -28,13 +28,22 @@ #include "ota.h" - - /** * @brief Maximum file path length on Linux */ #define OTA_FILE_PATH_LENGTH_MAX 512 +/** + * @brief The OTA platform interface status for generating + * absolute file path from the incoming relative file path. + */ +typedef enum OtaPalPathGenStatus +{ + OtaPalFileGenSuccess, /*!< @brief Absolute path generation success. */ + OtaPalCWDFailed, /*!< @brief getcwd failed to output path. */ + OtaPalBufferInsufficient /*!< @brief Buffer insufficient for storing the file path. */ +} OtaPalPathGenStatus_t; + /** * @brief Abort an OTA transfer. * diff --git a/platform/posix/ota_pal/source/ota_pal_posix.c b/platform/posix/ota_pal/source/ota_pal_posix.c index 023c537bbf..4e209b1dc3 100644 --- a/platform/posix/ota_pal/source/ota_pal_posix.c +++ b/platform/posix/ota_pal/source/ota_pal_posix.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "ota.h" #include "ota_pal_posix.h" @@ -57,7 +58,12 @@ static const char signingcredentialSIGNING_CERTIFICATE_PEM[] = "Paste code signi /** * @brief Size of buffer used in file operations on this platform (POSIX). */ -#define OTA_PAL_POSIX_BUF_SIZE ( ( size_t ) 4096U ) +#define OTA_PAL_POSIX_BUF_SIZE ( ( size_t ) 4096U ) + +/** + * @brief Name of the file used for storing platform image state. + */ +#define OTA_PLATFORM_IMAGE_STATE_FILE "PlatformImageState.txt" /** * @brief Specify the OTA signature algorithm we support on this platform. @@ -83,6 +89,15 @@ static OtaPalMainStatus_t Openssl_DigestVerify( EVP_MD_CTX * pSigContext, */ static OtaPalStatus_t otaPal_CheckFileSignature( OtaFileContext_t * const C ); +/** + * @brief Get the absolute file path from the environment. + * + * @param realFilePath Buffer to store the file path + file name. + * @param pFilePath File name to append to the end of current path. + */ +static OtaPalPathGenStatus_t getFilePathFromCWD( char * realFilePath, + const char * pFilePath ); + /*-----------------------------------------------------------*/ static EVP_PKEY * Openssl_GetPkeyFromCertificate( uint8_t * pCertFilePath ) @@ -317,6 +332,38 @@ static OtaPalStatus_t otaPal_CheckFileSignature( OtaFileContext_t * const C ) return OTA_PAL_COMBINE_ERR( mainErr, 0 ); } +static OtaPalPathGenStatus_t getFilePathFromCWD( char * pCompleteFilePath, + const char * pFileName ) +{ + char * pCurrentDir = NULL; + OtaPalPathGenStatus_t status = OtaPalFileGenSuccess; + + /* Get current directory. */ + pCurrentDir = getcwd( pCompleteFilePath, OTA_FILE_PATH_LENGTH_MAX - 1 ); + + if( pCurrentDir == NULL ) + { + LogError( ( "Failed to get current working directory: %s", strerror( errno ) ) ); + status = OtaPalCWDFailed; + } + else + { + /* Add the filename . */ + if( strlen( pCompleteFilePath ) + strlen( pFileName ) + 2U > OTA_FILE_PATH_LENGTH_MAX ) + { + LogError( ( "Insufficient space to generate file path" ) ); + status = OtaPalBufferInsufficient; + } + else + { + strcat( pCompleteFilePath, "/" ); + strcat( pCompleteFilePath, pFileName ); + } + } + + return status; +} + /*-----------------------------------------------------------*/ OtaPalStatus_t otaPal_Abort( OtaFileContext_t * const C ) @@ -367,6 +414,7 @@ OtaPalStatus_t otaPal_CreateFileForRx( OtaFileContext_t * const C ) { OtaPalStatus_t result = OTA_PAL_COMBINE_ERR( OtaPalUninitialized, 0 ); char realFilePath[ OTA_FILE_PATH_LENGTH_MAX ]; + OtaPalPathGenStatus_t status = OtaPalFileGenSuccess; if( C != NULL ) { @@ -374,30 +422,34 @@ OtaPalStatus_t otaPal_CreateFileForRx( OtaFileContext_t * const C ) { if( C->pFilePath[ 0 ] != ( uint8_t ) '/' ) { - /* POSIX port using standard library */ - /* coverity[misra_c_2012_rule_21_6_violation] */ - int res = snprintf( realFilePath, OTA_FILE_PATH_LENGTH_MAX, "%s/%s", getenv( "PWD" ), C->pFilePath ); - assert( res >= 0 ); - ( void ) res; /* Suppress the unused variable warning when assert is off. */ + status = getFilePathFromCWD( realFilePath, ( const char * ) C->pFilePath ); } else { ( void ) strncpy( realFilePath, ( const char * ) C->pFilePath, strlen( ( const char * ) C->pFilePath ) + 1U ); } - /* POSIX port using standard library */ - /* coverity[misra_c_2012_rule_21_6_violation] */ - C->pFile = fopen( ( const char * ) realFilePath, "w+b" ); - - if( C->pFile != NULL ) + if( status == OtaPalFileGenSuccess ) { - result = OTA_PAL_COMBINE_ERR( OtaPalSuccess, 0 ); - LogInfo( ( "Receive file created." ) ); + /* POSIX port using standard library */ + /* coverity[misra_c_2012_rule_21_6_violation] */ + C->pFile = fopen( ( const char * ) realFilePath, "w+b" ); + + if( C->pFile != NULL ) + { + result = OTA_PAL_COMBINE_ERR( OtaPalSuccess, 0 ); + LogInfo( ( "Receive file created." ) ); + } + else + { + result = OTA_PAL_COMBINE_ERR( OtaPalRxFileCreateFailed, errno ); + LogError( ( "Failed to start operation: Operation already started. failed to open -- %s Path ", C->pFilePath ) ); + } } else { - result = OTA_PAL_COMBINE_ERR( OtaPalRxFileCreateFailed, errno ); - LogError( ( "Failed to start operation: Operation already started. failed to open -- %s Path ", C->pFilePath ) ); + LogError( ( "Could not generate the absolute path for the file" ) ); + result = OTA_PAL_COMBINE_ERR( OtaPalRxFileCreateFailed, 0 ); } } else @@ -539,24 +591,28 @@ OtaPalStatus_t otaPal_SetPlatformImageState( OtaFileContext_t * const C, OtaImageState_t eState ) { OtaPalMainStatus_t mainErr = OtaPalBadImageState; + OtaPalPathGenStatus_t status = OtaPalFileGenSuccess; int32_t subErr = 0; FILE * pPlatformImageState = NULL; - char imageStateFile[ OTA_FILE_PATH_LENGTH_MAX ]; - + char imageStateFile[ OTA_FILE_PATH_LENGTH_MAX ] = { 0 }; ( void ) C; if( ( eState != OtaImageStateUnknown ) && ( eState <= OtaLastImageState ) ) { - /* POSIX port using standard library */ - /* coverity[misra_c_2012_rule_21_6_violation] */ - int res = snprintf( imageStateFile, OTA_FILE_PATH_LENGTH_MAX, "%s/%s", getenv( "PWD" ), "PlatformImageState.txt" ); - assert( res >= 0 ); - ( void ) res; /* Suppress the unused variable warning when assert is off. */ + /* Get file path for the image state file. */ + status = getFilePathFromCWD( imageStateFile, OTA_PLATFORM_IMAGE_STATE_FILE ); - /* POSIX port using standard library */ - /* coverity[misra_c_2012_rule_21_6_violation] */ - pPlatformImageState = fopen( imageStateFile, "w+b" ); + if( status == OtaPalFileGenSuccess ) + { + /* POSIX port using standard library */ + /* coverity[misra_c_2012_rule_21_6_violation] */ + pPlatformImageState = fopen( imageStateFile, "w+b" ); + } + else + { + LogError( ( "Could not generate the absolute path for the file" ) ); + } if( pPlatformImageState != NULL ) { @@ -591,7 +647,7 @@ OtaPalStatus_t otaPal_SetPlatformImageState( OtaFileContext_t * const C, } else { - LogError( ( "Unable to open image state file. error -- %d", errno ) ); + LogError( ( "Unable to open image state file. Path: %s error: %s", imageStateFile, strerror( errno ) ) ); subErr = errno; } } @@ -626,63 +682,68 @@ OtaPalStatus_t otaPal_ResetDevice( OtaFileContext_t * const C ) */ OtaPalImageState_t otaPal_GetPlatformImageState( OtaFileContext_t * const C ) { - FILE * pPlatformImageState; + FILE * pPlatformImageState = NULL; OtaImageState_t eSavedAgentState = OtaImageStateUnknown; OtaPalImageState_t ePalState = OtaPalImageStateUnknown; - char imageStateFile[ OTA_FILE_PATH_LENGTH_MAX ]; - - /* POSIX port using standard library */ - /* coverity[misra_c_2012_rule_21_6_violation] */ - int res = snprintf( imageStateFile, OTA_FILE_PATH_LENGTH_MAX, "%s/%s", getenv( "PWD" ), "PlatformImageState.txt" ); - - assert( res >= 0 ); - ( void ) res; /* Suppress the unused variable warning when assert is off. */ + OtaPalPathGenStatus_t status = OtaPalFileGenSuccess; + char imageStateFile[ OTA_FILE_PATH_LENGTH_MAX ] = { 0 }; ( void ) C; - /* POSIX port using standard library */ - /* coverity[misra_c_2012_rule_21_6_violation] */ - pPlatformImageState = fopen( imageStateFile, "r+b" ); + /* Get file path for the image state file. */ + status = getFilePathFromCWD( imageStateFile, OTA_PLATFORM_IMAGE_STATE_FILE ); - if( pPlatformImageState != NULL ) + if( status != OtaPalFileGenSuccess ) + { + LogError( ( "Could not generate the absolute path for the file" ) ); + ePalState = OtaPalImageStateInvalid; + } + else { /* POSIX port using standard library */ /* coverity[misra_c_2012_rule_21_6_violation] */ - if( 1U != fread( &eSavedAgentState, sizeof( OtaImageState_t ), 1, pPlatformImageState ) ) - { - /* If an error occurred reading the file, mark the state as aborted. */ - LogError( ( "Failed to read image state file." ) ); - ePalState = OtaPalImageStateInvalid; - } - else + pPlatformImageState = fopen( imageStateFile, "r+b" ); + + if( pPlatformImageState != NULL ) { - if( eSavedAgentState == OtaImageStateTesting ) + /* POSIX port using standard library */ + /* coverity[misra_c_2012_rule_21_6_violation] */ + if( 1U != fread( &eSavedAgentState, sizeof( OtaImageState_t ), 1, pPlatformImageState ) ) { - ePalState = OtaPalImageStatePendingCommit; + /* If an error occurred reading the file, mark the state as aborted. */ + LogError( ( "Failed to read image state file." ) ); + ePalState = OtaPalImageStateInvalid; } - else if( eSavedAgentState == OtaImageStateAccepted ) + else { - ePalState = OtaPalImageStateValid; + if( eSavedAgentState == OtaImageStateTesting ) + { + ePalState = OtaPalImageStatePendingCommit; + } + else if( eSavedAgentState == OtaImageStateAccepted ) + { + ePalState = OtaPalImageStateValid; + } + else + { + ePalState = OtaPalImageStateInvalid; + } } - else + + /* POSIX port using standard library */ + /* coverity[misra_c_2012_rule_21_6_violation] */ + if( 0 != fclose( pPlatformImageState ) ) { + LogError( ( "Failed to close image state file." ) ); ePalState = OtaPalImageStateInvalid; } } - - /* POSIX port using standard library */ - /* coverity[misra_c_2012_rule_21_6_violation] */ - if( 0 != fclose( pPlatformImageState ) ) + else { - LogError( ( "Failed to close image state file." ) ); - ePalState = OtaPalImageStateInvalid; + /* If no image state file exists, assume a factory image. */ + ePalState = OtaPalImageStateValid; /*lint !e64 Allow assignment. */ } } - else - { - /* If no image state file exists, assume a factory image. */ - ePalState = OtaPalImageStateValid; /*lint !e64 Allow assignment. */ - } return ePalState; } diff --git a/platform/posix/ota_pal/utest/CMakeLists.txt b/platform/posix/ota_pal/utest/CMakeLists.txt index 4308f66697..ebe5cb6e05 100644 --- a/platform/posix/ota_pal/utest/CMakeLists.txt +++ b/platform/posix/ota_pal/utest/CMakeLists.txt @@ -10,6 +10,7 @@ set( project_name "ota_pal" ) list( APPEND mock_list ${CMAKE_CURRENT_LIST_DIR}/mocks/stdio_api.h ${CMAKE_CURRENT_LIST_DIR}/mocks/openssl_api.h + ${CMAKE_CURRENT_LIST_DIR}/mocks/unistd_api.h ) #list the directories your mocks need list( APPEND mock_include_list diff --git a/platform/posix/ota_pal/utest/mocks/openssl_api.h b/platform/posix/ota_pal/utest/mocks/openssl_api.h index 621d29cbfd..db7fd712e2 100644 --- a/platform/posix/ota_pal/utest/mocks/openssl_api.h +++ b/platform/posix/ota_pal/utest/mocks/openssl_api.h @@ -20,8 +20,8 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef OPENSSL_API_H_ -#define OPENSSL_API_H_ +#ifndef OPENSSL_API_H +#define OPENSSL_API_H #include @@ -134,4 +134,4 @@ extern void * CRYPTO_malloc( size_t num, const char * file, int line ); -#endif /* ifndef OPENSSL_API_H_ */ +#endif /* ifndef OPENSSL_API_H */ diff --git a/platform/posix/ota_pal/utest/mocks/stdio_api.h b/platform/posix/ota_pal/utest/mocks/stdio_api.h index c5d159dfac..2efa90e6fd 100644 --- a/platform/posix/ota_pal/utest/mocks/stdio_api.h +++ b/platform/posix/ota_pal/utest/mocks/stdio_api.h @@ -20,8 +20,8 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef STDIO_API_H_ -#define STDIO_API_H_ +#ifndef STDIO_API_H +#define STDIO_API_H #include @@ -44,13 +44,6 @@ extern _STDIO_FILE_TYPE * fopen( const char * __filename, /* Close STREAM. */ extern int fclose( _STDIO_FILE_TYPE * __stream ); -/* CMock does not support variadic functions. This alias replaces the original - * function name to get around this issue. */ -extern int snprintf_alias( char * s, - size_t n, - const char * format, - ... ); - extern size_t fread( void * ptr, size_t size, size_t count, @@ -77,4 +70,4 @@ extern size_t fwrite_alias( const void * __restrict __ptr, size_t __n, _STDIO_FILE_TYPE * __restrict __s ); -#endif /* ifndef STDIO_API_H_ */ +#endif /* ifndef STDIO_API_H */ diff --git a/platform/posix/ota_pal/utest/mocks/unistd_api.h b/platform/posix/ota_pal/utest/mocks/unistd_api.h new file mode 100644 index 0000000000..ee1eed3f42 --- /dev/null +++ b/platform/posix/ota_pal/utest/mocks/unistd_api.h @@ -0,0 +1,29 @@ +/* + * OTA PAL V2.0.0 (Release Candidate) for POSIX + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef UNISTD_API_H +#define UNISTD_API_H + +extern char * getcwd( char * buf, + size_t size ); + +#endif /* ifndef UNISTD_API_H */ diff --git a/platform/posix/ota_pal/utest/ota_config.h b/platform/posix/ota_pal/utest/ota_config.h index c99c1a5580..35e2f9959d 100644 --- a/platform/posix/ota_pal/utest/ota_config.h +++ b/platform/posix/ota_pal/utest/ota_config.h @@ -167,8 +167,4 @@ * "fwrite". The function declaration for this alias is in "stdio_api.h". */ #define fwrite fwrite_alias -/* CMock does not support variadic functions. This alias replaces the original - * function name to get around this issue. */ -#define snprintf snprintf_alias - #endif /* _OTA_CONFIG_H_ */ diff --git a/platform/posix/ota_pal/utest/ota_pal_posix_utest.c b/platform/posix/ota_pal/utest/ota_pal_posix_utest.c index ac0a39a585..cfff282519 100644 --- a/platform/posix/ota_pal/utest/ota_pal_posix_utest.c +++ b/platform/posix/ota_pal/utest/ota_pal_posix_utest.c @@ -40,6 +40,7 @@ #include "ota_pal_posix.h" #include "mock_stdio_api.h" #include "mock_openssl_api.h" +#include "mock_unistd_api.h" /* errno error macro. errno.h can't be included in this file due to mocking. */ #define ENOENT 0x02 @@ -79,11 +80,11 @@ typedef enum CRYPTO_free_fn, fopen_fn, fclose_fn, - snprintf_fn, feof_fn, fread_fn, fseek_alias_fn, - fwrite_alias_fn + fwrite_alias_fn, + getcwd_fn } MockFunctionNames_t; static void OTA_PAL_FailSingleMock_Except_fread( MockFunctionNames_t funcToFail, @@ -92,6 +93,7 @@ static void OTA_PAL_FailSingleMock_openssl_BIO( MockFunctionNames_t funcToFail ) static void OTA_PAL_FailSingleMock_openssl_X509( MockFunctionNames_t funcToFail ); static void OTA_PAL_FailSingleMock_openssl_EVP( MockFunctionNames_t funcToFail ); static void OTA_PAL_FailSingleMock_openssl_crypto( MockFunctionNames_t funcToFail ); +static void OTA_PAL_FailSingleMock_unistd( MockFunctionNames_t funcToFail ); static void OTA_PAL_FailSingleMock_stdio( MockFunctionNames_t funcToFail, OtaImageState_t * pFreadStateToSet ); static void OTA_PAL_FailSingleMock( MockFunctionNames_t funcToFail, @@ -263,6 +265,16 @@ static void OTA_PAL_FailSingleMock_openssl_crypto( MockFunctionNames_t funcToFai CRYPTO_free_Ignore(); } +static void OTA_PAL_FailSingleMock_unistd( MockFunctionNames_t funcToFail ) +{ + char * getcwd_success = "a"; + char * getcwd_failure = NULL; + char * getcwd_return; + + getcwd_return = ( funcToFail == getcwd_fn ) ? getcwd_failure : getcwd_success; + getcwd_IgnoreAndReturn( getcwd_return ); +} + /** * @brief Helper function specify a single point of failure. This needs to be * updated each time a mocked function is added or removed to the OTA PAL unit @@ -275,10 +287,6 @@ static void OTA_PAL_FailSingleMock_stdio( MockFunctionNames_t funcToFail, { static FILE dummyFile; - /* On success, snprintf returns a positive number that is less than the amount of data requested. */ - const int snprintf_success = 0; - const int snprintf_failure = -1; - int snprintf_return; /* On success, fopen returns a FILE address that is not null. */ FILE * const fopen_success = &dummyFile; FILE * const fopen_failure = NULL; @@ -315,9 +323,6 @@ static void OTA_PAL_FailSingleMock_stdio( MockFunctionNames_t funcToFail, fopen_return = ( funcToFail == fopen_fn ) ? fopen_failure : fopen_success; fopen_IgnoreAndReturn( fopen_return ); - snprintf_return = ( funcToFail == snprintf_fn ) ? snprintf_failure : snprintf_success; - snprintf_alias_IgnoreAndReturn( snprintf_return ); - fread_return = ( funcToFail == fread_fn ) ? fread_failure : fread_success; fread_IgnoreAndReturn( fread_return ); fread_ReturnThruPtr_ptr( pFreadStateToSet ); @@ -343,6 +348,7 @@ static void OTA_PAL_FailSingleMock( MockFunctionNames_t funcToFail, OTA_PAL_FailSingleMock_openssl_X509( funcToFail ); OTA_PAL_FailSingleMock_openssl_crypto( funcToFail ); OTA_PAL_FailSingleMock_openssl_EVP( funcToFail ); + OTA_PAL_FailSingleMock_unistd( funcToFail ); } /* ====================== OTA PAL ABORT UNIT TESTS ====================== */ @@ -451,7 +457,7 @@ void test_OTAPAL_CreateFileForRx_FailedToCreateFile( void ) testFile.pFile = &placeholder_file; fopen_ExpectAnyArgsAndReturn( NULL ); - + OTA_PAL_FailSingleMock_unistd( none_fn ); /* Create a file that exists with w+b mode */ result = OTA_PAL_MAIN_ERR( otaPal_CreateFileForRx( &testFile ) ); TEST_ASSERT_EQUAL( OtaPalRxFileCreateFailed, result ); @@ -468,6 +474,7 @@ void test_OTAPAL_CreateFileForRx_ValidFileHandle( void ) otaFileContext.pFilePath = ( uint8_t * ) "placeholder_path"; + OTA_PAL_FailSingleMock_unistd( none_fn ); fopen_ExpectAnyArgsAndReturn( &placeholder_file ); result = OTA_PAL_MAIN_ERR( otaPal_CreateFileForRx( &otaFileContext ) ); TEST_ASSERT_EQUAL( OtaPalSuccess, result ); @@ -485,17 +492,63 @@ void test_OTAPAL_CreateFileForRx_PathTypes( void ) /* Test for a leading forward slash in the path. */ otaFileContext.pFilePath = ( uint8_t * ) "/placeholder_path"; + OTA_PAL_FailSingleMock_unistd( none_fn ); fopen_ExpectAnyArgsAndReturn( &placeholder_file ); result = OTA_PAL_MAIN_ERR( otaPal_CreateFileForRx( &otaFileContext ) ); TEST_ASSERT_EQUAL( OtaPalSuccess, result ); /* Test for no leading forward slash in the path. */ otaFileContext.pFilePath = ( uint8_t * ) "placeholder_path"; + OTA_PAL_FailSingleMock_unistd( none_fn ); fopen_ExpectAnyArgsAndReturn( &placeholder_file ); result = OTA_PAL_MAIN_ERR( otaPal_CreateFileForRx( &otaFileContext ) ); TEST_ASSERT_EQUAL( OtaPalSuccess, result ); } +/** + * @brief Test that otaPal_CreateFileForRx will correctly handle a file path + * that is too long. + */ +void test_OTAPAL_CreateFileForRx_InvalidPathLength( void ) +{ + OtaPalMainStatus_t result; + OtaFileContext_t otaFileContext; + const size_t invalidLength = OTA_FILE_PATH_LENGTH_MAX + 1U; + char invalidLengthPath[ invalidLength ]; + size_t i; + + /* Test calling getcwd and having it return a path that is too long. */ + for( i = 0U; i < ( invalidLength - 1U ); ++i ) + { + invalidLengthPath[ i ] = 'x'; + } + + invalidLengthPath[ invalidLength - 1U ] = '\0'; + otaFileContext.pFilePath = ( uint8_t * ) "placeholder_path"; + getcwd_ExpectAnyArgsAndReturn( "placeholder_return" ); + getcwd_ReturnArrayThruPtr_buf( invalidLengthPath, invalidLength ); + result = OTA_PAL_MAIN_ERR( otaPal_CreateFileForRx( &otaFileContext ) ); + TEST_ASSERT_EQUAL( OtaPalRxFileCreateFailed, result ); +} + +/** + * @brief Test that otaPal_CreateFileForRx will handle the getcwd command + * failing. + */ +void test_OTAPAL_CreateFileForRx_getcwd_fail( void ) +{ + OtaPalMainStatus_t result; + OtaFileContext_t otaFileContext; + OtaImageState_t validState = OtaImageStateTesting; + + + otaFileContext.pFilePath = ( uint8_t * ) "placeholder_path"; + + OTA_PAL_FailSingleMock( getcwd_fn, &validState ); + result = OTA_PAL_MAIN_ERR( otaPal_CreateFileForRx( &otaFileContext ) ); + TEST_ASSERT_EQUAL( OtaPalRxFileCreateFailed, result ); +} + /* =================== OTA PAL CLOSE FILE UNIT TESTS ==================== */ void test_OTAPAL_CloseFile_NullInput( void ) @@ -772,7 +825,7 @@ void test_OTAPAL_CloseFile_EVP_DigestVerifyInit_fail( void ) * implementation. It is defined by the "OTA_PAL_POSIX_BUF_SIZE" macro in the * OTA posix PAL implementation .c file. */ -void test_OTAPAL_CloseFile_MaxBlockSize() +void test_OTAPAL_CloseFile_MaxBlockSize( void ) { const size_t OTA_PAL_POSIX_BUF_SIZE = 4096U; OtaPalStatus_t result; @@ -943,6 +996,7 @@ void test_OTAPAL_SetPlatformImageState_HappyPath( void ) OtaFileContext_t otaFileContext; OtaImageState_t validState = OtaImageStateTesting; + OTA_PAL_FailSingleMock_unistd( none_fn ); OTA_PAL_FailSingleMock_stdio( none_fn, NULL ); result = otaPal_SetPlatformImageState( &otaFileContext, validState ); TEST_ASSERT_EQUAL( OtaPalSuccess, OTA_PAL_MAIN_ERR( result ) ); @@ -957,6 +1011,7 @@ void test_OTAPAL_SetPlatformImageState_fopen_fail( void ) OtaFileContext_t otaFileContext; OtaImageState_t validState = OtaImageStateTesting; + OTA_PAL_FailSingleMock_unistd( none_fn ); OTA_PAL_FailSingleMock_stdio( fopen_fn, NULL ); result = otaPal_SetPlatformImageState( &otaFileContext, validState ); TEST_ASSERT_EQUAL( OtaPalBadImageState, OTA_PAL_MAIN_ERR( result ) ); @@ -971,6 +1026,7 @@ void test_OTAPAL_SetPlatformImageState_fwrite_fail( void ) OtaFileContext_t otaFileContext; OtaImageState_t validState = OtaImageStateTesting; + OTA_PAL_FailSingleMock_unistd( none_fn ); OTA_PAL_FailSingleMock_stdio( fwrite_alias_fn, NULL ); result = otaPal_SetPlatformImageState( &otaFileContext, validState ); TEST_ASSERT_EQUAL( OtaPalBadImageState, OTA_PAL_MAIN_ERR( result ) ); @@ -985,6 +1041,7 @@ void test_OTAPAL_SetPlatformImageState_fclose_fail( void ) OtaFileContext_t otaFileContext; OtaImageState_t validState = OtaImageStateTesting; + OTA_PAL_FailSingleMock_unistd( none_fn ); OTA_PAL_FailSingleMock_stdio( fclose_fn, NULL ); result = otaPal_SetPlatformImageState( &otaFileContext, validState ); TEST_ASSERT_EQUAL( OtaPalBadImageState, OTA_PAL_MAIN_ERR( result ) ); @@ -1002,6 +1059,7 @@ void test_OTAPAL_GetPlatformImageState_fopen_fails( void ) OtaPalImageState_t ePalImageState; OtaFileContext_t otaFileContext; + OTA_PAL_FailSingleMock_unistd( none_fn ); OTA_PAL_FailSingleMock_stdio( fopen_fn, NULL ); /* The file failed to close, so it is invalid or in an unknown state. */ ePalImageState = otaPal_GetPlatformImageState( &otaFileContext ); @@ -1018,23 +1076,18 @@ void test_OTAPAL_GetPlatformImageState_fread_fails( void ) OtaPalImageState_t ePalImageState; OtaFileContext_t otaFileContext; + OTA_PAL_FailSingleMock_unistd( none_fn ); OTA_PAL_FailSingleMock_stdio( fread_fn, NULL ); ePalImageState = otaPal_GetPlatformImageState( &otaFileContext ); TEST_ASSERT_EQUAL( OtaPalImageStateInvalid, ePalImageState ); } -/** - * @brief This test validates that the valid states are correctly returned to - * the caller. - * */ void test_OTAPAL_GetPlatformImageState_fclose_fails( void ) { OtaPalImageState_t ePalImageState = OtaPalImageStateUnknown; OtaFileContext_t otaFileContext; FILE dummyFile; - /* On success, snprintf returns a positive number that is less than the amount of data requested. */ - const int snprintf_success_val = 0; /* On success, fopen returns a FILE address that is not null. */ FILE * const fopen_success_val = &dummyFile; @@ -1045,7 +1098,7 @@ void test_OTAPAL_GetPlatformImageState_fclose_fails( void ) const int fclose_fail_val = EOF; /* Predefine what functions are expected to be called. */ - snprintf_alias_ExpectAnyArgsAndReturn( snprintf_success_val ); + OTA_PAL_FailSingleMock_unistd( none_fn ); fopen_ExpectAnyArgsAndReturn( fopen_success_val ); fread_ExpectAnyArgsAndReturn( fread_success_val ); fclose_ExpectAnyArgsAndReturn( fclose_fail_val ); @@ -1071,8 +1124,6 @@ void test_OTAPAL_GetPlatformImageState_ValidStates( void ) * expected values. */ const OtaImageState_t invalidImageState = OtaLastImageState + 1; - /* On success, snprintf returns a positive number that is less than the amount of data requested. */ - const int snprintf_success_val = 0; /* On success, fopen returns a FILE address that is not null. */ FILE * const fopen_success_val = &dummyFile; @@ -1082,10 +1133,10 @@ void test_OTAPAL_GetPlatformImageState_ValidStates( void ) /* On success, fclose returns a zero. */ const int fclose_success_val = 0; + OTA_PAL_FailSingleMock_unistd( none_fn ); /* Test the scenario where the platform state is OtaImageStateTesting. */ freadResultingState = OtaImageStateTesting; /* Predefine what functions are expected to be called. */ - snprintf_alias_ExpectAnyArgsAndReturn( snprintf_success_val ); fopen_ExpectAnyArgsAndReturn( fopen_success_val ); fread_ExpectAnyArgsAndReturn( fread_success_val ); fread_ReturnThruPtr_ptr( &freadResultingState ); @@ -1097,7 +1148,6 @@ void test_OTAPAL_GetPlatformImageState_ValidStates( void ) /* Test the scenario where the platform state is OtaImageStateAccepted. */ freadResultingState = OtaImageStateAccepted; /* Predefine what functions are expected to be called. */ - snprintf_alias_ExpectAnyArgsAndReturn( snprintf_success_val ); fopen_ExpectAnyArgsAndReturn( fopen_success_val ); fread_ExpectAnyArgsAndReturn( fread_success_val ); fread_ReturnThruPtr_ptr( &freadResultingState ); @@ -1109,7 +1159,6 @@ void test_OTAPAL_GetPlatformImageState_ValidStates( void ) /* Test the scenario where the platform state is an unexpected value. */ freadResultingState = invalidImageState; /* Predefine what functions are expected to be called. */ - snprintf_alias_ExpectAnyArgsAndReturn( snprintf_success_val ); fopen_ExpectAnyArgsAndReturn( fopen_success_val ); fread_ExpectAnyArgsAndReturn( fread_success_val ); fread_ReturnThruPtr_ptr( &freadResultingState ); @@ -1118,3 +1167,14 @@ void test_OTAPAL_GetPlatformImageState_ValidStates( void ) ePalImageState = otaPal_GetPlatformImageState( &otaFileContext ); TEST_ASSERT_EQUAL( OtaPalImageStateInvalid, ePalImageState ); } + +void test_OTAPAL_GetPlatformImageState_getcwd_fail( void ) +{ + OtaPalImageState_t ePalImageState; + OtaFileContext_t otaFileContext; + + OTA_PAL_FailSingleMock_unistd( getcwd_fn ); + OTA_PAL_FailSingleMock_stdio( none_fn, NULL ); + ePalImageState = otaPal_GetPlatformImageState( &otaFileContext ); + TEST_ASSERT_EQUAL( OtaPalImageStateInvalid, ePalImageState ); +}