Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #2379, implement SB bulk transfer test #2380

Merged
merged 1 commit into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions modules/cfe_assert/inc/cfe_assert.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,23 @@ typedef void (*CFE_Assert_StatusCallback_t)(uint8 MessageType, const char *Prefi
*/
#define CFE_Assert_STATUS_STORE(FN) CFE_Assert_Status_Store(FN, __FILE__, __LINE__, #FN)

/**
** \brief Check if the stored status matches a possible value
**
** Allows the caller to check the value from a previous invocation of CFE_Assert_STATUS_STORE()
** without directly asserting on the value or changing test state.
**
** This may be useful in situations where a large volume of tests are being performed, such as
** during performance or load testing, where reporting all "PASS" cases may add signficant
** extra CPU usage and log volume, interfering with the result. This macro can be followed
** or combined with CFE_Assert_STATUS_MAY_BE / CFE_Assert_STATUS_MUST_BE to do actual reporting.

** \sa #CFE_Assert_STATUS_STORE, #CFE_Assert_STATUS_MAY_BE, #CFE_Assert_STATUS_MUST_BE
**
** \returns Actual CFE_Status_t value from the call
*/
#define CFE_Assert_STATUS_SILENTCHECK(expected) CFE_Assert_Status_SilentCheck(expected)

/*****************************************************************************/
/**
** \brief Retroactively check for an acceptable status value from CFE_Assert_STATUS_STORE
Expand Down Expand Up @@ -357,6 +374,17 @@ bool CFE_Assert_StatusCheck(CFE_Status_t Status, bool ExpectSuccess, UtAssert_Ca
*/
CFE_Status_t CFE_Assert_Status_Store(CFE_Status_t Status, const char *File, uint32 Line, const char *Text);

/**
** \brief Helper function to silently check status of a previously stored result
**
** \par Description
** This helper function will check the status previously stored to a
** temporary holding area, but does not assert on it.
**
** \returns true if status code matched, false if it did not match.
*/
bool CFE_Assert_Status_SilentCheck(CFE_Status_t Status);

/**
** \brief Helper function for nominal CFE calls with deferred check
**
Expand Down
7 changes: 6 additions & 1 deletion modules/cfe_assert/src/cfe_assert_runner.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ CFE_Status_t CFE_Assert_Status_Store(CFE_Status_t Status, const char *File, uint
return Status;
}

bool CFE_Assert_Status_SilentCheck(CFE_Status_t Status)
{
return (Status == CFE_Assert_Global.StoredStatus);
}

bool CFE_Assert_Status_DeferredCheck(CFE_Status_t Status, UtAssert_CaseType_t CaseType, const char *File, uint32 Line,
const char *Text)
{
Expand All @@ -125,7 +130,7 @@ bool CFE_Assert_Status_DeferredCheck(CFE_Status_t Status, UtAssert_CaseType_t Ca
}
else
{
Result = (Status == CFE_Assert_Global.StoredStatus);
Result = CFE_Assert_Status_SilentCheck(Status);
if (Result)
{
/* no extra tag added to "true" conditions */
Expand Down
3 changes: 2 additions & 1 deletion modules/cfe_testcase/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ include_directories(inc)

# Filenames based on doxygen groups.
# Create the app module
add_cfe_app(cfe_testcase
add_cfe_app(cfe_testcase
src/cfe_test.c
src/cfe_test_table.c
src/es_application_control_test.c
Expand All @@ -23,6 +23,7 @@ add_cfe_app(cfe_testcase
src/message_id_test.c
src/msg_api_test.c
src/resource_id_misc_test.c
src/sb_performance_test.c
src/sb_pipe_mang_test.c
src/sb_sendrecv_test.c
src/sb_subscription_test.c
Expand Down
1 change: 1 addition & 0 deletions modules/cfe_testcase/src/cfe_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ void CFE_TestMain(void)
SBPipeMangSetup();
SBSendRecvTestSetup();
SBSubscriptionTestSetup();
SBPerformanceTestSetup();
TBLContentAccessTestSetup();
TBLContentMangTestSetup();
TBLInformationTestSetup();
Expand Down
1 change: 1 addition & 0 deletions modules/cfe_testcase/src/cfe_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ void FSUtilTestSetup(void);
void MessageIdTestSetup(void);
void MsgApiTestSetup(void);
void ResourceIdMiscTestSetup(void);
void SBPerformanceTestSetup(void);
void SBPipeMangSetup(void);
void SBSendRecvTestSetup(void);
void SBSubscriptionTestSetup(void);
Expand Down
147 changes: 147 additions & 0 deletions modules/cfe_testcase/src/sb_performance_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/************************************************************************
* NASA Docket No. GSC-18,719-1, and identified as “core Flight System: Bootes”
*
* Copyright (c) 2020 United States Government as represented by the
* Administrator of the National Aeronautics and Space Administration.
* All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
************************************************************************/

/**
* @file
*
* Functional test of SB transmit/receive API performance
*
* The intent of this test is to perform a set of SB message transfers
* at a sufficiently high rate / volume such that the performance of
* the implementation can be characterized. Note that this
* cannot (currently) measure the performance directly, it merely implements a
* scenario that allows the performance to be measured by an external test
* harness.
*/

#include "cfe_test.h"
#include "cfe_msgids.h"
#include "cfe_test_msgids.h"

/* A simple command message */
typedef struct
{
CFE_MSG_CommandHeader_t CommandHeader;
uint32 CmdPayload;
} CFE_FT_TestCmdMessage_t;

/* A simple telemetry message */
typedef struct
{
CFE_MSG_TelemetryHeader_t TelemetryHeader;
uint32 TlmPayload;
} CFE_FT_TestTlmMessage_t;

/*
* This test procedure should be agnostic to specific MID values, but it should
* not overlap/interfere with real MIDs used by other apps.
*/
static const CFE_SB_MsgId_t CFE_FT_CMD_MSGID = CFE_SB_MSGID_WRAP_VALUE(CFE_TEST_CMD_MID);

Check notice

Code scanning / CodeQL

Variable scope too large

The variable CFE_FT_CMD_MSGID is only accessed in [TestBulkTransmitRecv](1) and should be scoped accordingly.
static const CFE_SB_MsgId_t CFE_FT_TLM_MSGID = CFE_SB_MSGID_WRAP_VALUE(CFE_TEST_HK_TLM_MID);

Check notice

Code scanning / CodeQL

Variable scope too large

The variable CFE_FT_TLM_MSGID is only accessed in [TestBulkTransmitRecv](1) and should be scoped accordingly.

void TestBulkTransmitRecv(void)

Check notice

Code scanning / CodeQL

Function too long

TestBulkTransmitRecv has too many lines (86, while 60 are allowed).

Check notice

Code scanning / CodeQL

Long function without assertion

All functions of more than 10 lines should have at least one assertion.
{
CFE_SB_PipeId_t PipeId1 = CFE_SB_INVALID_PIPE;
CFE_SB_PipeId_t PipeId2 = CFE_SB_INVALID_PIPE;
CFE_FT_TestCmdMessage_t CmdMsg;
CFE_FT_TestTlmMessage_t TlmMsg;
CFE_SB_Buffer_t * MsgBuf;
const CFE_FT_TestCmdMessage_t *CmdPtr;
const CFE_FT_TestTlmMessage_t *TlmPtr;
uint32 SendCount;
OS_time_t StartTime;
OS_time_t ElapsedTime;

memset(&CmdMsg, 0, sizeof(CmdMsg));
memset(&TlmMsg, 0, sizeof(TlmMsg));

UtPrintf("Testing: Bulk SB Transmit/Receive");
CFE_PSP_GetTime(&StartTime);

/* Setup, create a pipe and subscribe (one cmd, one tlm) */
UtAssert_INT32_EQ(CFE_SB_CreatePipe(&PipeId1, 5, "TestPipe1"), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_CreatePipe(&PipeId2, 5, "TestPipe2"), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_SubscribeEx(CFE_FT_CMD_MSGID, PipeId1, CFE_SB_DEFAULT_QOS, 3), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_SubscribeEx(CFE_FT_TLM_MSGID, PipeId2, CFE_SB_DEFAULT_QOS, 3), CFE_SUCCESS);

/* Initialize the message content */
UtAssert_INT32_EQ(CFE_MSG_Init(CFE_MSG_PTR(CmdMsg.CommandHeader), CFE_FT_CMD_MSGID, sizeof(CmdMsg)), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_MSG_Init(CFE_MSG_PTR(TlmMsg.TelemetryHeader), CFE_FT_TLM_MSGID, sizeof(TlmMsg)), CFE_SUCCESS);

for (SendCount = 0; SendCount < 1000000; ++SendCount)
{
CmdMsg.CmdPayload = SendCount;
TlmMsg.TlmPayload = ~SendCount;

/* In order to not "flood" with test results, this should be silent unless a failure occurs */
CFE_Assert_STATUS_STORE(CFE_SB_TransmitMsg(CFE_MSG_PTR(CmdMsg.CommandHeader), true));
if (!CFE_Assert_STATUS_SILENTCHECK(CFE_SUCCESS))
{
break;
}

CFE_Assert_STATUS_STORE(CFE_SB_TransmitMsg(CFE_MSG_PTR(TlmMsg.TelemetryHeader), true));
if (!CFE_Assert_STATUS_SILENTCHECK(CFE_SUCCESS))
{
break;
}

CFE_Assert_STATUS_STORE(CFE_SB_ReceiveBuffer(&MsgBuf, PipeId1, CFE_SB_POLL));
if (!CFE_Assert_STATUS_SILENTCHECK(CFE_SUCCESS))
{
break;
}

/* As above, to avoid flooding of test cases, only report mismatch here */
CmdPtr = (const void *)MsgBuf;
if (CmdPtr->CmdPayload != CmdMsg.CmdPayload)
{
UtAssert_UINT32_EQ(CmdPtr->CmdPayload, CmdMsg.CmdPayload);
break;
}

CFE_Assert_STATUS_STORE(CFE_SB_ReceiveBuffer(&MsgBuf, PipeId2, CFE_SB_POLL));
if (!CFE_Assert_STATUS_SILENTCHECK(CFE_SUCCESS))
{
break;
}

TlmPtr = (const void *)MsgBuf;
if (TlmPtr->TlmPayload != TlmMsg.TlmPayload)
{
UtAssert_UINT32_EQ(TlmPtr->TlmPayload, TlmMsg.TlmPayload);
break;
}

/* report progress periodically */
if ((SendCount % 50000) == 0)
{
UtPrintf("Success after %lu messages", (unsigned long)SendCount);
}
}

CFE_PSP_GetTime(&ElapsedTime);
ElapsedTime = OS_TimeSubtract(ElapsedTime, StartTime);

UtAssert_MIR("Elapsed time for SB bulk message test: %lu usec", OS_TimeGetTotalMicroseconds(ElapsedTime));
}

void SBPerformanceTestSetup(void)
{
UtTest_Add(TestBulkTransmitRecv, NULL, NULL, "Test Bulk SB Transmit/Receive");
}