From 586993c081b953963d2eb9ac635cd46391212357 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 25 Jul 2022 20:31:06 +0200 Subject: [PATCH] completed send helper tests --- src/fsfw/pus/Service17Test.cpp | 5 +- .../pus/Service1TelecommandVerification.cpp | 1 - src/fsfw/pus/Service5EventReporting.cpp | 1 - src/fsfw/storagemanager/LocalPool.cpp | 15 ++- src/fsfw/storagemanager/LocalPool.h | 1 + src/fsfw/storagemanager/StorageManagerIF.h | 2 + .../tmtcservices/CommandingServiceBase.cpp | 1 - src/fsfw/tmtcservices/PusServiceBase.cpp | 4 +- src/fsfw/tmtcservices/TmSendHelper.cpp | 34 ++++--- src/fsfw/tmtcservices/TmSendHelper.h | 22 +++-- .../datapoollocal/testLocalPoolManager.cpp | 50 +++++----- unittests/mocks/InternalErrorReporterMock.cpp | 6 ++ unittests/mocks/InternalErrorReporterMock.h | 5 +- unittests/mocks/MessageQueueMock.cpp | 16 +++- unittests/mocks/MessageQueueMock.h | 7 +- unittests/storagemanager/CMakeLists.txt | 4 +- .../{TestNewAccessor.cpp => testAccessor.cpp} | 6 +- .../{TestPool.cpp => testPool.cpp} | 9 +- unittests/tmtcservices/testSendHelper.cpp | 92 ++++++++++++++++++- 19 files changed, 211 insertions(+), 70 deletions(-) rename unittests/storagemanager/{TestNewAccessor.cpp => testAccessor.cpp} (98%) rename unittests/storagemanager/{TestPool.cpp => testPool.cpp} (97%) diff --git a/src/fsfw/pus/Service17Test.cpp b/src/fsfw/pus/Service17Test.cpp index d7c5a71b..631cf939 100644 --- a/src/fsfw/pus/Service17Test.cpp +++ b/src/fsfw/pus/Service17Test.cpp @@ -6,10 +6,7 @@ #include "fsfw/tmtcservices/tmHelpers.h" Service17Test::Service17Test(object_id_t objectId, uint16_t apid, uint8_t serviceId) - : PusServiceBase(objectId, apid, serviceId), - storeHelper(apid), - sendHelper(nullptr), - packetSubCounter(0) {} + : PusServiceBase(objectId, apid, serviceId), storeHelper(apid), packetSubCounter(0) {} Service17Test::~Service17Test() = default; diff --git a/src/fsfw/pus/Service1TelecommandVerification.cpp b/src/fsfw/pus/Service1TelecommandVerification.cpp index 624a73d0..7b5e7973 100644 --- a/src/fsfw/pus/Service1TelecommandVerification.cpp +++ b/src/fsfw/pus/Service1TelecommandVerification.cpp @@ -15,7 +15,6 @@ Service1TelecommandVerification::Service1TelecommandVerification(object_id_t obj apid(apid), serviceId(serviceId), targetDestination(targetDestination), - sendHelper(nullptr), storeHelper(apid) { tmQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth); } diff --git a/src/fsfw/pus/Service5EventReporting.cpp b/src/fsfw/pus/Service5EventReporting.cpp index e9c9c095..44f7861a 100644 --- a/src/fsfw/pus/Service5EventReporting.cpp +++ b/src/fsfw/pus/Service5EventReporting.cpp @@ -11,7 +11,6 @@ Service5EventReporting::Service5EventReporting(object_id_t objectId, uint16_t ap uint8_t serviceId, size_t maxNumberReportsPerCycle, uint32_t messageQueueDepth) : PusServiceBase(objectId, apid, serviceId), - sendHelper(nullptr), storeHelper(apid), maxNumberReportsPerCycle(maxNumberReportsPerCycle) { eventQueue = QueueFactory::instance()->createMessageQueue(messageQueueDepth); diff --git a/src/fsfw/storagemanager/LocalPool.cpp b/src/fsfw/storagemanager/LocalPool.cpp index cee1d407..f8b2bdb3 100644 --- a/src/fsfw/storagemanager/LocalPool.cpp +++ b/src/fsfw/storagemanager/LocalPool.cpp @@ -194,8 +194,6 @@ void LocalPool::clearStore() { for (auto& size : sizeList) { size = STORAGE_FREE; } - // std::memset(sizeList[index], 0xff, - // numberOfElements[index] * sizeof(size_type)); } } @@ -338,3 +336,16 @@ void LocalPool::clearSubPool(max_subpools_t subpoolIndex) { } LocalPool::max_subpools_t LocalPool::getNumberOfSubPools() const { return NUMBER_OF_SUBPOOLS; } + +bool LocalPool::hasDataAtId(store_address_t storeId) const { + if (storeId.poolIndex >= NUMBER_OF_SUBPOOLS) { + return false; + } + if ((storeId.packetIndex >= numberOfElements[storeId.poolIndex])) { + return false; + } + if (sizeLists[storeId.poolIndex][storeId.packetIndex] != STORAGE_FREE) { + return true; + } + return false; +} diff --git a/src/fsfw/storagemanager/LocalPool.h b/src/fsfw/storagemanager/LocalPool.h index 47f84955..1c1d4006 100644 --- a/src/fsfw/storagemanager/LocalPool.h +++ b/src/fsfw/storagemanager/LocalPool.h @@ -132,6 +132,7 @@ class LocalPool : public SystemObject, public StorageManagerIF { * @return */ max_subpools_t getNumberOfSubPools() const override; + bool hasDataAtId(store_address_t storeId) const override; protected: /** diff --git a/src/fsfw/storagemanager/StorageManagerIF.h b/src/fsfw/storagemanager/StorageManagerIF.h index a8313344..90ea4587 100644 --- a/src/fsfw/storagemanager/StorageManagerIF.h +++ b/src/fsfw/storagemanager/StorageManagerIF.h @@ -163,6 +163,8 @@ class StorageManagerIF : public HasReturnvaluesIF { virtual ReturnValue_t getFreeElement(store_address_t* storageId, size_t size, uint8_t** p_data, bool ignoreFault = false) = 0; + [[nodiscard]] virtual bool hasDataAtId(store_address_t storeId) const = 0; + /** * Clears the whole store. * Use with care! diff --git a/src/fsfw/tmtcservices/CommandingServiceBase.cpp b/src/fsfw/tmtcservices/CommandingServiceBase.cpp index 3fac5bd2..10cc2689 100644 --- a/src/fsfw/tmtcservices/CommandingServiceBase.cpp +++ b/src/fsfw/tmtcservices/CommandingServiceBase.cpp @@ -21,7 +21,6 @@ CommandingServiceBase::CommandingServiceBase(object_id_t setObjectId, uint16_t a service(service), timeoutSeconds(commandTimeoutSeconds), tmStoreHelper(apid), - tmSendHelper(nullptr), commandMap(numberOfParallelCommands) { commandQueue = QueueFactory::instance()->createMessageQueue(queueDepth); requestQueue = QueueFactory::instance()->createMessageQueue(queueDepth); diff --git a/src/fsfw/tmtcservices/PusServiceBase.cpp b/src/fsfw/tmtcservices/PusServiceBase.cpp index 6a21b65b..26f08694 100644 --- a/src/fsfw/tmtcservices/PusServiceBase.cpp +++ b/src/fsfw/tmtcservices/PusServiceBase.cpp @@ -131,8 +131,8 @@ void PusServiceBase::initializeTmHelpers(TmSendHelper& tmSendHelper, TmStoreHelp } void PusServiceBase::initializeTmSendHelper(TmSendHelper& tmSendHelper) { - tmSendHelper.setMsgQueue(requestQueue); - tmSendHelper.setMsgDestination(requestQueue->getDefaultDestination()); + tmSendHelper.setMsgQueue(*requestQueue); + tmSendHelper.setDefaultDestination(requestQueue->getDefaultDestination()); if (errReporter == nullptr) { errReporter = ObjectManager::instance()->get(objects::INTERNAL_ERROR_REPORTER); diff --git a/src/fsfw/tmtcservices/TmSendHelper.cpp b/src/fsfw/tmtcservices/TmSendHelper.cpp index 7b464ad8..0b9d854c 100644 --- a/src/fsfw/tmtcservices/TmSendHelper.cpp +++ b/src/fsfw/tmtcservices/TmSendHelper.cpp @@ -2,38 +2,50 @@ #include "fsfw/ipc/MessageQueueSenderIF.h" -TmSendHelper::TmSendHelper(MessageQueueIF *queue, InternalErrorReporterIF *reporter, +TmSendHelper::TmSendHelper() = default; + +TmSendHelper::TmSendHelper(MessageQueueIF &queue, InternalErrorReporterIF &reporter, MessageQueueId_t tmtcMsgDest) - : tmtcMsgDest(tmtcMsgDest), queue(queue), errReporter(reporter) {} + : defaultDest(tmtcMsgDest), queue(&queue), errReporter(&reporter) {} -TmSendHelper::TmSendHelper(MessageQueueIF *queue, InternalErrorReporterIF *reporter) - : queue(queue), errReporter(reporter) {} +TmSendHelper::TmSendHelper(MessageQueueIF &queue, InternalErrorReporterIF &reporter) + : queue(&queue), errReporter(&reporter) {} -TmSendHelper::TmSendHelper(InternalErrorReporterIF *reporter) : errReporter(reporter) {} +TmSendHelper::TmSendHelper(InternalErrorReporterIF &reporter) : errReporter(&reporter) {} ReturnValue_t TmSendHelper::sendPacket(const store_address_t &storeId) { if (queue == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } TmTcMessage message(storeId); - ReturnValue_t result = queue->sendMessage(tmtcMsgDest, &message, ignoreFault); + ReturnValue_t result = queue->sendMessage(defaultDest, &message, ignoreFault); if (result != HasReturnvaluesIF::RETURN_OK) { - if (errReporter != nullptr) { + if (errReporter != nullptr and not ignoreFault) { errReporter->lostTm(); } return result; } - return HasReturnvaluesIF::RETURN_OK; + return result; } -void TmSendHelper::setMsgDestination(MessageQueueId_t msgDest) { tmtcMsgDest = msgDest; } +void TmSendHelper::setDefaultDestination(MessageQueueId_t msgDest) { defaultDest = msgDest; } void TmSendHelper::setInternalErrorReporter(InternalErrorReporterIF *reporter) { errReporter = reporter; } -void TmSendHelper::setMsgQueue(MessageQueueIF *queue_) { queue = queue_; } +void TmSendHelper::setMsgQueue(MessageQueueIF &queue_) { queue = &queue_; } ReturnValue_t TmSendHelper::sendPacket(MessageQueueId_t dest, const store_address_t &storeId) { - setMsgDestination(dest); + setDefaultDestination(dest); return sendPacket(storeId); } + +MessageQueueId_t TmSendHelper::getDefaultDestination() const { return defaultDest; } + +bool TmSendHelper::areFaultsIgnored() const { return ignoreFault; } +void TmSendHelper::ignoreFaults() { ignoreFault = true; } +void TmSendHelper::dontIgnoreFaults() { ignoreFault = false; } + +InternalErrorReporterIF *TmSendHelper::getInternalErrorReporter() const { return errReporter; } + +MessageQueueIF *TmSendHelper::getMsgQueue() const { return queue; } diff --git a/src/fsfw/tmtcservices/TmSendHelper.h b/src/fsfw/tmtcservices/TmSendHelper.h index 4cb159da..dee5a495 100644 --- a/src/fsfw/tmtcservices/TmSendHelper.h +++ b/src/fsfw/tmtcservices/TmSendHelper.h @@ -9,22 +9,30 @@ class TmSendHelper { public: - TmSendHelper(MessageQueueIF* queue, InternalErrorReporterIF* reporter, + TmSendHelper(); + TmSendHelper(MessageQueueIF& queue, InternalErrorReporterIF& reporter, MessageQueueId_t tmtcMsgDest); - TmSendHelper(MessageQueueIF* queue, InternalErrorReporterIF* reporter); - explicit TmSendHelper(InternalErrorReporterIF* reporter); + TmSendHelper(MessageQueueIF& queue, InternalErrorReporterIF& reporter); + explicit TmSendHelper(InternalErrorReporterIF& reporter); - void setMsgQueue(MessageQueueIF* queue); - void setMsgDestination(MessageQueueId_t msgDest); + void setMsgQueue(MessageQueueIF& queue); + MessageQueueIF* getMsgQueue() const; + + void setDefaultDestination(MessageQueueId_t msgDest); + [[nodiscard]] MessageQueueId_t getDefaultDestination() const; + [[nodiscard]] bool areFaultsIgnored() const; + void ignoreFaults(); + void dontIgnoreFaults(); void setInternalErrorReporter(InternalErrorReporterIF* reporter); + [[nodiscard]] InternalErrorReporterIF* getInternalErrorReporter() const; ReturnValue_t sendPacket(MessageQueueId_t dest, const store_address_t& storeId); ReturnValue_t sendPacket(const store_address_t& storeId); private: - MessageQueueId_t tmtcMsgDest = MessageQueueIF::NO_QUEUE; + MessageQueueId_t defaultDest = MessageQueueIF::NO_QUEUE; bool ignoreFault = false; MessageQueueIF* queue = nullptr; - InternalErrorReporterIF* errReporter; + InternalErrorReporterIF* errReporter = nullptr; }; #endif // FSFW_TMTCPACKET_TMSENDHELPER_H diff --git a/unittests/datapoollocal/testLocalPoolManager.cpp b/unittests/datapoollocal/testLocalPoolManager.cpp index 228ab08c..e5282c16 100644 --- a/unittests/datapoollocal/testLocalPoolManager.cpp +++ b/unittests/datapoollocal/testLocalPoolManager.cpp @@ -12,8 +12,8 @@ #include #include "CatchDefinitions.h" -#include "mocks/LocalPoolOwnerBase.h" #include "mocks/HkReceiverMock.h" +#include "mocks/LocalPoolOwnerBase.h" TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { const MessageQueueId_t defaultDestId = 1; @@ -65,7 +65,7 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { REQUIRE(poolOwner.poolManager.performHkOperation() == retval::CATCH_OK); REQUIRE(poolOwnerMock.wasMessageSent() == true); - CHECK(poolOwnerMock.numberOfSentMessage() == 1); + CHECK(poolOwnerMock.numberOfSentMessages() == 1); REQUIRE(poolOwnerMock.getNextSentMessage(subscriberId, messageSent) == retval::CATCH_OK); CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::UPDATE_NOTIFICATION_SET)); @@ -76,7 +76,7 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { poolOwner.dataset.setChanged(true); REQUIRE(poolOwner.poolManager.performHkOperation() == retval::CATCH_OK); REQUIRE(poolOwnerMock.wasMessageSent() == true); - CHECK(poolOwnerMock.numberOfSentMessage() == 2); + CHECK(poolOwnerMock.numberOfSentMessages() == 2); // first message sent should be the update notification REQUIRE(poolOwnerMock.getNextSentMessage(subscriberId, messageSent) == retval::CATCH_OK); CHECK(messageSent.getCommand() == @@ -110,7 +110,7 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { /* Trigger generation of snapshot */ REQUIRE(poolOwner.poolManager.performHkOperation() == retval::CATCH_OK); REQUIRE(poolOwnerMock.wasMessageSent()); - CHECK(poolOwnerMock.numberOfSentMessage() == 1); + CHECK(poolOwnerMock.numberOfSentMessages() == 1); REQUIRE(poolOwnerMock.getNextSentMessage(subscriberId, messageSent) == retval::CATCH_OK); /* Check that snapshot was generated */ CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::UPDATE_SNAPSHOT_SET)); @@ -174,7 +174,7 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { /* Check update snapshot was sent. */ REQUIRE(poolOwnerMock.wasMessageSent()); - CHECK(poolOwnerMock.numberOfSentMessage() == 1); + CHECK(poolOwnerMock.numberOfSentMessages() == 1); /* Should have been reset. */ CHECK(poolVar->hasChanged() == false); @@ -222,7 +222,7 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { /* Check update notification was sent. */ REQUIRE(poolOwnerMock.wasMessageSent()); - CHECK(poolOwnerMock.numberOfSentMessage() == 1); + CHECK(poolOwnerMock.numberOfSentMessages() == 1); /* Should have been reset. */ CHECK(poolVar->hasChanged() == false); REQUIRE(poolOwnerMock.getNextSentMessage(subscriberId, messageSent) == retval::CATCH_OK); @@ -238,7 +238,7 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { REQUIRE(poolOwner.poolManager.performHkOperation() == retval::CATCH_OK); /* Now two messages should be sent. */ REQUIRE(poolOwnerMock.wasMessageSent()); - CHECK(poolOwnerMock.numberOfSentMessage() == 2); + CHECK(poolOwnerMock.numberOfSentMessages() == 2); poolOwnerMock.clearMessages(true); poolOwner.dataset.setChanged(true); @@ -247,9 +247,9 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { REQUIRE(poolOwner.poolManager.performHkOperation() == retval::CATCH_OK); /* Now three messages should be sent. */ REQUIRE(poolOwnerMock.wasMessageSent()); - CHECK(poolOwnerMock.numberOfSentMessage() == 3); - CHECK(poolOwnerMock.numberOfSentMessage(subscriberId) == 2); - CHECK(poolOwnerMock.numberOfSentMessage(hkDest) == 1); + CHECK(poolOwnerMock.numberOfSentMessages() == 3); + CHECK(poolOwnerMock.numberOfSentMessagesToDest(subscriberId) == 2); + CHECK(poolOwnerMock.numberOfSentMessagesToDest(hkDest) == 1); REQUIRE(poolOwnerMock.getNextSentMessage(subscriberId, messageSent) == retval::CATCH_OK); CHECK(messageSent.getCommand() == static_cast(HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE)); @@ -275,7 +275,7 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { REQUIRE(poolOwner.poolManager.performHkOperation() == retval::CATCH_OK); /* Now HK packet should be sent as message immediately. */ REQUIRE(poolOwnerMock.wasMessageSent()); - CHECK(poolOwnerMock.numberOfSentMessage() == 1); + CHECK(poolOwnerMock.numberOfSentMessages() == 1); CHECK(poolOwnerMock.clearLastSentMessage() == retval::CATCH_OK); LocalPoolDataSetBase* setHandle = poolOwner.getDataSetHandle(lpool::testSid); @@ -283,7 +283,7 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { CHECK(poolOwner.poolManager.generateHousekeepingPacket(lpool::testSid, setHandle, false) == retval::CATCH_OK); REQUIRE(poolOwnerMock.wasMessageSent()); - CHECK(poolOwnerMock.numberOfSentMessage() == 1); + CHECK(poolOwnerMock.numberOfSentMessages() == 1); CHECK(poolOwnerMock.clearLastSentMessage() == retval::CATCH_OK); CHECK(setHandle->getReportingEnabled() == true); @@ -292,7 +292,7 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); CHECK(setHandle->getReportingEnabled() == false); REQUIRE(poolOwnerMock.wasMessageSent()); - CHECK(poolOwnerMock.numberOfSentMessage() == 1); + CHECK(poolOwnerMock.numberOfSentMessages() == 1); CHECK(poolOwnerMock.clearLastSentMessage() == retval::CATCH_OK); HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, false); @@ -314,7 +314,7 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { resulting collection interval should be 1.0 second */ CHECK(poolOwner.dataset.getCollectionInterval() == 1.0); REQUIRE(poolOwnerMock.wasMessageSent()); - REQUIRE(poolOwnerMock.numberOfSentMessage() == 1); + REQUIRE(poolOwnerMock.numberOfSentMessages() == 1); CHECK(poolOwnerMock.clearLastSentMessage() == retval::CATCH_OK); HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false); @@ -322,13 +322,13 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); /* Now HK packet should be sent as message. */ REQUIRE(poolOwnerMock.wasMessageSent()); - REQUIRE(poolOwnerMock.numberOfSentMessage() == 1); + REQUIRE(poolOwnerMock.numberOfSentMessages() == 1); poolOwnerMock.clearMessages(); HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false); CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); REQUIRE(poolOwnerMock.wasMessageSent()); - REQUIRE(poolOwnerMock.numberOfSentMessage() == 1); + REQUIRE(poolOwnerMock.numberOfSentMessages() == 1); poolOwnerMock.clearMessages(); HousekeepingMessage::setUpdateNotificationSetCommand(&hkCmd, lpool::testSid); @@ -346,7 +346,7 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { static_cast(LocalDataPoolManager::WRONG_HK_PACKET_TYPE)); /* We still expect a failure message being sent */ REQUIRE(poolOwnerMock.wasMessageSent()); - REQUIRE(poolOwnerMock.numberOfSentMessage() == 1); + REQUIRE(poolOwnerMock.numberOfSentMessages() == 1); CHECK(poolOwnerMock.clearLastSentMessage() == retval::CATCH_OK); HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4, @@ -354,52 +354,52 @@ TEST_CASE("Local Pool Manager Tests", "[LocManTest]") { CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == static_cast(LocalDataPoolManager::WRONG_HK_PACKET_TYPE)); REQUIRE(poolOwnerMock.wasMessageSent()); - REQUIRE(poolOwnerMock.numberOfSentMessage() == 1); + REQUIRE(poolOwnerMock.numberOfSentMessages() == 1); CHECK(poolOwnerMock.clearLastSentMessage() == retval::CATCH_OK); HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false); CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == static_cast(LocalDataPoolManager::WRONG_HK_PACKET_TYPE)); REQUIRE(poolOwnerMock.wasMessageSent()); - REQUIRE(poolOwnerMock.numberOfSentMessage() == 1); + REQUIRE(poolOwnerMock.numberOfSentMessages() == 1); CHECK(poolOwnerMock.clearLastSentMessage() == retval::CATCH_OK); HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, true); CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); REQUIRE(poolOwnerMock.wasMessageSent()); - REQUIRE(poolOwnerMock.numberOfSentMessage() == 1); + REQUIRE(poolOwnerMock.numberOfSentMessages() == 1); poolOwnerMock.clearMessages(); HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4, true); CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); REQUIRE(poolOwnerMock.wasMessageSent()); - REQUIRE(poolOwnerMock.numberOfSentMessage() == 1); + REQUIRE(poolOwnerMock.numberOfSentMessages() == 1); poolOwnerMock.clearMessages(); HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, true); CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); REQUIRE(poolOwnerMock.wasMessageSent()); - REQUIRE(poolOwnerMock.numberOfSentMessage() == 1); + REQUIRE(poolOwnerMock.numberOfSentMessages() == 1); poolOwnerMock.clearMessages(); HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, true); CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); REQUIRE(poolOwnerMock.wasMessageSent()); - REQUIRE(poolOwnerMock.numberOfSentMessage() == 1); + REQUIRE(poolOwnerMock.numberOfSentMessages() == 1); poolOwnerMock.clearMessages(); HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false); CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == static_cast(LocalDataPoolManager::WRONG_HK_PACKET_TYPE)); REQUIRE(poolOwnerMock.wasMessageSent()); - REQUIRE(poolOwnerMock.numberOfSentMessage() == 1); + REQUIRE(poolOwnerMock.numberOfSentMessages() == 1); poolOwnerMock.clearMessages(); HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, true); CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK); REQUIRE(poolOwnerMock.wasMessageSent()); - REQUIRE(poolOwnerMock.numberOfSentMessage() == 1); + REQUIRE(poolOwnerMock.numberOfSentMessages() == 1); poolOwnerMock.clearMessages(); HousekeepingMessage::setUpdateNotificationVariableCommand(&hkCmd, lpool::uint8VarGpid); diff --git a/unittests/mocks/InternalErrorReporterMock.cpp b/unittests/mocks/InternalErrorReporterMock.cpp index c7758a13..f53a1ed4 100644 --- a/unittests/mocks/InternalErrorReporterMock.cpp +++ b/unittests/mocks/InternalErrorReporterMock.cpp @@ -5,3 +5,9 @@ InternalErrorReporterMock::InternalErrorReporterMock() = default; void InternalErrorReporterMock::queueMessageNotSent() { queueMsgNotSentCallCnt++; } void InternalErrorReporterMock::lostTm() { lostTmCallCnt++; } void InternalErrorReporterMock::storeFull() { storeFullCallCnt++; } + +void InternalErrorReporterMock::reset() { + queueMsgNotSentCallCnt = 0; + lostTmCallCnt = 0; + storeFullCallCnt = 0; +} diff --git a/unittests/mocks/InternalErrorReporterMock.h b/unittests/mocks/InternalErrorReporterMock.h index f6babe09..e1ad35ae 100644 --- a/unittests/mocks/InternalErrorReporterMock.h +++ b/unittests/mocks/InternalErrorReporterMock.h @@ -9,10 +9,11 @@ class InternalErrorReporterMock : public InternalErrorReporterIF { unsigned int lostTmCallCnt = 0; unsigned int storeFullCallCnt = 0; InternalErrorReporterMock(); + void reset(); + + private: void queueMessageNotSent() override; void lostTm() override; void storeFull() override; - - private: }; #endif // FSFW_TESTS_INTERNALERRORREPORTERMOCK_H diff --git a/unittests/mocks/MessageQueueMock.cpp b/unittests/mocks/MessageQueueMock.cpp index cb9bf0b7..c514cc2e 100644 --- a/unittests/mocks/MessageQueueMock.cpp +++ b/unittests/mocks/MessageQueueMock.cpp @@ -15,7 +15,7 @@ bool MessageQueueMock::wasMessageSent() const { [](const std::pair& pair) { return pair.second.callCount > 0; }); } -size_t MessageQueueMock::numberOfSentMessage() const { +size_t MessageQueueMock::numberOfSentMessages() const { size_t callCount = 0; for (auto& destInfo : sendMap) { callCount += destInfo.second.callCount; @@ -23,7 +23,7 @@ size_t MessageQueueMock::numberOfSentMessage() const { return callCount; } -size_t MessageQueueMock::numberOfSentMessage(MessageQueueId_t id) const { +size_t MessageQueueMock::numberOfSentMessagesToDest(MessageQueueId_t id) const { auto iter = sendMap.find(id); if (iter == sendMap.end()) { return 0; @@ -31,6 +31,10 @@ size_t MessageQueueMock::numberOfSentMessage(MessageQueueId_t id) const { return iter->second.callCount; } +size_t MessageQueueMock::numberOfSentMessagesToDefault() const { + return numberOfSentMessagesToDest(MessageQueueBase::getDefaultDestination()); +} + ReturnValue_t MessageQueueMock::clearLastReceivedMessage(bool clearCmdMsg) { if (receivedMsgs.empty()) { return MessageQueueIF::EMPTY; @@ -61,6 +65,10 @@ ReturnValue_t MessageQueueMock::sendMessageFrom(MessageQueueId_t sendTo, if (message == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } + if (nextSendFailsPair.first) { + nextSendFailsPair.first = false; + return nextSendFailsPair.second; + } auto iter = sendMap.find(sendTo); MessageQueueMessage messageCopy; if (iter == sendMap.end()) { @@ -162,3 +170,7 @@ void MessageQueueMock::clearEmptyEntries() { } } } +void MessageQueueMock::makeNextSendFail(ReturnValue_t retval) { + nextSendFailsPair.first = true; + nextSendFailsPair.second = retval; +} diff --git a/unittests/mocks/MessageQueueMock.h b/unittests/mocks/MessageQueueMock.h index fbfa1ba9..0be68223 100644 --- a/unittests/mocks/MessageQueueMock.h +++ b/unittests/mocks/MessageQueueMock.h @@ -32,8 +32,10 @@ class MessageQueueMock : public MessageQueueBase { //! Get message which was sent to a specific ID ReturnValue_t getNextSentMessage(MessageQueueId_t id, MessageQueueMessageIF& message); [[nodiscard]] bool wasMessageSent() const; - [[nodiscard]] size_t numberOfSentMessage() const; - [[nodiscard]] size_t numberOfSentMessage(MessageQueueId_t id) const; + void makeNextSendFail(ReturnValue_t retval); + [[nodiscard]] size_t numberOfSentMessages() const; + [[nodiscard]] size_t numberOfSentMessagesToDefault() const; + [[nodiscard]] size_t numberOfSentMessagesToDest(MessageQueueId_t id) const; /** * Pop a message, clearing it in the process. * @return @@ -53,6 +55,7 @@ class MessageQueueMock : public MessageQueueBase { using SendMap = std::map; SendMap sendMap; std::queue receivedMsgs; + std::pair nextSendFailsPair; void clearEmptyEntries(); ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override; diff --git a/unittests/storagemanager/CMakeLists.txt b/unittests/storagemanager/CMakeLists.txt index 7b6280df..d2bb4dbc 100644 --- a/unittests/storagemanager/CMakeLists.txt +++ b/unittests/storagemanager/CMakeLists.txt @@ -1,4 +1,4 @@ target_sources(${FSFW_TEST_TGT} PRIVATE - TestNewAccessor.cpp - TestPool.cpp + testAccessor.cpp + testPool.cpp ) diff --git a/unittests/storagemanager/TestNewAccessor.cpp b/unittests/storagemanager/testAccessor.cpp similarity index 98% rename from unittests/storagemanager/TestNewAccessor.cpp rename to unittests/storagemanager/testAccessor.cpp index 996239a6..1404646b 100644 --- a/unittests/storagemanager/TestNewAccessor.cpp +++ b/unittests/storagemanager/testAccessor.cpp @@ -6,11 +6,11 @@ #include "CatchDefinitions.h" -TEST_CASE("New Accessor", "[NewAccessor]") { +TEST_CASE("Pool Accessor", "[pool-accessor]") { LocalPool::LocalPoolConfig poolCfg = {{1, 10}}; LocalPool SimplePool = LocalPool(0, poolCfg); - std::array testDataArray; - std::array receptionArray; + std::array testDataArray{}; + std::array receptionArray{}; store_address_t testStoreId; ReturnValue_t result = retval::CATCH_FAILED; diff --git a/unittests/storagemanager/TestPool.cpp b/unittests/storagemanager/testPool.cpp similarity index 97% rename from unittests/storagemanager/TestPool.cpp rename to unittests/storagemanager/testPool.cpp index e37c6934..03cac72a 100644 --- a/unittests/storagemanager/TestPool.cpp +++ b/unittests/storagemanager/testPool.cpp @@ -10,10 +10,10 @@ TEST_CASE("Local Pool Simple Tests [1 Pool]", "[TestPool]") { LocalPool::LocalPoolConfig config = {{1, 10}}; LocalPool simplePool(0, config); - std::array testDataArray; - std::array receptionArray; + std::array testDataArray{}; + std::array receptionArray{}; store_address_t testStoreId; - ReturnValue_t result = retval::CATCH_FAILED; + ReturnValue_t result; uint8_t* pointer = nullptr; const uint8_t* constPointer = nullptr; @@ -23,8 +23,10 @@ TEST_CASE("Local Pool Simple Tests [1 Pool]", "[TestPool]") { size_t size = 10; SECTION("Basic tests") { + REQUIRE(not simplePool.hasDataAtId(testStoreId)); result = simplePool.addData(&testStoreId, testDataArray.data(), size); REQUIRE(result == retval::CATCH_OK); + REQUIRE(simplePool.hasDataAtId(testStoreId)); result = simplePool.getData(testStoreId, &constPointer, &size); REQUIRE(result == retval::CATCH_OK); memcpy(receptionArray.data(), constPointer, size); @@ -40,6 +42,7 @@ TEST_CASE("Local Pool Simple Tests [1 Pool]", "[TestPool]") { } result = simplePool.deleteData(testStoreId); REQUIRE(result == retval::CATCH_OK); + REQUIRE(not simplePool.hasDataAtId(testStoreId)); result = simplePool.addData(&testStoreId, testDataArray.data(), 15); CHECK(result == (int)StorageManagerIF::DATA_TOO_LARGE); } diff --git a/unittests/tmtcservices/testSendHelper.cpp b/unittests/tmtcservices/testSendHelper.cpp index fc5b86bd..9daeded5 100644 --- a/unittests/tmtcservices/testSendHelper.cpp +++ b/unittests/tmtcservices/testSendHelper.cpp @@ -1,15 +1,103 @@ #include #include +#include "fsfw/storagemanager/LocalPool.h" #include "fsfw/tmtcservices/TmSendHelper.h" +#include "fsfw/tmtcservices/TmStoreHelper.h" +#include "mocks/CdsShortTimestamperMock.h" #include "mocks/InternalErrorReporterMock.h" #include "mocks/MessageQueueMock.h" TEST_CASE("TM Send Helper", "[tm-send-helper]") { + MessageQueueId_t destId = 1; auto errReporter = InternalErrorReporterMock(); auto msgQueue = MessageQueueMock(); - TmSendHelper sendHelper(&msgQueue, &errReporter); + msgQueue.setDefaultDestination(destId); + TmSendHelper sendHelper(msgQueue, errReporter, destId); + auto timeStamper = CdsShortTimestamperMock(); + LocalPool::LocalPoolConfig cfg = {{5, 32}, {2, 64}}; + LocalPool pool(objects::NO_OBJECT, cfg); + auto storeHelper = TmStoreHelper(2, pool, timeStamper); - SECTION("State") { + SECTION("State and Setters") { + REQUIRE(sendHelper.getInternalErrorReporter() == &errReporter); + REQUIRE(sendHelper.getDefaultDestination() == destId); + REQUIRE(sendHelper.getMsgQueue() == &msgQueue); + } + + SECTION("Setters") { + REQUIRE(not sendHelper.areFaultsIgnored()); + sendHelper.ignoreFaults(); + REQUIRE(sendHelper.areFaultsIgnored()); + sendHelper.dontIgnoreFaults(); + REQUIRE(not sendHelper.areFaultsIgnored()); + REQUIRE(sendHelper.getDefaultDestination() == destId); + sendHelper.setDefaultDestination(destId + 1); + REQUIRE(sendHelper.getDefaultDestination() == destId + 1); + sendHelper.setInternalErrorReporter(nullptr); + REQUIRE(sendHelper.getInternalErrorReporter() == nullptr); + } + + SECTION("Default CTOR") { + TmSendHelper emptyHelper; + REQUIRE(emptyHelper.getInternalErrorReporter() == nullptr); + REQUIRE(emptyHelper.getDefaultDestination() == MessageQueueIF::NO_QUEUE); + store_address_t dummy; + // basic robustness + REQUIRE(emptyHelper.sendPacket(dummy) == HasReturnvaluesIF::RETURN_FAILED); + } + + SECTION("One Arg CTOR") { + TmSendHelper helper(errReporter); + REQUIRE(helper.getInternalErrorReporter() == &errReporter); + REQUIRE(helper.getDefaultDestination() == MessageQueueIF::NO_QUEUE); + REQUIRE(helper.getMsgQueue() == nullptr); + } + + SECTION("Two Arg CTOR") { + TmSendHelper helper(msgQueue, errReporter); + REQUIRE(helper.getInternalErrorReporter() == &errReporter); + REQUIRE(helper.getDefaultDestination() == MessageQueueIF::NO_QUEUE); + REQUIRE(helper.getMsgQueue() == &msgQueue); + } + SECTION("Send") { + storeHelper.preparePacket(17, 2, 0); + REQUIRE(storeHelper.addPacketToStore() == HasReturnvaluesIF::RETURN_OK); + store_address_t storeId = storeHelper.getCurrentAddr(); + REQUIRE(sendHelper.sendPacket(storeId) == HasReturnvaluesIF::RETURN_OK); + REQUIRE(msgQueue.wasMessageSent()); + REQUIRE(msgQueue.numberOfSentMessagesToDefault() == 1); + TmTcMessage msg; + REQUIRE(msgQueue.getNextSentMessage(msg) == HasReturnvaluesIF::RETURN_OK); + REQUIRE(msg.getStorageId() == storeId); + REQUIRE(pool.hasDataAtId(msg.getStorageId())); + } + + SECTION("Send to Non-Default") { + storeHelper.preparePacket(17, 2, 0); + REQUIRE(storeHelper.addPacketToStore() == HasReturnvaluesIF::RETURN_OK); + store_address_t storeId = storeHelper.getCurrentAddr(); + REQUIRE(sendHelper.sendPacket(destId + 1, storeId) == HasReturnvaluesIF::RETURN_OK); + REQUIRE(msgQueue.wasMessageSent()); + REQUIRE(msgQueue.numberOfSentMessagesToDest(destId + 1) == 1); + } + + SECTION("Sending fails, errors not ignored") { + msgQueue.makeNextSendFail(HasReturnvaluesIF::RETURN_FAILED); + storeHelper.preparePacket(17, 2, 0); + REQUIRE(storeHelper.addPacketToStore() == HasReturnvaluesIF::RETURN_OK); + store_address_t storeId = storeHelper.getCurrentAddr(); + REQUIRE(sendHelper.sendPacket(destId + 1, storeId) == HasReturnvaluesIF::RETURN_FAILED); + REQUIRE(errReporter.lostTmCallCnt == 1); + } + + SECTION("Sending fails, errors ignored") { + msgQueue.makeNextSendFail(HasReturnvaluesIF::RETURN_FAILED); + storeHelper.preparePacket(17, 2, 0); + sendHelper.ignoreFaults(); + REQUIRE(storeHelper.addPacketToStore() == HasReturnvaluesIF::RETURN_OK); + store_address_t storeId = storeHelper.getCurrentAddr(); + REQUIRE(sendHelper.sendPacket(destId + 1, storeId) == HasReturnvaluesIF::RETURN_FAILED); + REQUIRE(errReporter.lostTmCallCnt == 0); } } \ No newline at end of file