Skip to content

Commit

Permalink
Fix nasa#1680, add SB subscription functional test
Browse files Browse the repository at this point in the history
Add tests for the CFE SB subscription API:
 - CFE_SB_Subscribe
 - CFE_SB_SubscribeEx
 - CFE_SB_SubscribeLocal
 - CFE_SB_Unsubscribe
 - CFE_SB_UnsubscribeLocal
  • Loading branch information
jphickey committed Aug 11, 2021
1 parent eb9c523 commit 8e49996
Show file tree
Hide file tree
Showing 4 changed files with 256 additions and 0 deletions.
1 change: 1 addition & 0 deletions modules/cfe_testcase/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ add_cfe_app(cfe_testcase
src/fs_util_test.c
src/message_id_test.c
src/sb_pipe_mang_test.c
src/sb_subscription_test.c
src/tbl_content_access_test.c
src/tbl_content_mang_test.c
src/tbl_information_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 @@ -72,6 +72,7 @@ void CFE_TestMain(void)
FSUtilTestSetup();
MessageIdTestSetup();
SBPipeMangSetup();
SBSubscriptionTestSetup();
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 @@ -103,6 +103,7 @@ void FSHeaderTestSetup(void);
void FSUtilTestSetup(void);
void MessageIdTestSetup(void);
void SBPipeMangSetup(void);
void SBSubscriptionTestSetup(void);
void TBLContentAccessTestSetup(void);
void TBLContentMangTestSetup(void);
void TBLInformationTestSetup(void);
Expand Down
253 changes: 253 additions & 0 deletions modules/cfe_testcase/src/sb_subscription_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
/*************************************************************************
**
** GSC-18128-1, "Core Flight Executive Version 6.7"
**
** Copyright (c) 2006-2019 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 subscription APIs
* CFE_SB_Subscribe - Subscribe to a message on the software bus with default parameters.
* CFE_SB_SubscribeEx - Subscribe to a message on the software bus.
* CFE_SB_SubscribeLocal - Subscribe to a message while keeping the request local to a cpu.
* CFE_SB_Unsubscribe - Remove a subscription to a message on the software bus.
* CFE_SB_UnsubscribeLocal - Remove a subscription to a message on the software bus on the current CPU.
*/

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

/*
* 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);
static const CFE_SB_MsgId_t CFE_FT_TLM_MSGID = CFE_SB_MSGID_WRAP_VALUE(CFE_TEST_HK_TLM_MID);

void TestSubscribeUnsubscribe(void)
{
CFE_SB_PipeId_t PipeId1;
CFE_SB_PipeId_t PipeId2;

UtPrintf("Testing: CFE_SB_Subscribe, CFE_SB_Unsubscribe");

/* Setup, create some pipes */
UtAssert_INT32_EQ(CFE_SB_CreatePipe(&PipeId1, 3, "TestPipe1"), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_CreatePipe(&PipeId2, 3, "TestPipe2"), CFE_SUCCESS);

/* Subscribe - Confirm Bad MsgId Arg Rejection */
UtAssert_INT32_EQ(CFE_SB_Subscribe(CFE_SB_INVALID_MSG_ID, PipeId1), CFE_SB_BAD_ARGUMENT);
UtAssert_INT32_EQ(CFE_SB_Subscribe(CFE_SB_MSGID_RESERVED, PipeId2), CFE_SB_BAD_ARGUMENT);

/* Subscribe - Confirm Bad PipeId Arg Rejection */
UtAssert_INT32_EQ(CFE_SB_Subscribe(CFE_FT_CMD_MSGID, CFE_SB_INVALID_PIPE), CFE_SB_BAD_ARGUMENT);

/* Subscribe - Nominal */
UtAssert_INT32_EQ(CFE_SB_Subscribe(CFE_FT_CMD_MSGID, PipeId1), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_Subscribe(CFE_FT_TLM_MSGID, PipeId2), CFE_SUCCESS);

/* Subscribe - Duplicate */
UtAssert_INT32_EQ(CFE_SB_Subscribe(CFE_FT_CMD_MSGID, PipeId1), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_Subscribe(CFE_FT_TLM_MSGID, PipeId2), CFE_SUCCESS);

/* Subscribe - Nominal 2 */
UtAssert_INT32_EQ(CFE_SB_Subscribe(CFE_FT_TLM_MSGID, PipeId1), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_Subscribe(CFE_FT_CMD_MSGID, PipeId2), CFE_SUCCESS);

/* Unsubscribe - Confirm Bad MsgId Arg Rejection */
UtAssert_INT32_EQ(CFE_SB_Unsubscribe(CFE_SB_INVALID_MSG_ID, PipeId1), CFE_SB_BAD_ARGUMENT);
UtAssert_INT32_EQ(CFE_SB_Unsubscribe(CFE_SB_MSGID_RESERVED, PipeId2), CFE_SB_BAD_ARGUMENT);

/* Unsubscribe - Confirm Bad PipeId Arg Rejection */
UtAssert_INT32_EQ(CFE_SB_Unsubscribe(CFE_FT_CMD_MSGID, CFE_SB_INVALID_PIPE), CFE_SB_BAD_ARGUMENT);

/* Unsubscribe - Nominal */
UtAssert_INT32_EQ(CFE_SB_Unsubscribe(CFE_FT_CMD_MSGID, PipeId1), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_Unsubscribe(CFE_FT_TLM_MSGID, PipeId2), CFE_SUCCESS);

/* Unsubscribe - Already unsubscribed */
UtAssert_INT32_EQ(CFE_SB_Unsubscribe(CFE_FT_CMD_MSGID, PipeId1), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_Unsubscribe(CFE_FT_TLM_MSGID, PipeId2), CFE_SUCCESS);

/* Unsubscribe - Nominal 2 */
UtAssert_INT32_EQ(CFE_SB_Unsubscribe(CFE_FT_TLM_MSGID, PipeId1), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_Unsubscribe(CFE_FT_CMD_MSGID, PipeId2), CFE_SUCCESS);

/* Teardown - delete the pipes. */
UtAssert_INT32_EQ(CFE_SB_DeletePipe(PipeId1), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_DeletePipe(PipeId2), CFE_SUCCESS);
}

