tests can now be built as part of FSFW

This PR refactores the tests so they are built as part of the FSFW.
This is done by adding Catch2 with the FetchContent directive.

A future implementation might also use a system installation of Catch2
by first checking whether Catch2 can already be found as a package

The custom configuration folder testcfg was moved from the user folder
to the actual unittest folder.

The tests can be built by setting the CMake FSFW_BUILD_UNITTESTS option
to TRUE/ON. They are built with the static library and dropped inside
the build folders fsfw directory.
This commit is contained in:
2021-10-07 13:24:46 +02:00
parent 85a90a6ec5
commit ade15ad16d
51 changed files with 429 additions and 107 deletions

View File

@ -3,6 +3,6 @@ if(FSFW_ADD_INTERNAL_TESTS)
add_subdirectory(internal)
endif()
if(FSFW_ADD_UNITTESTS)
if(FSFW_BUILD_UNITTESTS)
add_subdirectory(unit)
endif()

View File

@ -1,9 +1,9 @@
#include "fsfw_tests/internal/InternalUnitTester.h"
#include "fsfw_tests/internal/UnittDefinitions.h"
#include "fsfw_tests/internal/osal/IntTestMq.h"
#include "fsfw_tests/internal/osal/IntTestSemaphore.h"
#include "fsfw_tests/internal/osal/IntTestMutex.h"
#include "fsfw_tests/internal/osal/testMq.h"
#include "fsfw_tests/internal/osal/testSemaphore.h"
#include "fsfw_tests/internal/osal/testMutex.h"
#include "fsfw_tests/internal/serialize/IntTestSerialization.h"
#include "fsfw_tests/internal/globalfunctions/TestArrayPrinter.h"

View File

@ -1,5 +1,5 @@
target_sources(${LIB_FSFW_NAME} PRIVATE
IntTestMq.cpp
IntTestMutex.cpp
IntTestSemaphore.cpp
testMq.cpp
testMutex.cpp
testSemaphore.cpp
)

View File

@ -0,0 +1 @@
#include "testCmdExecutor.h"

View File

@ -0,0 +1,10 @@
#ifndef FSFW_TESTS_SRC_FSFW_TESTS_INTERNAL_OSAL_TESTCMDEXECUTOR_H_
#define FSFW_TESTS_SRC_FSFW_TESTS_INTERNAL_OSAL_TESTCMDEXECUTOR_H_
namespace testcmdexec {
}
#endif /* FSFW_TESTS_SRC_FSFW_TESTS_INTERNAL_OSAL_TESTCMDEXECUTOR_H_ */

View File

@ -1,4 +1,4 @@
#include "fsfw_tests/internal/osal/IntTestMq.h"
#include "testMq.h"
#include "fsfw_tests/internal/UnittDefinitions.h"
#include <fsfw/ipc/MessageQueueIF.h>

View File

@ -1,4 +1,4 @@
#include "fsfw_tests/internal/osal/IntTestMutex.h"
#include "testMutex.h"
#include "fsfw_tests/internal/UnittDefinitions.h"
#include "fsfw/platform.h"

View File

@ -1,5 +1,5 @@
#include "fsfw/FSFW.h"
#include "fsfw_tests/internal/osal/IntTestSemaphore.h"
#include "testSemaphore.h"
#include "fsfw_tests/internal/UnittDefinitions.h"
#include "fsfw/tasks/SemaphoreFactory.h"

View File

