unit test for dhb

This commit is contained in:
Jakob Meier 2022-06-05 12:52:55 +02:00
parent 1611a4e1f0
commit bf673c56c6
22 changed files with 224 additions and 138 deletions

View File

@ -65,7 +65,9 @@ void DeviceHandlerBase::setThermalStateRequestPoolIds(lp_id_t thermalStatePoolId
} }
DeviceHandlerBase::~DeviceHandlerBase() { DeviceHandlerBase::~DeviceHandlerBase() {
if (comCookie != nullptr) {
delete comCookie; delete comCookie;
}
if (defaultFDIRUsed) { if (defaultFDIRUsed) {
delete fdirInstance; delete fdirInstance;
} }
@ -253,9 +255,11 @@ void DeviceHandlerBase::decrementDeviceReplyMap() {
replyToReply(replyPair.first, replyPair.second, TIMEOUT); replyToReply(replyPair.first, replyPair.second, TIMEOUT);
missedReply(replyPair.first); missedReply(replyPair.first);
timedOut = false; timedOut = false;
if (not replyPair.second.periodic) {
replyPair.second.active = false; replyPair.second.active = false;
} }
} }
}
} }
void DeviceHandlerBase::readCommandQueue() { void DeviceHandlerBase::readCommandQueue() {

View File

@ -88,6 +88,11 @@ ReturnValue_t EventManager::subscribeToEventRange(MessageQueueId_t listener, Eve
return result; return result;
} }
ReturnValue_t EventManager::unsubscribeFromAllEvents(MessageQueueId_t listener,
object_id_t object) {
return unsubscribeFromEventRange(listener, 0, 0, true, object);
}
ReturnValue_t EventManager::unsubscribeFromEventRange(MessageQueueId_t listener, EventId_t idFrom, ReturnValue_t EventManager::unsubscribeFromEventRange(MessageQueueId_t listener, EventId_t idFrom,
EventId_t idTo, bool idInverted, EventId_t idTo, bool idInverted,
object_id_t reporterFrom, object_id_t reporterFrom,

View File

@ -37,6 +37,8 @@ class EventManager : public EventManagerIF, public ExecutableObjectIF, public Sy
EventId_t idTo = 0, bool idInverted = false, EventId_t idTo = 0, bool idInverted = false,
object_id_t reporterFrom = 0, object_id_t reporterTo = 0, object_id_t reporterFrom = 0, object_id_t reporterTo = 0,
bool reporterInverted = false); bool reporterInverted = false);
ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener,
object_id_t object);
ReturnValue_t unsubscribeFromEventRange(MessageQueueId_t listener, EventId_t idFrom = 0, ReturnValue_t unsubscribeFromEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
EventId_t idTo = 0, bool idInverted = false, EventId_t idTo = 0, bool idInverted = false,
object_id_t reporterFrom = 0, object_id_t reporterTo = 0, object_id_t reporterFrom = 0, object_id_t reporterTo = 0,

View File

@ -20,6 +20,8 @@ class EventManagerIF {
bool forwardAllButSelected = false) = 0; bool forwardAllButSelected = false) = 0;
virtual ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event) = 0; virtual ReturnValue_t subscribeToEvent(MessageQueueId_t listener, EventId_t event) = 0;
virtual ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object) = 0; virtual ReturnValue_t subscribeToAllEventsFrom(MessageQueueId_t listener, object_id_t object) = 0;
virtual ReturnValue_t unsubscribeFromAllEvents(MessageQueueId_t listener,
object_id_t object) = 0;
virtual ReturnValue_t subscribeToEventRange(MessageQueueId_t listener, EventId_t idFrom = 0, virtual ReturnValue_t subscribeToEventRange(MessageQueueId_t listener, EventId_t idFrom = 0,
EventId_t idTo = 0, bool idInverted = false, EventId_t idTo = 0, bool idInverted = false,
object_id_t reporterFrom = 0, object_id_t reporterFrom = 0,

View File

@ -14,6 +14,16 @@ FailureIsolationBase::FailureIsolationBase(object_id_t owner, object_id_t parent
} }
FailureIsolationBase::~FailureIsolationBase() { FailureIsolationBase::~FailureIsolationBase() {
EventManagerIF* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
if (manager == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "FailureIsolationBase::~FailureIsolationBase: Event Manager has not"
" been initialized!"
<< std::endl;
#endif
return;
}
manager->unsubscribeFromAllEvents(eventQueue->getId(), ownerId);
QueueFactory::instance()->deleteMessageQueue(eventQueue); QueueFactory::instance()->deleteMessageQueue(eventQueue);
} }

View File

@ -60,14 +60,14 @@ ReturnValue_t FaultCounter::getParameter(uint8_t domainId, uint8_t uniqueId,
return INVALID_DOMAIN_ID; return INVALID_DOMAIN_ID;
} }
switch (uniqueId) { switch (static_cast<ParameterIds>(uniqueId)) {
case 0: case ParameterIds::FAILURE_THRESHOLD:
parameterWrapper->set(failureThreshold); parameterWrapper->set(failureThreshold);
break; break;
case 1: case ParameterIds::FAULT_COUNT:
parameterWrapper->set(faultCount); parameterWrapper->set(faultCount);
break; break;
case 2: case ParameterIds::TIMEOUT:
parameterWrapper->set(timer.timeout); parameterWrapper->set(timer.timeout);
break; break;
default: default:

View File

@ -6,6 +6,13 @@
class FaultCounter : public HasParametersIF { class FaultCounter : public HasParametersIF {
public: public:
enum class ParameterIds {
FAILURE_THRESHOLD,
FAULT_COUNT,
TIMEOUT
};
FaultCounter(); FaultCounter();
FaultCounter(uint32_t failureThreshold, uint32_t decrementAfterMs, FaultCounter(uint32_t failureThreshold, uint32_t decrementAfterMs,
uint8_t setParameterDomain = 0); uint8_t setParameterDomain = 0);
@ -25,7 +32,8 @@ class FaultCounter : public HasParametersIF {
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId, virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
ParameterWrapper *parameterWrapper, ParameterWrapper *parameterWrapper,
const ParameterWrapper *newValues, uint16_t startAtIndex); const ParameterWrapper *newValues = nullptr, uint16_t startAtIndex =
0);
void setParameterDomain(uint8_t domain); void setParameterDomain(uint8_t domain);

View File

@ -5,7 +5,9 @@
HealthHelper::HealthHelper(HasHealthIF* owner, object_id_t objectId) HealthHelper::HealthHelper(HasHealthIF* owner, object_id_t objectId)
: objectId(objectId), owner(owner) {} : objectId(objectId), owner(owner) {}
HealthHelper::~HealthHelper() {} HealthHelper::~HealthHelper() {
healthTable->removeObject(objectId);
}
ReturnValue_t HealthHelper::handleHealthCommand(CommandMessage* message) { ReturnValue_t HealthHelper::handleHealthCommand(CommandMessage* message) {
switch (message->getCommand()) { switch (message->getCommand()) {

View File

@ -27,6 +27,15 @@ ReturnValue_t HealthTable::registerObject(object_id_t object,
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t HealthTable::removeObject(object_id_t object) {
mapIterator = healthMap.find(object);
if (mapIterator == healthMap.end()) {
return HasReturnvaluesIF::RETURN_FAILED;
}
healthMap.erase(mapIterator);
return HasReturnvaluesIF::RETURN_OK;
}
void HealthTable::setHealth(object_id_t object, HasHealthIF::HealthState newState) { void HealthTable::setHealth(object_id_t object, HasHealthIF::HealthState newState) {
MutexGuard(mutex, timeoutType, mutexTimeoutMs); MutexGuard(mutex, timeoutType, mutexTimeoutMs);
HealthMap::iterator iter = healthMap.find(object); HealthMap::iterator iter = healthMap.find(object);

View File

@ -17,6 +17,7 @@ class HealthTable : public HealthTableIF, public SystemObject {
/** HealthTableIF overrides */ /** HealthTableIF overrides */
virtual ReturnValue_t registerObject( virtual ReturnValue_t registerObject(
object_id_t object, HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) override; object_id_t object, HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) override;
ReturnValue_t removeObject(object_id_t object) override;
virtual size_t getPrintSize() override; virtual size_t getPrintSize() override;
virtual void printAll(uint8_t* pointer, size_t maxSize) override; virtual void printAll(uint8_t* pointer, size_t maxSize) override;

View File

@ -14,6 +14,8 @@ class HealthTableIF : public ManagesHealthIF {
virtual ReturnValue_t registerObject( virtual ReturnValue_t registerObject(
object_id_t object, HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) = 0; object_id_t object, HasHealthIF::HealthState initilialState = HasHealthIF::HEALTHY) = 0;
virtual ReturnValue_t removeObject(object_id_t objectId) = 0;
virtual size_t getPrintSize() = 0; virtual size_t getPrintSize() = 0;
virtual void printAll(uint8_t *pointer, size_t maxSize) = 0; virtual void printAll(uint8_t *pointer, size_t maxSize) = 0;

View File

@ -23,3 +23,4 @@ add_subdirectory(tmtcpacket)
add_subdirectory(cfdp) add_subdirectory(cfdp)
add_subdirectory(hal) add_subdirectory(hal)
add_subdirectory(internalerror) add_subdirectory(internalerror)
add_subdirectory(devicehandler)

View File

@ -65,7 +65,7 @@ void Factory::setStaticFrameworkObjectIds() {
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION; VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT; DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
DeviceHandlerBase::rawDataReceiverId = objects::PUS_SERVICE_2_DEVICE_ACCESS; DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT;
LocalDataPoolManager::defaultHkDestination = objects::HK_RECEIVER_MOCK; LocalDataPoolManager::defaultHkDestination = objects::HK_RECEIVER_MOCK;

View File

@ -1,13 +1,14 @@
#include "ComIFMock.h" #include "ComIFMock.h"
#include "DeviceHandlerMock.h"
ComIFMock::ComIFMock(obejct_id_t objectId) {} ComIFMock::ComIFMock(object_id_t objectId) : SystemObject(objectId){}
ComIFMock::~ComIFMock() {} ComIFMock::~ComIFMock() {}
ReturnValue_t ComIFMock::initializeInterface(CookieIF *cookie) { return RETURN_OK; } ReturnValue_t ComIFMock::initializeInterface(CookieIF *cookie) { return RETURN_OK; }
ReturnValue_t ComIFMock::sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) { ReturnValue_t ComIFMock::sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) {
rememberSentByte = *sendData; data = *sendData;
return RETURN_OK; return RETURN_OK;
} }
@ -18,7 +19,29 @@ ReturnValue_t ComIFMock::requestReceiveMessage(CookieIF *cookie, size_t requestL
} }
ReturnValue_t ComIFMock::readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t *size) { ReturnValue_t ComIFMock::readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t *size) {
*size = sizeof(rememberSentByte); switch(testCase) {
*buffer = &rememberSentByte; case TestCase::MISSED_REPLY: {
*size = 0;
return RETURN_OK;
}
case TestCase::SIMPLE_COMMAND_NOMINAL: {
*size = 1;
data = DeviceHandlerMock::SIMPLE_COMMAND_DATA;
*buffer = &data;
break;
}
case TestCase::PERIODIC_REPLY_NOMINAL: {
*size = 1;
data = DeviceHandlerMock::PERIODIC_REPLY_DATA;
*buffer = &data;
break;
}
default:
break;
}
return RETURN_OK; return RETURN_OK;
} }
void ComIFMock::setTestCase(TestCase testCase_) {
testCase = testCase_;
}

View File

@ -2,6 +2,7 @@
#define TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_COMIFMOCK_H_ #define TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_COMIFMOCK_H_
#include <fsfw/devicehandlers/DeviceCommunicationIF.h> #include <fsfw/devicehandlers/DeviceCommunicationIF.h>
#include <fsfw/objectmanager/SystemObject.h>
/** /**
* @brief The ComIFMock supports the simulation of various device communication error cases * @brief The ComIFMock supports the simulation of various device communication error cases
@ -9,7 +10,9 @@
*/ */
class ComIFMock : public DeviceCommunicationIF, public SystemObject { class ComIFMock : public DeviceCommunicationIF, public SystemObject {
public: public:
ComIFMock(obejct_id_t objectId); enum class TestCase { SIMPLE_COMMAND_NOMINAL, PERIODIC_REPLY_NOMINAL, MISSED_REPLY };
ComIFMock(object_id_t objectId);
virtual ~ComIFMock(); virtual ~ComIFMock();
virtual ReturnValue_t initializeInterface(CookieIF *cookie) override; virtual ReturnValue_t initializeInterface(CookieIF *cookie) override;
@ -19,9 +22,15 @@ class ComIFMock : public DeviceCommunicationIF, public SystemObject {
virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie, size_t requestLen) override; virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie, size_t requestLen) override;
virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer,
size_t *size) override; size_t *size) override;
void setTestCase(TestCase testCase_);
private: private:
uint8_t rememberSentByte = 0; TestCase testCase = TestCase::SIMPLE_COMMAND_NOMINAL;
static const uint8_t SIMPLE_COMMAND_DATA = 1;
static const uint8_t PERIODIC_REPLY_DATA = 2;
uint8_t data = 0;
}; };
#endif /* TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_COMIFMOCK_H_ */ #endif /* TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_COMIFMOCK_H_ */

View File

@ -3,7 +3,7 @@
#include "fsfw/devicehandlers/CookieIF.h" #include "fsfw/devicehandlers/CookieIF.h"
class CookieIFMock { class CookieIFMock : public CookieIF {
public: public:
CookieIFMock(); CookieIFMock();
virtual ~CookieIFMock(); virtual ~CookieIFMock();

View File

@ -1,4 +1,5 @@
#include "DeviceHandlerCommander.h" #include "DeviceHandlerCommander.h"
#include <fsfw/ipc/QueueFactory.h>
DeviceHandlerCommander::DeviceHandlerCommander(object_id_t objectId) DeviceHandlerCommander::DeviceHandlerCommander(object_id_t objectId)
: SystemObject(objectId), commandActionHelper(this) { : SystemObject(objectId), commandActionHelper(this) {
@ -11,6 +12,7 @@ DeviceHandlerCommander::~DeviceHandlerCommander() {}
ReturnValue_t DeviceHandlerCommander::performOperation(uint8_t operationCode) { ReturnValue_t DeviceHandlerCommander::performOperation(uint8_t operationCode) {
readCommandQueue(); readCommandQueue();
return RETURN_OK;
} }
ReturnValue_t DeviceHandlerCommander::initialize() { ReturnValue_t DeviceHandlerCommander::initialize() {
@ -18,10 +20,6 @@ ReturnValue_t DeviceHandlerCommander::initialize() {
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
return result; return result;
} }
result = actionHelper.initialize(commandQueue);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -49,9 +47,6 @@ void DeviceHandlerCommander::readCommandQueue() {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK; for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK;
result = commandQueue->receiveMessage(&message)) { result = commandQueue->receiveMessage(&message)) {
if (result != HasReturnvaluesIF::RETURN_OK) {
continue;
}
result = commandActionHelper.handleReply(&message); result = commandActionHelper.handleReply(&message);
if (result == HasReturnvaluesIF::RETURN_OK) { if (result == HasReturnvaluesIF::RETURN_OK) {
continue; continue;

View File

@ -37,6 +37,8 @@ class DeviceHandlerCommander : public ExecutableObjectIF,
private: private:
static const uint32_t QUEUE_SIZE = 20;
MessageQueueIF* commandQueue = nullptr; MessageQueueIF* commandQueue = nullptr;
CommandActionHelper commandActionHelper; CommandActionHelper commandActionHelper;

View File

@ -1,18 +1,18 @@
#include "DeviceHandlerMock.h" #include "DeviceHandlerMock.h"
DeviceHandlerMock::DeviceHandlerMock(object_id_t objectId, object_id_t deviceCommunication) #include <catch2/catch_test_macros.hpp>
: DeviceHandlerBase(objetcId, deviceCommunication, nullptr) {}
DeviceHandlerMock::~DeviceHandlerMock() { DeviceHandlerMock::DeviceHandlerMock(object_id_t objectId, object_id_t deviceCommunication,
CookieIF *comCookie, FailureIsolationBase *fdirInstance)
: DeviceHandlerBase(objectId, deviceCommunication, comCookie, fdirInstance) {
mode = MODE_ON;
} }
void DeviceHandlerMock::doStartup() { DeviceHandlerMock::~DeviceHandlerMock() {}
setMode(_MODE_TO_ON);
}
void DeviceHandlerMock::doShutdown() { void DeviceHandlerMock::doStartUp() { setMode(_MODE_TO_ON); }
setMode(_MODE_POWER_DOWN);
} void DeviceHandlerMock::doShutDown() { setMode(_MODE_POWER_DOWN); }
ReturnValue_t DeviceHandlerMock::buildNormalDeviceCommand(DeviceCommandId_t *id) { ReturnValue_t DeviceHandlerMock::buildNormalDeviceCommand(DeviceCommandId_t *id) {
return NOTHING_TO_SEND; return NOTHING_TO_SEND;
@ -25,22 +25,32 @@ ReturnValue_t DeviceHandlerMock::buildTransitionDeviceCommand(DeviceCommandId_t
ReturnValue_t DeviceHandlerMock::buildCommandFromCommand(DeviceCommandId_t deviceCommand, ReturnValue_t DeviceHandlerMock::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
const uint8_t *commandData, const uint8_t *commandData,
size_t commandDataLen) { size_t commandDataLen) {
switch(deviceCommand) { switch (deviceCommand) {
case PERIODIC_REPLY_TEST_COMMAND: { case SIMPLE_COMMAND: {
commandBuffer[0] = periodicReplyTestData; commandBuffer[0] = SIMPLE_COMMAND_DATA;
rawPacket = commandBuffer; rawPacket = commandBuffer;
rawPacketLen = sizeof(periodicReplyTestData); rawPacketLen = sizeof(SIMPLE_COMMAND_DATA);
break;
} }
default: default:
WARN("DeviceHandlerMock::buildCommandFromCommand: Invalid device command"); WARN("DeviceHandlerMock::buildCommandFromCommand: Invalid device command");
break;
} }
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t DeviceHandlerMock::scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId, ReturnValue_t DeviceHandlerMock::scanForReply(const uint8_t *start, size_t len,
size_t *foundLen) { DeviceCommandId_t *foundId, size_t *foundLen) {
switch(*start) { switch (*start) {
case periodicReplyTestData: { case SIMPLE_COMMAND_DATA: {
*foundId = SIMPLE_COMMAND;
*foundLen = sizeof(SIMPLE_COMMAND_DATA);
return RETURN_OK;
break;
}
case PERIODIC_REPLY_DATA: {
*foundId = PERIODIC_REPLY;
*foundLen = sizeof(PERIODIC_REPLY_DATA);
return RETURN_OK; return RETURN_OK;
break; break;
} }
@ -51,20 +61,35 @@ ReturnValue_t DeviceHandlerMock::scanForReply(const uint8_t *start, size_t len,
} }
ReturnValue_t DeviceHandlerMock::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) { ReturnValue_t DeviceHandlerMock::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) {
switch(id){ switch (id) {
case PERIODIC_REPLY_TEST_COMMAND: case SIMPLE_COMMAND:
case PERIODIC_REPLY: {
periodicReplyReceived = true;
break; break;
}
default: default:
break; break;
} }
return RETURN_OK;
} }
void DeviceHandlerMock::fillCommandAndReplyMap() { void DeviceHandlerMock::fillCommandAndReplyMap() {
insertInCommandAndReplyMap(PERIODIC_REPLY_TEST_COMMAND, 2, nullptr, 0, true, false, 0, insertInCommandAndReplyMap(SIMPLE_COMMAND, 0, nullptr, 0, false, false, 0,
periodicReplyCountdown); &simpleCommandReplyTimeout);
insertInCommandAndReplyMap(PERIODIC_REPLY, 0, nullptr, 0, true, false, 0,
&periodicReplyCountdown);
} }
uint32_t DeviceHandlerMock::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { uint32_t DeviceHandlerMock::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 500; }
return 500;
void DeviceHandlerMock::changePeriodicReplyCountdown(uint32_t timeout) {
periodicReplyCountdown.setTimeout(0);
} }
void DeviceHandlerMock::resetPeriodicReplyState() {
periodicReplyReceived = false;
}
bool DeviceHandlerMock::getPeriodicReplyReceived() {
return periodicReplyReceived;
}

View File

@ -3,34 +3,44 @@
#include <fsfw/devicehandlers/DeviceHandlerBase.h> #include <fsfw/devicehandlers/DeviceHandlerBase.h>
class DeviceHandlerMock : public DeviceHandlerBase { class DeviceHandlerMock: public DeviceHandlerBase {
public: public:
static const DeviceCommandId_t PERIODIC_REPLY_TEST_COMMAND = 1; static const DeviceCommandId_t SIMPLE_COMMAND = 1;
static const DeviceCommandId_t PERIODIC_REPLY = 2;
DeviceHandlerMock(object_id_t objectId, object_id_t deviceCommunication); static const uint8_t SIMPLE_COMMAND_DATA = 1;
static const uint8_t PERIODIC_REPLY_DATA = 2;
DeviceHandlerMock(object_id_t objectId, object_id_t deviceCommunication,
CookieIF *comCookie, FailureIsolationBase* fdirInstance);
virtual ~DeviceHandlerMock(); virtual ~DeviceHandlerMock();
void changePeriodicReplyCountdown(uint32_t timeout);
void resetPeriodicReplyState();
bool getPeriodicReplyReceived();
protected: protected:
void doStartUp() override; void doStartUp() override;
void doStartShutdown() override; void doShutDown() override;
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override; ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) override; ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) override;
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t *commandData, ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand,
size_t commandDataLen) override; const uint8_t *commandData, size_t commandDataLen) override;
ReturnValue_t scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId, ReturnValue_t scanForReply(const uint8_t *start, size_t len,
size_t *foundLen) override; DeviceCommandId_t *foundId, size_t *foundLen) override;
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override; ReturnValue_t interpretDeviceReply(DeviceCommandId_t id,
const uint8_t *packet) override;
void fillCommandAndReplyMap() override; void fillCommandAndReplyMap() override;
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override; uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
private: private:
uint8_t periodicReplyTestData = 1; Countdown simpleCommandReplyTimeout = Countdown(50);
Countdown periodicReplyCountdown = Countdown(10); Countdown periodicReplyCountdown = Countdown(10);
uint8_t commandBuffer[1]; uint8_t commandBuffer[1];
bool periodicReplyReceived = false;
}; };
#endif /* TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_DEVICEHANDLERMOCK_H_ */ #endif /* TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_DEVICEHANDLERMOCK_H_ */

View File

@ -1,36 +1,61 @@
#include "TestDeviceHandlerBase.h"
#include <catch2/catch_test_macros.hpp> #include <catch2/catch_test_macros.hpp>
#include "ComIFMock.h"
#include "fsfw_tests/unit/devicehandler/DeviceHandlerMock.h" #include "ComIFMock.h"
#include "fsfw_tests/unit/devicehandler/DeviceHandlerCommander.h" #include "DeviceFdirMock.h"
#include "fsfw_tests/unit/devicehandler/CookieIFMock.h" #include "fsfw_tests/unit/devicehandler/CookieIFMock.h"
#include "fsfw_tests/unit/devicehandler/DeviceHandlerCommander.h"
#include "fsfw_tests/unit/devicehandler/DeviceHandlerMock.h"
#include "fsfw_tests/unit/testcfg/objects/systemObjectList.h" #include "fsfw_tests/unit/testcfg/objects/systemObjectList.h"
TEST_CASE("Device Handler Base", "[DeviceHandlerBase]") { TEST_CASE("Device Handler Base", "[DeviceHandlerBase]") {
SECTION("Periodic reply with countdown based timeout success") { // Will be deleted with DHB destructor
CookieIFMock cookieIFMock; CookieIFMock* cookieIFMock = new CookieIFMock;
ComIFperiodicMock comIFperiodic(objects::COM_IF_MOCK); ComIFMock comIF(objects::COM_IF_MOCK);
DeviceFdirMock deviceFdirMock(objects::DEVICE_HANDLER_MOCK, objects::NO_OBJECT);
DeviceHandlerMock deviceHandlerMock(objects::DEVICE_HANDLER_MOCK, objects::COM_IF_MOCK, DeviceHandlerMock deviceHandlerMock(objects::DEVICE_HANDLER_MOCK, objects::COM_IF_MOCK,
&cookieIFMock); cookieIFMock, &deviceFdirMock);
ReturnValue_t result = deviceHandlerMock.initialize(); ReturnValue_t result = deviceHandlerMock.initialize();
REQUIRE(result == RETURN_OK); REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
DeviceHandlerCommander deviceHandlerCommander(objects::DEVICE_HANDLER_COMMANDER); DeviceHandlerCommander deviceHandlerCommander(objects::DEVICE_HANDLER_COMMANDER);
result = deviceHandlerCommander.initialize(); result = deviceHandlerCommander.initialize();
REQUIRE(result == RETURN_OK); REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
SECTION("Commanding") {
comIF.setTestCase(ComIFMock::TestCase::SIMPLE_COMMAND_NOMINAL);
result = deviceHandlerCommander.sendCommand(objects::DEVICE_HANDLER_MOCK, result = deviceHandlerCommander.sendCommand(objects::DEVICE_HANDLER_MOCK,
DeviceHandlerMock::PERIODIC_REPLY_TEST_COMMAND); DeviceHandlerMock::SIMPLE_COMMAND);
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
deviceHandlerMock.performOperation(DeviceHandlerIF::PERFORM_OPERATION); deviceHandlerMock.performOperation(DeviceHandlerIF::PERFORM_OPERATION);
deviceHandlerMock.performOperation(DeviceHandlerIF::SEND_WRITE); deviceHandlerMock.performOperation(DeviceHandlerIF::SEND_WRITE);
deviceHandlerMock.performOperation(DeviceHandlerIF::GET_WRITE); deviceHandlerMock.performOperation(DeviceHandlerIF::GET_WRITE);
deviceHandlerMock.performOperation(DeviceHandlerIF::SEND_READ); deviceHandlerMock.performOperation(DeviceHandlerIF::SEND_READ);
deviceHandlerMock.performOperation(DeviceHandlerIF::GET_READ); deviceHandlerMock.performOperation(DeviceHandlerIF::GET_READ);
deviceHandlerCommander.performOperation();
result = deviceHandlerCommander.getReplyReturnCode(); result = deviceHandlerCommander.getReplyReturnCode();
REQUIRE(result == RETURN_OK); REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
}
SECTION("Periodic reply") {
comIF.setTestCase(ComIFMock::TestCase::PERIODIC_REPLY_NOMINAL);
deviceHandlerMock.performOperation(DeviceHandlerIF::PERFORM_OPERATION);
deviceHandlerMock.performOperation(DeviceHandlerIF::SEND_WRITE);
deviceHandlerMock.performOperation(DeviceHandlerIF::GET_WRITE);
deviceHandlerMock.performOperation(DeviceHandlerIF::SEND_READ);
deviceHandlerMock.performOperation(DeviceHandlerIF::GET_READ);
REQUIRE(deviceHandlerMock.getPeriodicReplyReceived() == true);
}
SECTION("Missed periodic reply") {
comIF.setTestCase(ComIFMock::TestCase::MISSED_REPLY);
// Set the timeout to 0 to immediately timeout the reply
deviceHandlerMock.changePeriodicReplyCountdown(0);
deviceHandlerMock.performOperation(DeviceHandlerIF::PERFORM_OPERATION);
deviceHandlerMock.performOperation(DeviceHandlerIF::SEND_WRITE);
deviceHandlerMock.performOperation(DeviceHandlerIF::GET_WRITE);
deviceHandlerMock.performOperation(DeviceHandlerIF::SEND_READ);
deviceHandlerMock.performOperation(DeviceHandlerIF::GET_READ);
uint32_t missedReplies = deviceFdirMock.getMissedReplyCount();
REQUIRE(missedReplies == 1);
} }
// SECTION("Periodic reply with countdown based timeout failed") {
//
// }
} }

View File

@ -1,49 +0,0 @@
#ifndef UNITTEST_HOSTED_TESTACTIONHELPER_H_
#define UNITTEST_HOSTED_TESTACTIONHELPER_H_
#include <fsfw/action/HasActionsIF.h>
#include <fsfw/ipc/MessageQueueIF.h>
#include <cstring>
#include "fsfw_tests/unit/CatchDefinitions.h"
class ActionHelperOwnerMockBase : public HasActionsIF {
public:
bool getCommandQueueCalled = false;
bool executeActionCalled = false;
static const size_t MAX_SIZE = 3;
uint8_t buffer[MAX_SIZE] = {0, 0, 0};
size_t size = 0;
MessageQueueId_t getCommandQueue() const override { return tconst::testQueueId; }
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
const uint8_t* data, size_t size) override {
executeActionCalled = true;
if (size > MAX_SIZE) {
return 0xAFFE;
}
this->size = size;
memcpy(buffer, data, size);
return HasReturnvaluesIF::RETURN_OK;
}
void clearBuffer() {
this->size = 0;
for (size_t i = 0; i < MAX_SIZE; i++) {
buffer[i] = 0;
}
}
void getBuffer(const uint8_t** ptr, size_t* size) {
if (size != nullptr) {
*size = this->size;
}
if (ptr != nullptr) {
*ptr = buffer;
}
}
};
#endif /* UNITTEST_TESTFW_NEWTESTS_TESTACTIONHELPER_H_ */