void TestSubscribeUnsubscribeLocal(void)
{
CFE_SB_PipeId_t PipeId1;
CFE_SB_PipeId_t PipeId2;

UtPrintf("Testing: CFE_SB_SubscribeLocal, CFE_SB_UnsubscribeLocal");

/* Setup, create some pipes */
UtAssert_INT32_EQ(CFE_SB_CreatePipe(&PipeId1, 3, "TestPipe1"), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_CreatePipe(&PipeId2, 3, "TestPipe2"), CFE_SUCCESS);

/* Subscribe - Confirm Bad MsgId Arg Rejection */
UtAssert_INT32_EQ(CFE_SB_SubscribeLocal(CFE_SB_INVALID_MSG_ID, PipeId1, 2), CFE_SB_BAD_ARGUMENT);
UtAssert_INT32_EQ(CFE_SB_SubscribeLocal(CFE_SB_MSGID_RESERVED, PipeId2, 2), CFE_SB_BAD_ARGUMENT);

/* Subscribe - Confirm Bad PipeId Arg Rejection */
UtAssert_INT32_EQ(CFE_SB_SubscribeLocal(CFE_FT_CMD_MSGID, CFE_SB_INVALID_PIPE, 2), CFE_SB_BAD_ARGUMENT);

/* Subscribe - Nominal */
UtAssert_INT32_EQ(CFE_SB_SubscribeLocal(CFE_FT_CMD_MSGID, PipeId1, 2), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_SubscribeLocal(CFE_FT_TLM_MSGID, PipeId2, 2), CFE_SUCCESS);

/* Subscribe - Duplicate */
UtAssert_INT32_EQ(CFE_SB_SubscribeLocal(CFE_FT_CMD_MSGID, PipeId1, 2), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_SubscribeLocal(CFE_FT_TLM_MSGID, PipeId2, 2), CFE_SUCCESS);

/* Subscribe - Nominal 2 */
UtAssert_INT32_EQ(CFE_SB_SubscribeLocal(CFE_FT_TLM_MSGID, PipeId1, 2), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_SubscribeLocal(CFE_FT_CMD_MSGID, PipeId2, 2), CFE_SUCCESS);

/* Unsubscribe - Confirm Bad MsgId Arg Rejection */
UtAssert_INT32_EQ(CFE_SB_UnsubscribeLocal(CFE_SB_INVALID_MSG_ID, PipeId1), CFE_SB_BAD_ARGUMENT);
UtAssert_INT32_EQ(CFE_SB_UnsubscribeLocal(CFE_SB_MSGID_RESERVED, PipeId2), CFE_SB_BAD_ARGUMENT);

/* Unsubscribe - Confirm Bad PipeId Arg Rejection */
UtAssert_INT32_EQ(CFE_SB_UnsubscribeLocal(CFE_FT_CMD_MSGID, CFE_SB_INVALID_PIPE), CFE_SB_BAD_ARGUMENT);

/* Unsubscribe - Nominal */
UtAssert_INT32_EQ(CFE_SB_UnsubscribeLocal(CFE_FT_CMD_MSGID, PipeId1), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_UnsubscribeLocal(CFE_FT_TLM_MSGID, PipeId2), CFE_SUCCESS);

/* Unsubscribe - Already unsubscribed */
UtAssert_INT32_EQ(CFE_SB_UnsubscribeLocal(CFE_FT_CMD_MSGID, PipeId1), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_UnsubscribeLocal(CFE_FT_TLM_MSGID, PipeId2), CFE_SUCCESS);

/* Unsubscribe - Nominal 2 */
UtAssert_INT32_EQ(CFE_SB_UnsubscribeLocal(CFE_FT_TLM_MSGID, PipeId1), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_UnsubscribeLocal(CFE_FT_CMD_MSGID, PipeId2), CFE_SUCCESS);

/* Teardown - delete the pipes. */
UtAssert_INT32_EQ(CFE_SB_DeletePipe(PipeId1), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_DeletePipe(PipeId2), CFE_SUCCESS);
}

