From df553bda2beebbbe21834c6a95274029aa365259 Mon Sep 17 00:00:00 2001
From: chinglee-iot <61685396+chinglee-iot@users.noreply.github.com>
Date: Wed, 31 Jan 2024 14:31:58 +0800
Subject: [PATCH] Update Cellular_CommonInit error handling (#163)
* Update Cellular_CommonInit error handling
* Update size table
* Update CBMC for Cellular_CommonInit
---
docs/doxygen/include/size_table.md | 4 +-
source/cellular_common_api.c | 61 ++++--
.../Cellular_CommonInit_harness.c | 4 +-
test/cbmc/proofs/Cellular_CommonInit/Makefile | 4 +-
test/cbmc/sources/cellular_modules.c | 73 +++---
test/unit-test/cellular_common_api_utest.c | 207 +++++++++++++++++-
6 files changed, 307 insertions(+), 46 deletions(-)
diff --git a/docs/doxygen/include/size_table.md b/docs/doxygen/include/size_table.md
index 1c39ee78..80795d8a 100644
--- a/docs/doxygen/include/size_table.md
+++ b/docs/doxygen/include/size_table.md
@@ -25,7 +25,7 @@
cellular_common_api.c |
0.7K |
- 0.6K |
+ 0.7K |
cellular_common.c |
@@ -45,6 +45,6 @@
Total estimates |
15.1K |
- 13.6K |
+ 13.7K |
diff --git a/source/cellular_common_api.c b/source/cellular_common_api.c
index d6a7e167..e1189452 100644
--- a/source/cellular_common_api.c
+++ b/source/cellular_common_api.c
@@ -146,25 +146,58 @@ CellularError_t Cellular_CommonInit( CellularHandle_t * pCellularHandle,
CellularError_t cellularStatus = CELLULAR_SUCCESS;
CellularContext_t * pContext = NULL;
- /* Init the common library. */
- cellularStatus = _Cellular_LibInit( pCellularHandle, pCommInterface, pTokenTable );
-
- /* Init the module. */
- if( cellularStatus == CELLULAR_SUCCESS )
+ if( pCellularHandle == NULL )
{
- pContext = *pCellularHandle;
- cellularStatus = Cellular_ModuleInit( pContext, &pContext->pModuleContext );
+ LogError( ( "Cellular_CommonInit pCellularHandle is NULL." ) );
+ cellularStatus = CELLULAR_INVALID_HANDLE;
}
-
- /* Setup UE, URC and query register status. */
- if( cellularStatus == CELLULAR_SUCCESS )
+ else if( pCommInterface == NULL )
{
- cellularStatus = Cellular_ModuleEnableUE( pContext );
+ LogError( ( "Cellular_CommonInit pCommInterface is NULL." ) );
+ cellularStatus = CELLULAR_BAD_PARAMETER;
}
-
- if( cellularStatus == CELLULAR_SUCCESS )
+ else if( pTokenTable == NULL )
+ {
+ LogError( ( "Cellular_CommonInit pTokenTable is NULL." ) );
+ cellularStatus = CELLULAR_BAD_PARAMETER;
+ }
+ else
{
- cellularStatus = Cellular_ModuleEnableUrc( pContext );
+ /* Init the common library. */
+ cellularStatus = _Cellular_LibInit( pCellularHandle, pCommInterface, pTokenTable );
+
+ if( cellularStatus == CELLULAR_SUCCESS )
+ {
+ pContext = ( CellularContext_t * ) ( *pCellularHandle );
+
+ cellularStatus = Cellular_ModuleInit( pContext, &pContext->pModuleContext );
+
+ if( cellularStatus == CELLULAR_SUCCESS )
+ {
+ cellularStatus = Cellular_ModuleEnableUE( pContext );
+
+ if( cellularStatus == CELLULAR_SUCCESS )
+ {
+ cellularStatus = Cellular_ModuleEnableUrc( pContext );
+ }
+
+ if( cellularStatus != CELLULAR_SUCCESS )
+ {
+ /* Clean up the resource allocated by cellular module here if
+ * Cellular_ModuleEnableUE or Cellular_ModuleEnableUrc returns
+ * error. */
+ ( void ) Cellular_ModuleCleanUp( pContext );
+ }
+ }
+
+ if( cellularStatus != CELLULAR_SUCCESS )
+ {
+ /* Clean up the resource in cellular common library if any of the
+ * module port function returns error. Error returned by _Cellular_LibInit
+ * is already handled in the implementation. */
+ ( void ) _Cellular_LibCleanup( pContext );
+ }
+ }
}
return cellularStatus;
diff --git a/test/cbmc/proofs/Cellular_CommonInit/Cellular_CommonInit_harness.c b/test/cbmc/proofs/Cellular_CommonInit/Cellular_CommonInit_harness.c
index 7ffc118d..5e1e9beb 100644
--- a/test/cbmc/proofs/Cellular_CommonInit/Cellular_CommonInit_harness.c
+++ b/test/cbmc/proofs/Cellular_CommonInit/Cellular_CommonInit_harness.c
@@ -96,5 +96,7 @@ void harness()
* Initialize the member of Cellular_CommonInit.
****************************************************************/
- Cellular_CommonInit( nondet_bool() ? NULL : &pHandle, &CellularCommInterface, &tokenTable );
+ Cellular_CommonInit( nondet_bool() ? NULL : &pHandle,
+ nondet_bool() ? NULL : &CellularCommInterface,
+ nondet_bool() ? NULL : &tokenTable );
}
diff --git a/test/cbmc/proofs/Cellular_CommonInit/Makefile b/test/cbmc/proofs/Cellular_CommonInit/Makefile
index 956dd779..dd991480 100755
--- a/test/cbmc/proofs/Cellular_CommonInit/Makefile
+++ b/test/cbmc/proofs/Cellular_CommonInit/Makefile
@@ -24,7 +24,7 @@ HARNESS_ENTRY=harness
HARNESS_FILE=Cellular_CommonInit_harness
PROOF_UID = Cellular_CommonInit
-DEFINES +=
+DEFINES += -DCBMC_TEST_CELLULAR_MODULE_RETURN_ERROR=1
INCLUDES +=
PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c
@@ -35,4 +35,6 @@ PROOF_SOURCES += $(SRCDIR)/test/cbmc/sources/cellular_modules.c
PROJECT_SOURCES += $(SRCDIR)/source/cellular_common_api.c
PROJECT_SOURCES += $(SRCDIR)/source/cellular_common.c
+UNWINDSET += __CPROVER_file_local_cellular_common_c_libClose.0:20
+
include ../Makefile.common
diff --git a/test/cbmc/sources/cellular_modules.c b/test/cbmc/sources/cellular_modules.c
index 489e0847..471d2360 100644
--- a/test/cbmc/sources/cellular_modules.c
+++ b/test/cbmc/sources/cellular_modules.c
@@ -33,41 +33,64 @@
/* Include paths for public enums, structures, and macros. */
#include "cellular_common_portable.h"
-CellularError_t Cellular_ModuleInit( const CellularContext_t * pContext,
- void ** ppModuleContext )
-{
- CellularError_t ret = nondet_int();
+#if ( CBMC_TEST_CELLULAR_MODULE_RETURN_ERROR == 1 )
- __CPROVER_assume( ret >= CELLULAR_SUCCESS && ret <= CELLULAR_UNKNOWN );
- return ret;
-}
+ CellularError_t Cellular_ModuleInit( const CellularContext_t * pContext,
+ void ** ppModuleContext )
+ {
+ CellularError_t ret = nondet_int();
+ __CPROVER_assume( ret >= CELLULAR_SUCCESS && ret <= CELLULAR_UNKNOWN );
+ return ret;
+ }
-CellularError_t Cellular_ModuleCleanUp( const CellularContext_t * pContext )
-{
- CellularError_t ret = nondet_int();
+ CellularError_t Cellular_ModuleCleanUp( const CellularContext_t * pContext )
+ {
+ CellularError_t ret = nondet_int();
- __CPROVER_assume( ret >= CELLULAR_SUCCESS && ret <= CELLULAR_UNKNOWN );
- return ret;
-}
+ __CPROVER_assume( ret >= CELLULAR_SUCCESS && ret <= CELLULAR_UNKNOWN );
+ return ret;
+ }
+ CellularError_t Cellular_ModuleEnableUE( CellularContext_t * pContext )
+ {
+ CellularError_t ret = nondet_int();
-CellularError_t Cellular_ModuleEnableUE( CellularContext_t * pContext )
-{
- CellularError_t ret = nondet_int();
+ __CPROVER_assume( ret >= CELLULAR_SUCCESS && ret <= CELLULAR_UNKNOWN );
+ return ret;
+ }
- __CPROVER_assume( ret >= CELLULAR_SUCCESS && ret <= CELLULAR_UNKNOWN );
- return ret;
-}
+ CellularError_t Cellular_ModuleEnableUrc( CellularContext_t * pContext )
+ {
+ CellularError_t ret = nondet_int();
+ __CPROVER_assume( ret >= CELLULAR_SUCCESS && ret <= CELLULAR_UNKNOWN );
+ return ret;
+ }
-CellularError_t Cellular_ModuleEnableUrc( CellularContext_t * pContext )
-{
- CellularError_t ret = nondet_int();
+#else /* #if ( CBMC_TEST_CELLULAR_MODULE_NO_ERROR == 1 ) */
- __CPROVER_assume( ret >= CELLULAR_SUCCESS && ret <= CELLULAR_UNKNOWN );
- return ret;
-}
+ CellularError_t Cellular_ModuleInit( const CellularContext_t * pContext,
+ void ** ppModuleContext )
+ {
+ return CELLULAR_SUCCESS;
+ }
+ CellularError_t Cellular_ModuleCleanUp( const CellularContext_t * pContext )
+ {
+ return CELLULAR_SUCCESS;
+ }
+
+ CellularError_t Cellular_ModuleEnableUE( CellularContext_t * pContext )
+ {
+ return CELLULAR_SUCCESS;
+ }
+
+ CellularError_t Cellular_ModuleEnableUrc( CellularContext_t * pContext )
+ {
+ return CELLULAR_SUCCESS;
+ }
+
+#endif /* #if ( CBMC_TEST_CELLULAR_MODULE_NO_ERROR == 1 ) */
/* ========================================================================== */
diff --git a/test/unit-test/cellular_common_api_utest.c b/test/unit-test/cellular_common_api_utest.c
index 787afa06..a0017f68 100644
--- a/test/unit-test/cellular_common_api_utest.c
+++ b/test/unit-test/cellular_common_api_utest.c
@@ -277,19 +277,220 @@ static CellularCommInterface_t cellularCommInterface =
/* ========================================================================== */
/**
- * @brief Test that null handler case for Cellular_CommonInit.
+ * @brief Cellular_CommonInit - Test the null pCommInterface parameter.
+ *
+ * Coverage
+ * @code{c}
+ * if( pCellularHandle == NULL )
+ * {
+ * LogError( ( "Cellular_CommonInit pCellularHandle is NULL." ) );
+ * cellularStatus = CELLULAR_INVALID_HANDLE;
+ * }
+ * @endcode
+ * ( pCellularHandle == NULL ) is true.
*/
void test_Cellular_CommonInit_Null_Handler( void )
{
CellularError_t cellularStatus = CELLULAR_SUCCESS;
- _Cellular_LibInit_IgnoreAndReturn( CELLULAR_INVALID_HANDLE );
-
+ /* API call. */
cellularStatus = Cellular_CommonInit( NULL, &cellularCommInterface, &tokenTable );
+ /* Verification. */
TEST_ASSERT_EQUAL( CELLULAR_INVALID_HANDLE, cellularStatus );
}
+/**
+ * @brief Cellular_CommonInit - Test the null pCommInterface parameter.
+ *
+ * Coverage
+ * @code{c}
+ * else if( pCommInterface == NULL )
+ * {
+ * LogError( ( "Cellular_CommonInit pCommInterface is NULL." ) );
+ * cellularStatus = CELLULAR_BAD_PARAMETER;
+ * }
+ * @endcode
+ * ( pCommInterface == NULL ) is true.
+ */
+void test_Cellular_CommonInit_Null_Comm_Interface( void )
+{
+ struct CellularContext * pHandler;
+ CellularError_t cellularStatus = CELLULAR_SUCCESS;
+
+ /* API call. */
+ cellularStatus = Cellular_CommonInit( &pHandler, NULL, &tokenTable );
+
+ /* Verification. */
+ TEST_ASSERT_EQUAL( CELLULAR_BAD_PARAMETER, cellularStatus );
+}
+
+/**
+ * @brief Cellular_CommonInit - Test the null pTokenTable parameter.
+ *
+ * Coverage
+ * @code{c}
+ * else if( pTokenTable == NULL )
+ * {
+ * LogError( ( "Cellular_CommonInit pTokenTable is NULL." ) );
+ * cellularStatus = CELLULAR_BAD_PARAMETER;
+ * }
+ * @endcode
+ * ( pTokenTable == NULL ) is true.
+ */
+void test_Cellular_CommonInit_Null_Token_Table( void )
+{
+ struct CellularContext * pHandler;
+ CellularError_t cellularStatus = CELLULAR_SUCCESS;
+
+ /* API call. */
+ cellularStatus = Cellular_CommonInit( &pHandler, &cellularCommInterface, NULL );
+
+ /* Verification. */
+ TEST_ASSERT_EQUAL( CELLULAR_BAD_PARAMETER, cellularStatus );
+}
+
+/**
+ * @brief Cellular_CommonInit - Test that _Cellular_LibInit returns error.
+ *
+ * Coverage
+ * @code{c}
+ * cellularStatus = _Cellular_LibInit( pCellularHandle, pCommInterface, pTokenTable );
+ * ...
+ * if( cellularStatus == CELLULAR_SUCCESS )
+ * {
+ * ...
+ * }
+ * @endcode
+ * ( cellularStatus == CELLULAR_SUCCESS ) is false.
+ */
+void test_Cellular_CommonInit_Lib_Init_error( void )
+{
+ struct CellularContext * pHandler;
+ CellularError_t cellularStatus = CELLULAR_SUCCESS;
+
+ /* Expectation. */
+ _Cellular_LibInit_IgnoreAndReturn( CELLULAR_RESOURCE_CREATION_FAIL );
+
+ /* API call. */
+ cellularStatus = Cellular_CommonInit( &pHandler, &cellularCommInterface, &tokenTable );
+
+ /* Verification. */
+ TEST_ASSERT_EQUAL( CELLULAR_RESOURCE_CREATION_FAIL, cellularStatus );
+}
+
+/**
+ * @brief Cellular_CommonInit - Test that Cellular_ModuleInit returns error.
+ *
+ * Coverage
+ * @code{c}
+ * cellularStatus = Cellular_ModuleInit( pContext, &pContext->pModuleContext );
+ * ...
+ * if( cellularStatus != CELLULAR_SUCCESS )
+ * {
+ * ( void ) _Cellular_LibCleanup( pContext );
+ * }
+ * @endcode
+ * ( cellularStatus != CELLULAR_SUCCESS ) is true.
+ */
+void test_Cellular_CommonInit_Module_Init_error( void )
+{
+ struct CellularContext xCellularContext = { 0 };
+ struct CellularContext * pContext;
+ CellularError_t cellularStatus = CELLULAR_SUCCESS;
+
+ /* Setup. */
+ pContext = &xCellularContext;
+
+ /* Expectation. */
+ _Cellular_LibInit_IgnoreAndReturn( CELLULAR_SUCCESS );
+ Cellular_ModuleInit_ExpectAndReturn( &xCellularContext, &xCellularContext.pModuleContext, CELLULAR_INTERNAL_FAILURE );
+ _Cellular_LibCleanup_ExpectAndReturn( &xCellularContext, CELLULAR_SUCCESS );
+
+ /* API call. */
+ cellularStatus = Cellular_CommonInit( &pContext, &cellularCommInterface, &tokenTable );
+
+ /* Verification. */
+ TEST_ASSERT_EQUAL( CELLULAR_INTERNAL_FAILURE, cellularStatus );
+}
+
+/**
+ * @brief Cellular_CommonInit - Test that Cellular_ModuleEnableUE returns error.
+ *
+ * Coverage
+ * @code{c}
+ * cellularStatus = Cellular_ModuleEnableUE( pContext );
+ * if( cellularStatus == CELLULAR_SUCCESS )
+ * {
+ * cellularStatus = Cellular_ModuleEnableUrc( pContext );
+ * }
+ * @endcode
+ * ( cellularStatus == CELLULAR_SUCCESS ) is false.
+ */
+void test_Cellular_CommonInit_Module_Enable_UE_error( void )
+{
+ struct CellularContext xCellularContext = { 0 };
+ struct CellularContext * pContext;
+ CellularError_t cellularStatus = CELLULAR_SUCCESS;
+
+ /* Setup. */
+ pContext = &xCellularContext;
+
+ /* Expectation. */
+ _Cellular_LibInit_IgnoreAndReturn( CELLULAR_SUCCESS );
+ Cellular_ModuleInit_ExpectAndReturn( &xCellularContext, &xCellularContext.pModuleContext, CELLULAR_SUCCESS );
+ Cellular_ModuleEnableUE_ExpectAndReturn( &xCellularContext, CELLULAR_INTERNAL_FAILURE );
+
+ Cellular_ModuleCleanUp_ExpectAndReturn( &xCellularContext, CELLULAR_SUCCESS );
+ _Cellular_LibCleanup_ExpectAndReturn( &xCellularContext, CELLULAR_SUCCESS );
+
+ /* API call. */
+ cellularStatus = Cellular_CommonInit( &pContext, &cellularCommInterface, &tokenTable );
+
+ /* Verification. */
+ TEST_ASSERT_EQUAL( CELLULAR_INTERNAL_FAILURE, cellularStatus );
+}
+
+/**
+ * @brief Cellular_CommonInit - Test that Cellular_ModuleEnableUrc returns error.
+ *
+ * Coverage
+ * @code{c}
+ * ...
+ * cellularStatus = Cellular_ModuleEnableUrc( pContext );
+ * ...
+ * if( cellularStatus != CELLULAR_SUCCESS )
+ * {
+ * cellularStatus = Cellular_ModuleCleanUp( pContext );
+ * }
+ * @endcode
+ * ( cellularStatus != CELLULAR_SUCCESS ) is true.
+ */
+void test_Cellular_CommonInit_Module_Enable_URC_error( void )
+{
+ struct CellularContext xCellularContext = { 0 };
+ struct CellularContext * pContext;
+ CellularError_t cellularStatus = CELLULAR_SUCCESS;
+
+ /* Setup. */
+ pContext = &xCellularContext;
+
+ /* Expectation. */
+ _Cellular_LibInit_IgnoreAndReturn( CELLULAR_SUCCESS );
+ Cellular_ModuleInit_ExpectAndReturn( &xCellularContext, &xCellularContext.pModuleContext, CELLULAR_SUCCESS );
+ Cellular_ModuleEnableUE_ExpectAndReturn( &xCellularContext, CELLULAR_SUCCESS );
+ Cellular_ModuleEnableUrc_ExpectAndReturn( &xCellularContext, CELLULAR_INTERNAL_FAILURE );
+
+ Cellular_ModuleCleanUp_ExpectAndReturn( &xCellularContext, CELLULAR_SUCCESS );
+ _Cellular_LibCleanup_ExpectAndReturn( &xCellularContext, CELLULAR_SUCCESS );
+
+ /* API call. */
+ cellularStatus = Cellular_CommonInit( &pContext, &cellularCommInterface, &tokenTable );
+
+ /* Verification. */
+ TEST_ASSERT_EQUAL( CELLULAR_INTERNAL_FAILURE, cellularStatus );
+}
+
/**
* @brief Test that happy path case for Cellular_CommonInit.
*/