@ -1,16 +1,17 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${FSFW_TEST_TGT} PRIVATE
CatchDefinitions.cpp
CatchFactory.cpp
printChar.cpp
)
if(FSFW_CUSTOM_UNITTEST_RUNNER)
target_sources(${TARGET_NAME} PRIVATE
# if(FSFW_CUSTOM_UNITTEST_RUNNER)
target_sources(${FSFW_TEST_TGT} PRIVATE
CatchRunner.cpp
CatchSetup.cpp
)
endif()
# endif()
add_subdirectory(testcfg)
add_subdirectory(action)
add_subdirectory(container)
add_subdirectory(osal)

View File

@ -1,7 +1,7 @@
#ifndef FSFW_CATCHFACTORY_H_
#define FSFW_CATCHFACTORY_H_
#include "TestsConfig.h"
#include "tests/TestsConfig.h"
#include "fsfw/objectmanager/SystemObjectIF.h"
#include "fsfw/objectmanager/ObjectManager.h"

View File

@ -14,7 +14,7 @@
extern int customSetup();
int fsfwtest::customMain(int argc, char* argv[]) {
int main(int argc, char* argv[]) {
customSetup();
// Catch internal function call

View File

@ -7,7 +7,7 @@ namespace fsfwtest {
* Can be called by upper level main() if default Catch2 main is overriden
* @return
*/
int customMain(int argc, char* argv[]);
//int customMain(int argc, char* argv[]);
}

View File

@ -1,3 +1,3 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${FSFW_TEST_TGT} PRIVATE
TestActionHelper.cpp
)

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${FSFW_TEST_TGT} PRIVATE
RingBufferTest.cpp
TestArrayList.cpp
TestDynamicFifo.cpp

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${FSFW_TEST_TGT} PRIVATE
LocalPoolVariableTest.cpp
LocalPoolVectorTest.cpp
DataSetTest.cpp

View File

@ -1,3 +1,3 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${FSFW_TEST_TGT} PRIVATE
testDleEncoder.cpp
)

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${FSFW_TEST_TGT} PRIVATE
TestMessageQueue.cpp
TestSemaphore.cpp
)

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${FSFW_TEST_TGT} PRIVATE
TestSerialBufferAdapter.cpp
TestSerialization.cpp
TestSerialLinkedPacket.cpp

View File

@ -1,4 +1,4 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${FSFW_TEST_TGT} PRIVATE
TestNewAccessor.cpp
TestPool.cpp
)

View File

