1
0
forked from fsfw/fsfw

separate unittest folder

This commit is contained in:
2022-07-18 11:42:51 +02:00
parent 3b23fb77b4
commit 8465670374
107 changed files with 1 additions and 1 deletions

View File

@ -0,0 +1,8 @@
target_sources(${FSFW_TEST_TGT} PRIVATE
CookieIFMock.cpp
ComIFMock.cpp
DeviceHandlerCommander.cpp
DeviceHandlerMock.cpp
DeviceFdirMock.cpp
TestDeviceHandlerBase.cpp
)

View File

@ -0,0 +1,46 @@
#include "ComIFMock.h"
#include "DeviceHandlerMock.h"
ComIFMock::ComIFMock(object_id_t objectId) : SystemObject(objectId) {}
ComIFMock::~ComIFMock() {}
ReturnValue_t ComIFMock::initializeInterface(CookieIF *cookie) { return RETURN_OK; }
ReturnValue_t ComIFMock::sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) {
data = *sendData;
return RETURN_OK;
}
ReturnValue_t ComIFMock::getSendSuccess(CookieIF *cookie) { return RETURN_OK; }
ReturnValue_t ComIFMock::requestReceiveMessage(CookieIF *cookie, size_t requestLen) {
return RETURN_OK;
}
ReturnValue_t ComIFMock::readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t *size) {
switch (testCase) {
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;
}
void ComIFMock::setTestCase(TestCase testCase_) { testCase = testCase_; }

View File

@ -0,0 +1,37 @@
#ifndef TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_COMIFMOCK_H_
#define TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_COMIFMOCK_H_
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
#include <fsfw/objectmanager/SystemObject.h>
/**
* @brief The ComIFMock supports the simulation of various device communication error cases
* like incomplete or wrong replies and can be used to test the
* DeviceHandlerBase.
*/
class ComIFMock : public DeviceCommunicationIF, public SystemObject {
public:
enum class TestCase { SIMPLE_COMMAND_NOMINAL, PERIODIC_REPLY_NOMINAL, MISSED_REPLY };
ComIFMock(object_id_t objectId);
virtual ~ComIFMock();
virtual ReturnValue_t initializeInterface(CookieIF *cookie) override;
virtual ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t *sendData,
size_t sendLen) override;
virtual ReturnValue_t getSendSuccess(CookieIF *cookie) override;
virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie, size_t requestLen) override;
virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer,
size_t *size) override;
void setTestCase(TestCase testCase_);
private:
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_ */

View File

@ -0,0 +1,5 @@
#include "CookieIFMock.h"
CookieIFMock::CookieIFMock() {}
CookieIFMock::~CookieIFMock() {}

View File

@ -0,0 +1,12 @@
#ifndef TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_COOKIEIFMOCK_H_
#define TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_COOKIEIFMOCK_H_
#include "fsfw/devicehandlers/CookieIF.h"
class CookieIFMock : public CookieIF {
public:
CookieIFMock();
virtual ~CookieIFMock();
};
#endif /* TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_COOKIEIFMOCK_H_ */

View File

@ -0,0 +1,18 @@
#include "DeviceFdirMock.h"
#include <tests/src/fsfw_tests/unit/devicehandler/DeviceFdirMock.h>
DeviceFdirMock::DeviceFdirMock(object_id_t owner, object_id_t parent)
: DeviceHandlerFailureIsolation(owner, parent) {}
DeviceFdirMock::~DeviceFdirMock() {}
uint32_t DeviceFdirMock::getMissedReplyCount() {
ParameterWrapper parameterWrapper;
this->getParameter(MISSED_REPLY_DOMAIN_ID,
static_cast<uint8_t>(FaultCounter::ParameterIds::FAULT_COUNT),
&parameterWrapper, nullptr, 0);
uint32_t missedReplyCount = 0;
parameterWrapper.getElement(&missedReplyCount);
return missedReplyCount;
}

View File