void TestSubscribeEx(void)
{
CFE_SB_PipeId_t PipeId1;
CFE_SB_PipeId_t PipeId2;

/*
* NOTE: CFE_SB_SubscribeEx adds a "Quality" parameter for Qos, which is
* not utilized in the current SB implementation (only "default" is available).
*
* Otherwise, it is basically the same as the regular "CFE_SB_Subscribe" call.
*/
UtPrintf("Testing: CFE_SB_SubscribeEx");

/* Setup, create some pipes */
UtAssert_INT32_EQ(CFE_SB_CreatePipe(&PipeId1, 3, "TestPipe1"), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_CreatePipe(&PipeId2, 3, "TestPipe2"), CFE_SUCCESS);

/*
* For completeness, repeat the bad arg rejection tests, even though internally
* it is likely identical (all going through CFE_SB_SubscribeFull). However
* this implementation detail should not be assumed in a black box test environment.
*/

/* Subscribe - Confirm Bad MsgId Arg Rejection */
UtAssert_INT32_EQ(CFE_SB_SubscribeEx(CFE_SB_INVALID_MSG_ID, PipeId1, CFE_SB_DEFAULT_QOS, 2), CFE_SB_BAD_ARGUMENT);
UtAssert_INT32_EQ(CFE_SB_SubscribeEx(CFE_SB_MSGID_RESERVED, PipeId2, CFE_SB_DEFAULT_QOS, 2), CFE_SB_BAD_ARGUMENT);

/* Subscribe - Confirm Bad PipeId Arg Rejection */
UtAssert_INT32_EQ(CFE_SB_SubscribeEx(CFE_FT_CMD_MSGID, CFE_SB_INVALID_PIPE, CFE_SB_DEFAULT_QOS, 2),
CFE_SB_BAD_ARGUMENT);

/* Subscribe - Nominal */
UtAssert_INT32_EQ(CFE_SB_SubscribeEx(CFE_FT_CMD_MSGID, PipeId1, CFE_SB_DEFAULT_QOS, 2), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_SubscribeEx(CFE_FT_TLM_MSGID, PipeId2, CFE_SB_DEFAULT_QOS, 2), CFE_SUCCESS);

/* Teardown - delete the pipes (this also unsubscribes automatically) */
UtAssert_INT32_EQ(CFE_SB_DeletePipe(PipeId1), CFE_SUCCESS);
UtAssert_INT32_EQ(CFE_SB_DeletePipe(PipeId2), CFE_SUCCESS);
}