@ -0,0 +1,28 @@
target_sources(${FSFW_TEST_TGT} PRIVATE
ipc/MissionMessageTypes.cpp
pollingsequence/PollingSequenceFactory.cpp
)
# Add include paths for the executable
target_include_directories(${FSFW_TEST_TGT} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
# These translation files are actually not that relevant for the tests. However, the FSFW tests
# compile against a user-configured variant of the FSFW, which might be configured to include
# translation information. Therefore, empty dummy translation files are compiled here
# so the tests compile in any case.
# If a special translation file for object IDs exists, compile it.
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/objects/translateObjects.cpp")
target_sources(${FSFW_TEST_TGT} PRIVATE
objects/translateObjects.cpp
)
endif()
# If a special translation file for events exists, compile it.
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/objects/translateObjects.cpp")
target_sources(${FSFW_TEST_TGT} PRIVATE
events/translateEvents.cpp
)
endif()

View File

@ -0,0 +1,75 @@
#ifndef CONFIG_FSFWCONFIG_H_
#define CONFIG_FSFWCONFIG_H_
#include <cstddef>
#include <cstdint>
//! Used to determine whether C++ ostreams are used which can increase
//! the binary size significantly. If this is disabled,
//! the C stdio functions can be used alternatively
#define FSFW_CPP_OSTREAM_ENABLED 0
//! More FSFW related printouts depending on level. Useful for development.
#define FSFW_VERBOSE_LEVEL 1
//! Can be used to completely disable printouts, even the C stdio ones.
#if FSFW_CPP_OSTREAM_ENABLED == 0 && FSFW_VERBOSE_LEVEL == 0
#define FSFW_DISABLE_PRINTOUT 0
#endif
#define FSFW_USE_PUS_C_TELEMETRY 1
#define FSFW_USE_PUS_C_TELECOMMANDS 1
//! Can be used to disable the ANSI color sequences for C stdio.
#define FSFW_COLORED_OUTPUT 1
//! If FSFW_OBJ_EVENT_TRANSLATION is set to one,
//! additional output which requires the translation files translateObjects
//! and translateEvents (and their compiled source files)
#define FSFW_OBJ_EVENT_TRANSLATION 0
#if FSFW_OBJ_EVENT_TRANSLATION == 1
//! Specify whether info events are printed too.
#define FSFW_DEBUG_INFO 1
#include "objects/translateObjects.h"
#include "events/translateEvents.h"
#else
#endif
//! When using the newlib nano library, C99 support for stdio facilities
//! will not be provided. This define should be set to 1 if this is the case.
#define FSFW_NO_C99_IO 1
//! Specify whether a special mode store is used for Subsystem components.
#define FSFW_USE_MODESTORE 0
//! Defines if the real time scheduler for linux should be used.
//! If set to 0, this will also disable priority settings for linux
//! as most systems will not allow to set nice values without privileges
//! For embedded linux system set this to 1.
//! If set to 1 the binary needs "cap_sys_nice=eip" privileges to run
#define FSFW_USE_REALTIME_FOR_LINUX 1
namespace fsfwconfig {
//! Default timestamp size. The default timestamp will be an seven byte CDC short timestamp.
static constexpr uint8_t FSFW_MISSION_TIMESTAMP_SIZE = 7;
//! Configure the allocated pool sizes for the event manager.
static constexpr size_t FSFW_EVENTMGMR_MATCHTREE_NODES = 240;
static constexpr size_t FSFW_EVENTMGMT_EVENTIDMATCHERS = 120;
static constexpr size_t FSFW_EVENTMGMR_RANGEMATCHERS = 120;
//! Defines the FIFO depth of each commanding service base which
//! also determines how many commands a CSB service can handle in one cycle
//! simultaneously. This will increase the required RAM for
//! each CSB service !
static constexpr uint8_t FSFW_CSB_FIFO_DEPTH = 6;
static constexpr size_t FSFW_PRINT_BUFFER_SIZE = 124;
static constexpr size_t FSFW_MAX_TM_PACKET_SIZE = 2048;
}
#endif /* CONFIG_FSFWCONFIG_H_ */

View File

@ -0,0 +1,15 @@
#ifndef CONFIG_TMTC_TMTCSIZE_H_
#define CONFIG_TMTC_TMTCSIZE_H_
#include <cstdint>
#include <cstddef>
#define OBSW_PRINT_MISSED_DEADLINES 0
#define OBSW_VERBOSE_LEVEL 0
#define OBSW_ADD_TEST_CODE 1
namespace config {
static constexpr uint32_t MAX_STORED_TELECOMMANDS = 2000;
}
#endif /* CONFIG_TMTC_TMTCSIZE_H_ */

View File

@ -0,0 +1,21 @@
#ifndef FSFW_UNITTEST_CONFIG_TESTSCONFIG_H_
#define FSFW_UNITTEST_CONFIG_TESTSCONFIG_H_
#define FSFW_ADD_DEFAULT_FACTORY_FUNCTIONS 1
#ifdef __cplusplus
#include "objects/systemObjectList.h"
#include "events/subsystemIdRanges.h"
#include "returnvalues/classIds.h"
namespace config {
#endif
/* Add mission configuration flags here */
#ifdef __cplusplus
}
#endif
#endif /* FSFW_UNITTEST_CONFIG_TESTSCONFIG_H_ */

View File

@ -0,0 +1,5 @@
#include "logicalAddresses.h"

View File

@ -0,0 +1,16 @@
#ifndef CONFIG_DEVICES_LOGICALADDRESSES_H_
#define CONFIG_DEVICES_LOGICALADDRESSES_H_
#include <fsfw/devicehandlers/CookieIF.h>
#include "common/devices/commonAddresses.h"
#include <cstdint>
namespace addresses {
/* Logical addresses have uint32_t datatype */
enum logicalAddresses: address_t {
};
}
#endif /* CONFIG_DEVICES_LOGICALADDRESSES_H_ */

View File

@ -0,0 +1,4 @@
#include "powerSwitcherList.h"

View File

@ -0,0 +1,12 @@
#ifndef CONFIG_DEVICES_POWERSWITCHERLIST_H_
#define CONFIG_DEVICES_POWERSWITCHERLIST_H_
namespace switches {
/* Switches are uint8_t datatype and go from 0 to 255 */
enum switcherList {
};
}
#endif /* CONFIG_DEVICES_POWERSWITCHERLIST_H_ */

View File

@ -0,0 +1,21 @@
#ifndef CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_
#define CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_
#include "fsfw/events/fwSubsystemIdRanges.h"
#include "common/events/commonSubsystemIds.h"
#include <cstdint>
/**
* @brief Custom subsystem IDs can be added here
* @details
* Subsystem IDs are used to create unique events.
*/
namespace SUBSYSTEM_ID {
enum: uint8_t {
SUBSYSTEM_ID_START = COMMON_SUBSYSTEM_ID_RANGE,
SUBSYSTEM_ID_END // [EXPORT] : [END]
};
}
#endif /* CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_ */

View File

@ -0,0 +1,15 @@
/**
* @brief Auto-generated event translation file. Contains 81 translations.
* @details
* Generated on: 2021-05-18 16:28:16
*/
#include "translateEvents.h"
const char * translateEvents(Event event) {
switch( (event & 0xffff) ) {
default:
return "UNKNOWN_EVENT";
}
return 0;
}

View File

@ -0,0 +1,8 @@
#ifndef FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_
#define FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_
#include <fsfw/events/Event.h>
const char * translateEvents(Event event);
#endif /* FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_ */

View File

@ -0,0 +1,12 @@
#include "MissionMessageTypes.h"
#include <fsfw/ipc/CommandMessage.h>
void messagetypes::clearMissionMessage(CommandMessage* message) {
switch(message->getMessageType()) {
default:
break;
}
}

View File

@ -0,0 +1,22 @@
#ifndef CONFIG_IPC_MISSIONMESSAGETYPES_H_
#define CONFIG_IPC_MISSIONMESSAGETYPES_H_
#include <fsfw/ipc/FwMessageTypes.h>
class CommandMessage;
/**
* Custom command messages are specified here.
* Most messages needed to use FSFW are already located in
* <fsfw/ipc/FwMessageTypes.h>
* @param message Generic Command Message
*/
namespace messagetypes{
enum MESSAGE_TYPE {
MISSION_MESSAGE_TYPE_START = FW_MESSAGES_COUNT,
};
void clearMissionMessage(CommandMessage* message);
}
#endif /* CONFIG_IPC_MISSIONMESSAGETYPES_H_ */

View File

@ -0,0 +1,29 @@
#ifndef HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
#define HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
#include "fsfw/objectmanager/frameworkObjects.h"
#include "common/objects/commonObjectsList.h"
#include <cstdint>
// The objects will be instantiated in the ID order
namespace objects {
enum sourceObjects: uint32_t {
/* All addresses between start and end are reserved for the FSFW */
FSFW_CONFIG_RESERVED_START = PUS_SERVICE_1_VERIFICATION,
FSFW_CONFIG_RESERVED_END = TM_STORE,
UDP_BRIDGE = 15,
UDP_POLLING_TASK = 16,
TEST_ECHO_COM_IF = 20,
TEST_DEVICE = 21,
HK_RECEIVER_MOCK = 22,
TEST_LOCAL_POOL_OWNER_BASE = 25,
SHARED_SET_ID = 26
};
}
#endif /* BSP_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ */

View File

@ -0,0 +1,19 @@
/**
* @brief Auto-generated object translation file.
* @details
* Contains 69 translations.
* Generated on: 2021-05-18 16:37:37
*/
#include "translateObjects.h"
const char *NO_OBJECT_STRING = "NO_OBJECT";
const char* translateObject(object_id_t object) {
switch( (object & 0xFFFFFFFF) ) {
case 0xFFFFFFFF:
return NO_OBJECT_STRING;
default:
return "UNKNOWN_OBJECT";
}
return 0;
}

View File

@ -0,0 +1,8 @@
#ifndef FSFWCONFIG_OBJECTS_TRANSLATEOBJECTS_H_
#define FSFWCONFIG_OBJECTS_TRANSLATEOBJECTS_H_
#include <fsfw/objectmanager/SystemObjectIF.h>
const char* translateObject(object_id_t object);
#endif /* FSFWCONFIG_OBJECTS_TRANSLATEOBJECTS_H_ */

View File

@ -0,0 +1,39 @@
#include "PollingSequenceFactory.h"
#include "tests/TestsConfig.h"
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
ReturnValue_t pst::pollingSequenceInitDefault(
FixedTimeslotTaskIF *thisSequence) {
/* Length of a communication cycle */
uint32_t length = thisSequence->getPeriodMs();
/* Add polling sequence table here */
thisSequence->addSlot(objects::TEST_DEVICE, 0,
DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::TEST_DEVICE, 0.3,
DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TEST_DEVICE, 0.45 * length,
DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::TEST_DEVICE, 0.6 * length,
DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TEST_DEVICE, 0.8 * length,
DeviceHandlerIF::GET_READ);
if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) {
return HasReturnvaluesIF::RETURN_OK;
}
else {
#if FSFW_CPP_OSTREAM_ENABLED
sif::error << "pst::pollingSequenceInitDefault: Sequence invalid!"
<< std::endl;
#else
sif::printError("pst::pollingSequenceInitDefault: Sequence invalid!");
#endif
return HasReturnvaluesIF::RETURN_FAILED;
}
}