@ -0,0 +1,18 @@
#ifndef TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_DEVICEFDIRMOCK_H_
#define TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_DEVICEFDIRMOCK_H_
#include "fsfw/devicehandlers/DeviceHandlerFailureIsolation.h"
class DeviceFdirMock : public DeviceHandlerFailureIsolation {
public:
DeviceFdirMock(object_id_t owner, object_id_t parent);
virtual ~DeviceFdirMock();
uint32_t getMissedReplyCount();
private:
static const uint8_t STRANGE_REPLY_DOMAIN_ID = 0xF0;
static const uint8_t MISSED_REPLY_DOMAIN_ID = 0xF1;
};
#endif /* TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_DEVICEFDIRMOCK_H_ */

View File

@ -0,0 +1,64 @@
#include "DeviceHandlerCommander.h"
#include <fsfw/ipc/QueueFactory.h>
DeviceHandlerCommander::DeviceHandlerCommander(object_id_t objectId)
: SystemObject(objectId), commandActionHelper(this) {
auto mqArgs = MqArgs(this->getObjectId());
commandQueue = QueueFactory::instance()->createMessageQueue(
QUEUE_SIZE, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
}
DeviceHandlerCommander::~DeviceHandlerCommander() {}
ReturnValue_t DeviceHandlerCommander::performOperation(uint8_t operationCode) {
readCommandQueue();
return RETURN_OK;
}
ReturnValue_t DeviceHandlerCommander::initialize() {
ReturnValue_t result = commandActionHelper.initialize();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
return HasReturnvaluesIF::RETURN_OK;
}
MessageQueueIF* DeviceHandlerCommander::getCommandQueuePtr() { return commandQueue; }
void DeviceHandlerCommander::stepSuccessfulReceived(ActionId_t actionId, uint8_t step) {}
void DeviceHandlerCommander::stepFailedReceived(ActionId_t actionId, uint8_t step,
ReturnValue_t returnCode) {}
void DeviceHandlerCommander::dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) {
}
void DeviceHandlerCommander::completionSuccessfulReceived(ActionId_t actionId) {
lastReplyReturnCode = RETURN_OK;
}
void DeviceHandlerCommander::completionFailedReceived(ActionId_t actionId,
ReturnValue_t returnCode) {
lastReplyReturnCode = returnCode;
}
void DeviceHandlerCommander::readCommandQueue() {
CommandMessage message;
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
for (result = commandQueue->receiveMessage(&message); result == HasReturnvaluesIF::RETURN_OK;
result = commandQueue->receiveMessage(&message)) {
result = commandActionHelper.handleReply(&message);
if (result == HasReturnvaluesIF::RETURN_OK) {
continue;
}
}
}
ReturnValue_t DeviceHandlerCommander::sendCommand(object_id_t target, ActionId_t actionId) {
return commandActionHelper.commandAction(target, actionId, nullptr, 0);
}
ReturnValue_t DeviceHandlerCommander::getReplyReturnCode() { return lastReplyReturnCode; }
void DeviceHandlerCommander::resetReplyReturnCode() { lastReplyReturnCode = RETURN_FAILED; }

View File

@ -0,0 +1,50 @@
#ifndef TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_DEVICEHANDLERCOMMANDER_H_
#define TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_DEVICEHANDLERCOMMANDER_H_
#include "fsfw/action/CommandActionHelper.h"
#include "fsfw/action/CommandsActionsIF.h"
#include "fsfw/objectmanager/SystemObject.h"
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
#include "fsfw/tasks/ExecutableObjectIF.h"
class DeviceHandlerCommander : public ExecutableObjectIF,
public SystemObject,
public CommandsActionsIF,
public HasReturnvaluesIF {
public:
DeviceHandlerCommander(object_id_t objectId);
virtual ~DeviceHandlerCommander();
ReturnValue_t performOperation(uint8_t operationCode = 0);
ReturnValue_t initialize() override;
MessageQueueIF* getCommandQueuePtr() override;
void stepSuccessfulReceived(ActionId_t actionId, uint8_t step) override;
void stepFailedReceived(ActionId_t actionId, uint8_t step, ReturnValue_t returnCode) override;
void dataReceived(ActionId_t actionId, const uint8_t* data, uint32_t size) override;
void completionSuccessfulReceived(ActionId_t actionId) override;
void completionFailedReceived(ActionId_t actionId, ReturnValue_t returnCode) override;
/**
* @brief Calling this function will send the command to the device handler object.
*
* @param target Object ID of the device handler
* @param actionId Action ID of the command to send
*/
ReturnValue_t sendCommand(object_id_t target, ActionId_t actionId);
ReturnValue_t getReplyReturnCode();
void resetReplyReturnCode();
private:
static const uint32_t QUEUE_SIZE = 20;
MessageQueueIF* commandQueue = nullptr;
CommandActionHelper commandActionHelper;
ReturnValue_t lastReplyReturnCode = RETURN_FAILED;
void readCommandQueue();
};
#endif /* TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_DEVICEHANDLERCOMMANDER_H_ */

