diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a1f7d1a..5ff66a6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,7 @@ endif() option(FSFW_WARNING_SHADOW_LOCAL_GCC "Enable -Wshadow=local warning in GCC" ON) # Options to exclude parts of the FSFW from compilation. option(FSFW_ADD_INTERNAL_TESTS "Add internal unit tests" ON) +option(FSFW_ADD_UNITTESTS "Add regular unittests. Requires Catch2" OFF) option(FSFW_ADD_HAL "Add Hardware Abstraction Layer" ON) # Optional sources @@ -38,7 +39,7 @@ elseif(${CMAKE_CXX_STANDARD} LESS 11) endif() # Backwards comptability -if(OS_FSFW) +if(OS_FSFW AND NOT FSFW_OSAL) message(WARNING "Please pass the FSFW OSAL as FSFW_OSAL instead of OS_FSFW") set(FSFW_OSAL OS_FSFW) endif() diff --git a/hal/src/fsfw_hal/linux/UnixFileGuard.cpp b/hal/src/fsfw_hal/linux/UnixFileGuard.cpp index f7901018..5019343e 100644 --- a/hal/src/fsfw_hal/linux/UnixFileGuard.cpp +++ b/hal/src/fsfw_hal/linux/UnixFileGuard.cpp @@ -1,5 +1,10 @@ +#include "fsfw/FSFW.h" +#include "fsfw/serviceinterface.h" #include "fsfw_hal/linux/UnixFileGuard.h" +#include +#include + UnixFileGuard::UnixFileGuard(std::string device, int* fileDescriptor, int flags, std::string diagnosticPrefix): fileDescriptor(fileDescriptor) { @@ -10,12 +15,11 @@ UnixFileGuard::UnixFileGuard(std::string device, int* fileDescriptor, int flags, if (*fileDescriptor < 0) { #if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << diagnosticPrefix <<"Opening device failed with error code " << errno << - "." << std::endl; - sif::warning << "Error description: " << strerror(errno) << std::endl; + sif::warning << diagnosticPrefix << ": Opening device failed with error code " << + errno << ": " << strerror(errno) << std::endl; #else - sif::printError("%sOpening device failed with error code %d.\n", diagnosticPrefix); - sif::printWarning("Error description: %s\n", strerror(errno)); + sif::printWarning("%s: Opening device failed with error code %d: %s\n", + diagnosticPrefix, errno, strerror(errno)); #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ #endif /* FSFW_VERBOSE_LEVEL >= 1 */ openStatus = OPEN_FILE_FAILED; diff --git a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp index fafe67be..48bf7449 100644 --- a/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp +++ b/hal/src/fsfw_hal/linux/spi/SpiComIF.cpp @@ -90,7 +90,7 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { int fileDescriptor = 0; UnixFileGuard fileHelper(spiCookie->getSpiDevice(), &fileDescriptor, O_RDWR, - "SpiComIF::initializeInterface: "); + "SpiComIF::initializeInterface"); if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { return fileHelper.getOpenResult(); } @@ -184,7 +184,7 @@ ReturnValue_t SpiComIF::performRegularSendOperation(SpiCookie *spiCookie, const /* Prepare transfer */ int fileDescriptor = 0; std::string device = spiCookie->getSpiDevice(); - UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage: "); + UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, "SpiComIF::sendMessage"); if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { return OPENING_FILE_FAILED; } @@ -273,7 +273,7 @@ ReturnValue_t SpiComIF::performHalfDuplexReception(SpiCookie* spiCookie) { std::string device = spiCookie->getSpiDevice(); int fileDescriptor = 0; UnixFileGuard fileHelper(device, &fileDescriptor, O_RDWR, - "SpiComIF::requestReceiveMessage: "); + "SpiComIF::requestReceiveMessage"); if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { return OPENING_FILE_FAILED; } diff --git a/hal/src/fsfw_hal/linux/uart/UartComIF.cpp b/hal/src/fsfw_hal/linux/uart/UartComIF.cpp index f52b6b1e..f5754c6e 100644 --- a/hal/src/fsfw_hal/linux/uart/UartComIF.cpp +++ b/hal/src/fsfw_hal/linux/uart/UartComIF.cpp @@ -1,6 +1,7 @@ -#include "fsfw_hal/linux/uart/UartComIF.h" +#include "UartComIF.h" #include "OBSWConfig.h" +#include "fsfw_hal/linux/utility.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include @@ -60,7 +61,13 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) { struct termios options = {}; std::string deviceFile = uartCookie->getDeviceFile(); - int fd = open(deviceFile.c_str(), O_RDWR); + int flags = O_RDWR; + if(uartCookie->getUartMode() == UartModes::CANONICAL) { + // In non-canonical mode, don't specify O_NONBLOCK because these properties will be + // controlled by the VTIME and VMIN parameters and O_NONBLOCK would override this + flags |= O_NONBLOCK; + } + int fd = open(deviceFile.c_str(), flags); if (fd < 0) { sif::warning << "UartComIF::configureUartPort: Failed to open uart " << deviceFile << @@ -259,23 +266,22 @@ void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCooki ReturnValue_t UartComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) { - int fd = 0; std::string deviceFile; UartDeviceMapIter uartDeviceMapIter; - if(sendData == nullptr) { - sif::debug << "UartComIF::sendMessage: Send Data is nullptr" << std::endl; - return RETURN_FAILED; - } - if(sendLen == 0) { return RETURN_OK; } + if(sendData == nullptr) { + sif::warning << "UartComIF::sendMessage: Send data is nullptr" << std::endl; + return RETURN_FAILED; + } + UartCookie* uartCookie = dynamic_cast(cookie); if(uartCookie == nullptr) { - sif::debug << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl; + sif::warning << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl; return NULLPOINTER; } @@ -347,12 +353,13 @@ ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceM size_t maxReplySize = uartCookie.getMaxReplyLen(); int fd = iter->second.fileDescriptor; auto bufferPtr = iter->second.replyBuffer.data(); + iter->second.replyLen = 0; do { size_t allowedReadSize = 0; if(currentBytesRead >= maxReplySize) { // Overflow risk. Emit warning, trigger event and break. If this happens, // the reception buffer is not large enough or data is not polled often enough. -#if OBSW_VERBOSE_LEVEL >= 1 +#if FSFW_VERBOSE_LEVEL >= 1 #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "UartComIF::requestReceiveMessage: Next read would cause overflow!" << std::endl; @@ -370,7 +377,20 @@ ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceM bytesRead = read(fd, bufferPtr, allowedReadSize); if (bytesRead < 0) { - return RETURN_FAILED; + // EAGAIN: No data available in non-blocking mode + if(errno != EAGAIN) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "UartComIF::handleCanonicalRead: read failed with code" << + errno << ": " << strerror(errno) << std::endl; +#else + sif::printWarning("UartComIF::handleCanonicalRead: read failed with code %d: %s\n", + errno, strerror(errno)); +#endif +#endif + return RETURN_FAILED; + } + } else if(bytesRead > 0) { iter->second.replyLen += bytesRead; diff --git a/hal/src/fsfw_hal/linux/uart/UartCookie.cpp b/hal/src/fsfw_hal/linux/uart/UartCookie.cpp index 339c7451..1c52e9cd 100644 --- a/hal/src/fsfw_hal/linux/uart/UartCookie.cpp +++ b/hal/src/fsfw_hal/linux/uart/UartCookie.cpp @@ -4,8 +4,8 @@ UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode, uint32_t baudrate, size_t maxReplyLen): - handlerId(handlerId), deviceFile(deviceFile), uartMode(uartMode), baudrate(baudrate), - maxReplyLen(maxReplyLen) { + handlerId(handlerId), deviceFile(deviceFile), uartMode(uartMode), + baudrate(baudrate), maxReplyLen(maxReplyLen) { } UartCookie::~UartCookie() {} diff --git a/src/fsfw/FSFWVersion.h b/src/fsfw/FSFWVersion.h index df2d49a5..f8e89694 100644 --- a/src/fsfw/FSFWVersion.h +++ b/src/fsfw/FSFWVersion.h @@ -1,12 +1,10 @@ -#ifndef FSFW_DEFAULTCFG_VERSION_H_ -#define FSFW_DEFAULTCFG_VERSION_H_ +#ifndef FSFW_VERSION_H_ +#define FSFW_VERSION_H_ const char* const FSFW_VERSION_NAME = "ASTP"; #define FSFW_VERSION 1 -#define FSFW_SUBVERSION 0 -#define FSFW_REVISION 0 +#define FSFW_SUBVERSION 2 +#define FSFW_REVISION 0 - - -#endif /* FSFW_DEFAULTCFG_VERSION_H_ */ +#endif /* FSFW_VERSION_H_ */ diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp index 96fe031a..c3fc023e 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.cpp +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.cpp @@ -469,7 +469,7 @@ ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceRep auto replyIter = deviceReplyMap.find(deviceReply); if (replyIter == deviceReplyMap.end()) { triggerEvent(INVALID_DEVICE_COMMAND, deviceReply); - return RETURN_FAILED; + return COMMAND_NOT_SUPPORTED; } else { DeviceReplyInfo *info = &(replyIter->second); if (maxDelayCycles != 0) { @@ -481,6 +481,25 @@ ReturnValue_t DeviceHandlerBase::updateReplyMapEntry(DeviceCommandId_t deviceRep } } +ReturnValue_t DeviceHandlerBase::updatePeriodicReply(bool enable, DeviceCommandId_t deviceReply) { + auto replyIter = deviceReplyMap.find(deviceReply); + if (replyIter == deviceReplyMap.end()) { + triggerEvent(INVALID_DEVICE_COMMAND, deviceReply); + return COMMAND_NOT_SUPPORTED; + } else { + DeviceReplyInfo *info = &(replyIter->second); + if(not info->periodic) { + return COMMAND_NOT_SUPPORTED; + } + if(enable) { + info->delayCycles = info->maxDelayCycles; + } + else { + info->delayCycles = 0; + } + } + return HasReturnvaluesIF::RETURN_OK; +} ReturnValue_t DeviceHandlerBase::setReplyDataset(DeviceCommandId_t replyId, LocalPoolDataSetBase *dataSet) { diff --git a/src/fsfw/devicehandlers/DeviceHandlerBase.h b/src/fsfw/devicehandlers/DeviceHandlerBase.h index 53bd1e65..30d36ef0 100644 --- a/src/fsfw/devicehandlers/DeviceHandlerBase.h +++ b/src/fsfw/devicehandlers/DeviceHandlerBase.h @@ -449,7 +449,9 @@ protected: * @param replyLen Will be supplied to the requestReceiveMessage call of * the communication interface. * @param periodic Indicates if the command is periodic (i.e. it is sent - * by the device repeatedly without request) or not. Default is aperiodic (0) + * by the device repeatedly without request) or not. Default is aperiodic (0). + * Please note that periodic replies are disabled by default. You can enable them with + * #updatePeriodicReply * @return - @c RETURN_OK when the command was successfully inserted, * - @c RETURN_FAILED else. */ @@ -464,7 +466,9 @@ protected: * @param maxDelayCycles The maximum number of delay cycles the reply waits * until it times out. * @param periodic Indicates if the command is periodic (i.e. it is sent - * by the device repeatedly without request) or not. Default is aperiodic (0) + * by the device repeatedly without request) or not. Default is aperiodic (0). + * Please note that periodic replies are disabled by default. You can enable them with + * #updatePeriodicReply * @return - @c RETURN_OK when the command was successfully inserted, * - @c RETURN_FAILED else. */ @@ -480,6 +484,14 @@ protected: */ ReturnValue_t insertInCommandMap(DeviceCommandId_t deviceCommand); + /** + * Enables a periodic reply for a given command. It sets to delay cycles to the specified + * maximum delay cycles for a given reply ID if enabled or to 0 if disabled. + * @param enable Specify whether to enable or disable a given periodic reply + * @return + */ + ReturnValue_t updatePeriodicReply(bool enable, DeviceCommandId_t deviceReply); + /** * @brief This function returns the reply length of the next reply to read. * @@ -493,16 +505,14 @@ protected: virtual size_t getNextReplyLength(DeviceCommandId_t deviceCommand); /** - * @brief This is a helper method to facilitate updating entries - * in the reply map. + * @brief This is a helper method to facilitate updating entries in the reply map. * @param deviceCommand Identifier of the reply to update. - * @param delayCycles The current number of delay cycles to wait. - * As stated in #fillCommandAndCookieMap, to disable periodic commands, - * this is set to zero. + * @param delayCycles The current number of delay cycles to wait. As stated in + * #fillCommandAndReplyMap, to disable periodic commands, this is set to zero. * @param maxDelayCycles The maximum number of delay cycles the reply waits * until it times out. By passing 0 the entry remains untouched. * @param periodic Indicates if the command is periodic (i.e. it is sent - * by the device repeatedly without request) or not.Default is aperiodic (0). + * by the device repeatedly without request) or not. Default is aperiodic (0). * Warning: The setting always overrides the value that was entered in the map. * @return - @c RETURN_OK when the command was successfully inserted, * - @c RETURN_FAILED else. diff --git a/src/fsfw/osal/common/TcpTmTcBridge.cpp b/src/fsfw/osal/common/TcpTmTcBridge.cpp index 24f1a281..3cd03c36 100644 --- a/src/fsfw/osal/common/TcpTmTcBridge.cpp +++ b/src/fsfw/osal/common/TcpTmTcBridge.cpp @@ -1,6 +1,5 @@ #include "fsfw/platform.h" #include "fsfw/osal/common/TcpTmTcBridge.h" -#include "fsfw/osal/common/tcpipHelpers.h" #include "fsfw/serviceinterface/ServiceInterface.h" #include "fsfw/ipc/MutexGuard.h" @@ -17,8 +16,6 @@ #endif -const std::string TcpTmTcBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; - TcpTmTcBridge::TcpTmTcBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId, object_id_t tcStoreId): TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { diff --git a/src/fsfw/osal/common/TcpTmTcBridge.h b/src/fsfw/osal/common/TcpTmTcBridge.h index 6cfacb9f..dc46f1f0 100644 --- a/src/fsfw/osal/common/TcpTmTcBridge.h +++ b/src/fsfw/osal/common/TcpTmTcBridge.h @@ -2,7 +2,7 @@ #define FSFW_OSAL_COMMON_TCPTMTCBRIDGE_H_ #include "TcpIpBase.h" -#include "../../tmtcservices/TmTcBridge.h" +#include "fsfw/tmtcservices/TmTcBridge.h" #ifdef _WIN32 @@ -29,8 +29,6 @@ class TcpTmTcBridge: public TmTcBridge { friend class TcpTmTcServer; public: - /* The ports chosen here should not be used by any other process. */ - static const std::string DEFAULT_UDP_SERVER_PORT; /** * Constructor diff --git a/src/fsfw/osal/common/TcpTmTcServer.cpp b/src/fsfw/osal/common/TcpTmTcServer.cpp index f94449bb..11ab71af 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.cpp +++ b/src/fsfw/osal/common/TcpTmTcServer.cpp @@ -22,14 +22,14 @@ #define FSFW_TCP_RECV_WIRETAPPING_ENABLED 0 #endif -const std::string TcpTmTcServer::DEFAULT_TCP_SERVER_PORT = "7303"; +const std::string TcpTmTcServer::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; TcpTmTcServer::TcpTmTcServer(object_id_t objectId, object_id_t tmtcTcpBridge, size_t receptionBufferSize, std::string customTcpServerPort): SystemObject(objectId), tmtcBridgeId(tmtcTcpBridge), tcpPort(customTcpServerPort), receptionBuffer(receptionBufferSize) { if(tcpPort == "") { - tcpPort = DEFAULT_TCP_SERVER_PORT; + tcpPort = DEFAULT_SERVER_PORT; } } @@ -200,6 +200,10 @@ void TcpTmTcServer::setTcpBacklog(uint8_t tcpBacklog) { this->tcpBacklog = tcpBacklog; } +std::string TcpTmTcServer::getTcpPort() const { + return tcpPort; +} + ReturnValue_t TcpTmTcServer::handleTmSending(socket_t connSocket) { // Access to the FIFO is mutex protected because it is filled by the bridge MutexGuard(tmtcBridge->mutex, tmtcBridge->timeoutType, tmtcBridge->mutexTimeoutMs); diff --git a/src/fsfw/osal/common/TcpTmTcServer.h b/src/fsfw/osal/common/TcpTmTcServer.h index f7c36d69..c6916080 100644 --- a/src/fsfw/osal/common/TcpTmTcServer.h +++ b/src/fsfw/osal/common/TcpTmTcServer.h @@ -3,13 +3,14 @@ #include "TcpIpBase.h" -#include "../../platform.h" -#include "../../ipc/messageQueueDefinitions.h" -#include "../../ipc/MessageQueueIF.h" -#include "../../objectmanager/frameworkObjects.h" -#include "../../objectmanager/SystemObject.h" -#include "../../storagemanager/StorageManagerIF.h" -#include "../../tasks/ExecutableObjectIF.h" +#include "fsfw/platform.h" +#include "fsfw/osal/common/tcpipHelpers.h" +#include "fsfw/ipc/messageQueueDefinitions.h" +#include "fsfw/ipc/MessageQueueIF.h" +#include "fsfw/objectmanager/frameworkObjects.h" +#include "fsfw/objectmanager/SystemObject.h" +#include "fsfw/storagemanager/StorageManagerIF.h" +#include "fsfw/tasks/ExecutableObjectIF.h" #ifdef PLATFORM_UNIX #include @@ -41,10 +42,9 @@ class TcpTmTcServer: public TcpIpBase, public ExecutableObjectIF { public: - /* The ports chosen here should not be used by any other process. */ - static const std::string DEFAULT_TCP_SERVER_PORT; + static const std::string DEFAULT_SERVER_PORT; - static constexpr size_t ETHERNET_MTU_SIZE = 1500; + static constexpr size_t ETHERNET_MTU_SIZE = 1500; /** * TCP Server Constructor @@ -65,6 +65,8 @@ public: ReturnValue_t performOperation(uint8_t opCode) override; ReturnValue_t initializeAfterTaskCreation() override; + std::string getTcpPort() const; + protected: StorageManagerIF* tcStore = nullptr; StorageManagerIF* tmStore = nullptr; diff --git a/src/fsfw/osal/common/UdpTmTcBridge.cpp b/src/fsfw/osal/common/UdpTmTcBridge.cpp index 7015cf4a..734a2b15 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.cpp +++ b/src/fsfw/osal/common/UdpTmTcBridge.cpp @@ -17,13 +17,13 @@ #define FSFW_UDP_SEND_WIRETAPPING_ENABLED 0 #endif -const std::string UdpTmTcBridge::DEFAULT_UDP_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; +const std::string UdpTmTcBridge::DEFAULT_SERVER_PORT = tcpip::DEFAULT_SERVER_PORT; UdpTmTcBridge::UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, std::string udpServerPort, object_id_t tmStoreId, object_id_t tcStoreId): TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) { if(udpServerPort == "") { - this->udpServerPort = DEFAULT_UDP_SERVER_PORT; + this->udpServerPort = DEFAULT_SERVER_PORT; } else { this->udpServerPort = udpServerPort; @@ -108,6 +108,10 @@ UdpTmTcBridge::~UdpTmTcBridge() { } } +std::string UdpTmTcBridge::getUdpPort() const { + return udpServerPort; +} + ReturnValue_t UdpTmTcBridge::sendTm(const uint8_t *data, size_t dataLen) { int flags = 0; diff --git a/src/fsfw/osal/common/UdpTmTcBridge.h b/src/fsfw/osal/common/UdpTmTcBridge.h index 7a346de5..4d634e64 100644 --- a/src/fsfw/osal/common/UdpTmTcBridge.h +++ b/src/fsfw/osal/common/UdpTmTcBridge.h @@ -2,8 +2,8 @@ #define FSFW_OSAL_COMMON_TMTCUDPBRIDGE_H_ #include "TcpIpBase.h" -#include "../../platform.h" -#include "../../tmtcservices/TmTcBridge.h" +#include "fsfw/platform.h" +#include "fsfw/tmtcservices/TmTcBridge.h" #ifdef PLATFORM_WIN #include @@ -28,7 +28,7 @@ class UdpTmTcBridge: friend class UdpTcPollingTask; public: /* The ports chosen here should not be used by any other process. */ - static const std::string DEFAULT_UDP_SERVER_PORT; + static const std::string DEFAULT_SERVER_PORT; UdpTmTcBridge(object_id_t objectId, object_id_t tcDestination, std::string udpServerPort = "", object_id_t tmStoreId = objects::TM_STORE, @@ -44,6 +44,8 @@ public: void checkAndSetClientAddress(sockaddr& clientAddress); + std::string getUdpPort() const; + protected: virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override; diff --git a/src/fsfw/osal/common/tcpipCommon.h b/src/fsfw/osal/common/tcpipCommon.h index ce7a90cd..5a04144e 100644 --- a/src/fsfw/osal/common/tcpipCommon.h +++ b/src/fsfw/osal/common/tcpipCommon.h @@ -1,7 +1,7 @@ #ifndef FSFW_OSAL_COMMON_TCPIPCOMMON_H_ #define FSFW_OSAL_COMMON_TCPIPCOMMON_H_ -#include "../../timemanager/clockDefinitions.h" +#include "fsfw/timemanager/clockDefinitions.h" #include #ifdef _WIN32 @@ -13,7 +13,7 @@ namespace tcpip { -const char* const DEFAULT_SERVER_PORT = "7301"; +static constexpr char DEFAULT_SERVER_PORT[] = "7301"; enum class Protocol { UDP, diff --git a/tests/src/fsfw_tests/unit/CMakeLists.txt b/tests/src/fsfw_tests/unit/CMakeLists.txt index 255063f3..01e4d19c 100644 --- a/tests/src/fsfw_tests/unit/CMakeLists.txt +++ b/tests/src/fsfw_tests/unit/CMakeLists.txt @@ -1,3 +1,16 @@ +target_sources(${TARGET_NAME} PRIVATE + CatchDefinitions.cpp + CatchFactory.cpp + printChar.cpp +) + +if(FSFW_CUSTOM_UNITTEST_RUNNER) + target_sources(${TARGET_NAME} PRIVATE + CatchRunner.cpp + CatchSetup.cpp + ) +endif() + add_subdirectory(action) add_subdirectory(container) add_subdirectory(osal) diff --git a/tests/user/unittest/core/CatchDefinitions.cpp b/tests/src/fsfw_tests/unit/CatchDefinitions.cpp similarity index 100% rename from tests/user/unittest/core/CatchDefinitions.cpp rename to tests/src/fsfw_tests/unit/CatchDefinitions.cpp diff --git a/tests/user/unittest/core/CatchDefinitions.h b/tests/src/fsfw_tests/unit/CatchDefinitions.h similarity index 100% rename from tests/user/unittest/core/CatchDefinitions.h rename to tests/src/fsfw_tests/unit/CatchDefinitions.h diff --git a/tests/user/unittest/core/CatchFactory.cpp b/tests/src/fsfw_tests/unit/CatchFactory.cpp similarity index 91% rename from tests/user/unittest/core/CatchFactory.cpp rename to tests/src/fsfw_tests/unit/CatchFactory.cpp index ff591b8e..010ab5dd 100644 --- a/tests/user/unittest/core/CatchFactory.cpp +++ b/tests/src/fsfw_tests/unit/CatchFactory.cpp @@ -1,17 +1,21 @@ #include "CatchFactory.h" +#include "datapoollocal/LocalPoolOwnerBase.h" +#include "mocks/HkReceiverMock.h" + #include #include #include #include -#include +#include #include #include #include #include #include -#include -#include + + +#if FSFW_ADD_DEFAULT_FACTORY_FUNCTIONS == 1 /** * @brief Produces system objects. @@ -26,7 +30,7 @@ * * @ingroup init */ -void Factory::produce(void) { +void Factory::produceFrameworkObjects(void* args) { setStaticFrameworkObjectIds(); new EventManager(objects::EVENT_MANAGER); new HealthTable(objects::HEALTH_TABLE); @@ -55,7 +59,6 @@ void Factory::produce(void) { }; new PoolManager(objects::IPC_STORE, poolCfg); } - } void Factory::setStaticFrameworkObjectIds() { @@ -77,5 +80,4 @@ void Factory::setStaticFrameworkObjectIds() { TmPacketBase::timeStamperId = objects::NO_OBJECT; } - - +#endif diff --git a/tests/src/fsfw_tests/unit/CatchFactory.h b/tests/src/fsfw_tests/unit/CatchFactory.h new file mode 100644 index 00000000..ae0629e5 --- /dev/null +++ b/tests/src/fsfw_tests/unit/CatchFactory.h @@ -0,0 +1,24 @@ +#ifndef FSFW_CATCHFACTORY_H_ +#define FSFW_CATCHFACTORY_H_ + +#include "TestConfig.h" +#include "fsfw/objectmanager/SystemObjectIF.h" +#include "fsfw/objectmanager/ObjectManager.h" + +// TODO: It is possible to solve this more cleanly using a special class which +// is allowed to set the object IDs and has virtual functions. +#if FSFW_ADD_DEFAULT_FACTORY_FUNCTIONS == 1 + +namespace Factory { + /** + * @brief Creates all SystemObject elements which are persistent + * during execution. + */ + void produceFrameworkObjects(void* args); + void setStaticFrameworkObjectIds(); + +} + +#endif /* FSFW_ADD_DEFAULT_FSFW_FACTORY == 1 */ + +#endif /* FSFW_CATCHFACTORY_H_ */ diff --git a/tests/user/unittest/core/CatchRunner.cpp b/tests/src/fsfw_tests/unit/CatchRunner.cpp similarity index 78% rename from tests/user/unittest/core/CatchRunner.cpp rename to tests/src/fsfw_tests/unit/CatchRunner.cpp index 886d641f..c96db7f4 100644 --- a/tests/user/unittest/core/CatchRunner.cpp +++ b/tests/src/fsfw_tests/unit/CatchRunner.cpp @@ -6,7 +6,7 @@ * from the eclipse market place to get colored characters. */ -#include +#include "CatchRunner.h" #define CATCH_CONFIG_COLOUR_WINDOWS @@ -14,11 +14,11 @@ extern int customSetup(); -int main( int argc, char* argv[] ) { +int fsfwtest::customMain(int argc, char* argv[]) { customSetup(); // Catch internal function call - int result = Catch::Session().run( argc, argv ); + int result = Catch::Session().run(argc, argv); // global clean-up return result; diff --git a/tests/src/fsfw_tests/unit/CatchRunner.h b/tests/src/fsfw_tests/unit/CatchRunner.h new file mode 100644 index 00000000..720625c6 --- /dev/null +++ b/tests/src/fsfw_tests/unit/CatchRunner.h @@ -0,0 +1,14 @@ +#ifndef FSFW_TESTS_USER_UNITTEST_CORE_CATCHRUNNER_H_ +#define FSFW_TESTS_USER_UNITTEST_CORE_CATCHRUNNER_H_ + +namespace fsfwtest { + +/** + * Can be called by upper level main() if default Catch2 main is overriden + * @return + */ +int customMain(int argc, char* argv[]); + +} + +#endif /* FSFW_TESTS_USER_UNITTEST_CORE_CATCHRUNNER_H_ */ diff --git a/tests/user/unittest/core/CatchSetup.cpp b/tests/src/fsfw_tests/unit/CatchSetup.cpp similarity index 57% rename from tests/user/unittest/core/CatchSetup.cpp rename to tests/src/fsfw_tests/unit/CatchSetup.cpp index bda31400..a0791bc9 100644 --- a/tests/user/unittest/core/CatchSetup.cpp +++ b/tests/src/fsfw_tests/unit/CatchSetup.cpp @@ -5,10 +5,9 @@ #include #endif -#include -#include -#include -#include +#include "fsfw/objectmanager/ObjectManager.h" +#include "fsfw/storagemanager/StorageManagerIF.h" +#include "fsfw/serviceinterface/ServiceInterface.h" /* Global instantiations normally done in main.cpp */ @@ -24,13 +23,11 @@ ServiceInterfaceStream warning("WARNING"); } #endif -/* Global object manager */ -ObjectManagerIF *objectManager; - int customSetup() { // global setup - objectManager = new ObjectManager(Factory::produce); - objectManager -> initialize(); + ObjectManager* objMan = ObjectManager::instance(); + objMan->setObjectFactoryFunction(Factory::produceFrameworkObjects, nullptr); + objMan->initialize(); return 0; } diff --git a/tests/src/fsfw_tests/unit/action/TestActionHelper.cpp b/tests/src/fsfw_tests/unit/action/TestActionHelper.cpp index 126979f6..3129b001 100644 --- a/tests/src/fsfw_tests/unit/action/TestActionHelper.cpp +++ b/tests/src/fsfw_tests/unit/action/TestActionHelper.cpp @@ -1,13 +1,10 @@ #include "TestActionHelper.h" - -#include +#include "fsfw_tests/unit/mocks/MessageQueueMockBase.h" #include #include -#include #include - #include diff --git a/tests/src/fsfw_tests/unit/action/TestActionHelper.h b/tests/src/fsfw_tests/unit/action/TestActionHelper.h index 641ea2c6..34b228c0 100644 --- a/tests/src/fsfw_tests/unit/action/TestActionHelper.h +++ b/tests/src/fsfw_tests/unit/action/TestActionHelper.h @@ -1,12 +1,11 @@ #ifndef UNITTEST_HOSTED_TESTACTIONHELPER_H_ #define UNITTEST_HOSTED_TESTACTIONHELPER_H_ +#include "fsfw_tests/unit/CatchDefinitions.h" #include #include -#include #include - class ActionHelperOwnerMockBase: public HasActionsIF { public: bool getCommandQueueCalled = false; diff --git a/tests/src/fsfw_tests/unit/container/RingBufferTest.cpp b/tests/src/fsfw_tests/unit/container/RingBufferTest.cpp index 32a2502d..819401ab 100644 --- a/tests/src/fsfw_tests/unit/container/RingBufferTest.cpp +++ b/tests/src/fsfw_tests/unit/container/RingBufferTest.cpp @@ -1,4 +1,4 @@ -#include +#include "fsfw_tests/unit/CatchDefinitions.h" #include #include diff --git a/tests/src/fsfw_tests/unit/container/TestArrayList.cpp b/tests/src/fsfw_tests/unit/container/TestArrayList.cpp index 1fd330b6..9417144c 100644 --- a/tests/src/fsfw_tests/unit/container/TestArrayList.cpp +++ b/tests/src/fsfw_tests/unit/container/TestArrayList.cpp @@ -1,8 +1,9 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include -#include /** * @brief Array List test diff --git a/tests/src/fsfw_tests/unit/container/TestDynamicFifo.cpp b/tests/src/fsfw_tests/unit/container/TestDynamicFifo.cpp index 2b572d52..a1bab3ba 100644 --- a/tests/src/fsfw_tests/unit/container/TestDynamicFifo.cpp +++ b/tests/src/fsfw_tests/unit/container/TestDynamicFifo.cpp @@ -1,9 +1,10 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include #include -#include TEST_CASE( "Dynamic Fifo Tests", "[TestDynamicFifo]") { INFO("Dynamic Fifo Tests"); diff --git a/tests/src/fsfw_tests/unit/container/TestFifo.cpp b/tests/src/fsfw_tests/unit/container/TestFifo.cpp index fbcd40cc..311dd8fd 100644 --- a/tests/src/fsfw_tests/unit/container/TestFifo.cpp +++ b/tests/src/fsfw_tests/unit/container/TestFifo.cpp @@ -1,9 +1,10 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include #include -#include TEST_CASE( "Static Fifo Tests", "[TestFifo]") { INFO("Fifo Tests"); diff --git a/tests/src/fsfw_tests/unit/container/TestFixedArrayList.cpp b/tests/src/fsfw_tests/unit/container/TestFixedArrayList.cpp index 1a85f30d..ed597f73 100644 --- a/tests/src/fsfw_tests/unit/container/TestFixedArrayList.cpp +++ b/tests/src/fsfw_tests/unit/container/TestFixedArrayList.cpp @@ -1,8 +1,9 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include -#include TEST_CASE( "FixedArrayList Tests", "[TestFixedArrayList]") { diff --git a/tests/src/fsfw_tests/unit/container/TestFixedMap.cpp b/tests/src/fsfw_tests/unit/container/TestFixedMap.cpp index 297171ca..488418b9 100644 --- a/tests/src/fsfw_tests/unit/container/TestFixedMap.cpp +++ b/tests/src/fsfw_tests/unit/container/TestFixedMap.cpp @@ -1,8 +1,9 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include -#include template class FixedMap; diff --git a/tests/src/fsfw_tests/unit/container/TestFixedOrderedMultimap.cpp b/tests/src/fsfw_tests/unit/container/TestFixedOrderedMultimap.cpp index a47d6efb..23d91744 100644 --- a/tests/src/fsfw_tests/unit/container/TestFixedOrderedMultimap.cpp +++ b/tests/src/fsfw_tests/unit/container/TestFixedOrderedMultimap.cpp @@ -1,8 +1,9 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include -#include TEST_CASE( "FixedOrderedMultimap Tests", "[TestFixedOrderedMultimap]") { INFO("FixedOrderedMultimap Tests"); diff --git a/tests/src/fsfw_tests/unit/container/TestPlacementFactory.cpp b/tests/src/fsfw_tests/unit/container/TestPlacementFactory.cpp index 14cf8eb4..1e328fc7 100644 --- a/tests/src/fsfw_tests/unit/container/TestPlacementFactory.cpp +++ b/tests/src/fsfw_tests/unit/container/TestPlacementFactory.cpp @@ -1,10 +1,11 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include #include #include -#include TEST_CASE( "PlacementFactory Tests", "[TestPlacementFactory]") { INFO("PlacementFactory Tests"); diff --git a/tests/src/fsfw_tests/unit/datapoollocal/DataSetTest.cpp b/tests/src/fsfw_tests/unit/datapoollocal/DataSetTest.cpp index b8748eb4..94b13f2f 100644 --- a/tests/src/fsfw_tests/unit/datapoollocal/DataSetTest.cpp +++ b/tests/src/fsfw_tests/unit/datapoollocal/DataSetTest.cpp @@ -1,7 +1,5 @@ #include "LocalPoolOwnerBase.h" - -#include -#include +#include "fsfw_tests/unit/CatchDefinitions.h" #include #include @@ -10,7 +8,8 @@ #include #include -#include +#include +#include TEST_CASE("DataSetTest" , "[DataSetTest]") { LocalPoolOwnerBase* poolOwner = ObjectManager::instance()-> diff --git a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolManagerTest.cpp b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolManagerTest.cpp index 4a4d08fb..7b2f9412 100644 --- a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolManagerTest.cpp +++ b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolManagerTest.cpp @@ -1,7 +1,5 @@ #include "LocalPoolOwnerBase.h" - -#include -#include +#include "fsfw_tests/unit/CatchDefinitions.h" #include #include @@ -10,7 +8,10 @@ #include #include #include -#include + +#include +#include + #include diff --git a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolOwnerBase.h b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolOwnerBase.h index c0e41ddf..ea5bb7e0 100644 --- a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolOwnerBase.h +++ b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolOwnerBase.h @@ -2,6 +2,7 @@ #define FSFW_UNITTEST_TESTS_DATAPOOLLOCAL_LOCALPOOLOWNERBASE_H_ #include "objects/systemObjectList.h" +#include "../mocks/MessageQueueMockBase.h" #include #include @@ -10,7 +11,6 @@ #include #include #include -#include #include namespace lpool { diff --git a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolVariableTest.cpp b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolVariableTest.cpp index 514d8125..648a76e2 100644 --- a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolVariableTest.cpp +++ b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolVariableTest.cpp @@ -1,10 +1,10 @@ #include "LocalPoolOwnerBase.h" +#include "fsfw_tests/unit/CatchDefinitions.h" -#include #include #include -#include +#include TEST_CASE("LocalPoolVariable" , "[LocPoolVarTest]") { LocalPoolOwnerBase* poolOwner = ObjectManager::instance()-> diff --git a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolVectorTest.cpp b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolVectorTest.cpp index 5b3dd105..3f846dec 100644 --- a/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolVectorTest.cpp +++ b/tests/src/fsfw_tests/unit/datapoollocal/LocalPoolVectorTest.cpp @@ -1,9 +1,10 @@ #include "LocalPoolOwnerBase.h" +#include "fsfw_tests/unit/CatchDefinitions.h" #include #include #include -#include + TEST_CASE("LocalPoolVector" , "[LocPoolVecTest]") { LocalPoolOwnerBase* poolOwner = ObjectManager::instance()-> diff --git a/tests/src/fsfw_tests/unit/mocks/MessageQueueMockBase.h b/tests/src/fsfw_tests/unit/mocks/MessageQueueMockBase.h index 3000f7fb..93a00b7a 100644 --- a/tests/src/fsfw_tests/unit/mocks/MessageQueueMockBase.h +++ b/tests/src/fsfw_tests/unit/mocks/MessageQueueMockBase.h @@ -1,9 +1,12 @@ #ifndef FSFW_UNITTEST_TESTS_MOCKS_MESSAGEQUEUEMOCKBASE_H_ #define FSFW_UNITTEST_TESTS_MOCKS_MESSAGEQUEUEMOCKBASE_H_ -#include -#include -#include +#include "fsfw_tests/unit/CatchDefinitions.h" + +#include "fsfw/ipc/CommandMessage.h" +#include "fsfw/ipc/MessageQueueIF.h" +#include "fsfw/ipc/MessageQueueMessage.h" + #include #include diff --git a/tests/src/fsfw_tests/unit/osal/TestMessageQueue.cpp b/tests/src/fsfw_tests/unit/osal/TestMessageQueue.cpp index e33b7240..07197bf7 100644 --- a/tests/src/fsfw_tests/unit/osal/TestMessageQueue.cpp +++ b/tests/src/fsfw_tests/unit/osal/TestMessageQueue.cpp @@ -1,8 +1,9 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include -#include #include diff --git a/tests/user/unittest/core/printChar.cpp b/tests/src/fsfw_tests/unit/printChar.cpp similarity index 100% rename from tests/user/unittest/core/printChar.cpp rename to tests/src/fsfw_tests/unit/printChar.cpp diff --git a/tests/user/unittest/core/printChar.h b/tests/src/fsfw_tests/unit/printChar.h similarity index 100% rename from tests/user/unittest/core/printChar.h rename to tests/src/fsfw_tests/unit/printChar.h diff --git a/tests/src/fsfw_tests/unit/serialize/TestSerialBufferAdapter.cpp b/tests/src/fsfw_tests/unit/serialize/TestSerialBufferAdapter.cpp index 1938746d..01d75881 100644 --- a/tests/src/fsfw_tests/unit/serialize/TestSerialBufferAdapter.cpp +++ b/tests/src/fsfw_tests/unit/serialize/TestSerialBufferAdapter.cpp @@ -1,7 +1,9 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include -#include + #include diff --git a/tests/src/fsfw_tests/unit/serialize/TestSerialLinkedPacket.cpp b/tests/src/fsfw_tests/unit/serialize/TestSerialLinkedPacket.cpp index b90ae9f8..b6bb214d 100644 --- a/tests/src/fsfw_tests/unit/serialize/TestSerialLinkedPacket.cpp +++ b/tests/src/fsfw_tests/unit/serialize/TestSerialLinkedPacket.cpp @@ -1,10 +1,9 @@ #include "TestSerialLinkedPacket.h" -#include +#include "fsfw_tests/unit/CatchDefinitions.h" #include #include -#include #include diff --git a/tests/src/fsfw_tests/unit/serialize/TestSerialization.cpp b/tests/src/fsfw_tests/unit/serialize/TestSerialization.cpp index 3de581ec..64deae3b 100644 --- a/tests/src/fsfw_tests/unit/serialize/TestSerialization.cpp +++ b/tests/src/fsfw_tests/unit/serialize/TestSerialization.cpp @@ -1,8 +1,8 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" #include #include #include -#include #include diff --git a/tests/src/fsfw_tests/unit/storagemanager/TestNewAccessor.cpp b/tests/src/fsfw_tests/unit/storagemanager/TestNewAccessor.cpp index 10d05c6b..bd1634b7 100644 --- a/tests/src/fsfw_tests/unit/storagemanager/TestNewAccessor.cpp +++ b/tests/src/fsfw_tests/unit/storagemanager/TestNewAccessor.cpp @@ -1,6 +1,9 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include + #include -#include + #include #include diff --git a/tests/src/fsfw_tests/unit/storagemanager/TestPool.cpp b/tests/src/fsfw_tests/unit/storagemanager/TestPool.cpp index d05a3dd6..013ecf86 100644 --- a/tests/src/fsfw_tests/unit/storagemanager/TestPool.cpp +++ b/tests/src/fsfw_tests/unit/storagemanager/TestPool.cpp @@ -1,8 +1,9 @@ +#include "fsfw_tests/unit/CatchDefinitions.h" + #include #include #include -#include #include diff --git a/tests/user/CMakeLists.txt b/tests/user/CMakeLists.txt index df16c756..2e1fdee3 100644 --- a/tests/user/CMakeLists.txt +++ b/tests/user/CMakeLists.txt @@ -32,7 +32,7 @@ if(NOT FSFW_OSAL) set(FSFW_OSAL host CACHE STRING "OS for the FSFW.") endif() -option(CUSTOM_UNITTEST_RUNNER +option(FSFW_CUSTOM_UNITTEST_RUNNER "Specify whether custom main or Catch2 main is used" TRUE ) @@ -49,7 +49,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED True) # Set names and variables set(TARGET_NAME ${CMAKE_PROJECT_NAME}) -if(CUSTOM_UNITTEST_RUNNER) +if(FSFW_CUSTOM_UNITTEST_RUNNER) set(CATCH2_TARGET Catch2) else() set(CATCH2_TARGET Catch2WithMain) diff --git a/tests/user/testcfg/TestsConfig.h.in b/tests/user/testcfg/TestsConfig.h.in index 0341583d..7d950070 100644 --- a/tests/user/testcfg/TestsConfig.h.in +++ b/tests/user/testcfg/TestsConfig.h.in @@ -1,6 +1,8 @@ #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" diff --git a/tests/user/unittest/CMakeLists.txt b/tests/user/unittest/CMakeLists.txt deleted file mode 100644 index ad6d4787..00000000 --- a/tests/user/unittest/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_subdirectory(core) diff --git a/tests/user/unittest/core/CMakeLists.txt b/tests/user/unittest/core/CMakeLists.txt deleted file mode 100644 index 0989926c..00000000 --- a/tests/user/unittest/core/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -target_sources(${TARGET_NAME} PRIVATE - CatchDefinitions.cpp - CatchFactory.cpp - CatchRunner.cpp - CatchSetup.cpp - printChar.cpp -) - -if(CUSTOM_UNITTEST_RUNNER) - target_sources(${TARGET_NAME} PRIVATE - CatchRunner.cpp - ) -endif() \ No newline at end of file diff --git a/tests/user/unittest/core/CatchFactory.h b/tests/user/unittest/core/CatchFactory.h deleted file mode 100644 index 024f762e..00000000 --- a/tests/user/unittest/core/CatchFactory.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef FSFW_CATCHFACTORY_H_ -#define FSFW_CATCHFACTORY_H_ - -#include - -namespace Factory { - /** - * @brief Creates all SystemObject elements which are persistent - * during execution. - */ - void produce(void* args); - void setStaticFrameworkObjectIds(); - -} - -#endif /* FSFW_CATCHFACTORY_H_ */ diff --git a/tests/user/unittest/core/core.mk b/tests/user/unittest/core/core.mk deleted file mode 100644 index 3e5626d3..00000000 --- a/tests/user/unittest/core/core.mk +++ /dev/null @@ -1,3 +0,0 @@ -CXXSRC += $(wildcard $(CURRENTPATH)/*.cpp) - -INCLUDES += $(CURRENTPATH) \ No newline at end of file