View File

@ -0,0 +1,32 @@
#ifndef POLLINGSEQUENCEFACTORY_H_
#define POLLINGSEQUENCEFACTORY_H_
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
class FixedTimeslotTaskIF;
/**
* All device handlers are scheduled by adding them into Polling Sequence Tables (PST)
* to satisfy stricter timing requirements of device communication,
* A device handler has four different communication steps:
* 1. DeviceHandlerIF::SEND_WRITE -> Send write via interface
* 2. DeviceHandlerIF::GET_WRITE -> Get confirmation for write
* 3. DeviceHandlerIF::SEND_READ -> Send read request
* 4. DeviceHandlerIF::GET_READ -> Read from interface
* The PST specifies precisely when the respective ComIF functions are called
* during the communication cycle time.
* The task is created using the FixedTimeslotTaskIF,
* which utilises the underlying Operating System Abstraction Layer (OSAL)
*
* @param thisSequence FixedTimeslotTaskIF * object is passed inside the Factory class when creating the PST
* @return
*/
namespace pst {
/* Default PST */
ReturnValue_t pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence);
}
#endif /* POLLINGSEQUENCEINIT_H_ */

View File

@ -0,0 +1,17 @@
#ifndef CONFIG_RETURNVALUES_CLASSIDS_H_
#define CONFIG_RETURNVALUES_CLASSIDS_H_
#include "common/returnvalues/commonClassIds.h"
#include "fsfw/returnvalues/FwClassIds.h"
/**
* @brief CLASS_ID defintions which are required for custom returnvalues.
*/
namespace CLASS_ID {
enum {
MISSION_CLASS_ID_START = FW_CLASS_ID_COUNT,
};
}
#endif /* CONFIG_RETURNVALUES_CLASSIDS_H_ */