View File

@ -0,0 +1,103 @@
#include "DeviceHandlerMock.h"
#include <catch2/catch_test_macros.hpp>
DeviceHandlerMock::DeviceHandlerMock(object_id_t objectId, object_id_t deviceCommunication,
CookieIF *comCookie, FailureIsolationBase *fdirInstance)
: DeviceHandlerBase(objectId, deviceCommunication, comCookie, fdirInstance) {
mode = MODE_ON;
}
DeviceHandlerMock::~DeviceHandlerMock() {}
void DeviceHandlerMock::doStartUp() { setMode(_MODE_TO_ON); }
void DeviceHandlerMock::doShutDown() { setMode(_MODE_POWER_DOWN); }
ReturnValue_t DeviceHandlerMock::buildNormalDeviceCommand(DeviceCommandId_t *id) {
return NOTHING_TO_SEND;
}
ReturnValue_t DeviceHandlerMock::buildTransitionDeviceCommand(DeviceCommandId_t *id) {
return NOTHING_TO_SEND;
}
ReturnValue_t DeviceHandlerMock::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
const uint8_t *commandData,
size_t commandDataLen) {
switch (deviceCommand) {
case SIMPLE_COMMAND: {
commandBuffer[0] = SIMPLE_COMMAND_DATA;
rawPacket = commandBuffer;
rawPacketLen = sizeof(SIMPLE_COMMAND_DATA);
break;
}
default:
WARN("DeviceHandlerMock::buildCommandFromCommand: Invalid device command");
break;
}
return RETURN_OK;
}
ReturnValue_t DeviceHandlerMock::scanForReply(const uint8_t *start, size_t len,
DeviceCommandId_t *foundId, size_t *foundLen) {
switch (*start) {
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;
break;
}
default:
break;
}
return RETURN_FAILED;
}
ReturnValue_t DeviceHandlerMock::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) {
switch (id) {
case SIMPLE_COMMAND:
case PERIODIC_REPLY: {
periodicReplyReceived = true;
break;
}
default:
break;
}
return RETURN_OK;
}
void DeviceHandlerMock::fillCommandAndReplyMap() {
insertInCommandAndReplyMap(SIMPLE_COMMAND, 0, nullptr, 0, false, false, 0,
&simpleCommandReplyTimeout);
insertInCommandAndReplyMap(PERIODIC_REPLY, 0, nullptr, 0, true, false, 0,
&periodicReplyCountdown);
}
uint32_t DeviceHandlerMock::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 500; }
void DeviceHandlerMock::changePeriodicReplyCountdown(uint32_t timeout) {
periodicReplyCountdown.setTimeout(timeout);
}
void DeviceHandlerMock::changeSimpleCommandReplyCountdown(uint32_t timeout) {
simpleCommandReplyTimeout.setTimeout(timeout);
}
void DeviceHandlerMock::resetPeriodicReplyState() { periodicReplyReceived = false; }
bool DeviceHandlerMock::getPeriodicReplyReceived() { return periodicReplyReceived; }
ReturnValue_t DeviceHandlerMock::enablePeriodicReply(DeviceCommandId_t replyId) {
return updatePeriodicReply(true, replyId);
}
ReturnValue_t DeviceHandlerMock::disablePeriodicReply(DeviceCommandId_t replyId) {
return updatePeriodicReply(false, replyId);
}

View File

