Skip to content

Commit

Permalink
Bug Fix: OTA_Resume only restarts selftest timer while selftesting (#439
Browse files Browse the repository at this point in the history
)

* fix: Only resume selftest timer while selftesting

* New unit tests + 100% coverage

* fix cbmc test
  • Loading branch information
dachalco committed Jun 17, 2022
1 parent eceee4a commit 7102153
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 5 deletions.
11 changes: 7 additions & 4 deletions source/ota.c
Original file line number Diff line number Diff line change
Expand Up @@ -3478,10 +3478,13 @@ OtaErr_t OTA_Resume( void )
/*
* Resume timers.
*/
( void ) otaAgent.pOtaInterface->os.timer.start( OtaSelfTestTimer,
"OtaSelfTestTimer",
otaconfigSELF_TEST_RESPONSE_WAIT_MS,
otaTimerCallback );
if( platformInSelftest() )
{
( void ) otaAgent.pOtaInterface->os.timer.start( OtaSelfTestTimer,
"OtaSelfTestTimer",
otaconfigSELF_TEST_RESPONSE_WAIT_MS,
otaTimerCallback );
}

( void ) otaAgent.pOtaInterface->os.timer.start( OtaRequestTimer,
"OtaRequestTimer",
Expand Down
1 change: 1 addition & 0 deletions test/cbmc/proofs/OTA_Resume/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ REMOVE_FUNCTION_BODY += OTA_SignalEvent

RESTRICT_FUNCTION_POINTER += OTA_Resume.function_pointer_call.1/startTimerStub
RESTRICT_FUNCTION_POINTER += OTA_Resume.function_pointer_call.2/startTimerStub
RESTRICT_FUNCTION_POINTER += platformInSelftest.function_pointer_call.1/getPlatformImageStateStub

# If this proof is found to consume huge amounts of RAM, you can set the
# EXPENSIVE variable. With new enough versions of the proof tools, this will
Expand Down
3 changes: 2 additions & 1 deletion test/cbmc/proofs/OTA_Resume/OTA_Resume_harness.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ void OTA_Resume_harness()
{
OtaInterfaces_t otaInterface;

/* Initialize os timers. */
/* Initialize os timers and self-test state fetcher */
otaInterface.pal.getPlatformImageState = getPlatformImageStateStub;
otaInterface.os.timer.start = startTimerStub;
otaAgent.pOtaInterface = &otaInterface;

Expand Down
90 changes: 90 additions & 0 deletions test/unit-test/ota_utest.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,12 @@ static uint8_t pLargerJobNameBuffer[ OTA_JOB_ID_MAX_SIZE * 2 ];
/* A counter to record how many file blocks are received. */
static int otaReceivedFileBlockNumber = 0;

/* A boolean reflecting the state of the self-test timer. */
static bool bSelfTestTimerIsActive = false;

/* A boolean reflecting the state of the data request timer. */
static bool bRequestTimerIsActive = false;

/* ========================================================================== */

/* Global static variable defined in ota.c for managing the state machine. */
Expand Down Expand Up @@ -346,6 +352,26 @@ static OtaOsStatus_t stubOSTimerStart( OtaTimerId_t timerId,
return OtaOsSuccess;
}

static OtaOsStatus_t mockOSTimerStart( OtaTimerId_t timerId,
const char * const pTimerName,
const uint32_t timeout,
OtaTimerCallback_t callback )
{
if( timerId == OtaRequestTimer )
{
bRequestTimerIsActive = true;
}
else if( timerId == OtaSelfTestTimer )
{
bSelfTestTimerIsActive = true;
}

( void ) pTimerName;
( void ) timeout;
( void ) callback;
return OtaOsSuccess;
}

static OtaOsStatus_t mockOSTimerInvokeCallback( OtaTimerId_t timerId,
const char * const pTimerName,
const uint32_t timeout,
Expand Down Expand Up @@ -375,6 +401,20 @@ static OtaOsStatus_t stubOSTimerStop( OtaTimerId_t timerId )
return OtaOsSuccess;
}

static OtaOsStatus_t mockOSTimerStop( OtaTimerId_t timerId )
{
if( timerId == OtaRequestTimer )
{
bRequestTimerIsActive = false;
}
else if( timerId == OtaSelfTestTimer )
{
bSelfTestTimerIsActive = false;
}

return OtaOsSuccess;
}

static OtaOsStatus_t stubOSTimerDelete( OtaTimerId_t timerId )
{
( void ) timerId;
Expand Down Expand Up @@ -1197,6 +1237,56 @@ void test_OTA_ResumeFailedWhenSuspended()
TEST_ASSERT_EQUAL( OtaAgentStateSuspended, OTA_GetState() );
}

void test_OTA_ResumeSelfTestTimerRestart()
{
otaGoToState( OtaAgentStateSuspended );
TEST_ASSERT_EQUAL( OtaAgentStateSuspended, OTA_GetState() );

/* Reset timer state and configure mocked timer function for tracking timer state */
bSelfTestTimerIsActive = false;
bRequestTimerIsActive = false;
otaInterfaces.os.timer.start = mockOSTimerStart;
otaInterfaces.os.timer.stop = mockOSTimerStop;
otaInterfaces.os.event.send = mockOSEventSend;

/* Let the PAL always says it's in self test. */
otaInterfaces.pal.getPlatformImageState = mockPalGetPlatformImageStateAlwaysPendingCommit;
TEST_ASSERT_EQUAL( OtaErrNone, OTA_Resume() );

/* Self test timer should be restarted if the device is self testing. */
TEST_ASSERT_TRUE( bSelfTestTimerIsActive );
TEST_ASSERT_TRUE( bRequestTimerIsActive );

/* As this was a nominal flow, OTA should resume without issue. */
receiveAndProcessOtaEvent();
TEST_ASSERT_EQUAL( OtaAgentStateRequestingJob, OTA_GetState() );
}

void test_OTA_ResumeNoSelfTestTimerRestart()
{
otaGoToState( OtaAgentStateSuspended );
TEST_ASSERT_EQUAL( OtaAgentStateSuspended, OTA_GetState() );

/* Reset timer state and configure mocked timer function for tracking timer state */
bSelfTestTimerIsActive = false;
bRequestTimerIsActive = false;
otaInterfaces.os.timer.start = mockOSTimerStart;
otaInterfaces.os.timer.stop = mockOSTimerStop;
otaInterfaces.os.event.send = mockOSEventSend;

/* Let the PAL always says it's not in self test. */
otaInterfaces.pal.getPlatformImageState = mockPalGetPlatformImageStateAlwaysInvalid;
TEST_ASSERT_EQUAL( OtaErrNone, OTA_Resume() );

/* Self test timer should NOT be restarted if the device is not self testing. */
TEST_ASSERT_FALSE( bSelfTestTimerIsActive );
TEST_ASSERT_TRUE( bRequestTimerIsActive );

/* As this was a nominal flow, OTA should resume without issue. */
receiveAndProcessOtaEvent();
TEST_ASSERT_EQUAL( OtaAgentStateRequestingJob, OTA_GetState() );
}

void test_OTA_Statistics()
{
otaGoToState( OtaAgentStateReady );
Expand Down

0 comments on commit 7102153

Please sign in to comment.