void TestSBMaxSubscriptions(void)
{
CFE_Status_t Status;
uint32 NumSubs;
CFE_SB_MsgId_t TestMsgId;
CFE_SB_PipeId_t PipeId;

UtPrintf("Testing: CFE_SB_Subscribe, max routing table limit");

/* Setup, create a pipe */
UtAssert_INT32_EQ(CFE_SB_CreatePipe(&PipeId, 2, "TestPipe"), CFE_SUCCESS);

/*
* Test max subscriptions - note this depends on the actual number of _other_ apps
* that are running and have made other subscriptions. Therefore it is not predictable
* exactly how many iterations of this loop will succeed, but it should be fewer than
* CFE_PLATFORM_SB_MAX_MSG_IDS.
*
* NOTE: after this loop, it may not be possible to add any more routes at all, until
* a processor reset is done, because routes are never actually deleted for sequence number persistence.
*/
NumSubs = 0;
while (NumSubs <= CFE_PLATFORM_SB_MAX_MSG_IDS)
{
/* fabricate a msgid to subscribe to (this may overlap real msgids) */
TestMsgId = CFE_SB_MSGID_WRAP_VALUE(CFE_PLATFORM_CMD_MID_BASE + NumSubs);

Status = CFE_SB_Subscribe(TestMsgId, PipeId);
if (Status != CFE_SUCCESS)
{
break;
}

++NumSubs;
}

/* Check that the number of subscriptions was within range */
UtAssert_NONZERO(NumSubs);
UtAssert_UINT32_LTEQ(NumSubs, CFE_PLATFORM_SB_MAX_MSG_IDS);

/* The last pass should have returned CFE_SB_MAX_MSGS_MET */
UtAssert_True(Status == CFE_SB_MAX_MSGS_MET,
"CFE_SB_Subscribe(TestMsgId, PipeId1) (%ld) == CFE_SB_MAX_MSGS_MET (%ld)", (long)Status,
(long)CFE_SB_MAX_MSGS_MET);

/* Note this should also remove any subscriptions from the above loop */
UtAssert_INT32_EQ(CFE_SB_DeletePipe(PipeId), CFE_SUCCESS);
}

void SBSubscriptionTestSetup(void)
{
UtTest_Add(TestSubscribeUnsubscribe, NULL, NULL, "Test SB Subscribe/Unsubscribe");
UtTest_Add(TestSubscribeUnsubscribeLocal, NULL, NULL, "Test SB SubscribeLocal/UnsubscribeLocal");
UtTest_Add(TestSubscribeEx, NULL, NULL, "Test SB SubscribeEx");

/*
* NOTE: The TestSBMaxSubscriptions() is not included/added by default, as it will fill the
* routing table and make it not possible to add new routes until the system is reset.
*
* The test can be optionally enabled by the user and should pass, if this is not a concern.
*/
}

0 comments on commit 8e49996

Please sign in to comment.