View File

@ -0,0 +1,19 @@
#ifndef CONFIG_TMTC_APID_H_
#define CONFIG_TMTC_APID_H_
#include <cstdint>
/**
* Application Process Definition: entity, uniquely identified by an
* application process ID (APID), capable of generating telemetry source
* packets and receiving telecommand packets.
*
* Chose APID(s) for mission and define it here.
*/
namespace apid {
static const uint16_t DEFAULT_APID = 0x00;
static const uint16_t SOURCE_OBSW = 0x73;
}
#endif /* CONFIG_TMTC_APID_H_ */

View File

@ -0,0 +1,25 @@
#ifndef CONFIG_TMTC_PUSIDS_HPP_
#define CONFIG_TMTC_PUSIDS_HPP_
#include <cstdint>
namespace pus {
enum Ids: uint8_t {
PUS_SERVICE_1 = 1,
PUS_SERVICE_2 = 2,
PUS_SERVICE_3 = 3,
PUS_SERVICE_5 = 5,
PUS_SERVICE_6 = 6,
PUS_SERVICE_8 = 8,
PUS_SERVICE_9 = 9,
PUS_SERVICE_11 = 11,
PUS_SERVICE_17 = 17,
PUS_SERVICE_19 = 19,
PUS_SERVICE_20 = 20,
PUS_SERVICE_23 = 23,
PUS_SERVICE_200 = 200,
PUS_SERVICE_201 = 201,
};
};
#endif /* CONFIG_TMTC_PUSIDS_HPP_ */

View File

@ -1,3 +1,3 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${FSFW_TEST_TGT} PRIVATE
TestCountdown.cpp
)

View File

@ -1,3 +1,3 @@
target_sources(${TARGET_NAME} PRIVATE
target_sources(${FSFW_TEST_TGT} PRIVATE
PusTmTest.cpp
)