Merge branch 'development' into mueller/DHB-update

This commit is contained in:
Steffen Gaisser 2020-12-08 14:51:38 +01:00
commit 6bda443181
38 changed files with 453 additions and 352 deletions

View File

@ -1,5 +1,8 @@
## Changes from ASTP 0.0.1 to 1.0.0
### Host OSAL
- Bugfix in MessageQueue, which caused the sender not to be set properly
### FreeRTOS OSAL

View File

@ -7,16 +7,26 @@ PeriodicOperationDivider::PeriodicOperationDivider(uint32_t divider,
}
bool PeriodicOperationDivider::checkAndIncrement() {
if(counter >= divider) {
bool opNecessary = check();
if(opNecessary) {
if(resetAutomatically) {
counter = 0;
}
return true;
return opNecessary;
}
counter ++;
return opNecessary;
}
bool PeriodicOperationDivider::check() {
if(counter >= divider) {
return true;
}
return false;
}
void PeriodicOperationDivider::resetCounter() {
counter = 0;
}

View File

@ -21,17 +21,27 @@ public:
*/
PeriodicOperationDivider(uint32_t divider, bool resetAutomatically = true);
/**
* Check whether operation is necessary.
* If an operation is necessary and the class has been
* configured to be reset automatically, the counter will be reset.
* If not, the counter will be incremented.
*
* @return
* -@c true if the counter is larger or equal to the divider
* -@c false otherwise
*/
bool checkAndIncrement();
/**
* Checks whether an operation is necessary.
* This function will not increment the counter!
* @return
* -@c true if the counter is larger or equal to the divider
* -@c false otherwise
*/
bool check();
/**
* Can be used to reset the counter to 0 manually.
*/

View File

@ -46,7 +46,7 @@ FixedTimeslotTask::FixedTimeslotTask(const char *name, TaskPriority setPriority,
<< GetLastError() << std::endl;
}
#elif defined(LINUX)
// we can just copy and paste the code from linux here.
// TODO: we can just copy and paste the code from the linux OSAL here.
#endif
}
@ -116,7 +116,8 @@ void FixedTimeslotTask::taskFunctionality() {
if (not pollingSeqTable.slotFollowsImmediately()) {
// we need to wait before executing the current slot
// this gives us the time to wait:
interval = chron_ms(this->pollingSeqTable.getIntervalToPreviousSlotMs());
interval = chron_ms(
this->pollingSeqTable.getIntervalToPreviousSlotMs());
delayForInterval(&currentStartTime, interval);
//TODO deadline missed check
}

View File

@ -74,7 +74,7 @@ protected:
//!< Typedef for the List of objects.
typedef std::vector<ExecutableObjectIF*> ObjectList;
std::thread mainThread;
std::atomic<bool> terminateThread = false;
std::atomic<bool> terminateThread { false };
//! Polling sequence table which contains the object to execute
//! and information like the timeslots and the passed execution step.

View File

@ -34,7 +34,7 @@ ReturnValue_t MessageQueue::sendToDefaultFrom(MessageQueueMessageIF* message,
}
ReturnValue_t MessageQueue::reply(MessageQueueMessageIF* message) {
if (this->lastPartner != 0) {
if (this->lastPartner != MessageQueueIF::NO_QUEUE) {
return sendMessageFrom(this->lastPartner, message, this->getId());
} else {
return MessageQueueIF::NO_REPLY_PARTNER;
@ -106,6 +106,7 @@ bool MessageQueue::isDefaultDestinationSet() const {
ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
bool ignoreFault) {
message->setSender(sentFrom);
if(message->getMessageSize() > message->getMaximumMessageSize()) {
// Actually, this should never happen or an error will be emitted
// in MessageQueueMessage.
@ -126,7 +127,6 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
// TODO: Better returnvalue
return HasReturnvaluesIF::RETURN_FAILED;
}
if(targetQueue->messageQueue.size() < targetQueue->messageDepth) {
MutexHelper mutexLock(targetQueue->queueLock,
MutexIF::TimeoutType::WAITING, 20);
@ -145,7 +145,6 @@ ReturnValue_t MessageQueue::sendMessageFromMessageQueue(MessageQueueId_t sendTo,
else {
return MessageQueueIF::FULL;
}
message->setSender(sentFrom);
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -4,21 +4,18 @@
Mutex::Mutex() {}
ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) {
if(timeoutMs == MutexIF::BLOCKING) {
if(timeoutType == MutexIF::BLOCKING) {
mutex.lock();
locked = true;
return HasReturnvaluesIF::RETURN_OK;
}
else if(timeoutMs == MutexIF::POLLING) {
else if(timeoutType == MutexIF::POLLING) {
if(mutex.try_lock()) {
locked = true;
return HasReturnvaluesIF::RETURN_OK;
}
}
else if(timeoutMs > MutexIF::POLLING){
auto chronoMs = std::chrono::milliseconds(timeoutMs);
if(mutex.try_lock_for(chronoMs)) {
locked = true;
return HasReturnvaluesIF::RETURN_OK;
}
}
@ -26,11 +23,7 @@ ReturnValue_t Mutex::lockMutex(TimeoutType timeoutType, uint32_t timeoutMs) {
}
ReturnValue_t Mutex::unlockMutex() {
if(not locked) {
return MutexIF::CURR_THREAD_DOES_NOT_OWN_MUTEX;
}
mutex.unlock();
locked = false;
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -22,7 +22,7 @@ public:
std::timed_mutex* getMutexHandle();
private:
bool locked = false;
//bool locked = false;
std::timed_mutex mutex;
};

View File

@ -89,6 +89,10 @@ ReturnValue_t PeriodicTask::sleepFor(uint32_t ms) {
}
void PeriodicTask::taskFunctionality() {
for (const auto& object: objectList) {
object->initializeAfterTaskCreation();
}
std::chrono::milliseconds periodChrono(static_cast<uint32_t>(period*1000));
auto currentStartTime {
std::chrono::duration_cast<std::chrono::milliseconds>(
@ -101,13 +105,10 @@ void PeriodicTask::taskFunctionality() {
if(terminateThread.load()) {
break;
}
for (ObjectList::iterator it = objectList.begin();
it != objectList.end(); ++it) {
(*it)->performOperation();
for (const auto& object: objectList) {
object->performOperation();
}
if(not delayForInterval(&currentStartTime, periodChrono)) {
sif::warning << "PeriodicTask: " << taskName <<
" missed deadline!\n" << std::flush;
if(deadlineMissedFunc != nullptr) {
this->deadlineMissedFunc();
}
@ -121,6 +122,7 @@ ReturnValue_t PeriodicTask::addComponent(object_id_t object) {
if (newObject == nullptr) {
return HasReturnvaluesIF::RETURN_FAILED;
}
newObject->setTaskIF(this);
objectList.push_back(newObject);
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -69,7 +69,7 @@ protected:
//!< Typedef for the List of objects.
typedef std::vector<ExecutableObjectIF*> ObjectList;
std::thread mainThread;
std::atomic<bool> terminateThread = false;
std::atomic<bool> terminateThread { false };
/**
* @brief This attribute holds a list of objects to be executed.

View File

@ -6,6 +6,7 @@ TmTcWinUdpBridge::TmTcWinUdpBridge(object_id_t objectId,
uint16_t serverPort, uint16_t clientPort):
TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId) {
mutex = MutexFactory::instance()->createMutex();
communicationLinkUp = false;
// Initiates Winsock DLL.
WSAData wsaData;
@ -90,7 +91,6 @@ ReturnValue_t TmTcWinUdpBridge::sendTm(const uint8_t *data, size_t dataLen) {
// sif::debug << "TmTcUnixUdpBridge::sendTm: " << bytesSent << " bytes were"
// " sent." << std::endl;
return HasReturnvaluesIF::RETURN_OK;
return HasReturnvaluesIF::RETURN_OK;
}
void TmTcWinUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) {
@ -101,6 +101,7 @@ void TmTcWinUdpBridge::checkAndSetClientAddress(sockaddr_in newAddress) {
// &newAddress.sin_addr.s_addr, ipAddress, 15) << std::endl;
// sif::debug << "IP Address Old: " << inet_ntop(AF_INET,
// &clientAddress.sin_addr.s_addr, ipAddress, 15) << std::endl;
registerCommConnect();
// Set new IP address if it has changed.
if(clientAddress.sin_addr.s_addr != newAddress.sin_addr.s_addr) {
@ -114,7 +115,7 @@ void TmTcWinUdpBridge::handleSocketError() {
switch(errCode) {
case(WSANOTINITIALISED): {
sif::info << "TmTcWinUdpBridge::handleSocketError: WSANOTINITIALISED: "
<< "WSAStartup(...) call " << "necessary" << std::endl;
<< "WSAStartup(...) call necessary" << std::endl;
break;
}
default: {
@ -154,11 +155,11 @@ void TmTcWinUdpBridge::handleSendError() {
switch(errCode) {
case(WSANOTINITIALISED): {
sif::info << "TmTcWinUdpBridge::handleSendError: WSANOTINITIALISED: "
<< "WSAStartup(...) call " << "necessary" << std::endl;
<< "WSAStartup(...) call necessary" << std::endl;
break;
}
case(WSAEADDRNOTAVAIL): {
sif::info << "TmTcWinUdpBridge::handleReadError: WSAEADDRNOTAVAIL: "
sif::info << "TmTcWinUdpBridge::handleSendError: WSAEADDRNOTAVAIL: "
<< "Check target address. " << std::endl;
break;
}

View File

@ -0,0 +1,48 @@
#ifndef FSFW_PUS_SERVICEPACKETS_SERVICE201PACKETS_H_
#define FSFW_PUS_SERVICEPACKETS_SERVICE201PACKETS_H_
#include "../../serialize/SerialLinkedListAdapter.h"
#include "../../serialize/SerializeIF.h"
#include "../../health/HasHealthIF.h"
class HealthSetCommand: public SerialLinkedListAdapter<SerializeIF> { //!< [EXPORT] : [SUBSERVICE] 1
public:
HealthSetCommand() {
setLinks();
}
HasHealthIF::HealthState getHealth() {
return static_cast<HasHealthIF::HealthState>(health.entry);
}
private:
void setLinks() {
setStart(&objectId);
objectId.setNext(&health);
}
SerializeElement<uint32_t> objectId; //!< [EXPORT] : [COMMENT] Target object Id
SerializeElement<uint8_t> health; //!< [EXPORT] : [COMMENT] Health to set
};
class HealthSetReply: public SerialLinkedListAdapter<SerializeIF> { //!< [EXPORT] : [SUBSERVICE] 2
public:
HealthSetReply(uint8_t health_, uint8_t oldHealth_):
health(health_), oldHealth(oldHealth_)
{
setLinks();
}
private:
HealthSetReply(const HealthSetReply &reply);
void setLinks() {
setStart(&objectId);
objectId.setNext(&health);
health.setNext(&oldHealth);
}
SerializeElement<uint32_t> objectId; //!< [EXPORT] : [COMMENT] Source object ID
SerializeElement<uint8_t> health; //!< [EXPORT] : [COMMENT] New Health
SerializeElement<uint8_t> oldHealth; //!< [EXPORT] : [COMMENT] Old Health
};
#endif /* FSFW_PUS_SERVICEPACKETS_SERVICE201PACKETS_H_ */

View File

@ -1,8 +1,7 @@
#include "CatchDefinitions.h"
#include "CatchFactory.h"
#include <testcfg/cdatapool/dataPoolInit.h>
#include <testcfg/objects/Factory.h>
#ifdef GCOV
#include <gcov.h>

View File

@ -2,7 +2,7 @@
#define FRAMEWORK_TEST_UNITTESTCLASS_H_
#include "UnittDefinitions.h"
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include "../../returnvalues/HasReturnvaluesIF.h"
/**
* @brief Can be used for internal testing, for example for hardware specific

View File

@ -1,4 +1,4 @@
#include <fsfw/unittest/internal/UnittDefinitions.h>
#include "UnittDefinitions.h"
ReturnValue_t unitt::put_error(std::string errorId) {
sif::error << "Unit Tester error: Failed at test ID "

View File

@ -1,7 +1,8 @@
#include <fsfw/ipc/MessageQueueIF.h>
#include <fsfw/ipc/QueueFactory.h>
#include <fsfw/unittest/internal/osal/IntTestMq.h>
#include <fsfw/unittest/internal/UnittDefinitions.h>
#include "IntTestMq.h"
#include "../UnittDefinitions.h"
#include "../../ipc/MessageQueueIF.h"
#include "../../ipc/QueueFactory.h"
#include <array>

View File

@ -1,10 +1,10 @@
#include "IntTestMutex.h"
#include <fsfw/ipc/MutexFactory.h>
#include <unittest/internal/UnittDefinitions.h>
#include "../../ipc/MutexFactory.h"
#include "../UnittDefinitions.h"
#if defined(hosted)
#include <fsfw/osal/hosted/Mutex.h>
#include "../../osal/hosted/Mutex.h"
#include <thread>
#include <future>
#endif
@ -20,7 +20,7 @@ void testmutex::testMutex() {
// timed_mutex from the C++ library specifies undefined behaviour if
// the timed mutex is locked twice from the same thread.
#if defined(hosted)
// hold on, this actually worked ? :-D This calls the function from
// This calls the function from
// another thread and stores the returnvalue in a future.
auto future = std::async(&MutexIF::lockMutex, mutex, 1);
result = future.get();

View File

@ -1,8 +1,9 @@
#include "IntTestSemaphore.h"
#include <fsfw/tasks/SemaphoreFactory.h>
#include <unittest/internal/UnittDefinitions.h>
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
#include <fsfw/timemanager/Stopwatch.h>
#include "../UnittDefinitions.h"
#include "../../tasks/SemaphoreFactory.h"
#include "../../serviceinterface/ServiceInterfaceStream.h"
#include "../../timemanager/Stopwatch.h"
void testsemaph::testBinSemaph() {

View File

@ -1,8 +1,9 @@
#include "IntTestSerialization.h"
#include <fsfw/serialize/SerializeElement.h>
#include <fsfw/serialize/SerialBufferAdapter.h>
#include <unittest/internal/UnittDefinitions.h>
#include <fsfw/serialize/SerializeIF.h>
#include "../UnittDefinitions.h"
#include "../../serialize/SerializeElement.h"
#include "../../serialize/SerialBufferAdapter.h"
#include "../../serialize/SerializeIF.h"
#include <array>
using retval = HasReturnvaluesIF;

View File

@ -1,6 +1,7 @@
#ifndef UNITTEST_INTERNAL_INTTESTSERIALIZATION_H_
#define UNITTEST_INTERNAL_INTTESTSERIALIZATION_H_
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#ifndef FSFW_UNITTEST_INTERNAL_INTTESTSERIALIZATION_H_
#define FSFW_UNITTEST_INTERNAL_INTTESTSERIALIZATION_H_
#include "../../returnvalues/HasReturnvaluesIF.h"
#include <array>
namespace testserialize {
@ -12,4 +13,4 @@ ReturnValue_t test_serial_buffer_adapter();
extern std::array<uint8_t, 512> test_array;
}
#endif /* UNITTEST_INTERNAL_INTTESTSERIALIZATION_H_ */
#endif /* FSFW_UNITTEST_INTERNAL_INTTESTSERIALIZATION_H_ */

View File

@ -0,0 +1,60 @@
#include "CatchFactory.h"
#include <fsfw/events/EventManager.h>
#include <fsfw/health/HealthTable.h>
#include <fsfw/internalError/InternalErrorReporter.h>
#include <fsfw/objectmanager/frameworkObjects.h>
#include <fsfw/storagemanager/PoolManager.h>
/**
* @brief Produces system objects.
* @details
* Build tasks by using SystemObject Interface (Interface).
* Header files of all tasks must be included
* Please note that an object has to implement the system object interface
* if the interface validity is checked or retrieved later by using the
* get<TargetInterface>(object_id) function from the ObjectManagerIF.
*
* Framework objects are created first.
*
* @ingroup init
*/
void Factory::produce(void) {
setStaticFrameworkObjectIds();
new EventManager(objects::EVENT_MANAGER);
new HealthTable(objects::HEALTH_TABLE);
//new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER);
{
static constexpr uint8_t NUMBER_OF_POOLS = 5;
const uint16_t element_sizes[NUMBER_OF_POOLS] = {16, 32, 64, 128, 1024};
const uint16_t n_elements[NUMBER_OF_POOLS] = {100, 50, 25, 15, 5};
new PoolManager<NUMBER_OF_POOLS>(objects::TC_STORE, element_sizes,
n_elements);
}
{
static constexpr uint8_t NUMBER_OF_POOLS = 5;
const uint16_t element_sizes[NUMBER_OF_POOLS] = {16, 32, 64, 128, 1024};
const uint16_t n_elements[NUMBER_OF_POOLS] = {100, 50, 25, 15, 5};
new PoolManager<NUMBER_OF_POOLS>(objects::TM_STORE, element_sizes,
n_elements);
}
{
static constexpr uint8_t NUMBER_OF_POOLS = 6;
const uint16_t element_sizes[NUMBER_OF_POOLS] = {32, 64, 512,
1024, 2048, 4096};
const uint16_t n_elements[NUMBER_OF_POOLS] = {200, 100, 50, 25, 15, 5};
new PoolManager<NUMBER_OF_POOLS>(objects::IPC_STORE, element_sizes,
n_elements);
}
}
void Factory::setStaticFrameworkObjectIds() {
}

View File

@ -1,34 +0,0 @@
#include "Factory.h"
#include <fsfw/events/EventManager.h>
#include <fsfw/health/HealthTable.h>
#include <fsfw/internalError/InternalErrorReporter.h>
#include <fsfw/objectmanager/frameworkObjects.h>
/**
* @brief Produces system objects.
* @details
* Build tasks by using SystemObject Interface (Interface).
* Header files of all tasks must be included
* Please note that an object has to implement the system object interface
* if the interface validity is checked or retrieved later by using the
* get<TargetInterface>(object_id) function from the ObjectManagerIF.
*
* Framework objects are created first.
*
* @ingroup init
*/
void Factory::produce(void) {
setStaticFrameworkObjectIds();
new EventManager(objects::EVENT_MANAGER);
new HealthTable(objects::HEALTH_TABLE);
new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER);
}
void Factory::setStaticFrameworkObjectIds() {
}

View File

@ -3,6 +3,7 @@ CXXSRC += $(wildcard $(CURRENTPATH)/ipc/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/objects/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/pollingsequence/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/events/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/*.cpp)
INCLUDES += $(CURRENTPATH)
INCLUDES += $(CURRENTPATH)/objects

View File

@ -1,106 +1,107 @@
//#include "TestActionHelper.h"
//#include <fsfw/action/ActionHelper.h>
//#include <fsfw/ipc/CommandMessage.h>
//#include <catch2/catch.hpp>
//#include "../../core/CatchDefinitions.h"
//
//
//TEST_CASE( "Action Helper" , "[ActionHelper]") {
// ActionHelperOwnerMockBase testDhMock;
// MessageQueueMockBase testMqMock;
// ActionHelper actionHelper = ActionHelper(
// &testDhMock, dynamic_cast<MessageQueueIF*>(&testMqMock));
// CommandMessage actionMessage;
// ActionId_t testActionId = 777;
// std::array <uint8_t, 3> testParams {1, 2, 3};
// store_address_t paramAddress;
// StorageManagerIF *ipcStore = tglob::getIpcStoreHandle();
// ipcStore->addData(&paramAddress, testParams.data(), 3);
// REQUIRE(actionHelper.initialize() == retval::CATCH_OK);
//
// SECTION ("Simple tests") {
// ActionMessage::setCommand(&actionMessage, testActionId, paramAddress);
// CHECK(not testDhMock.executeActionCalled);
// REQUIRE(actionHelper.handleActionMessage(&actionMessage) == retval::CATCH_OK);
// CHECK(testDhMock.executeActionCalled);
// // No message is sent if everything is alright.
// CHECK(not testMqMock.wasMessageSent());
// store_address_t invalidAddress;
// ActionMessage::setCommand(&actionMessage, testActionId, invalidAddress);
// actionHelper.handleActionMessage(&actionMessage);
// CHECK(testMqMock.wasMessageSent());
// const uint8_t* ptr = nullptr;
// size_t size = 0;
// REQUIRE(ipcStore->getData(paramAddress, &ptr, &size) == static_cast<uint32_t>(StorageManagerIF::DATA_DOES_NOT_EXIST));
// REQUIRE(ptr == nullptr);
// REQUIRE(size == 0);
// testDhMock.getBuffer(&ptr, &size);
// REQUIRE(size == 3);
// for(uint8_t i = 0; i<3;i++){
// REQUIRE(ptr[i] == (i+1));
// }
// testDhMock.clearBuffer();
// }
//
// SECTION("Handle failures"){
// actionMessage.setCommand(1234);
// REQUIRE(actionHelper.handleActionMessage(&actionMessage) == static_cast<uint32_t>(CommandMessage::UNKNOWN_COMMAND));
// CHECK(not testMqMock.wasMessageSent());
// uint16_t step = 5;
// ReturnValue_t status = 0x1234;
// actionHelper.step(step, testMqMock.getId(), testActionId, status);
// step += 1;
// CHECK(testMqMock.wasMessageSent());
// CommandMessage testMessage;
// REQUIRE(testMqMock.receiveMessage(&testMessage) == static_cast<uint32_t>(HasReturnvaluesIF::RETURN_OK));
// REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::STEP_FAILED));
// REQUIRE(testMessage.getParameter() == static_cast<uint32_t>(testActionId));
// uint32_t parameter2 = ((uint32_t)step << 16) | (uint32_t)status;
// REQUIRE(testMessage.getParameter2() == parameter2);
// REQUIRE(ActionMessage::getStep(&testMessage) == step);
// }
//
// SECTION("Handle finish"){
// CHECK(not testMqMock.wasMessageSent());
// ReturnValue_t status = 0x9876;
// actionHelper.finish(testMqMock.getId(), testActionId, status);
// CHECK(testMqMock.wasMessageSent());
// CommandMessage testMessage;
// REQUIRE(testMqMock.receiveMessage(&testMessage) == static_cast<uint32_t>(HasReturnvaluesIF::RETURN_OK));
// REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::COMPLETION_FAILED));
// REQUIRE(ActionMessage::getActionId(&testMessage) == testActionId);
// REQUIRE(ActionMessage::getReturnCode(&testMessage) == static_cast<uint32_t>(status));
// }
//
// SECTION("Handle failed"){
// store_address_t toLongParamAddress = StorageManagerIF::INVALID_ADDRESS;
// std::array<uint8_t, 5> toLongData = {5, 4, 3, 2, 1};
// REQUIRE(ipcStore->addData(&toLongParamAddress, toLongData.data(), 5) == retval::CATCH_OK);
// ActionMessage::setCommand(&actionMessage, testActionId, toLongParamAddress);
// CHECK(not testDhMock.executeActionCalled);
// REQUIRE(actionHelper.handleActionMessage(&actionMessage) == retval::CATCH_OK);
// REQUIRE(ipcStore->getData(toLongParamAddress).first == static_cast<uint32_t>(StorageManagerIF::DATA_DOES_NOT_EXIST));
// CommandMessage testMessage;
// REQUIRE(testMqMock.receiveMessage(&testMessage) == static_cast<uint32_t>(HasReturnvaluesIF::RETURN_OK));
// REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::STEP_FAILED));
// REQUIRE(ActionMessage::getReturnCode(&testMessage) == 0xAFFE);
// REQUIRE(ActionMessage::getStep(&testMessage) == 0);
// REQUIRE(ActionMessage::getActionId(&testMessage) == testActionId);
// }
//
// SECTION("Missing IPC Data"){
// ActionMessage::setCommand(&actionMessage, testActionId, StorageManagerIF::INVALID_ADDRESS);
// CHECK(not testDhMock.executeActionCalled);
// REQUIRE(actionHelper.handleActionMessage(&actionMessage) == retval::CATCH_OK);
// CommandMessage testMessage;
// REQUIRE(testMqMock.receiveMessage(&testMessage) == static_cast<uint32_t>(HasReturnvaluesIF::RETURN_OK));
// REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::STEP_FAILED));
// REQUIRE(ActionMessage::getReturnCode(&testMessage) == static_cast<uint32_t>(StorageManagerIF::ILLEGAL_STORAGE_ID));
// REQUIRE(ActionMessage::getStep(&testMessage) == 0);
// }
//
//
// SECTION("Data Reply"){
//
// }
//}
#include "TestActionHelper.h"
#include <fsfw/action/ActionHelper.h>
#include <fsfw/ipc/CommandMessage.h>
#include <catch2/catch.hpp>
#include "../../core/CatchDefinitions.h"
TEST_CASE( "Action Helper" , "[ActionHelper]") {
ActionHelperOwnerMockBase testDhMock;
MessageQueueMockBase testMqMock;
ActionHelper actionHelper = ActionHelper(
&testDhMock, dynamic_cast<MessageQueueIF*>(&testMqMock));
CommandMessage actionMessage;
ActionId_t testActionId = 777;
std::array <uint8_t, 3> testParams {1, 2, 3};
store_address_t paramAddress;
StorageManagerIF *ipcStore = tglob::getIpcStoreHandle();
REQUIRE(ipcStore != nullptr);
ipcStore->addData(&paramAddress, testParams.data(), 3);
REQUIRE(actionHelper.initialize() == retval::CATCH_OK);
SECTION ("Simple tests") {
ActionMessage::setCommand(&actionMessage, testActionId, paramAddress);
CHECK(not testDhMock.executeActionCalled);
REQUIRE(actionHelper.handleActionMessage(&actionMessage) == retval::CATCH_OK);
CHECK(testDhMock.executeActionCalled);
// No message is sent if everything is alright.
CHECK(not testMqMock.wasMessageSent());
store_address_t invalidAddress;
ActionMessage::setCommand(&actionMessage, testActionId, invalidAddress);
actionHelper.handleActionMessage(&actionMessage);
CHECK(testMqMock.wasMessageSent());
const uint8_t* ptr = nullptr;
size_t size = 0;
REQUIRE(ipcStore->getData(paramAddress, &ptr, &size) == static_cast<uint32_t>(StorageManagerIF::DATA_DOES_NOT_EXIST));
REQUIRE(ptr == nullptr);
REQUIRE(size == 0);
testDhMock.getBuffer(&ptr, &size);
REQUIRE(size == 3);
for(uint8_t i = 0; i<3;i++){
REQUIRE(ptr[i] == (i+1));
}
testDhMock.clearBuffer();
}
SECTION("Handle failures"){
actionMessage.setCommand(1234);
REQUIRE(actionHelper.handleActionMessage(&actionMessage) == static_cast<uint32_t>(CommandMessage::UNKNOWN_COMMAND));
CHECK(not testMqMock.wasMessageSent());
uint16_t step = 5;
ReturnValue_t status = 0x1234;
actionHelper.step(step, testMqMock.getId(), testActionId, status);
step += 1;
CHECK(testMqMock.wasMessageSent());
CommandMessage testMessage;
REQUIRE(testMqMock.receiveMessage(&testMessage) == static_cast<uint32_t>(HasReturnvaluesIF::RETURN_OK));
REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::STEP_FAILED));
REQUIRE(testMessage.getParameter() == static_cast<uint32_t>(testActionId));
uint32_t parameter2 = ((uint32_t)step << 16) | (uint32_t)status;
REQUIRE(testMessage.getParameter2() == parameter2);
REQUIRE(ActionMessage::getStep(&testMessage) == step);
}
SECTION("Handle finish"){
CHECK(not testMqMock.wasMessageSent());
ReturnValue_t status = 0x9876;
actionHelper.finish(testMqMock.getId(), testActionId, status);
CHECK(testMqMock.wasMessageSent());
CommandMessage testMessage;
REQUIRE(testMqMock.receiveMessage(&testMessage) == static_cast<uint32_t>(HasReturnvaluesIF::RETURN_OK));
REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::COMPLETION_FAILED));
REQUIRE(ActionMessage::getActionId(&testMessage) == testActionId);
REQUIRE(ActionMessage::getReturnCode(&testMessage) == static_cast<uint32_t>(status));
}
SECTION("Handle failed"){
store_address_t toLongParamAddress = StorageManagerIF::INVALID_ADDRESS;
std::array<uint8_t, 5> toLongData = {5, 4, 3, 2, 1};
REQUIRE(ipcStore->addData(&toLongParamAddress, toLongData.data(), 5) == retval::CATCH_OK);
ActionMessage::setCommand(&actionMessage, testActionId, toLongParamAddress);
CHECK(not testDhMock.executeActionCalled);
REQUIRE(actionHelper.handleActionMessage(&actionMessage) == retval::CATCH_OK);
REQUIRE(ipcStore->getData(toLongParamAddress).first == static_cast<uint32_t>(StorageManagerIF::DATA_DOES_NOT_EXIST));
CommandMessage testMessage;
REQUIRE(testMqMock.receiveMessage(&testMessage) == static_cast<uint32_t>(HasReturnvaluesIF::RETURN_OK));
REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::STEP_FAILED));
REQUIRE(ActionMessage::getReturnCode(&testMessage) == 0xAFFE);
REQUIRE(ActionMessage::getStep(&testMessage) == 0);
REQUIRE(ActionMessage::getActionId(&testMessage) == testActionId);
}
SECTION("Missing IPC Data"){
ActionMessage::setCommand(&actionMessage, testActionId, StorageManagerIF::INVALID_ADDRESS);
CHECK(not testDhMock.executeActionCalled);
REQUIRE(actionHelper.handleActionMessage(&actionMessage) == retval::CATCH_OK);
CommandMessage testMessage;
REQUIRE(testMqMock.receiveMessage(&testMessage) == static_cast<uint32_t>(HasReturnvaluesIF::RETURN_OK));
REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::STEP_FAILED));
REQUIRE(ActionMessage::getReturnCode(&testMessage) == static_cast<uint32_t>(StorageManagerIF::ILLEGAL_STORAGE_ID));
REQUIRE(ActionMessage::getStep(&testMessage) == 0);
}
SECTION("Data Reply"){
}
}

View File

@ -1,131 +1,132 @@
//#ifndef UNITTEST_HOSTED_TESTACTIONHELPER_H_
//#define UNITTEST_HOSTED_TESTACTIONHELPER_H_
//
//#include <fsfw/action/HasActionsIF.h>
//#include <fsfw/ipc/MessageQueueIF.h>
//#include <fsfw/unittest/core/CatchDefinitions.h>
//#include <cstring>
//
//
//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;
// }
// }
//};
//
//
//class MessageQueueMockBase: public MessageQueueIF {
//public:
// MessageQueueId_t myQueueId = 0;
// bool defaultDestSet = false;
// bool messageSent = false;
//
//
//
// bool wasMessageSent() {
// bool tempMessageSent = messageSent;
// messageSent = false;
// return tempMessageSent;
// }
//
// virtual ReturnValue_t reply( MessageQueueMessage* message ) {
// messageSent = true;
// lastMessage = (*message);
// return HasReturnvaluesIF::RETURN_OK;
// };
// virtual ReturnValue_t receiveMessage(MessageQueueMessage* message,
// MessageQueueId_t *receivedFrom) {
// (*message) = lastMessage;
// lastMessage.clear();
// return HasReturnvaluesIF::RETURN_OK;
// }
// virtual ReturnValue_t receiveMessage(MessageQueueMessage* message) {
// (*message) = lastMessage;
// lastMessage.clear();
// return HasReturnvaluesIF::RETURN_OK;
// }
// virtual ReturnValue_t flush(uint32_t* count) {
// return HasReturnvaluesIF::RETURN_OK;
// }
// virtual MessageQueueId_t getLastPartner() const {
// return tconst::testQueueId;
// }
// virtual MessageQueueId_t getId() const {
// return tconst::testQueueId;
// }
// virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo,
// MessageQueueMessage* message, MessageQueueId_t sentFrom,
// bool ignoreFault = false ) {
// messageSent = true;
// lastMessage = (*message);
// return HasReturnvaluesIF::RETURN_OK;
// }
// virtual ReturnValue_t sendMessage( MessageQueueId_t sendTo,
// MessageQueueMessage* message, bool ignoreFault = false ) override {
// messageSent = true;
// lastMessage = (*message);
// return HasReturnvaluesIF::RETURN_OK;
// }
// virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessage* message,
// MessageQueueId_t sentFrom, bool ignoreFault = false ) {
// messageSent = true;
// lastMessage = (*message);
// return HasReturnvaluesIF::RETURN_OK;
// }
// virtual ReturnValue_t sendToDefault( MessageQueueMessage* message ) {
// messageSent = true;
// lastMessage = (*message);
// return HasReturnvaluesIF::RETURN_OK;
// }
// virtual void setDefaultDestination(MessageQueueId_t defaultDestination) {
// myQueueId = defaultDestination;
// defaultDestSet = true;
// }
//
// virtual MessageQueueId_t getDefaultDestination() const {
// return myQueueId;
// }
// virtual bool isDefaultDestinationSet() const {
// return defaultDestSet;
// }
//private:
// MessageQueueMessage lastMessage;
//
//};
//
//
//#endif /* UNITTEST_TESTFW_NEWTESTS_TESTACTIONHELPER_H_ */
#ifndef UNITTEST_HOSTED_TESTACTIONHELPER_H_
#define UNITTEST_HOSTED_TESTACTIONHELPER_H_
#include <fsfw/action/HasActionsIF.h>
#include <fsfw/ipc/MessageQueueIF.h>
#include <fsfw/unittest/core/CatchDefinitions.h>
#include <cstring>
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;
}
}
};
class MessageQueueMockBase: public MessageQueueIF {
public:
MessageQueueId_t myQueueId = 0;
bool defaultDestSet = false;
bool messageSent = false;
bool wasMessageSent() {
bool tempMessageSent = messageSent;
messageSent = false;
return tempMessageSent;
}
virtual ReturnValue_t reply( MessageQueueMessageIF* message ) {
messageSent = true;
lastMessage = *(dynamic_cast<MessageQueueMessage*>(message));
return HasReturnvaluesIF::RETURN_OK;
};
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
MessageQueueId_t *receivedFrom) {
(*message) = lastMessage;
lastMessage.clear();
return HasReturnvaluesIF::RETURN_OK;
}
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message) {
memcpy(message->getBuffer(), lastMessage.getBuffer(),
message->getMessageSize());
lastMessage.clear();
return HasReturnvaluesIF::RETURN_OK;
}
virtual ReturnValue_t flush(uint32_t* count) {
return HasReturnvaluesIF::RETURN_OK;
}
virtual MessageQueueId_t getLastPartner() const {
return tconst::testQueueId;
}
virtual MessageQueueId_t getId() const {
return tconst::testQueueId;
}
virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo,
MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
bool ignoreFault = false ) {
messageSent = true;
lastMessage = *(dynamic_cast<MessageQueueMessage*>(message));
return HasReturnvaluesIF::RETURN_OK;
}
virtual ReturnValue_t sendMessage( MessageQueueId_t sendTo,
MessageQueueMessageIF* message, bool ignoreFault = false ) override {
messageSent = true;
lastMessage = *(dynamic_cast<MessageQueueMessage*>(message));
return HasReturnvaluesIF::RETURN_OK;
}
virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessageIF* message,
MessageQueueId_t sentFrom, bool ignoreFault = false ) {
messageSent = true;
lastMessage = *(dynamic_cast<MessageQueueMessage*>(message));
return HasReturnvaluesIF::RETURN_OK;
}
virtual ReturnValue_t sendToDefault( MessageQueueMessageIF* message ) {
messageSent = true;
lastMessage = *(dynamic_cast<MessageQueueMessage*>(message));
return HasReturnvaluesIF::RETURN_OK;
}
virtual void setDefaultDestination(MessageQueueId_t defaultDestination) {
myQueueId = defaultDestination;
defaultDestSet = true;
}
virtual MessageQueueId_t getDefaultDestination() const {
return myQueueId;
}
virtual bool isDefaultDestinationSet() const {
return defaultDestSet;
}
private:
MessageQueueMessage lastMessage;
};
#endif /* UNITTEST_TESTFW_NEWTESTS_TESTACTIONHELPER_H_ */

View File

@ -1,7 +1,7 @@
#include <fsfw/container/SimpleRingBuffer.h>
#include <catch2/catch.hpp>
#include "../../core/CatchDefinitions.h"
#include "../../container/SimpleRingBuffer.h"
#include <catch2/catch.hpp>
#include <cstring>
TEST_CASE("Ring Buffer Test" , "[RingBufferTest]") {

View File

@ -1,5 +1,6 @@
#include <fsfw/container/ArrayList.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include "../../container/ArrayList.h"
#include "../../returnvalues/HasReturnvaluesIF.h"
#include <catch2/catch.hpp>
#include "../../core/CatchDefinitions.h"

View File

@ -1,7 +1,7 @@
#include <fsfw/container/DynamicFIFO.h>
#include <fsfw/container/FIFO.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include "../../container/DynamicFIFO.h"
#include "../../container/FIFO.h"
#include "../../returnvalues/HasReturnvaluesIF.h"
#include <catch.hpp>
#include <CatchDefinitions.h>

View File

@ -1,7 +1,7 @@
#include <fsfw/container/DynamicFIFO.h>
#include <fsfw/container/FIFO.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include "../../container/DynamicFIFO.h"
#include "../../container/FIFO.h"
#include "../../returnvalues/HasReturnvaluesIF.h"
#include <catch2/catch.hpp>
#include "../../core/CatchDefinitions.h"

View File

@ -1,7 +1,7 @@
#include "../../core/CatchDefinitions.h"
#include <fsfw/container/FixedArrayList.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include "../../container/FixedArrayList.h"
#include "../../returnvalues/HasReturnvaluesIF.h"
#include <catch2/catch.hpp>

View File

@ -1,5 +1,5 @@
#include <fsfw/container/FixedMap.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include "../../container/FixedMap.h"
#include "../../returnvalues/HasReturnvaluesIF.h"
#include <catch2/catch.hpp>
#include "../../core/CatchDefinitions.h"

View File

@ -1,5 +1,5 @@
#include <fsfw/container/FixedOrderedMultimap.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include "../../container/FixedOrderedMultimap.h"
#include "../../returnvalues/HasReturnvaluesIF.h"
#include <catch2/catch.hpp>
#include "../../core/CatchDefinitions.h"

View File

@ -1,8 +1,8 @@
#include <fsfw/ipc/MessageQueueIF.h>
#include <fsfw/ipc/QueueFactory.h>
#include "catch.hpp"
#include "../../ipc/MessageQueueIF.h"
#include "../../ipc/QueueFactory.h"
#include <catch.hpp>
#include <array>
#include "core/CatchDefinitions.h"
#include "../../core/CatchDefinitions.h"
TEST_CASE("MessageQueue Basic Test","[TestMq]") {
MessageQueueIF* testSenderMq =

View File

@ -1,4 +1,4 @@
#include <fsfw/serialize/SerialBufferAdapter.h>
#include "../../serialize/SerialBufferAdapter.h"
#include <catch2/catch.hpp>
#include "../../core/CatchDefinitions.h"

View File

@ -1,8 +1,9 @@
#include <fsfw/globalfunctions/arrayprinter.h>
#include "TestSerialLinkedPacket.h"
#include "../../core/CatchDefinitions.h"
#include "../../globalfunctions/arrayprinter.h"
#include <catch2/catch.hpp>
#include "../../core/CatchDefinitions.h"
#include "TestSerialLinkedPacket.h"
TEST_CASE("Serial Linked Packet" , "[SerLinkPacket]") {

View File

@ -1,4 +1,4 @@
#include <fsfw/serialize/SerializeAdapter.h>
#include "../../serialize/SerializeAdapter.h"
#include "catch.hpp"
#include <array>