Release v5.0.0 #657

Merged
gaisser merged 578 commits from development into master 2022-07-25 15:05:57 +02:00
4 changed files with 101 additions and 107 deletions
Showing only changes of commit 4862edfdb5 - Show all commits

View File

@ -57,7 +57,7 @@ ReturnValue_t InternalErrorReporter::performOperation(uint8_t opCode) {
internalErrorDataset.storeHits.value += newStoreHits; internalErrorDataset.storeHits.value += newStoreHits;
internalErrorDataset.tmHits.value += newTmHits; internalErrorDataset.tmHits.value += newTmHits;
internalErrorDataset.setValidity(true, true); internalErrorDataset.setValidity(true, true);
if((newQueueHits != 0) or (newStoreHits !=0) or (newTmHits != 0)){ if ((newQueueHits != 0) or (newStoreHits != 0) or (newTmHits != 0)) {
internalErrorDataset.setChanged(true); internalErrorDataset.setChanged(true);
} }
} }

View File

@ -125,13 +125,13 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
memcpy(targetQueue->messageQueue.back().data(), message->getBuffer(), memcpy(targetQueue->messageQueue.back().data(), message->getBuffer(),
message->getMaximumMessageSize()); message->getMaximumMessageSize());
} else { } else {
if (not ignoreFault) { if (not ignoreFault) {
InternalErrorReporterIF* internalErrorReporter = InternalErrorReporterIF* internalErrorReporter =
ObjectManager::instance()->get<InternalErrorReporterIF>(objects::INTERNAL_ERROR_REPORTER); ObjectManager::instance()->get<InternalErrorReporterIF>(objects::INTERNAL_ERROR_REPORTER);
if (internalErrorReporter != nullptr) { if (internalErrorReporter != nullptr) {
internalErrorReporter->queueMessageNotSent(); internalErrorReporter->queueMessageNotSent();
} }
} }
return MessageQueueIF::FULL; return MessageQueueIF::FULL;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;

View File

@ -1,9 +1,9 @@
#include <fsfw/housekeeping/HousekeepingSnapshot.h>
#include <fsfw/internalerror/InternalErrorReporter.h>
#include <fsfw/ipc/MessageQueueIF.h> #include <fsfw/ipc/MessageQueueIF.h>
#include <fsfw/ipc/QueueFactory.h> #include <fsfw/ipc/QueueFactory.h>
#include <fsfw/internalerror/InternalErrorReporter.h>
#include <fsfw/objectmanager/ObjectManager.h> #include <fsfw/objectmanager/ObjectManager.h>
#include <fsfw/timemanager/CCSDSTime.h> #include <fsfw/timemanager/CCSDSTime.h>
#include <fsfw/housekeeping/HousekeepingSnapshot.h>
#include <array> #include <array>
#include <catch2/catch_test_macros.hpp> #include <catch2/catch_test_macros.hpp>
@ -16,87 +16,89 @@
#include "fsfw_tests/unit/mocks/PeriodicTaskIFMock.h" #include "fsfw_tests/unit/mocks/PeriodicTaskIFMock.h"
TEST_CASE("Internal Error Reporter", "[TestInternalError]") { TEST_CASE("Internal Error Reporter", "[TestInternalError]") {
PeriodicTaskMock task(10); PeriodicTaskMock task(10);
ObjectManagerIF* manager = ObjectManager::instance(); ObjectManagerIF* manager = ObjectManager::instance();
if(manager == nullptr){ if (manager == nullptr) {
FAIL(); FAIL();
}
InternalErrorReporter* internalErrorReporter = dynamic_cast<InternalErrorReporter*>(
ObjectManager::instance()->get<InternalErrorReporterIF>(objects::INTERNAL_ERROR_REPORTER));
if (internalErrorReporter == nullptr) {
FAIL();
}
task.addComponent(objects::INTERNAL_ERROR_REPORTER);
MessageQueueIF* testQueue = QueueFactory::instance()->createMessageQueue(1);
MessageQueueIF* hkQueue = QueueFactory::instance()->createMessageQueue(1);
internalErrorReporter->getSubscriptionInterface()->subscribeForSetUpdateMessage(
InternalErrorDataset::ERROR_SET_ID, objects::NO_OBJECT, hkQueue->getId(), true);
StorageManagerIF* ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
SECTION("MessageQueueFull") {
CommandMessage message;
ActionMessage::setCompletionReply(&message, 10, true);
auto result = hkQueue->sendMessage(testQueue->getId(), &message);
REQUIRE(result == retval::CATCH_OK);
uint32_t queueHits = 0;
uint32_t lostTm = 0;
uint32_t storeHits = 0;
/* We don't know if another test caused a queue Hit so we will enforce one,
then remeber the queueHit count and force another hit */
internalErrorReporter->queueMessageNotSent();
internalErrorReporter->performOperation(0);
{
CommandMessage hkMessage;
result = hkQueue->receiveMessage(&hkMessage);
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
REQUIRE(hkMessage.getCommand() == HousekeepingMessage::UPDATE_SNAPSHOT_SET);
store_address_t storeAddress;
gp_id_t gpid =
HousekeepingMessage::getUpdateSnapshotVariableCommand(&hkMessage, &storeAddress);
REQUIRE(gpid.objectId == objects::INTERNAL_ERROR_REPORTER);
// We need the object ID of the reporter here (NO_OBJECT)
InternalErrorDataset dataset(objects::INTERNAL_ERROR_REPORTER);
CCSDSTime::CDS_short time;
ConstAccessorPair data = ipcStore->getData(storeAddress);
REQUIRE(data.first == HasReturnvaluesIF::RETURN_OK);
HousekeepingSnapshot hkSnapshot(&time, &dataset);
const uint8_t* buffer = data.second.data();
size_t size = data.second.size();
result = hkSnapshot.deSerialize(&buffer, &size, SerializeIF::Endianness::MACHINE);
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
// Remember the amount of queueHits before to see the increase
queueHits = dataset.queueHits.value;
lostTm = dataset.tmHits.value;
storeHits = dataset.storeHits.value;
} }
InternalErrorReporter* internalErrorReporter = result = hkQueue->sendMessage(testQueue->getId(), &message);
dynamic_cast<InternalErrorReporter*>(ObjectManager::instance()->get<InternalErrorReporterIF>(objects::INTERNAL_ERROR_REPORTER)); REQUIRE(result == MessageQueueIF::FULL);
if(internalErrorReporter == nullptr){ internalErrorReporter->lostTm();
FAIL(); internalErrorReporter->storeFull();
{
internalErrorReporter->performOperation(0);
CommandMessage hkMessage;
result = hkQueue->receiveMessage(&hkMessage);
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
REQUIRE(hkMessage.getCommand() == HousekeepingMessage::UPDATE_SNAPSHOT_SET);
store_address_t storeAddress;
gp_id_t gpid =
HousekeepingMessage::getUpdateSnapshotVariableCommand(&hkMessage, &storeAddress);
REQUIRE(gpid.objectId == objects::INTERNAL_ERROR_REPORTER);
ConstAccessorPair data = ipcStore->getData(storeAddress);
REQUIRE(data.first == HasReturnvaluesIF::RETURN_OK);
CCSDSTime::CDS_short time;
// We need the object ID of the reporter here (NO_OBJECT)
InternalErrorDataset dataset(objects::INTERNAL_ERROR_REPORTER);
HousekeepingSnapshot hkSnapshot(&time, &dataset);
const uint8_t* buffer = data.second.data();
size_t size = data.second.size();
result = hkSnapshot.deSerialize(&buffer, &size, SerializeIF::Endianness::MACHINE);
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
// Test that we had one more queueHit
REQUIRE(dataset.queueHits.value == (queueHits + 1));
REQUIRE(dataset.tmHits.value == (lostTm + 1));
REQUIRE(dataset.storeHits.value == (storeHits + 1));
} }
task.addComponent(objects::INTERNAL_ERROR_REPORTER); }
MessageQueueIF* testQueue = QueueFactory::instance()->createMessageQueue(1); QueueFactory::instance()->deleteMessageQueue(testQueue);
MessageQueueIF* hkQueue = QueueFactory::instance()->createMessageQueue(1); QueueFactory::instance()->deleteMessageQueue(hkQueue);
internalErrorReporter->getSubscriptionInterface()->
subscribeForSetUpdateMessage(InternalErrorDataset::ERROR_SET_ID, objects::NO_OBJECT, hkQueue->getId(), true);
StorageManagerIF* ipcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
SECTION("MessageQueueFull"){
CommandMessage message;
ActionMessage::setCompletionReply(&message, 10, true);
auto result = hkQueue->sendMessage(testQueue->getId(), &message);
REQUIRE(result == retval::CATCH_OK);
uint32_t queueHits = 0;
uint32_t lostTm = 0;
uint32_t storeHits = 0;
/* We don't know if another test caused a queue Hit so we will enforce one,
then remeber the queueHit count and force another hit */
internalErrorReporter->queueMessageNotSent();
internalErrorReporter->performOperation(0);
{
CommandMessage hkMessage;
result = hkQueue->receiveMessage(&hkMessage);
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
REQUIRE(hkMessage.getCommand() == HousekeepingMessage::UPDATE_SNAPSHOT_SET);
store_address_t storeAddress;
gp_id_t gpid = HousekeepingMessage::getUpdateSnapshotVariableCommand(&hkMessage, &storeAddress);
REQUIRE(gpid.objectId == objects::INTERNAL_ERROR_REPORTER);
// We need the object ID of the reporter here (NO_OBJECT)
InternalErrorDataset dataset(objects::INTERNAL_ERROR_REPORTER);
CCSDSTime::CDS_short time;
ConstAccessorPair data = ipcStore->getData(storeAddress);
REQUIRE(data.first == HasReturnvaluesIF::RETURN_OK);
HousekeepingSnapshot hkSnapshot(&time, &dataset);
const uint8_t* buffer = data.second.data();
size_t size = data.second.size();
result = hkSnapshot.deSerialize(&buffer, &size, SerializeIF::Endianness::MACHINE);
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
// Remember the amount of queueHits before to see the increase
queueHits = dataset.queueHits.value;
lostTm = dataset.tmHits.value;
storeHits = dataset.storeHits.value;
}
result = hkQueue->sendMessage(testQueue->getId(), &message);
REQUIRE(result == MessageQueueIF::FULL);
internalErrorReporter->lostTm();
internalErrorReporter->storeFull();
{
internalErrorReporter->performOperation(0);
CommandMessage hkMessage;
result = hkQueue->receiveMessage(&hkMessage);
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
REQUIRE(hkMessage.getCommand() == HousekeepingMessage::UPDATE_SNAPSHOT_SET);
store_address_t storeAddress;
gp_id_t gpid = HousekeepingMessage::getUpdateSnapshotVariableCommand(&hkMessage, &storeAddress);
REQUIRE(gpid.objectId == objects::INTERNAL_ERROR_REPORTER);
ConstAccessorPair data = ipcStore->getData(storeAddress);
REQUIRE(data.first == HasReturnvaluesIF::RETURN_OK);
CCSDSTime::CDS_short time;
// We need the object ID of the reporter here (NO_OBJECT)
InternalErrorDataset dataset(objects::INTERNAL_ERROR_REPORTER);
HousekeepingSnapshot hkSnapshot(&time, &dataset);
const uint8_t* buffer = data.second.data();
size_t size = data.second.size();
result = hkSnapshot.deSerialize(&buffer, &size, SerializeIF::Endianness::MACHINE);
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
// Test that we had one more queueHit
REQUIRE(dataset.queueHits.value == (queueHits + 1));
REQUIRE(dataset.tmHits.value == (lostTm + 1));
REQUIRE(dataset.storeHits.value == (storeHits + 1));
}
}
QueueFactory::instance()->deleteMessageQueue(testQueue);
QueueFactory::instance()->deleteMessageQueue(hkQueue);
} }

View File

@ -1,14 +1,12 @@
#ifndef FSFW_UNITTEST_TESTS_MOCKS_PERIODICTASKMOCK_H_ #ifndef FSFW_UNITTEST_TESTS_MOCKS_PERIODICTASKMOCK_H_
#define FSFW_UNITTEST_TESTS_MOCKS_PERIODICTASKMOCK_H_ #define FSFW_UNITTEST_TESTS_MOCKS_PERIODICTASKMOCK_H_
#include <fsfw/tasks/PeriodicTaskIF.h>
#include <fsfw/tasks/ExecutableObjectIF.h> #include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/tasks/PeriodicTaskIF.h>
class PeriodicTaskMock: public PeriodicTaskIF{ class PeriodicTaskMock : public PeriodicTaskIF {
public: public:
PeriodicTaskMock(uint32_t period = 5):period(period){ PeriodicTaskMock(uint32_t period = 5) : period(period) {}
}
/** /**
* @brief A virtual destructor as it is mandatory for interfaces. * @brief A virtual destructor as it is mandatory for interfaces.
*/ */
@ -17,29 +15,23 @@ public:
* @brief With the startTask method, a created task can be started * @brief With the startTask method, a created task can be started
* for the first time. * for the first time.
*/ */
virtual ReturnValue_t startTask() override{ virtual ReturnValue_t startTask() override { return HasReturnvaluesIF::RETURN_OK; };
return HasReturnvaluesIF::RETURN_OK;
};
virtual ReturnValue_t addComponent(object_id_t object) override{ virtual ReturnValue_t addComponent(object_id_t object) override {
ExecutableObjectIF* executableObject = ObjectManager::instance()->get<ExecutableObjectIF>(objects::INTERNAL_ERROR_REPORTER); ExecutableObjectIF* executableObject =
if(executableObject == nullptr){ ObjectManager::instance()->get<ExecutableObjectIF>(objects::INTERNAL_ERROR_REPORTER);
return HasReturnvaluesIF::RETURN_FAILED; if (executableObject == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
} }
executableObject->setTaskIF(this); executableObject->setTaskIF(this);
executableObject->initializeAfterTaskCreation(); executableObject->initializeAfterTaskCreation();
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
}; };
virtual ReturnValue_t sleepFor(uint32_t ms) override{ virtual ReturnValue_t sleepFor(uint32_t ms) override { return HasReturnvaluesIF::RETURN_OK; };
return HasReturnvaluesIF::RETURN_OK;
};
virtual uint32_t getPeriodMs() const override{ virtual uint32_t getPeriodMs() const override { return period; };
return period;
};
uint32_t period; uint32_t period;
}; };
#endif // FSFW_UNITTEST_TESTS_MOCKS_PERIODICTASKMOCK_H_
#endif // FSFW_UNITTEST_TESTS_MOCKS_PERIODICTASKMOCK_H_