@ -0,0 +1,46 @@
#ifndef TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_DEVICEHANDLERMOCK_H_
#define TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_DEVICEHANDLERMOCK_H_
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
class DeviceHandlerMock : public DeviceHandlerBase {
public:
static const DeviceCommandId_t SIMPLE_COMMAND = 1;
static const DeviceCommandId_t PERIODIC_REPLY = 2;
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();
void changePeriodicReplyCountdown(uint32_t timeout);
void changeSimpleCommandReplyCountdown(uint32_t timeout);
void resetPeriodicReplyState();
bool getPeriodicReplyReceived();
ReturnValue_t enablePeriodicReply(DeviceCommandId_t replyId);
ReturnValue_t disablePeriodicReply(DeviceCommandId_t replyId);
protected:
void doStartUp() override;
void doShutDown() override;
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) override;
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t *commandData,
size_t commandDataLen) override;
ReturnValue_t scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId,
size_t *foundLen) override;
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override;
void fillCommandAndReplyMap() override;
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
private:
Countdown simpleCommandReplyTimeout = Countdown(1000);
Countdown periodicReplyCountdown = Countdown(1000);
uint8_t commandBuffer[1];
bool periodicReplyReceived = false;
};
#endif /* TESTS_SRC_FSFW_TESTS_UNIT_DEVICEHANDLER_DEVICEHANDLERMOCK_H_ */

View File

@ -0,0 +1,95 @@
#include <catch2/catch_test_macros.hpp>
#include "ComIFMock.h"
#include "DeviceFdirMock.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"
TEST_CASE("Device Handler Base", "[DeviceHandlerBase]") {
// Will be deleted with DHB destructor
CookieIFMock* cookieIFMock = new CookieIFMock;
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,
cookieIFMock, &deviceFdirMock);
ReturnValue_t result = deviceHandlerMock.initialize();
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
DeviceHandlerCommander deviceHandlerCommander(objects::DEVICE_HANDLER_COMMANDER);
result = deviceHandlerCommander.initialize();
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
SECTION("Commanding nominal") {
comIF.setTestCase(ComIFMock::TestCase::SIMPLE_COMMAND_NOMINAL);
result = deviceHandlerCommander.sendCommand(objects::DEVICE_HANDLER_MOCK,
DeviceHandlerMock::SIMPLE_COMMAND);
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
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);
deviceHandlerCommander.performOperation();
result = deviceHandlerCommander.getReplyReturnCode();
uint32_t missedReplies = deviceFdirMock.getMissedReplyCount();
REQUIRE(missedReplies == 0);
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
}
SECTION("Commanding missed reply") {
comIF.setTestCase(ComIFMock::TestCase::MISSED_REPLY);
deviceHandlerCommander.resetReplyReturnCode();
// Set the timeout to 0 to immediately timeout the reply
deviceHandlerMock.changeSimpleCommandReplyCountdown(0);
result = deviceHandlerCommander.sendCommand(objects::DEVICE_HANDLER_MOCK,
DeviceHandlerMock::SIMPLE_COMMAND);
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
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);
deviceHandlerMock.performOperation(DeviceHandlerIF::PERFORM_OPERATION);
deviceHandlerCommander.performOperation();
result = deviceHandlerCommander.getReplyReturnCode();
REQUIRE(result == DeviceHandlerIF::TIMEOUT);
uint32_t missedReplies = deviceFdirMock.getMissedReplyCount();
REQUIRE(missedReplies == 1);
}
SECTION("Periodic reply nominal") {
comIF.setTestCase(ComIFMock::TestCase::PERIODIC_REPLY_NOMINAL);
deviceHandlerMock.enablePeriodicReply(DeviceHandlerMock::PERIODIC_REPLY);
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.enablePeriodicReply(DeviceHandlerMock::PERIODIC_REPLY);
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);
// Test if disabling of periodic reply
deviceHandlerMock.disablePeriodicReply(DeviceHandlerMock::PERIODIC_REPLY);
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);
missedReplies = deviceFdirMock.getMissedReplyCount();
// Should still be 1 because periodic reply is now disabled
REQUIRE(missedReplies == 1);
}
}