reapply clang format
This commit is contained in:
@ -2,200 +2,179 @@
|
||||
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
|
||||
|
||||
TestAssembly::TestAssembly(object_id_t objectId, object_id_t parentId, object_id_t testDevice0,
|
||||
object_id_t testDevice1):
|
||||
AssemblyBase(objectId, parentId), deviceHandler0Id(testDevice0),
|
||||
deviceHandler1Id(testDevice1) {
|
||||
ModeListEntry newModeListEntry;
|
||||
newModeListEntry.setObject(testDevice0);
|
||||
newModeListEntry.setMode(MODE_OFF);
|
||||
newModeListEntry.setSubmode(SUBMODE_NONE);
|
||||
object_id_t testDevice1)
|
||||
: AssemblyBase(objectId, parentId),
|
||||
deviceHandler0Id(testDevice0),
|
||||
deviceHandler1Id(testDevice1) {
|
||||
ModeListEntry newModeListEntry;
|
||||
newModeListEntry.setObject(testDevice0);
|
||||
newModeListEntry.setMode(MODE_OFF);
|
||||
newModeListEntry.setSubmode(SUBMODE_NONE);
|
||||
|
||||
commandTable.insert(newModeListEntry);
|
||||
commandTable.insert(newModeListEntry);
|
||||
|
||||
newModeListEntry.setObject(testDevice1);
|
||||
newModeListEntry.setMode(MODE_OFF);
|
||||
newModeListEntry.setSubmode(SUBMODE_NONE);
|
||||
|
||||
commandTable.insert(newModeListEntry);
|
||||
newModeListEntry.setObject(testDevice1);
|
||||
newModeListEntry.setMode(MODE_OFF);
|
||||
newModeListEntry.setSubmode(SUBMODE_NONE);
|
||||
|
||||
commandTable.insert(newModeListEntry);
|
||||
}
|
||||
|
||||
TestAssembly::~TestAssembly() {
|
||||
}
|
||||
TestAssembly::~TestAssembly() {}
|
||||
|
||||
ReturnValue_t TestAssembly::commandChildren(Mode_t mode,
|
||||
Submode_t submode) {
|
||||
ReturnValue_t TestAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "TestAssembly: Received command to go to mode " << mode <<
|
||||
" submode " << (int) submode << std::endl;
|
||||
sif::info << "TestAssembly: Received command to go to mode " << mode << " submode "
|
||||
<< (int)submode << std::endl;
|
||||
#else
|
||||
sif::printInfo("TestAssembly: Received command to go to mode %d submode %d\n", mode, submode);
|
||||
sif::printInfo("TestAssembly: Received command to go to mode %d submode %d\n", mode, submode);
|
||||
#endif
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
if(mode == MODE_OFF){
|
||||
commandTable[0].setMode(MODE_OFF);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
commandTable[1].setMode(MODE_OFF);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
else if(mode == DeviceHandlerIF::MODE_NORMAL) {
|
||||
if(submode == submodes::SINGLE){
|
||||
commandTable[0].setMode(MODE_OFF);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
commandTable[1].setMode(MODE_OFF);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
// We try to prefer 0 here but we try to switch to 1 even if it might fail
|
||||
if(isDeviceAvailable(deviceHandler0Id)) {
|
||||
if (childrenMap[deviceHandler0Id].mode == MODE_ON) {
|
||||
commandTable[0].setMode(mode);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
else {
|
||||
commandTable[0].setMode(MODE_ON);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
result = NEED_SECOND_STEP;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (childrenMap[deviceHandler1Id].mode == MODE_ON) {
|
||||
commandTable[1].setMode(mode);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
else{
|
||||
commandTable[1].setMode(MODE_ON);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
result = NEED_SECOND_STEP;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
// Dual Mode Normal
|
||||
if (childrenMap[deviceHandler0Id].mode == MODE_ON) {
|
||||
commandTable[0].setMode(mode);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
else{
|
||||
commandTable[0].setMode(MODE_ON);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
result = NEED_SECOND_STEP;
|
||||
}
|
||||
if (childrenMap[deviceHandler1Id].mode == MODE_ON) {
|
||||
commandTable[1].setMode(mode);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
else{
|
||||
commandTable[1].setMode(MODE_ON);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
result = NEED_SECOND_STEP;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
//Mode ON
|
||||
if(submode == submodes::SINGLE){
|
||||
commandTable[0].setMode(MODE_OFF);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
commandTable[1].setMode(MODE_OFF);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
// We try to prefer 0 here but we try to switch to 1 even if it might fail
|
||||
if(isDeviceAvailable(deviceHandler0Id)){
|
||||
commandTable[0].setMode(MODE_ON);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
else{
|
||||
commandTable[1].setMode(MODE_ON);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
}
|
||||
else{
|
||||
commandTable[0].setMode(MODE_ON);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
commandTable[1].setMode(MODE_ON);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
}
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
if (mode == MODE_OFF) {
|
||||
commandTable[0].setMode(MODE_OFF);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
commandTable[1].setMode(MODE_OFF);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
} else if (mode == DeviceHandlerIF::MODE_NORMAL) {
|
||||
if (submode == submodes::SINGLE) {
|
||||
commandTable[0].setMode(MODE_OFF);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
commandTable[1].setMode(MODE_OFF);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
// We try to prefer 0 here but we try to switch to 1 even if it might fail
|
||||
if (isDeviceAvailable(deviceHandler0Id)) {
|
||||
if (childrenMap[deviceHandler0Id].mode == MODE_ON) {
|
||||
commandTable[0].setMode(mode);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
} else {
|
||||
commandTable[0].setMode(MODE_ON);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
result = NEED_SECOND_STEP;
|
||||
}
|
||||
} else {
|
||||
if (childrenMap[deviceHandler1Id].mode == MODE_ON) {
|
||||
commandTable[1].setMode(mode);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
} else {
|
||||
commandTable[1].setMode(MODE_ON);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
result = NEED_SECOND_STEP;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Dual Mode Normal
|
||||
if (childrenMap[deviceHandler0Id].mode == MODE_ON) {
|
||||
commandTable[0].setMode(mode);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
} else {
|
||||
commandTable[0].setMode(MODE_ON);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
result = NEED_SECOND_STEP;
|
||||
}
|
||||
if (childrenMap[deviceHandler1Id].mode == MODE_ON) {
|
||||
commandTable[1].setMode(mode);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
} else {
|
||||
commandTable[1].setMode(MODE_ON);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
result = NEED_SECOND_STEP;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Mode ON
|
||||
if (submode == submodes::SINGLE) {
|
||||
commandTable[0].setMode(MODE_OFF);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
commandTable[1].setMode(MODE_OFF);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
// We try to prefer 0 here but we try to switch to 1 even if it might fail
|
||||
if (isDeviceAvailable(deviceHandler0Id)) {
|
||||
commandTable[0].setMode(MODE_ON);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
} else {
|
||||
commandTable[1].setMode(MODE_ON);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
} else {
|
||||
commandTable[0].setMode(MODE_ON);
|
||||
commandTable[0].setSubmode(SUBMODE_NONE);
|
||||
commandTable[1].setMode(MODE_ON);
|
||||
commandTable[1].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
HybridIterator<ModeListEntry> iter(commandTable.begin(),
|
||||
commandTable.end());
|
||||
executeTable(iter);
|
||||
return result;
|
||||
HybridIterator<ModeListEntry> iter(commandTable.begin(), commandTable.end());
|
||||
executeTable(iter);
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t TestAssembly::isModeCombinationValid(Mode_t mode,
|
||||
Submode_t submode) {
|
||||
switch (mode) {
|
||||
case MODE_OFF:
|
||||
if (submode == SUBMODE_NONE) {
|
||||
return RETURN_OK;
|
||||
} else {
|
||||
return INVALID_SUBMODE;
|
||||
}
|
||||
case DeviceHandlerIF::MODE_NORMAL:
|
||||
case MODE_ON:
|
||||
if (submode < 3) {
|
||||
return RETURN_OK;
|
||||
} else {
|
||||
return INVALID_SUBMODE;
|
||||
}
|
||||
}
|
||||
return INVALID_MODE;
|
||||
ReturnValue_t TestAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) {
|
||||
switch (mode) {
|
||||
case MODE_OFF:
|
||||
if (submode == SUBMODE_NONE) {
|
||||
return RETURN_OK;
|
||||
} else {
|
||||
return INVALID_SUBMODE;
|
||||
}
|
||||
case DeviceHandlerIF::MODE_NORMAL:
|
||||
case MODE_ON:
|
||||
if (submode < 3) {
|
||||
return RETURN_OK;
|
||||
} else {
|
||||
return INVALID_SUBMODE;
|
||||
}
|
||||
}
|
||||
return INVALID_MODE;
|
||||
}
|
||||
|
||||
ReturnValue_t TestAssembly::initialize() {
|
||||
ReturnValue_t result = AssemblyBase::initialize();
|
||||
if(result != RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
handler0 = ObjectManager::instance()->get<TestDevice>(deviceHandler0Id);
|
||||
handler1 = ObjectManager::instance()->get<TestDevice>(deviceHandler1Id);
|
||||
if((handler0 == nullptr) or (handler1 == nullptr)){
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
ReturnValue_t result = AssemblyBase::initialize();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
handler0 = ObjectManager::instance()->get<TestDevice>(deviceHandler0Id);
|
||||
handler1 = ObjectManager::instance()->get<TestDevice>(deviceHandler1Id);
|
||||
if ((handler0 == nullptr) or (handler1 == nullptr)) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
handler0->setParentQueue(this->getCommandQueue());
|
||||
handler1->setParentQueue(this->getCommandQueue());
|
||||
handler0->setParentQueue(this->getCommandQueue());
|
||||
handler1->setParentQueue(this->getCommandQueue());
|
||||
|
||||
|
||||
result = registerChild(deviceHandler0Id);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = registerChild(deviceHandler1Id);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
result = registerChild(deviceHandler0Id);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = registerChild(deviceHandler1Id);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t TestAssembly::checkChildrenStateOn(
|
||||
Mode_t wantedMode, Submode_t wantedSubmode) {
|
||||
if(submode == submodes::DUAL){
|
||||
for(const auto& info:childrenMap) {
|
||||
if(info.second.mode != wantedMode or info.second.mode != wantedSubmode){
|
||||
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
|
||||
}
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
else if(submode == submodes::SINGLE) {
|
||||
for(const auto& info:childrenMap) {
|
||||
if(info.second.mode == wantedMode and info.second.mode != wantedSubmode){
|
||||
return RETURN_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return INVALID_SUBMODE;
|
||||
ReturnValue_t TestAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) {
|
||||
if (submode == submodes::DUAL) {
|
||||
for (const auto& info : childrenMap) {
|
||||
if (info.second.mode != wantedMode or info.second.mode != wantedSubmode) {
|
||||
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
|
||||
}
|
||||
}
|
||||
return RETURN_OK;
|
||||
} else if (submode == submodes::SINGLE) {
|
||||
for (const auto& info : childrenMap) {
|
||||
if (info.second.mode == wantedMode and info.second.mode != wantedSubmode) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return INVALID_SUBMODE;
|
||||
}
|
||||
|
||||
bool TestAssembly::isDeviceAvailable(object_id_t object) {
|
||||
if(healthHelper.healthTable->getHealth(object) == HasHealthIF::HEALTHY){
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
if (healthHelper.healthTable->getHealth(object) == HasHealthIF::HEALTHY) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -2,55 +2,51 @@
|
||||
#define MISSION_ASSEMBLIES_TESTASSEMBLY_H_
|
||||
|
||||
#include <fsfw/devicehandlers/AssemblyBase.h>
|
||||
|
||||
#include "../devices/TestDeviceHandler.h"
|
||||
|
||||
class TestAssembly: public AssemblyBase {
|
||||
public:
|
||||
TestAssembly(object_id_t objectId, object_id_t parentId, object_id_t testDevice0,
|
||||
object_id_t testDevice1);
|
||||
virtual ~TestAssembly();
|
||||
ReturnValue_t initialize() override;
|
||||
class TestAssembly : public AssemblyBase {
|
||||
public:
|
||||
TestAssembly(object_id_t objectId, object_id_t parentId, object_id_t testDevice0,
|
||||
object_id_t testDevice1);
|
||||
virtual ~TestAssembly();
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
enum submodes: Submode_t{
|
||||
SINGLE = 0,
|
||||
DUAL = 1
|
||||
};
|
||||
enum submodes : Submode_t { SINGLE = 0, DUAL = 1 };
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Command children to reach [mode,submode] combination
|
||||
* Can be done by setting #commandsOutstanding correctly,
|
||||
* or using executeTable()
|
||||
* @param mode
|
||||
* @param submode
|
||||
* @return
|
||||
* - @c RETURN_OK if ok
|
||||
* - @c NEED_SECOND_STEP if children need to be commanded again
|
||||
*/
|
||||
ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override;
|
||||
/**
|
||||
* Check whether desired assembly mode was achieved by checking the modes
|
||||
* or/and health states of child device handlers.
|
||||
* The assembly template class will also call this function if a health
|
||||
* or mode change of a child device handler was detected.
|
||||
* @param wantedMode
|
||||
* @param wantedSubmode
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode)
|
||||
override;
|
||||
protected:
|
||||
/**
|
||||
* Command children to reach [mode,submode] combination
|
||||
* Can be done by setting #commandsOutstanding correctly,
|
||||
* or using executeTable()
|
||||
* @param mode
|
||||
* @param submode
|
||||
* @return
|
||||
* - @c RETURN_OK if ok
|
||||
* - @c NEED_SECOND_STEP if children need to be commanded again
|
||||
*/
|
||||
ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override;
|
||||
/**
|
||||
* Check whether desired assembly mode was achieved by checking the modes
|
||||
* or/and health states of child device handlers.
|
||||
* The assembly template class will also call this function if a health
|
||||
* or mode change of a child device handler was detected.
|
||||
* @param wantedMode
|
||||
* @param wantedSubmode
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override;
|
||||
|
||||
ReturnValue_t checkChildrenStateOn(Mode_t wantedMode,
|
||||
Submode_t wantedSubmode) override;
|
||||
private:
|
||||
FixedArrayList<ModeListEntry, 2> commandTable;
|
||||
object_id_t deviceHandler0Id = 0;
|
||||
object_id_t deviceHandler1Id = 0;
|
||||
TestDevice* handler0 = nullptr;
|
||||
TestDevice* handler1 = nullptr;
|
||||
ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override;
|
||||
|
||||
private:
|
||||
FixedArrayList<ModeListEntry, 2> commandTable;
|
||||
object_id_t deviceHandler0Id = 0;
|
||||
object_id_t deviceHandler1Id = 0;
|
||||
TestDevice* handler0 = nullptr;
|
||||
TestDevice* handler1 = nullptr;
|
||||
|
||||
bool isDeviceAvailable(object_id_t object);
|
||||
bool isDeviceAvailable(object_id_t object);
|
||||
};
|
||||
|
||||
#endif /* MISSION_ASSEMBLIES_TESTASSEMBLY_H_ */
|
||||
|
@ -4,45 +4,34 @@
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
|
||||
TestController::TestController(object_id_t objectId, object_id_t parentId,
|
||||
size_t commandQueueDepth):
|
||||
ExtendedControllerBase(objectId, parentId, commandQueueDepth) {
|
||||
}
|
||||
TestController::TestController(object_id_t objectId, object_id_t parentId, size_t commandQueueDepth)
|
||||
: ExtendedControllerBase(objectId, parentId, commandQueueDepth) {}
|
||||
|
||||
TestController::~TestController() {
|
||||
}
|
||||
TestController::~TestController() {}
|
||||
|
||||
ReturnValue_t TestController::handleCommandMessage(CommandMessage *message) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
void TestController::performControlOperation() {
|
||||
void TestController::performControlOperation() {}
|
||||
|
||||
}
|
||||
|
||||
void TestController::handleChangedDataset(sid_t sid, store_address_t storeId, bool* clearMessage) {
|
||||
|
||||
}
|
||||
void TestController::handleChangedDataset(sid_t sid, store_address_t storeId, bool *clearMessage) {}
|
||||
|
||||
void TestController::handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId,
|
||||
bool* clearMessage) {
|
||||
}
|
||||
bool *clearMessage) {}
|
||||
|
||||
LocalPoolDataSetBase* TestController::getDataSetHandle(sid_t sid) {
|
||||
return nullptr;
|
||||
}
|
||||
LocalPoolDataSetBase *TestController::getDataSetHandle(sid_t sid) { return nullptr; }
|
||||
|
||||
ReturnValue_t TestController::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
LocalDataPoolManager &poolManager) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t TestController::initializeAfterTaskCreation() {
|
||||
return ExtendedControllerBase::initializeAfterTaskCreation();
|
||||
return ExtendedControllerBase::initializeAfterTaskCreation();
|
||||
}
|
||||
|
||||
ReturnValue_t TestController::checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t *msToReachTheMode) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
uint32_t *msToReachTheMode) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
@ -1,38 +1,36 @@
|
||||
#ifndef MISSION_CONTROLLER_TESTCONTROLLER_H_
|
||||
#define MISSION_CONTROLLER_TESTCONTROLLER_H_
|
||||
|
||||
#include "../devices/devicedefinitions/testDeviceDefinitions.h"
|
||||
#include <fsfw/controller/ExtendedControllerBase.h>
|
||||
|
||||
#include "../devices/devicedefinitions/testDeviceDefinitions.h"
|
||||
|
||||
class TestController:
|
||||
public ExtendedControllerBase {
|
||||
public:
|
||||
TestController(object_id_t objectId, object_id_t parentId, size_t commandQueueDepth = 10);
|
||||
virtual~ TestController();
|
||||
protected:
|
||||
class TestController : public ExtendedControllerBase {
|
||||
public:
|
||||
TestController(object_id_t objectId, object_id_t parentId, size_t commandQueueDepth = 10);
|
||||
virtual ~TestController();
|
||||
|
||||
// Extended Controller Base overrides
|
||||
ReturnValue_t handleCommandMessage(CommandMessage *message) override;
|
||||
void performControlOperation() override;
|
||||
protected:
|
||||
// Extended Controller Base overrides
|
||||
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
|
||||
void performControlOperation() override;
|
||||
|
||||
// HasLocalDatapoolIF callbacks
|
||||
virtual void handleChangedDataset(sid_t sid, store_address_t storeId,
|
||||
bool* clearMessage) override;
|
||||
virtual void handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId,
|
||||
bool* clearMessage) override;
|
||||
// HasLocalDatapoolIF callbacks
|
||||
virtual void handleChangedDataset(sid_t sid, store_address_t storeId,
|
||||
bool* clearMessage) override;
|
||||
virtual void handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId,
|
||||
bool* clearMessage) override;
|
||||
|
||||
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t *msToReachTheMode) override;
|
||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||
uint32_t* msToReachTheMode) override;
|
||||
|
||||
ReturnValue_t initializeAfterTaskCreation() override;
|
||||
ReturnValue_t initializeAfterTaskCreation() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
#endif /* MISSION_CONTROLLER_TESTCONTROLLER_H_ */
|
||||
|
@ -1,18 +1,16 @@
|
||||
#ifndef MISSION_CONTROLLER_CTRLDEFINITIONS_TESTCTRLDEFINITIONS_H_
|
||||
#define MISSION_CONTROLLER_CTRLDEFINITIONS_TESTCTRLDEFINITIONS_H_
|
||||
|
||||
#include <fsfw/objectmanager/SystemObjectIF.h>
|
||||
#include <OBSWConfig.h>
|
||||
#include <fsfw/objectmanager/SystemObjectIF.h>
|
||||
|
||||
namespace testcontroller {
|
||||
|
||||
enum sourceObjectIds: object_id_t {
|
||||
DEVICE_0_ID = objects::TEST_DEVICE_HANDLER_0,
|
||||
DEVICE_1_ID = objects::TEST_DEVICE_HANDLER_1,
|
||||
enum sourceObjectIds : object_id_t {
|
||||
DEVICE_0_ID = objects::TEST_DEVICE_HANDLER_0,
|
||||
DEVICE_1_ID = objects::TEST_DEVICE_HANDLER_1,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* MISSION_CONTROLLER_CTRLDEFINITIONS_TESTCTRLDEFINITIONS_H_ */
|
||||
|
@ -1,14 +1,10 @@
|
||||
#include "TestCookie.h"
|
||||
|
||||
TestCookie::TestCookie(address_t address, size_t replyMaxLen):
|
||||
address(address), replyMaxLen(replyMaxLen) {}
|
||||
TestCookie::TestCookie(address_t address, size_t replyMaxLen)
|
||||
: address(address), replyMaxLen(replyMaxLen) {}
|
||||
|
||||
TestCookie::~TestCookie() {}
|
||||
|
||||
address_t TestCookie::getAddress() const {
|
||||
return address;
|
||||
}
|
||||
address_t TestCookie::getAddress() const { return address; }
|
||||
|
||||
size_t TestCookie::getReplyMaxLen() const {
|
||||
return replyMaxLen;
|
||||
}
|
||||
size_t TestCookie::getReplyMaxLen() const { return replyMaxLen; }
|
||||
|
@ -2,21 +2,23 @@
|
||||
#define MISSION_DEVICES_TESTCOOKIE_H_
|
||||
|
||||
#include <fsfw/devicehandlers/CookieIF.h>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
/**
|
||||
* @brief Really simple cookie which does not do a lot.
|
||||
*/
|
||||
class TestCookie: public CookieIF {
|
||||
public:
|
||||
TestCookie(address_t address, size_t maxReplyLen);
|
||||
virtual ~TestCookie();
|
||||
class TestCookie : public CookieIF {
|
||||
public:
|
||||
TestCookie(address_t address, size_t maxReplyLen);
|
||||
virtual ~TestCookie();
|
||||
|
||||
address_t getAddress() const;
|
||||
size_t getReplyMaxLen() const;
|
||||
private:
|
||||
address_t address = 0;
|
||||
size_t replyMaxLen = 0;
|
||||
address_t getAddress() const;
|
||||
size_t getReplyMaxLen() const;
|
||||
|
||||
private:
|
||||
address_t address = 0;
|
||||
size_t replyMaxLen = 0;
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_TESTCOOKIE_H_ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,6 @@
|
||||
#define TEST_TESTDEVICES_TESTDEVICEHANDLER_H_
|
||||
|
||||
#include "devicedefinitions/testDeviceDefinitions.h"
|
||||
|
||||
#include "fsfw/devicehandlers/DeviceHandlerBase.h"
|
||||
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
||||
#include "fsfw/timemanager/Countdown.h"
|
||||
@ -22,121 +21,114 @@
|
||||
* @author R. Mueller
|
||||
* @ingroup devices
|
||||
*/
|
||||
class TestDevice: public DeviceHandlerBase {
|
||||
public:
|
||||
/**
|
||||
* Build the test device in the factory.
|
||||
* @param objectId This ID will be assigned to the test device handler.
|
||||
* @param comIF The ID of the Communication IF used by test device handler.
|
||||
* @param cookie Cookie object used by the test device handler. This is
|
||||
* also used and passed to the comIF object.
|
||||
* @param onImmediately This will start a transition to MODE_ON immediately
|
||||
* so the device handler jumps into #doStartUp. Should only be used
|
||||
* in development to reduce need of commanding while debugging.
|
||||
* @param changingDataset
|
||||
* Will be used later to change the local datasets containeds in the device.
|
||||
*/
|
||||
TestDevice(object_id_t objectId, object_id_t comIF, CookieIF * cookie,
|
||||
testdevice::DeviceIndex deviceIdx = testdevice::DeviceIndex::DEVICE_0,
|
||||
bool fullInfoPrintout = false, bool changingDataset = true);
|
||||
class TestDevice : public DeviceHandlerBase {
|
||||
public:
|
||||
/**
|
||||
* Build the test device in the factory.
|
||||
* @param objectId This ID will be assigned to the test device handler.
|
||||
* @param comIF The ID of the Communication IF used by test device handler.
|
||||
* @param cookie Cookie object used by the test device handler. This is
|
||||
* also used and passed to the comIF object.
|
||||
* @param onImmediately This will start a transition to MODE_ON immediately
|
||||
* so the device handler jumps into #doStartUp. Should only be used
|
||||
* in development to reduce need of commanding while debugging.
|
||||
* @param changingDataset
|
||||
* Will be used later to change the local datasets containeds in the device.
|
||||
*/
|
||||
TestDevice(object_id_t objectId, object_id_t comIF, CookieIF* cookie,
|
||||
testdevice::DeviceIndex deviceIdx = testdevice::DeviceIndex::DEVICE_0,
|
||||
bool fullInfoPrintout = false, bool changingDataset = true);
|
||||
|
||||
/**
|
||||
* This can be used to enable and disable a lot of demo print output.
|
||||
* @param enable
|
||||
*/
|
||||
void enableFullDebugOutput(bool enable);
|
||||
/**
|
||||
* This can be used to enable and disable a lot of demo print output.
|
||||
* @param enable
|
||||
*/
|
||||
void enableFullDebugOutput(bool enable);
|
||||
|
||||
virtual ~ TestDevice();
|
||||
virtual ~TestDevice();
|
||||
|
||||
//! Size of internal buffer used for communication.
|
||||
static constexpr uint8_t MAX_BUFFER_SIZE = 255;
|
||||
//! Size of internal buffer used for communication.
|
||||
static constexpr uint8_t MAX_BUFFER_SIZE = 255;
|
||||
|
||||
//! Unique index if the device handler is created multiple times.
|
||||
testdevice::DeviceIndex deviceIdx = testdevice::DeviceIndex::DEVICE_0;
|
||||
//! Unique index if the device handler is created multiple times.
|
||||
testdevice::DeviceIndex deviceIdx = testdevice::DeviceIndex::DEVICE_0;
|
||||
|
||||
protected:
|
||||
testdevice::TestDataSet dataset;
|
||||
//! This is used to reset the dataset after a commanded change has been made.
|
||||
bool resetAfterChange = false;
|
||||
bool commandSent = false;
|
||||
protected:
|
||||
testdevice::TestDataSet dataset;
|
||||
//! This is used to reset the dataset after a commanded change has been made.
|
||||
bool resetAfterChange = false;
|
||||
bool commandSent = false;
|
||||
|
||||
/** DeviceHandlerBase overrides (see DHB documentation) */
|
||||
/** DeviceHandlerBase overrides (see DHB documentation) */
|
||||
|
||||
/**
|
||||
* Hook into the DHB #performOperation call which is executed
|
||||
* periodically.
|
||||
*/
|
||||
void performOperationHook() override;
|
||||
/**
|
||||
* Hook into the DHB #performOperation call which is executed
|
||||
* periodically.
|
||||
*/
|
||||
void performOperationHook() override;
|
||||
|
||||
virtual void doStartUp() override;
|
||||
virtual void doShutDown() override;
|
||||
virtual void doStartUp() override;
|
||||
virtual void doShutDown() override;
|
||||
|
||||
virtual ReturnValue_t buildNormalDeviceCommand(
|
||||
DeviceCommandId_t * id) override;
|
||||
virtual ReturnValue_t buildTransitionDeviceCommand(
|
||||
DeviceCommandId_t * id) override;
|
||||
virtual ReturnValue_t buildCommandFromCommand(DeviceCommandId_t
|
||||
deviceCommand, const uint8_t * commandData,
|
||||
size_t commandDataLen) override;
|
||||
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
|
||||
virtual ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override;
|
||||
virtual ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
||||
const uint8_t* commandData,
|
||||
size_t commandDataLen) override;
|
||||
|
||||
virtual void fillCommandAndReplyMap() override;
|
||||
virtual void fillCommandAndReplyMap() override;
|
||||
|
||||
virtual ReturnValue_t scanForReply(const uint8_t *start, size_t len,
|
||||
DeviceCommandId_t *foundId, size_t *foundLen) override;
|
||||
virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id,
|
||||
const uint8_t *packet) override;
|
||||
virtual uint32_t getTransitionDelayMs(Mode_t modeFrom,
|
||||
Mode_t modeTo) override;
|
||||
virtual ReturnValue_t scanForReply(const uint8_t* start, size_t len, DeviceCommandId_t* foundId,
|
||||
size_t* foundLen) override;
|
||||
virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override;
|
||||
virtual uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||
|
||||
virtual void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override;
|
||||
virtual void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override;
|
||||
|
||||
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
virtual LocalPoolObjectBase* getPoolObjectHandle(lp_id_t localPoolId) override;
|
||||
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
virtual LocalPoolObjectBase* getPoolObjectHandle(lp_id_t localPoolId) override;
|
||||
|
||||
/* HasParametersIF overrides */
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper *parameterWrapper,
|
||||
const ParameterWrapper *newValues, uint16_t startAtIndex) override;
|
||||
/* HasParametersIF overrides */
|
||||
virtual ReturnValue_t getParameter(uint8_t domainId, uint8_t uniqueId,
|
||||
ParameterWrapper* parameterWrapper,
|
||||
const ParameterWrapper* newValues,
|
||||
uint16_t startAtIndex) override;
|
||||
|
||||
uint8_t commandBuffer[MAX_BUFFER_SIZE];
|
||||
uint8_t commandBuffer[MAX_BUFFER_SIZE];
|
||||
|
||||
bool fullInfoPrintout = false;
|
||||
bool oneShot = true;
|
||||
bool fullInfoPrintout = false;
|
||||
bool oneShot = true;
|
||||
|
||||
/* Variables for parameter service */
|
||||
uint32_t testParameter0 = 0;
|
||||
int32_t testParameter1 = -2;
|
||||
float vectorFloatParams2[3] = {};
|
||||
/* Variables for parameter service */
|
||||
uint32_t testParameter0 = 0;
|
||||
int32_t testParameter1 = -2;
|
||||
float vectorFloatParams2[3] = {};
|
||||
|
||||
/* Change device handler functionality, changeable via parameter service */
|
||||
uint8_t periodicPrintout = false;
|
||||
uint8_t changingDatasets = false;
|
||||
/* Change device handler functionality, changeable via parameter service */
|
||||
uint8_t periodicPrintout = false;
|
||||
uint8_t changingDatasets = false;
|
||||
|
||||
ReturnValue_t buildNormalModeCommand(DeviceCommandId_t deviceCommand,
|
||||
const uint8_t* commandData, size_t commandDataLen);
|
||||
ReturnValue_t buildTestCommand0(DeviceCommandId_t deviceCommand, const uint8_t* commandData,
|
||||
size_t commandDataLen);
|
||||
ReturnValue_t buildTestCommand1(DeviceCommandId_t deviceCommand, const uint8_t* commandData,
|
||||
size_t commandDataLen);
|
||||
void passOnCommand(DeviceCommandId_t command, const uint8_t* commandData,
|
||||
size_t commandDataLen);
|
||||
ReturnValue_t buildNormalModeCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData,
|
||||
size_t commandDataLen);
|
||||
ReturnValue_t buildTestCommand0(DeviceCommandId_t deviceCommand, const uint8_t* commandData,
|
||||
size_t commandDataLen);
|
||||
ReturnValue_t buildTestCommand1(DeviceCommandId_t deviceCommand, const uint8_t* commandData,
|
||||
size_t commandDataLen);
|
||||
void passOnCommand(DeviceCommandId_t command, const uint8_t* commandData, size_t commandDataLen);
|
||||
|
||||
ReturnValue_t interpretingNormalModeReply();
|
||||
ReturnValue_t interpretingTestReply0(DeviceCommandId_t id,
|
||||
const uint8_t* packet);
|
||||
ReturnValue_t interpretingTestReply1(DeviceCommandId_t id,
|
||||
const uint8_t* packet);
|
||||
ReturnValue_t interpretingTestReply2(DeviceCommandId_t id, const uint8_t* packet);
|
||||
ReturnValue_t interpretingNormalModeReply();
|
||||
ReturnValue_t interpretingTestReply0(DeviceCommandId_t id, const uint8_t* packet);
|
||||
ReturnValue_t interpretingTestReply1(DeviceCommandId_t id, const uint8_t* packet);
|
||||
ReturnValue_t interpretingTestReply2(DeviceCommandId_t id, const uint8_t* packet);
|
||||
|
||||
/* Some timer utilities */
|
||||
uint8_t divider1 = 2;
|
||||
PeriodicOperationDivider opDivider1 = PeriodicOperationDivider(divider1);
|
||||
uint8_t divider2 = 10;
|
||||
PeriodicOperationDivider opDivider2 = PeriodicOperationDivider(divider2);
|
||||
static constexpr uint32_t initTimeout = 2000;
|
||||
Countdown countdown1 = Countdown(initTimeout);
|
||||
/* Some timer utilities */
|
||||
uint8_t divider1 = 2;
|
||||
PeriodicOperationDivider opDivider1 = PeriodicOperationDivider(divider1);
|
||||
uint8_t divider2 = 10;
|
||||
PeriodicOperationDivider opDivider2 = PeriodicOperationDivider(divider2);
|
||||
static constexpr uint32_t initTimeout = 2000;
|
||||
Countdown countdown1 = Countdown(initTimeout);
|
||||
};
|
||||
|
||||
|
||||
#endif /* TEST_TESTDEVICES_TESTDEVICEHANDLER_H_ */
|
||||
|
@ -1,86 +1,82 @@
|
||||
#include "TestEchoComIF.h"
|
||||
#include "TestCookie.h"
|
||||
|
||||
#include <fsfw/serialize/SerializeAdapter.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
||||
#include <fsfw/tmtcpacket/pus/tm.h>
|
||||
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
||||
|
||||
#include "TestCookie.h"
|
||||
|
||||
TestEchoComIF::TestEchoComIF(object_id_t objectId):
|
||||
SystemObject(objectId) {
|
||||
}
|
||||
TestEchoComIF::TestEchoComIF(object_id_t objectId) : SystemObject(objectId) {}
|
||||
|
||||
TestEchoComIF::~TestEchoComIF() {}
|
||||
|
||||
ReturnValue_t TestEchoComIF::initializeInterface(CookieIF * cookie) {
|
||||
TestCookie* dummyCookie = dynamic_cast<TestCookie*>(cookie);
|
||||
if(dummyCookie == nullptr) {
|
||||
ReturnValue_t TestEchoComIF::initializeInterface(CookieIF *cookie) {
|
||||
TestCookie *dummyCookie = dynamic_cast<TestCookie *>(cookie);
|
||||
if (dummyCookie == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "TestEchoComIF::initializeInterface: Invalid cookie!" << std::endl;
|
||||
sif::warning << "TestEchoComIF::initializeInterface: Invalid cookie!" << std::endl;
|
||||
#else
|
||||
sif::printWarning("TestEchoComIF::initializeInterface: Invalid cookie!\n");
|
||||
sif::printWarning("TestEchoComIF::initializeInterface: Invalid cookie!\n");
|
||||
#endif
|
||||
return NULLPOINTER;
|
||||
}
|
||||
return NULLPOINTER;
|
||||
}
|
||||
|
||||
auto resultPair = replyMap.emplace(
|
||||
dummyCookie->getAddress(), ReplyBuffer(dummyCookie->getReplyMaxLen()));
|
||||
if(not resultPair.second) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return RETURN_OK;
|
||||
auto resultPair =
|
||||
replyMap.emplace(dummyCookie->getAddress(), ReplyBuffer(dummyCookie->getReplyMaxLen()));
|
||||
if (not resultPair.second) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t TestEchoComIF::sendMessage(CookieIF *cookie,
|
||||
const uint8_t * sendData, size_t sendLen) {
|
||||
TestCookie* dummyCookie = dynamic_cast<TestCookie*>(cookie);
|
||||
if(dummyCookie == nullptr) {
|
||||
return NULLPOINTER;
|
||||
}
|
||||
ReturnValue_t TestEchoComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData,
|
||||
size_t sendLen) {
|
||||
TestCookie *dummyCookie = dynamic_cast<TestCookie *>(cookie);
|
||||
if (dummyCookie == nullptr) {
|
||||
return NULLPOINTER;
|
||||
}
|
||||
|
||||
ReplyBuffer& replyBuffer = replyMap.find(dummyCookie->getAddress())->second;
|
||||
if(sendLen > replyBuffer.capacity()) {
|
||||
ReplyBuffer &replyBuffer = replyMap.find(dummyCookie->getAddress())->second;
|
||||
if (sendLen > replyBuffer.capacity()) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "TestEchoComIF::sendMessage: Send length " << sendLen << " larger than "
|
||||
"current reply buffer length!" << std::endl;
|
||||
sif::warning << "TestEchoComIF::sendMessage: Send length " << sendLen
|
||||
<< " larger than "
|
||||
"current reply buffer length!"
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printWarning("TestEchoComIF::sendMessage: Send length %d larger than current "
|
||||
"reply buffer length!\n", sendLen);
|
||||
sif::printWarning(
|
||||
"TestEchoComIF::sendMessage: Send length %d larger than current "
|
||||
"reply buffer length!\n",
|
||||
sendLen);
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
replyBuffer.resize(sendLen);
|
||||
memcpy(replyBuffer.data(), sendData, sendLen);
|
||||
return RETURN_OK;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
replyBuffer.resize(sendLen);
|
||||
memcpy(replyBuffer.data(), sendData, sendLen);
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t TestEchoComIF::getSendSuccess(CookieIF *cookie) {
|
||||
return RETURN_OK;
|
||||
ReturnValue_t TestEchoComIF::getSendSuccess(CookieIF *cookie) { return RETURN_OK; }
|
||||
|
||||
ReturnValue_t TestEchoComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLen) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t TestEchoComIF::requestReceiveMessage(CookieIF *cookie,
|
||||
size_t requestLen) {
|
||||
return RETURN_OK;
|
||||
ReturnValue_t TestEchoComIF::readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t *size) {
|
||||
TestCookie *dummyCookie = dynamic_cast<TestCookie *>(cookie);
|
||||
if (dummyCookie == nullptr) {
|
||||
return NULLPOINTER;
|
||||
}
|
||||
|
||||
ReplyBuffer &replyBuffer = replyMap.find(dummyCookie->getAddress())->second;
|
||||
*buffer = replyBuffer.data();
|
||||
*size = replyBuffer.size();
|
||||
|
||||
dummyReplyCounter++;
|
||||
if (dummyReplyCounter == 10) {
|
||||
// add anything that needs to be read periodically by dummy handler
|
||||
dummyReplyCounter = 0;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t TestEchoComIF::readReceivedMessage(CookieIF *cookie,
|
||||
uint8_t **buffer, size_t *size) {
|
||||
TestCookie* dummyCookie = dynamic_cast<TestCookie*>(cookie);
|
||||
if(dummyCookie == nullptr) {
|
||||
return NULLPOINTER;
|
||||
}
|
||||
|
||||
ReplyBuffer& replyBuffer = replyMap.find(dummyCookie->getAddress())->second;
|
||||
*buffer = replyBuffer.data();
|
||||
*size = replyBuffer.size();
|
||||
|
||||
dummyReplyCounter ++;
|
||||
if(dummyReplyCounter == 10) {
|
||||
// add anything that needs to be read periodically by dummy handler
|
||||
dummyReplyCounter = 0;
|
||||
}
|
||||
return RETURN_OK;
|
||||
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,8 @@
|
||||
#define TEST_TESTDEVICES_TESTECHOCOMIF_H_
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw/ipc/MessageQueueIF.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw/tmtcservices/AcceptsTelemetryIF.h>
|
||||
|
||||
#include <vector>
|
||||
@ -13,44 +13,40 @@
|
||||
* @details Assign this com IF in the factory when creating the device handler
|
||||
* @ingroup test
|
||||
*/
|
||||
class TestEchoComIF: public DeviceCommunicationIF, public SystemObject {
|
||||
public:
|
||||
TestEchoComIF(object_id_t objectId);
|
||||
virtual ~TestEchoComIF();
|
||||
class TestEchoComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
public:
|
||||
TestEchoComIF(object_id_t objectId);
|
||||
virtual ~TestEchoComIF();
|
||||
|
||||
/**
|
||||
* DeviceCommunicationIF overrides
|
||||
* (see DeviceCommunicationIF documentation
|
||||
*/
|
||||
ReturnValue_t initializeInterface(CookieIF * cookie) override;
|
||||
ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t * sendData,
|
||||
size_t sendLen) override;
|
||||
ReturnValue_t getSendSuccess(CookieIF *cookie) override;
|
||||
ReturnValue_t requestReceiveMessage(CookieIF *cookie,
|
||||
size_t requestLen) override;
|
||||
ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer,
|
||||
size_t *size) override;
|
||||
/**
|
||||
* DeviceCommunicationIF overrides
|
||||
* (see DeviceCommunicationIF documentation
|
||||
*/
|
||||
ReturnValue_t initializeInterface(CookieIF *cookie) override;
|
||||
ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) override;
|
||||
ReturnValue_t getSendSuccess(CookieIF *cookie) override;
|
||||
ReturnValue_t requestReceiveMessage(CookieIF *cookie, size_t requestLen) override;
|
||||
ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t *size) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
/**
|
||||
* Send TM packet which contains received data as TM[17,130].
|
||||
* Wiretapping will do the same.
|
||||
* @param data
|
||||
* @param len
|
||||
*/
|
||||
void sendTmPacket(const uint8_t *data, uint32_t len);
|
||||
|
||||
/**
|
||||
* Send TM packet which contains received data as TM[17,130].
|
||||
* Wiretapping will do the same.
|
||||
* @param data
|
||||
* @param len
|
||||
*/
|
||||
void sendTmPacket(const uint8_t *data,uint32_t len);
|
||||
AcceptsTelemetryIF *funnel = nullptr;
|
||||
MessageQueueIF *tmQueue = nullptr;
|
||||
size_t replyMaxLen = 0;
|
||||
|
||||
AcceptsTelemetryIF* funnel = nullptr;
|
||||
MessageQueueIF* tmQueue = nullptr;
|
||||
size_t replyMaxLen = 0;
|
||||
using ReplyBuffer = std::vector<uint8_t>;
|
||||
std::map<address_t, ReplyBuffer> replyMap;
|
||||
|
||||
using ReplyBuffer = std::vector<uint8_t>;
|
||||
std::map<address_t, ReplyBuffer> replyMap;
|
||||
uint8_t dummyReplyCounter = 0;
|
||||
|
||||
uint8_t dummyReplyCounter = 0;
|
||||
|
||||
uint16_t packetSubCounter = 0;
|
||||
uint16_t packetSubCounter = 0;
|
||||
};
|
||||
|
||||
#endif /* TEST_TESTDEVICES_TESTECHOCOMIF_H_ */
|
||||
|
@ -6,18 +6,15 @@
|
||||
|
||||
namespace testdevice {
|
||||
|
||||
enum ParameterUniqueIds: uint8_t {
|
||||
TEST_UINT32_0,
|
||||
TEST_INT32_1,
|
||||
TEST_FLOAT_VEC3_2,
|
||||
PERIODIC_PRINT_ENABLED,
|
||||
CHANGING_DATASETS
|
||||
enum ParameterUniqueIds : uint8_t {
|
||||
TEST_UINT32_0,
|
||||
TEST_INT32_1,
|
||||
TEST_FLOAT_VEC3_2,
|
||||
PERIODIC_PRINT_ENABLED,
|
||||
CHANGING_DATASETS
|
||||
};
|
||||
|
||||
enum DeviceIndex: uint32_t {
|
||||
DEVICE_0,
|
||||
DEVICE_1
|
||||
};
|
||||
enum DeviceIndex : uint32_t { DEVICE_0, DEVICE_1 };
|
||||
|
||||
/** Normal mode command. This ID is also used to access the set variable via the housekeeping
|
||||
service */
|
||||
@ -59,39 +56,34 @@ static constexpr DeviceCommandId_t TEST_SNAPSHOT = 5;
|
||||
//! Generates a random value for variable 1 of the dataset.
|
||||
static constexpr DeviceCommandId_t GENERATE_SET_VAR_1_RNG_VALUE = 6;
|
||||
|
||||
|
||||
/**
|
||||
* These parameters are sent back with the command ID as a data reply
|
||||
*/
|
||||
static constexpr uint16_t COMMAND_1_PARAM1 = 0xBAB0; //!< param1, 2 bytes
|
||||
static constexpr uint16_t COMMAND_1_PARAM1 = 0xBAB0; //!< param1, 2 bytes
|
||||
//! param2, 8 bytes
|
||||
static constexpr uint64_t COMMAND_1_PARAM2 = 0x000000524F42494E;
|
||||
|
||||
static constexpr size_t TEST_COMMAND_0_SIZE = sizeof(TEST_COMMAND_0);
|
||||
static constexpr size_t TEST_COMMAND_1_SIZE = sizeof(TEST_COMMAND_1) + sizeof(COMMAND_1_PARAM1) +
|
||||
sizeof(COMMAND_1_PARAM2);
|
||||
static constexpr size_t TEST_COMMAND_1_SIZE =
|
||||
sizeof(TEST_COMMAND_1) + sizeof(COMMAND_1_PARAM1) + sizeof(COMMAND_1_PARAM2);
|
||||
|
||||
enum PoolIds: lp_id_t {
|
||||
TEST_UINT8_ID = 0,
|
||||
TEST_UINT32_ID = 1,
|
||||
TEST_FLOAT_VEC_3_ID = 2
|
||||
};
|
||||
enum PoolIds : lp_id_t { TEST_UINT8_ID = 0, TEST_UINT32_ID = 1, TEST_FLOAT_VEC_3_ID = 2 };
|
||||
|
||||
static constexpr uint8_t TEST_SET_ID = TEST_NORMAL_MODE_CMD;
|
||||
|
||||
class TestDataSet: public StaticLocalDataSet<3> {
|
||||
public:
|
||||
TestDataSet(HasLocalDataPoolIF* owner): StaticLocalDataSet(owner, TEST_SET_ID) {}
|
||||
TestDataSet(object_id_t owner): StaticLocalDataSet(sid_t(owner, TEST_SET_ID)) {}
|
||||
class TestDataSet : public StaticLocalDataSet<3> {
|
||||
public:
|
||||
TestDataSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, TEST_SET_ID) {}
|
||||
TestDataSet(object_id_t owner) : StaticLocalDataSet(sid_t(owner, TEST_SET_ID)) {}
|
||||
|
||||
lp_var_t<uint8_t> testUint8Var = lp_var_t<uint8_t>(
|
||||
gp_id_t(this->getCreatorObjectId(), PoolIds::TEST_UINT8_ID), this);
|
||||
lp_var_t<uint32_t> testUint32Var = lp_var_t<uint32_t>(
|
||||
gp_id_t(this->getCreatorObjectId(), PoolIds::TEST_UINT32_ID), this);
|
||||
lp_vec_t<float ,3> testFloat3Vec = lp_vec_t<float, 3>(
|
||||
gp_id_t(this->getCreatorObjectId(), PoolIds::TEST_FLOAT_VEC_3_ID), this);
|
||||
lp_var_t<uint8_t> testUint8Var =
|
||||
lp_var_t<uint8_t>(gp_id_t(this->getCreatorObjectId(), PoolIds::TEST_UINT8_ID), this);
|
||||
lp_var_t<uint32_t> testUint32Var =
|
||||
lp_var_t<uint32_t>(gp_id_t(this->getCreatorObjectId(), PoolIds::TEST_UINT32_ID), this);
|
||||
lp_vec_t<float, 3> testFloat3Vec =
|
||||
lp_vec_t<float, 3>(gp_id_t(this->getCreatorObjectId(), PoolIds::TEST_FLOAT_VEC_3_ID), this);
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace testdevice
|
||||
|
||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_TESTDEVICEDEFINITIONS_H_ */
|
||||
|
@ -6,63 +6,58 @@
|
||||
bool TestTask::oneShotAction = true;
|
||||
MutexIF* TestTask::testLock = nullptr;
|
||||
|
||||
TestTask::TestTask(object_id_t objectId):
|
||||
SystemObject(objectId), testMode(testModes::A) {
|
||||
if(testLock == nullptr) {
|
||||
testLock = MutexFactory::instance()->createMutex();
|
||||
}
|
||||
IPCStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
TestTask::TestTask(object_id_t objectId) : SystemObject(objectId), testMode(testModes::A) {
|
||||
if (testLock == nullptr) {
|
||||
testLock = MutexFactory::instance()->createMutex();
|
||||
}
|
||||
IPCStore = ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
}
|
||||
|
||||
TestTask::~TestTask() {
|
||||
}
|
||||
TestTask::~TestTask() {}
|
||||
|
||||
ReturnValue_t TestTask::performOperation(uint8_t operationCode) {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
testLock->lockMutex(MutexIF::TimeoutType::WAITING, 20);
|
||||
if(oneShotAction) {
|
||||
// Add code here which should only be run once
|
||||
performOneShotAction();
|
||||
oneShotAction = false;
|
||||
}
|
||||
testLock->unlockMutex();
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
testLock->lockMutex(MutexIF::TimeoutType::WAITING, 20);
|
||||
if (oneShotAction) {
|
||||
// Add code here which should only be run once
|
||||
performOneShotAction();
|
||||
oneShotAction = false;
|
||||
}
|
||||
testLock->unlockMutex();
|
||||
|
||||
// Add code here which should only be run once per performOperation
|
||||
performPeriodicAction();
|
||||
// Add code here which should only be run once per performOperation
|
||||
performPeriodicAction();
|
||||
|
||||
// Add code here which should only be run on alternating cycles.
|
||||
if(testMode == testModes::A) {
|
||||
performActionA();
|
||||
testMode = testModes::B;
|
||||
}
|
||||
else if(testMode == testModes::B) {
|
||||
performActionB();
|
||||
testMode = testModes::A;
|
||||
}
|
||||
return result;
|
||||
// Add code here which should only be run on alternating cycles.
|
||||
if (testMode == testModes::A) {
|
||||
performActionA();
|
||||
testMode = testModes::B;
|
||||
} else if (testMode == testModes::B) {
|
||||
performActionB();
|
||||
testMode = testModes::A;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t TestTask::performOneShotAction() {
|
||||
/* Everything here will only be performed once. */
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
/* Everything here will only be performed once. */
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t TestTask::performPeriodicAction() {
|
||||
/* This is performed each task cycle */
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
return result;
|
||||
/* This is performed each task cycle */
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t TestTask::performActionA() {
|
||||
/* This is performed each alternating task cycle */
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
return result;
|
||||
/* This is performed each alternating task cycle */
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t TestTask::performActionB() {
|
||||
/* This is performed each alternating task cycle */
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
return result;
|
||||
/* This is performed each alternating task cycle */
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef MISSION_DEMO_TESTTASK_H_
|
||||
#define MISSION_DEMO_TESTTASK_H_
|
||||
|
||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw/storagemanager/StorageManagerIF.h>
|
||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||
|
||||
/**
|
||||
* @brief Test class for general C++ testing and any other code which will not be part of the
|
||||
@ -11,33 +11,27 @@
|
||||
* @details
|
||||
* Should not be used for board specific tests. Instead, a derived board test class should be used.
|
||||
*/
|
||||
class TestTask :
|
||||
public SystemObject,
|
||||
public ExecutableObjectIF,
|
||||
public HasReturnvaluesIF {
|
||||
public:
|
||||
TestTask(object_id_t objectId);
|
||||
virtual ~TestTask();
|
||||
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||
class TestTask : public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF {
|
||||
public:
|
||||
TestTask(object_id_t objectId);
|
||||
virtual ~TestTask();
|
||||
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||
|
||||
protected:
|
||||
virtual ReturnValue_t performOneShotAction();
|
||||
virtual ReturnValue_t performPeriodicAction();
|
||||
virtual ReturnValue_t performActionA();
|
||||
virtual ReturnValue_t performActionB();
|
||||
protected:
|
||||
virtual ReturnValue_t performOneShotAction();
|
||||
virtual ReturnValue_t performPeriodicAction();
|
||||
virtual ReturnValue_t performActionA();
|
||||
virtual ReturnValue_t performActionB();
|
||||
|
||||
enum testModes: uint8_t {
|
||||
A,
|
||||
B
|
||||
};
|
||||
enum testModes : uint8_t { A, B };
|
||||
|
||||
testModes testMode;
|
||||
bool testFlag = false;
|
||||
testModes testMode;
|
||||
bool testFlag = false;
|
||||
|
||||
private:
|
||||
static bool oneShotAction;
|
||||
static MutexIF* testLock;
|
||||
StorageManagerIF* IPCStore;
|
||||
private:
|
||||
static bool oneShotAction;
|
||||
static MutexIF* testLock;
|
||||
StorageManagerIF* IPCStore;
|
||||
};
|
||||
|
||||
#endif /* TESTTASK_H_ */
|
||||
|
@ -1,45 +1,41 @@
|
||||
#include "fsfw_tests/internal/InternalUnitTester.h"
|
||||
#include "fsfw_tests/internal/UnittDefinitions.h"
|
||||
|
||||
#include "fsfw_tests/internal/osal/testMq.h"
|
||||
#include "fsfw_tests/internal/osal/testSemaphore.h"
|
||||
#include "fsfw_tests/internal/osal/testMutex.h"
|
||||
#include "fsfw_tests/internal/serialize/IntTestSerialization.h"
|
||||
#include "fsfw_tests/internal/globalfunctions/TestArrayPrinter.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "fsfw_tests/internal/UnittDefinitions.h"
|
||||
#include "fsfw_tests/internal/globalfunctions/TestArrayPrinter.h"
|
||||
#include "fsfw_tests/internal/osal/testMq.h"
|
||||
#include "fsfw_tests/internal/osal/testMutex.h"
|
||||
#include "fsfw_tests/internal/osal/testSemaphore.h"
|
||||
#include "fsfw_tests/internal/serialize/IntTestSerialization.h"
|
||||
|
||||
InternalUnitTester::InternalUnitTester() {}
|
||||
|
||||
InternalUnitTester::~InternalUnitTester() {}
|
||||
|
||||
ReturnValue_t InternalUnitTester::performTests(
|
||||
const struct InternalUnitTester::TestConfig& testConfig) {
|
||||
const struct InternalUnitTester::TestConfig& testConfig) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "Running internal unit tests.. Error messages might follow" <<
|
||||
std::endl;
|
||||
sif::info << "Running internal unit tests.. Error messages might follow" << std::endl;
|
||||
#else
|
||||
sif::printInfo("Running internal unit tests..\n");
|
||||
sif::printInfo("Running internal unit tests..\n");
|
||||
#endif
|
||||
|
||||
testserialize::test_serialization();
|
||||
testmq::testMq();
|
||||
if(testConfig.testSemaphores) {
|
||||
testsemaph::testBinSemaph();
|
||||
testsemaph::testCountingSemaph();
|
||||
}
|
||||
testmutex::testMutex();
|
||||
if(testConfig.testArrayPrinter) {
|
||||
arrayprinter::testArrayPrinter();
|
||||
}
|
||||
testserialize::test_serialization();
|
||||
testmq::testMq();
|
||||
if (testConfig.testSemaphores) {
|
||||
testsemaph::testBinSemaph();
|
||||
testsemaph::testCountingSemaph();
|
||||
}
|
||||
testmutex::testMutex();
|
||||
if (testConfig.testArrayPrinter) {
|
||||
arrayprinter::testArrayPrinter();
|
||||
}
|
||||
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "Internal unit tests finished." << std::endl;
|
||||
sif::info << "Internal unit tests finished." << std::endl;
|
||||
#else
|
||||
sif::printInfo("Internal unit tests finished.\n");
|
||||
sif::printInfo("Internal unit tests finished.\n");
|
||||
#endif
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include "UnittDefinitions.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief Can be used for internal testing, for example for hardware specific
|
||||
* tests which can not be run on a host-machine.
|
||||
@ -14,22 +13,21 @@
|
||||
* which simply calls all other tests from other files manually.
|
||||
* Maybe there is a better way..
|
||||
*/
|
||||
class InternalUnitTester: public HasReturnvaluesIF {
|
||||
public:
|
||||
struct TestConfig {
|
||||
bool testArrayPrinter = false;
|
||||
bool testSemaphores = true;
|
||||
};
|
||||
class InternalUnitTester : public HasReturnvaluesIF {
|
||||
public:
|
||||
struct TestConfig {
|
||||
bool testArrayPrinter = false;
|
||||
bool testSemaphores = true;
|
||||
};
|
||||
|
||||
InternalUnitTester();
|
||||
virtual~ InternalUnitTester();
|
||||
InternalUnitTester();
|
||||
virtual ~InternalUnitTester();
|
||||
|
||||
/**
|
||||
* Some function which calls all other tests
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t performTests(const struct InternalUnitTester::TestConfig& testConfig);
|
||||
/**
|
||||
* Some function which calls all other tests
|
||||
* @return
|
||||
*/
|
||||
virtual ReturnValue_t performTests(const struct InternalUnitTester::TestConfig& testConfig);
|
||||
};
|
||||
|
||||
|
||||
#endif /* FRAMEWORK_TEST_UNITTESTCLASS_H_ */
|
||||
|
@ -1,11 +1,10 @@
|
||||
#include "fsfw_tests/internal/UnittDefinitions.h"
|
||||
|
||||
ReturnValue_t unitt::put_error(std::string errorId) {
|
||||
ReturnValue_t unitt::put_error(std::string errorId) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "Unit Tester error: Failed at test ID "
|
||||
<< errorId << std::endl;
|
||||
sif::error << "Unit Tester error: Failed at test ID " << errorId << std::endl;
|
||||
#else
|
||||
sif::printError("Unit Tester error: Failed at test ID %s\n", errorId.c_str());
|
||||
sif::printError("Unit Tester error: Failed at test ID %s\n", errorId.c_str());
|
||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
@ -1,35 +1,33 @@
|
||||
#ifndef UNITTEST_INTERNAL_UNITTDEFINITIONS_H_
|
||||
#define UNITTEST_INTERNAL_UNITTDEFINITIONS_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
namespace tv {
|
||||
// POD test values
|
||||
static const bool tv_bool = true;
|
||||
static const uint8_t tv_uint8 {5};
|
||||
static const uint16_t tv_uint16 {283};
|
||||
static const uint32_t tv_uint32 {929221};
|
||||
static const uint64_t tv_uint64 {2929329429};
|
||||
static const uint8_t tv_uint8{5};
|
||||
static const uint16_t tv_uint16{283};
|
||||
static const uint32_t tv_uint32{929221};
|
||||
static const uint64_t tv_uint64{2929329429};
|
||||
|
||||
static const int8_t tv_int8 {-16};
|
||||
static const int16_t tv_int16 {-829};
|
||||
static const int32_t tv_int32 {-2312};
|
||||
static const int8_t tv_int8{-16};
|
||||
static const int16_t tv_int16{-829};
|
||||
static const int32_t tv_int32{-2312};
|
||||
|
||||
static const float tv_float {8.2149214};
|
||||
static const float tv_float{8.2149214};
|
||||
static const float tv_sfloat = {-922.2321321};
|
||||
static const double tv_double {9.2132142141e8};
|
||||
static const double tv_sdouble {-2.2421e19};
|
||||
}
|
||||
static const double tv_double{9.2132142141e8};
|
||||
static const double tv_sdouble{-2.2421e19};
|
||||
} // namespace tv
|
||||
|
||||
namespace unitt {
|
||||
ReturnValue_t put_error(std::string errorId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* UNITTEST_INTERNAL_UNITTDEFINITIONS_H_ */
|
||||
|
@ -1,29 +1,28 @@
|
||||
#include "fsfw_tests/internal/globalfunctions/TestArrayPrinter.h"
|
||||
|
||||
void arrayprinter::testArrayPrinter() {
|
||||
{
|
||||
const std::array<uint8_t, 5> testDataSmall = {0x01, 0x02, 0x03, 0x04, 0x05};
|
||||
arrayprinter::print(testDataSmall.data(), testDataSmall.size());
|
||||
arrayprinter::print(testDataSmall.data(), testDataSmall.size(), OutputType::DEC);
|
||||
arrayprinter::print(testDataSmall.data(), testDataSmall.size(), OutputType::BIN);
|
||||
}
|
||||
{
|
||||
const std::array<uint8_t, 5> testDataSmall = {0x01, 0x02, 0x03, 0x04, 0x05};
|
||||
arrayprinter::print(testDataSmall.data(), testDataSmall.size());
|
||||
arrayprinter::print(testDataSmall.data(), testDataSmall.size(), OutputType::DEC);
|
||||
arrayprinter::print(testDataSmall.data(), testDataSmall.size(), OutputType::BIN);
|
||||
}
|
||||
|
||||
{
|
||||
std::array<uint8_t, 16> testDataMed;
|
||||
for(size_t idx = 0; idx < testDataMed.size(); idx ++) {
|
||||
testDataMed[idx] = testDataMed.size() - idx;
|
||||
}
|
||||
arrayprinter::print(testDataMed.data(), testDataMed.size());
|
||||
arrayprinter::print(testDataMed.data(), testDataMed.size(), OutputType::DEC, 8);
|
||||
{
|
||||
std::array<uint8_t, 16> testDataMed;
|
||||
for (size_t idx = 0; idx < testDataMed.size(); idx++) {
|
||||
testDataMed[idx] = testDataMed.size() - idx;
|
||||
}
|
||||
arrayprinter::print(testDataMed.data(), testDataMed.size());
|
||||
arrayprinter::print(testDataMed.data(), testDataMed.size(), OutputType::DEC, 8);
|
||||
}
|
||||
|
||||
{
|
||||
std::array<uint8_t, 32> testDataLarge;
|
||||
for(size_t idx = 0; idx < testDataLarge.size(); idx ++) {
|
||||
testDataLarge[idx] = idx;
|
||||
}
|
||||
arrayprinter::print(testDataLarge.data(), testDataLarge.size());
|
||||
arrayprinter::print(testDataLarge.data(), testDataLarge.size(), OutputType::DEC);
|
||||
{
|
||||
std::array<uint8_t, 32> testDataLarge;
|
||||
for (size_t idx = 0; idx < testDataLarge.size(); idx++) {
|
||||
testDataLarge[idx] = idx;
|
||||
}
|
||||
|
||||
arrayprinter::print(testDataLarge.data(), testDataLarge.size());
|
||||
arrayprinter::print(testDataLarge.data(), testDataLarge.size(), OutputType::DEC);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define FSFW_UNITTEST_INTERNAL_GLOBALFUNCTIONS_TESTARRAYPRINTER_H_
|
||||
|
||||
#include <fsfw/globalfunctions/arrayprinter.h>
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace arrayprinter {
|
||||
|
@ -1,52 +1,50 @@
|
||||
#include "testMq.h"
|
||||
#include "fsfw_tests/internal/UnittDefinitions.h"
|
||||
|
||||
#include <fsfw/ipc/MessageQueueIF.h>
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "fsfw_tests/internal/UnittDefinitions.h"
|
||||
|
||||
using retval = HasReturnvaluesIF;
|
||||
|
||||
void testmq::testMq() {
|
||||
std::string id = "[testMq]";
|
||||
MessageQueueIF* testSenderMq =
|
||||
QueueFactory::instance()->createMessageQueue(1);
|
||||
MessageQueueId_t testSenderMqId = testSenderMq->getId();
|
||||
std::string id = "[testMq]";
|
||||
MessageQueueIF* testSenderMq = QueueFactory::instance()->createMessageQueue(1);
|
||||
MessageQueueId_t testSenderMqId = testSenderMq->getId();
|
||||
|
||||
MessageQueueIF* testReceiverMq =
|
||||
QueueFactory::instance()->createMessageQueue(1);
|
||||
MessageQueueId_t testReceiverMqId = testReceiverMq->getId();
|
||||
std::array<uint8_t, 20> testData { 0 };
|
||||
testData[0] = 42;
|
||||
MessageQueueMessage testMessage(testData.data(), 1);
|
||||
testSenderMq->setDefaultDestination(testReceiverMqId);
|
||||
MessageQueueIF* testReceiverMq = QueueFactory::instance()->createMessageQueue(1);
|
||||
MessageQueueId_t testReceiverMqId = testReceiverMq->getId();
|
||||
std::array<uint8_t, 20> testData{0};
|
||||
testData[0] = 42;
|
||||
MessageQueueMessage testMessage(testData.data(), 1);
|
||||
testSenderMq->setDefaultDestination(testReceiverMqId);
|
||||
|
||||
auto result = testSenderMq->sendMessage(testReceiverMqId, &testMessage);
|
||||
if (result != retval::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
MessageQueueMessage recvMessage;
|
||||
result = testReceiverMq->receiveMessage(&recvMessage);
|
||||
if (result != retval::RETURN_OK or recvMessage.getData()[0] != 42) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
|
||||
auto result = testSenderMq->sendMessage(testReceiverMqId, &testMessage);
|
||||
if(result != retval::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
MessageQueueMessage recvMessage;
|
||||
result = testReceiverMq->receiveMessage(&recvMessage);
|
||||
if(result != retval::RETURN_OK or recvMessage.getData()[0] != 42) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
|
||||
result = testSenderMq->sendMessage(testReceiverMqId, &testMessage);
|
||||
if(result != retval::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
MessageQueueId_t senderId = 0;
|
||||
result = testReceiverMq->receiveMessage(&recvMessage,&senderId);
|
||||
if(result != retval::RETURN_OK or recvMessage.getData()[0] != 42) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
if(senderId != testSenderMqId) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
senderId = testReceiverMq->getLastPartner();
|
||||
if(senderId != testSenderMqId) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
result = testSenderMq->sendMessage(testReceiverMqId, &testMessage);
|
||||
if (result != retval::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
MessageQueueId_t senderId = 0;
|
||||
result = testReceiverMq->receiveMessage(&recvMessage, &senderId);
|
||||
if (result != retval::RETURN_OK or recvMessage.getData()[0] != 42) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
if (senderId != testSenderMqId) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
senderId = testReceiverMq->getLastPartner();
|
||||
if (senderId != testSenderMqId) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
}
|
||||
|
@ -5,5 +5,4 @@ namespace testmq {
|
||||
void testMq();
|
||||
}
|
||||
|
||||
|
||||
#endif /* UNITTEST_INTERNAL_INTESTMQ_H_ */
|
||||
|
@ -1,48 +1,48 @@
|
||||
#include "testMutex.h"
|
||||
#include "fsfw_tests/internal/UnittDefinitions.h"
|
||||
#include "fsfw/platform.h"
|
||||
|
||||
#include <fsfw/ipc/MutexFactory.h>
|
||||
|
||||
#include "fsfw/platform.h"
|
||||
#include "fsfw_tests/internal/UnittDefinitions.h"
|
||||
|
||||
#if defined PLATFORM_WIN || defined PLATFORM_UNIX
|
||||
#include "fsfw/osal/host/Mutex.h"
|
||||
|
||||
#include <thread>
|
||||
#include <future>
|
||||
#endif
|
||||
#include <thread>
|
||||
|
||||
#include "fsfw/osal/host/Mutex.h"
|
||||
#endif
|
||||
|
||||
void testmutex::testMutex() {
|
||||
std::string id = "[testMutex]";
|
||||
MutexIF* mutex = MutexFactory::instance()->createMutex();
|
||||
auto result = mutex->lockMutex(MutexIF::TimeoutType::POLLING);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
// timed_mutex from the C++ library specifies undefined behaviour if
|
||||
// the timed mutex is locked twice from the same thread.
|
||||
// TODO: we should pass a define like FSFW_OSAL_HOST to the build.
|
||||
std::string id = "[testMutex]";
|
||||
MutexIF* mutex = MutexFactory::instance()->createMutex();
|
||||
auto result = mutex->lockMutex(MutexIF::TimeoutType::POLLING);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
// timed_mutex from the C++ library specifies undefined behaviour if
|
||||
// the timed mutex is locked twice from the same thread.
|
||||
// TODO: we should pass a define like FSFW_OSAL_HOST to the build.
|
||||
#if defined PLATFORM_WIN || defined PLATFORM_UNIX
|
||||
// This calls the function from
|
||||
// another thread and stores the returnvalue in a future.
|
||||
auto future = std::async(&MutexIF::lockMutex, mutex, MutexIF::TimeoutType::WAITING, 1);
|
||||
result = future.get();
|
||||
// This calls the function from
|
||||
// another thread and stores the returnvalue in a future.
|
||||
auto future = std::async(&MutexIF::lockMutex, mutex, MutexIF::TimeoutType::WAITING, 1);
|
||||
result = future.get();
|
||||
#else
|
||||
result = mutex->lockMutex(MutexIF::TimeoutType::WAITING, 1);
|
||||
result = mutex->lockMutex(MutexIF::TimeoutType::WAITING, 1);
|
||||
#endif
|
||||
if(result != MutexIF::MUTEX_TIMEOUT) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
if (result != MutexIF::MUTEX_TIMEOUT) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
|
||||
result = mutex->unlockMutex();
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
result = mutex->unlockMutex();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
|
||||
#if !defined PLATFORM_WIN && !defined PLATFORM_UNIX
|
||||
result = mutex->unlockMutex();
|
||||
if(result != MutexIF::CURR_THREAD_DOES_NOT_OWN_MUTEX) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
result = mutex->unlockMutex();
|
||||
if (result != MutexIF::CURR_THREAD_DOES_NOT_OWN_MUTEX) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -5,6 +5,4 @@ namespace testmutex {
|
||||
void testMutex();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* UNITTEST_INTERNAL_INTTESTMUTEX_H_ */
|
||||
|
@ -1,165 +1,155 @@
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "testSemaphore.h"
|
||||
#include "fsfw_tests/internal/UnittDefinitions.h"
|
||||
|
||||
#include "fsfw/tasks/SemaphoreFactory.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include "fsfw/timemanager/Stopwatch.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include "fsfw/tasks/SemaphoreFactory.h"
|
||||
#include "fsfw/timemanager/Stopwatch.h"
|
||||
#include "fsfw_tests/internal/UnittDefinitions.h"
|
||||
|
||||
void testsemaph::testBinSemaph() {
|
||||
std::string id = "[BinSemaphore]";
|
||||
SemaphoreIF* binSemaph =
|
||||
SemaphoreFactory::instance()->createBinarySemaphore();
|
||||
if(binSemaph == nullptr) {
|
||||
return;
|
||||
}
|
||||
testBinSemaphoreImplementation(binSemaph, id);
|
||||
SemaphoreFactory::instance()->deleteSemaphore(binSemaph);
|
||||
std::string id = "[BinSemaphore]";
|
||||
SemaphoreIF* binSemaph = SemaphoreFactory::instance()->createBinarySemaphore();
|
||||
if (binSemaph == nullptr) {
|
||||
return;
|
||||
}
|
||||
testBinSemaphoreImplementation(binSemaph, id);
|
||||
SemaphoreFactory::instance()->deleteSemaphore(binSemaph);
|
||||
#if defined FSFW_OSAL_FREERTOS
|
||||
SemaphoreIF* binSemaphUsingTask =
|
||||
SemaphoreFactory::instance()->createBinarySemaphore(1);
|
||||
testBinSemaphoreImplementation(binSemaphUsingTask, id);
|
||||
SemaphoreFactory::instance()->deleteSemaphore(binSemaphUsingTask);
|
||||
SemaphoreIF* binSemaphUsingTask = SemaphoreFactory::instance()->createBinarySemaphore(1);
|
||||
testBinSemaphoreImplementation(binSemaphUsingTask, id);
|
||||
SemaphoreFactory::instance()->deleteSemaphore(binSemaphUsingTask);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void testsemaph::testCountingSemaph() {
|
||||
std::string id = "[CountingSemaph]";
|
||||
{
|
||||
// First test: create a binary semaphore by using a counting semaphore.
|
||||
SemaphoreIF* countingSemaph = SemaphoreFactory::instance()->
|
||||
createCountingSemaphore(1,1);
|
||||
if(countingSemaph == nullptr) {
|
||||
return;
|
||||
}
|
||||
testBinSemaphoreImplementation(countingSemaph, id);
|
||||
SemaphoreFactory::instance()->deleteSemaphore(countingSemaph);
|
||||
std::string id = "[CountingSemaph]";
|
||||
{
|
||||
// First test: create a binary semaphore by using a counting semaphore.
|
||||
SemaphoreIF* countingSemaph = SemaphoreFactory::instance()->createCountingSemaphore(1, 1);
|
||||
if (countingSemaph == nullptr) {
|
||||
return;
|
||||
}
|
||||
testBinSemaphoreImplementation(countingSemaph, id);
|
||||
SemaphoreFactory::instance()->deleteSemaphore(countingSemaph);
|
||||
#if defined FSFW_OSAL_FREERTOS
|
||||
countingSemaph = SemaphoreFactory::instance()->
|
||||
createCountingSemaphore(1, 1, 1);
|
||||
testBinSemaphoreImplementation(countingSemaph, id);
|
||||
SemaphoreFactory::instance()->deleteSemaphore(countingSemaph);
|
||||
countingSemaph = SemaphoreFactory::instance()->createCountingSemaphore(1, 1, 1);
|
||||
testBinSemaphoreImplementation(countingSemaph, id);
|
||||
SemaphoreFactory::instance()->deleteSemaphore(countingSemaph);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Second test: counting semaphore with count 3 and init count of 3.
|
||||
SemaphoreIF* countingSemaph = SemaphoreFactory::instance()->
|
||||
createCountingSemaphore(3,3);
|
||||
testCountingSemaphImplementation(countingSemaph, id);
|
||||
SemaphoreFactory::instance()->deleteSemaphore(countingSemaph);
|
||||
{
|
||||
// Second test: counting semaphore with count 3 and init count of 3.
|
||||
SemaphoreIF* countingSemaph = SemaphoreFactory::instance()->createCountingSemaphore(3, 3);
|
||||
testCountingSemaphImplementation(countingSemaph, id);
|
||||
SemaphoreFactory::instance()->deleteSemaphore(countingSemaph);
|
||||
#if defined FSFW_OSAL_FREERTOS
|
||||
countingSemaph = SemaphoreFactory::instance()->
|
||||
createCountingSemaphore(3, 0, 1);
|
||||
uint8_t semaphCount = countingSemaph->getSemaphoreCounter();
|
||||
if(semaphCount != 0) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
// release 3 times in a row
|
||||
for(int i = 0; i < 3; i++) {
|
||||
auto result = countingSemaph->release();
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
}
|
||||
testCountingSemaphImplementation(countingSemaph, id);
|
||||
SemaphoreFactory::instance()->deleteSemaphore(countingSemaph);
|
||||
countingSemaph = SemaphoreFactory::instance()->createCountingSemaphore(3, 0, 1);
|
||||
uint8_t semaphCount = countingSemaph->getSemaphoreCounter();
|
||||
if (semaphCount != 0) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
// release 3 times in a row
|
||||
for (int i = 0; i < 3; i++) {
|
||||
auto result = countingSemaph->release();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
}
|
||||
testCountingSemaphImplementation(countingSemaph, id);
|
||||
SemaphoreFactory::instance()->deleteSemaphore(countingSemaph);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void testsemaph::testBinSemaphoreImplementation(SemaphoreIF* binSemaph, std::string id) {
|
||||
uint8_t semaphCount = binSemaph->getSemaphoreCounter();
|
||||
if (semaphCount != 1) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
|
||||
void testsemaph::testBinSemaphoreImplementation(SemaphoreIF* binSemaph,
|
||||
std::string id) {
|
||||
uint8_t semaphCount = binSemaph->getSemaphoreCounter();
|
||||
if(semaphCount != 1) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
ReturnValue_t result = binSemaph->release();
|
||||
if (result != SemaphoreIF::SEMAPHORE_NOT_OWNED) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
result = binSemaph->acquire(SemaphoreIF::BLOCKING);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
|
||||
ReturnValue_t result = binSemaph->release();
|
||||
if(result != SemaphoreIF::SEMAPHORE_NOT_OWNED) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
result = binSemaph->acquire(SemaphoreIF::BLOCKING);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
|
||||
// There is not really a point in testing time related, the task
|
||||
// might get interrupted..
|
||||
{
|
||||
//Stopwatch stopwatch(false);
|
||||
result = binSemaph->acquire(SemaphoreIF::TimeoutType::WAITING, 10);
|
||||
//dur_millis_t time = stopwatch.stop();
|
||||
// There is not really a point in testing time related, the task
|
||||
// might get interrupted..
|
||||
{
|
||||
// Stopwatch stopwatch(false);
|
||||
result = binSemaph->acquire(SemaphoreIF::TimeoutType::WAITING, 10);
|
||||
// dur_millis_t time = stopwatch.stop();
|
||||
// if(abs(time - 10) > 2) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
// sif::error << "UnitTester: Semaphore timeout measured incorrect."
|
||||
// << std::endl;
|
||||
#endif
|
||||
// unitt::put_error(id);
|
||||
// }
|
||||
}
|
||||
// unitt::put_error(id);
|
||||
// }
|
||||
}
|
||||
|
||||
if(result != SemaphoreIF::SEMAPHORE_TIMEOUT) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
if (result != SemaphoreIF::SEMAPHORE_TIMEOUT) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
|
||||
semaphCount = binSemaph->getSemaphoreCounter();
|
||||
if(semaphCount != 0) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
semaphCount = binSemaph->getSemaphoreCounter();
|
||||
if (semaphCount != 0) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
|
||||
result = binSemaph->release();
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
result = binSemaph->release();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
}
|
||||
|
||||
void testsemaph::testCountingSemaphImplementation(SemaphoreIF* countingSemaph,
|
||||
std::string id) {
|
||||
// check count getter function
|
||||
uint8_t semaphCount = countingSemaph->getSemaphoreCounter();
|
||||
if(semaphCount != 3) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
ReturnValue_t result = countingSemaph->release();
|
||||
if(result != SemaphoreIF::SEMAPHORE_NOT_OWNED) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
// acquire 3 times in a row
|
||||
for(int i = 0; i < 3; i++) {
|
||||
result = countingSemaph->acquire(SemaphoreIF::BLOCKING);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
}
|
||||
void testsemaph::testCountingSemaphImplementation(SemaphoreIF* countingSemaph, std::string id) {
|
||||
// check count getter function
|
||||
uint8_t semaphCount = countingSemaph->getSemaphoreCounter();
|
||||
if (semaphCount != 3) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
ReturnValue_t result = countingSemaph->release();
|
||||
if (result != SemaphoreIF::SEMAPHORE_NOT_OWNED) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
// acquire 3 times in a row
|
||||
for (int i = 0; i < 3; i++) {
|
||||
result = countingSemaph->acquire(SemaphoreIF::BLOCKING);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Stopwatch stopwatch(false);
|
||||
// attempt to take when count is 0, measure time
|
||||
result = countingSemaph->acquire(SemaphoreIF::TimeoutType::WAITING, 10);
|
||||
dur_millis_t time = stopwatch.stop();
|
||||
if(std::abs(static_cast<int32_t>(time - 10)) > 1) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
}
|
||||
{
|
||||
Stopwatch stopwatch(false);
|
||||
// attempt to take when count is 0, measure time
|
||||
result = countingSemaph->acquire(SemaphoreIF::TimeoutType::WAITING, 10);
|
||||
dur_millis_t time = stopwatch.stop();
|
||||
if (std::abs(static_cast<int32_t>(time - 10)) > 1) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
}
|
||||
|
||||
if(result != SemaphoreIF::SEMAPHORE_TIMEOUT) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
if (result != SemaphoreIF::SEMAPHORE_TIMEOUT) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
|
||||
// release 3 times in a row
|
||||
for(int i = 0; i < 3; i++) {
|
||||
result = countingSemaph->release();
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
}
|
||||
// assert correct full count
|
||||
if(countingSemaph->getSemaphoreCounter() != 3) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
// release 3 times in a row
|
||||
for (int i = 0; i < 3; i++) {
|
||||
result = countingSemaph->release();
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
}
|
||||
// assert correct full count
|
||||
if (countingSemaph->getSemaphoreCounter() != 3) {
|
||||
unitt::put_error(id);
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,7 @@ namespace testsemaph {
|
||||
void testBinSemaph();
|
||||
void testBinSemaphoreImplementation(SemaphoreIF* binSemaph, std::string id);
|
||||
void testCountingSemaph();
|
||||
void testCountingSemaphImplementation(SemaphoreIF* countingSemaph,
|
||||
std::string id);
|
||||
}
|
||||
|
||||
void testCountingSemaphImplementation(SemaphoreIF* countingSemaph, std::string id);
|
||||
} // namespace testsemaph
|
||||
|
||||
#endif /* UNITTEST_INTERNAL_INTTESTSEMAPHORE_H_ */
|
||||
|
@ -1,232 +1,210 @@
|
||||
#include "fsfw_tests/internal/serialize/IntTestSerialization.h"
|
||||
#include "fsfw_tests/internal/UnittDefinitions.h"
|
||||
|
||||
#include <fsfw/serialize/SerializeElement.h>
|
||||
#include <fsfw/serialize/SerialBufferAdapter.h>
|
||||
#include <fsfw/serialize/SerializeElement.h>
|
||||
#include <fsfw/serialize/SerializeIF.h>
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "fsfw_tests/internal/UnittDefinitions.h"
|
||||
|
||||
using retval = HasReturnvaluesIF;
|
||||
std::array<uint8_t, 512> testserialize::test_array = { 0 };
|
||||
std::array<uint8_t, 512> testserialize::test_array = {0};
|
||||
|
||||
ReturnValue_t testserialize::test_serialization() {
|
||||
// Here, we test all serialization tools. First test basic cases.
|
||||
ReturnValue_t result = test_endianness_tools();
|
||||
if(result != retval::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = test_autoserialization();
|
||||
if(result != retval::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = test_serial_buffer_adapter();
|
||||
if(result != retval::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return retval::RETURN_OK;
|
||||
// Here, we test all serialization tools. First test basic cases.
|
||||
ReturnValue_t result = test_endianness_tools();
|
||||
if (result != retval::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = test_autoserialization();
|
||||
if (result != retval::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = test_serial_buffer_adapter();
|
||||
if (result != retval::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return retval::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t testserialize::test_endianness_tools() {
|
||||
std::string id = "[test_endianness_tools]";
|
||||
test_array[0] = 0;
|
||||
test_array[1] = 0;
|
||||
uint16_t two_byte_value = 1;
|
||||
size_t size = 0;
|
||||
uint8_t* p_array = test_array.data();
|
||||
SerializeAdapter::serialize(&two_byte_value, &p_array, &size, 2,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
// Little endian: Value one on first byte
|
||||
if(test_array[0] != 1 and test_array[1] != 0) {
|
||||
return unitt::put_error(id);
|
||||
std::string id = "[test_endianness_tools]";
|
||||
test_array[0] = 0;
|
||||
test_array[1] = 0;
|
||||
uint16_t two_byte_value = 1;
|
||||
size_t size = 0;
|
||||
uint8_t* p_array = test_array.data();
|
||||
SerializeAdapter::serialize(&two_byte_value, &p_array, &size, 2,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
// Little endian: Value one on first byte
|
||||
if (test_array[0] != 1 and test_array[1] != 0) {
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
p_array = test_array.data();
|
||||
size = 0;
|
||||
SerializeAdapter::serialize(&two_byte_value, &p_array, &size, 2,
|
||||
SerializeIF::Endianness::BIG);
|
||||
// Big endian: Value one on second byte
|
||||
if(test_array[0] != 0 and test_array[1] != 1) {
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
return retval::RETURN_OK;
|
||||
p_array = test_array.data();
|
||||
size = 0;
|
||||
SerializeAdapter::serialize(&two_byte_value, &p_array, &size, 2, SerializeIF::Endianness::BIG);
|
||||
// Big endian: Value one on second byte
|
||||
if (test_array[0] != 0 and test_array[1] != 1) {
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
return retval::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t testserialize::test_autoserialization() {
|
||||
std::string id = "[test_autoserialization]";
|
||||
// Unit Test getSerializedSize
|
||||
if(SerializeAdapter::
|
||||
getSerializedSize(&tv::tv_bool) != sizeof(tv::tv_bool) or
|
||||
SerializeAdapter::
|
||||
getSerializedSize(&tv::tv_uint8) != sizeof(tv::tv_uint8) or
|
||||
SerializeAdapter::
|
||||
getSerializedSize(&tv::tv_uint16) != sizeof(tv::tv_uint16) or
|
||||
SerializeAdapter::
|
||||
getSerializedSize(&tv::tv_uint32) != sizeof(tv::tv_uint32) or
|
||||
SerializeAdapter::
|
||||
getSerializedSize(&tv::tv_uint64) != sizeof(tv::tv_uint64) or
|
||||
SerializeAdapter::
|
||||
getSerializedSize(&tv::tv_int8) != sizeof(tv::tv_int8) or
|
||||
SerializeAdapter::
|
||||
getSerializedSize(&tv::tv_double) != sizeof(tv::tv_double) or
|
||||
SerializeAdapter::
|
||||
getSerializedSize(&tv::tv_int16) != sizeof(tv::tv_int16) or
|
||||
SerializeAdapter::
|
||||
getSerializedSize(&tv::tv_int32) != sizeof(tv::tv_int32) or
|
||||
SerializeAdapter::
|
||||
getSerializedSize(&tv::tv_float) != sizeof(tv::tv_float))
|
||||
{
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
std::string id = "[test_autoserialization]";
|
||||
// Unit Test getSerializedSize
|
||||
if (SerializeAdapter::getSerializedSize(&tv::tv_bool) != sizeof(tv::tv_bool) or
|
||||
SerializeAdapter::getSerializedSize(&tv::tv_uint8) != sizeof(tv::tv_uint8) or
|
||||
SerializeAdapter::getSerializedSize(&tv::tv_uint16) != sizeof(tv::tv_uint16) or
|
||||
SerializeAdapter::getSerializedSize(&tv::tv_uint32) != sizeof(tv::tv_uint32) or
|
||||
SerializeAdapter::getSerializedSize(&tv::tv_uint64) != sizeof(tv::tv_uint64) or
|
||||
SerializeAdapter::getSerializedSize(&tv::tv_int8) != sizeof(tv::tv_int8) or
|
||||
SerializeAdapter::getSerializedSize(&tv::tv_double) != sizeof(tv::tv_double) or
|
||||
SerializeAdapter::getSerializedSize(&tv::tv_int16) != sizeof(tv::tv_int16) or
|
||||
SerializeAdapter::getSerializedSize(&tv::tv_int32) != sizeof(tv::tv_int32) or
|
||||
SerializeAdapter::getSerializedSize(&tv::tv_float) != sizeof(tv::tv_float)) {
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
|
||||
size_t serialized_size = 0;
|
||||
uint8_t * p_array = test_array.data();
|
||||
size_t serialized_size = 0;
|
||||
uint8_t* p_array = test_array.data();
|
||||
|
||||
SerializeAdapter::serialize(&tv::tv_bool, &p_array,
|
||||
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_uint8, &p_array,
|
||||
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_uint16, &p_array,
|
||||
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_uint32, &p_array,
|
||||
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_int8, &p_array,
|
||||
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_int16, &p_array,
|
||||
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_int32, &p_array,
|
||||
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_uint64, &p_array,
|
||||
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_float, &p_array,
|
||||
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_double, &p_array,
|
||||
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_sfloat, &p_array,
|
||||
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_sdouble, &p_array,
|
||||
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
// expected size is 1 + 1 + 2 + 4 + 1 + 2 + 4 + 8 + 4 + 8 + 4 + 8
|
||||
if(serialized_size != 47) {
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
SerializeAdapter::serialize(&tv::tv_bool, &p_array, &serialized_size, test_array.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_uint8, &p_array, &serialized_size, test_array.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_uint16, &p_array, &serialized_size, test_array.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_uint32, &p_array, &serialized_size, test_array.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_int8, &p_array, &serialized_size, test_array.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_int16, &p_array, &serialized_size, test_array.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_int32, &p_array, &serialized_size, test_array.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_uint64, &p_array, &serialized_size, test_array.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_float, &p_array, &serialized_size, test_array.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_double, &p_array, &serialized_size, test_array.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_sfloat, &p_array, &serialized_size, test_array.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_sdouble, &p_array, &serialized_size, test_array.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
// expected size is 1 + 1 + 2 + 4 + 1 + 2 + 4 + 8 + 4 + 8 + 4 + 8
|
||||
if (serialized_size != 47) {
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
|
||||
p_array = test_array.data();
|
||||
size_t remaining_size = serialized_size;
|
||||
bool tv_bool;
|
||||
uint8_t tv_uint8;
|
||||
uint16_t tv_uint16;
|
||||
uint32_t tv_uint32;
|
||||
int8_t tv_int8;
|
||||
int16_t tv_int16;
|
||||
int32_t tv_int32;
|
||||
uint64_t tv_uint64;
|
||||
float tv_float;
|
||||
double tv_double;
|
||||
float tv_sfloat;
|
||||
double tv_sdouble;
|
||||
p_array = test_array.data();
|
||||
size_t remaining_size = serialized_size;
|
||||
bool tv_bool;
|
||||
uint8_t tv_uint8;
|
||||
uint16_t tv_uint16;
|
||||
uint32_t tv_uint32;
|
||||
int8_t tv_int8;
|
||||
int16_t tv_int16;
|
||||
int32_t tv_int32;
|
||||
uint64_t tv_uint64;
|
||||
float tv_float;
|
||||
double tv_double;
|
||||
float tv_sfloat;
|
||||
double tv_sdouble;
|
||||
|
||||
SerializeAdapter::deSerialize(&tv_bool,
|
||||
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_uint8,
|
||||
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_uint16,
|
||||
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_uint32,
|
||||
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_int8,
|
||||
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_int16,
|
||||
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_int32,
|
||||
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_uint64,
|
||||
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_float,
|
||||
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_double,
|
||||
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_sfloat,
|
||||
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_sdouble,
|
||||
const_cast<const uint8_t**>(&p_array), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_bool, const_cast<const uint8_t**>(&p_array), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_uint8, const_cast<const uint8_t**>(&p_array), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_uint16, const_cast<const uint8_t**>(&p_array), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_uint32, const_cast<const uint8_t**>(&p_array), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_int8, const_cast<const uint8_t**>(&p_array), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_int16, const_cast<const uint8_t**>(&p_array), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_int32, const_cast<const uint8_t**>(&p_array), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_uint64, const_cast<const uint8_t**>(&p_array), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_float, const_cast<const uint8_t**>(&p_array), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_double, const_cast<const uint8_t**>(&p_array), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_sfloat, const_cast<const uint8_t**>(&p_array), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tv_sdouble, const_cast<const uint8_t**>(&p_array), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
|
||||
if(tv_bool != tv::tv_bool or tv_uint8 != tv::tv_uint8 or
|
||||
tv_uint16 != tv::tv_uint16 or tv_uint32 != tv::tv_uint32 or
|
||||
tv_uint64 != tv::tv_uint64 or tv_int8 != tv::tv_int8 or
|
||||
tv_int16 != tv::tv_int16 or tv_int32 != tv::tv_int32)
|
||||
{
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
if (tv_bool != tv::tv_bool or tv_uint8 != tv::tv_uint8 or tv_uint16 != tv::tv_uint16 or
|
||||
tv_uint32 != tv::tv_uint32 or tv_uint64 != tv::tv_uint64 or tv_int8 != tv::tv_int8 or
|
||||
tv_int16 != tv::tv_int16 or tv_int32 != tv::tv_int32) {
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
|
||||
// These epsilon values were just guessed.. It appears to work though.
|
||||
if(abs(tv_float - tv::tv_float) > 0.0001 or
|
||||
abs(tv_double - tv::tv_double) > 0.01 or
|
||||
abs(tv_sfloat - tv::tv_sfloat) > 0.0001 or
|
||||
abs(tv_sdouble - tv::tv_sdouble) > 0.01) {
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
// These epsilon values were just guessed.. It appears to work though.
|
||||
if (abs(tv_float - tv::tv_float) > 0.0001 or abs(tv_double - tv::tv_double) > 0.01 or
|
||||
abs(tv_sfloat - tv::tv_sfloat) > 0.0001 or abs(tv_sdouble - tv::tv_sdouble) > 0.01) {
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
|
||||
// Check overflow
|
||||
return retval::RETURN_OK;
|
||||
// Check overflow
|
||||
return retval::RETURN_OK;
|
||||
}
|
||||
|
||||
// TODO: Also test for constant buffers.
|
||||
ReturnValue_t testserialize::test_serial_buffer_adapter() {
|
||||
std::string id = "[test_serial_buffer_adapter]";
|
||||
std::string id = "[test_serial_buffer_adapter]";
|
||||
|
||||
// I will skip endian swapper testing, its going to be changed anyway..
|
||||
// uint8_t tv::tv_uint8_swapped = EndianSwapper::swap(tv::tv_uint8);
|
||||
// I will skip endian swapper testing, its going to be changed anyway..
|
||||
// uint8_t tv::tv_uint8_swapped = EndianSwapper::swap(tv::tv_uint8);
|
||||
|
||||
size_t serialized_size = 0;
|
||||
uint8_t * p_array = test_array.data();
|
||||
std::array<uint8_t, 5> test_serial_buffer {5, 4, 3, 2, 1};
|
||||
SerialBufferAdapter<uint8_t> tv_serial_buffer_adapter =
|
||||
SerialBufferAdapter<uint8_t>(test_serial_buffer.data(),
|
||||
test_serial_buffer.size(), false);
|
||||
uint16_t testUint16 = 16;
|
||||
size_t serialized_size = 0;
|
||||
uint8_t* p_array = test_array.data();
|
||||
std::array<uint8_t, 5> test_serial_buffer{5, 4, 3, 2, 1};
|
||||
SerialBufferAdapter<uint8_t> tv_serial_buffer_adapter =
|
||||
SerialBufferAdapter<uint8_t>(test_serial_buffer.data(), test_serial_buffer.size(), false);
|
||||
uint16_t testUint16 = 16;
|
||||
|
||||
SerializeAdapter::serialize(&tv::tv_bool, &p_array,&serialized_size,
|
||||
test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv_serial_buffer_adapter, &p_array,
|
||||
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&testUint16, &p_array, &serialized_size,
|
||||
test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv::tv_bool, &p_array, &serialized_size, test_array.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv_serial_buffer_adapter, &p_array, &serialized_size,
|
||||
test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&testUint16, &p_array, &serialized_size, test_array.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
|
||||
if(serialized_size != 8 or test_array[0] != true or test_array[1] != 5
|
||||
or test_array[2] != 4 or test_array[3] != 3 or test_array[4] != 2
|
||||
or test_array[5] != 1)
|
||||
{
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
memcpy(&testUint16, test_array.data() + 6, sizeof(testUint16));
|
||||
if(testUint16 != 16) {
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
if (serialized_size != 8 or test_array[0] != true or test_array[1] != 5 or test_array[2] != 4 or
|
||||
test_array[3] != 3 or test_array[4] != 2 or test_array[5] != 1) {
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
memcpy(&testUint16, test_array.data() + 6, sizeof(testUint16));
|
||||
if (testUint16 != 16) {
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
|
||||
// Serialize with size field
|
||||
SerialBufferAdapter<uint8_t> tv_serial_buffer_adapter2 =
|
||||
SerialBufferAdapter<uint8_t>(test_serial_buffer.data(),
|
||||
test_serial_buffer.size(), true);
|
||||
serialized_size = 0;
|
||||
p_array = test_array.data();
|
||||
SerializeAdapter::serialize(&tv::tv_bool, &p_array,&serialized_size,
|
||||
test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv_serial_buffer_adapter2, &p_array,
|
||||
&serialized_size, test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&testUint16, &p_array, &serialized_size,
|
||||
test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
// Serialize with size field
|
||||
SerialBufferAdapter<uint8_t> tv_serial_buffer_adapter2 =
|
||||
SerialBufferAdapter<uint8_t>(test_serial_buffer.data(), test_serial_buffer.size(), true);
|
||||
serialized_size = 0;
|
||||
p_array = test_array.data();
|
||||
SerializeAdapter::serialize(&tv::tv_bool, &p_array, &serialized_size, test_array.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv_serial_buffer_adapter2, &p_array, &serialized_size,
|
||||
test_array.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&testUint16, &p_array, &serialized_size, test_array.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
|
||||
if(serialized_size != 9 or test_array[0] != true or test_array[1] != 5
|
||||
or test_array[2] != 5 or test_array[3] != 4 or test_array[4] != 3
|
||||
or test_array[5] != 2 or test_array[6] != 1)
|
||||
{
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
memcpy(&testUint16, test_array.data() + 7, sizeof(testUint16));
|
||||
if(testUint16 != 16) {
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
return retval::RETURN_OK;
|
||||
if (serialized_size != 9 or test_array[0] != true or test_array[1] != 5 or test_array[2] != 5 or
|
||||
test_array[3] != 4 or test_array[4] != 3 or test_array[5] != 2 or test_array[6] != 1) {
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
memcpy(&testUint16, test_array.data() + 7, sizeof(testUint16));
|
||||
if (testUint16 != 16) {
|
||||
return unitt::put_error(id);
|
||||
}
|
||||
return retval::RETURN_OK;
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
#ifndef FSFW_UNITTEST_INTERNAL_INTTESTSERIALIZATION_H_
|
||||
#define FSFW_UNITTEST_INTERNAL_INTTESTSERIALIZATION_H_
|
||||
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include <array>
|
||||
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
namespace testserialize {
|
||||
ReturnValue_t test_serialization();
|
||||
ReturnValue_t test_endianness_tools();
|
||||
@ -11,6 +12,6 @@ ReturnValue_t test_autoserialization();
|
||||
ReturnValue_t test_serial_buffer_adapter();
|
||||
|
||||
extern std::array<uint8_t, 512> test_array;
|
||||
}
|
||||
} // namespace testserialize
|
||||
|
||||
#endif /* FSFW_UNITTEST_INTERNAL_INTTESTSERIALIZATION_H_ */
|
||||
|
@ -1,16 +1,17 @@
|
||||
#include "CatchDefinitions.h"
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
|
||||
StorageManagerIF* tglob::getIpcStoreHandle() {
|
||||
if(ObjectManager::instance() != nullptr) {
|
||||
return ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
} else {
|
||||
if (ObjectManager::instance() != nullptr) {
|
||||
return ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);
|
||||
} else {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "Global object manager uninitialized" << std::endl;
|
||||
sif::error << "Global object manager uninitialized" << std::endl;
|
||||
#else
|
||||
sif::printError("Global object manager uninitialized\n\r");
|
||||
sif::printError("Global object manager uninitialized\n\r");
|
||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -8,14 +8,14 @@
|
||||
namespace retval {
|
||||
static constexpr int CATCH_OK = static_cast<int>(HasReturnvaluesIF::RETURN_OK);
|
||||
static constexpr int CATCH_FAILED = static_cast<int>(HasReturnvaluesIF::RETURN_FAILED);
|
||||
}
|
||||
} // namespace retval
|
||||
|
||||
namespace tconst {
|
||||
static constexpr MessageQueueId_t testQueueId = 42;
|
||||
static constexpr MessageQueueId_t testQueueId = 42;
|
||||
}
|
||||
|
||||
namespace tglob {
|
||||
StorageManagerIF* getIpcStoreHandle();
|
||||
StorageManagerIF* getIpcStoreHandle();
|
||||
}
|
||||
|
||||
#endif /* FSFW_UNITTEST_CORE_CATCHDEFINITIONS_H_ */
|
||||
|
@ -1,11 +1,7 @@
|
||||
#include "CatchFactory.h"
|
||||
#include "tests/TestsConfig.h"
|
||||
#include "datapoollocal/LocalPoolOwnerBase.h"
|
||||
#include "mocks/HkReceiverMock.h"
|
||||
|
||||
#include <fsfw/datapoollocal/LocalDataPoolManager.h>
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
|
||||
#include <fsfw/events/EventManager.h>
|
||||
#include <fsfw/health/HealthTable.h>
|
||||
#include <fsfw/internalerror/InternalErrorReporter.h>
|
||||
@ -15,6 +11,9 @@
|
||||
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
||||
#include <fsfw/tmtcservices/PusServiceBase.h>
|
||||
|
||||
#include "datapoollocal/LocalPoolOwnerBase.h"
|
||||
#include "mocks/HkReceiverMock.h"
|
||||
#include "tests/TestsConfig.h"
|
||||
|
||||
#if FSFW_ADD_DEFAULT_FACTORY_FUNCTIONS == 1
|
||||
|
||||
@ -32,53 +31,47 @@
|
||||
* @ingroup init
|
||||
*/
|
||||
void Factory::produceFrameworkObjects(void* args) {
|
||||
setStaticFrameworkObjectIds();
|
||||
new EventManager(objects::EVENT_MANAGER);
|
||||
new HealthTable(objects::HEALTH_TABLE);
|
||||
new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER);
|
||||
setStaticFrameworkObjectIds();
|
||||
new EventManager(objects::EVENT_MANAGER);
|
||||
new HealthTable(objects::HEALTH_TABLE);
|
||||
new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER);
|
||||
|
||||
new LocalPoolOwnerBase (objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
new HkReceiverMock(objects::HK_RECEIVER_MOCK);
|
||||
new LocalPoolOwnerBase(objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
new HkReceiverMock(objects::HK_RECEIVER_MOCK);
|
||||
|
||||
{
|
||||
PoolManager::LocalPoolConfig poolCfg = {
|
||||
{100, 16}, {50, 32}, {25, 64} , {15, 128}, {5, 1024}
|
||||
};
|
||||
new PoolManager(objects::TC_STORE, poolCfg);
|
||||
}
|
||||
{
|
||||
PoolManager::LocalPoolConfig poolCfg = {{100, 16}, {50, 32}, {25, 64}, {15, 128}, {5, 1024}};
|
||||
new PoolManager(objects::TC_STORE, poolCfg);
|
||||
}
|
||||
|
||||
{
|
||||
PoolManager::LocalPoolConfig poolCfg = {
|
||||
{100, 16}, {50, 32}, {25, 64} , {15, 128}, {5, 1024}
|
||||
};
|
||||
new PoolManager(objects::TM_STORE, poolCfg);
|
||||
}
|
||||
{
|
||||
PoolManager::LocalPoolConfig poolCfg = {{100, 16}, {50, 32}, {25, 64}, {15, 128}, {5, 1024}};
|
||||
new PoolManager(objects::TM_STORE, poolCfg);
|
||||
}
|
||||
|
||||
{
|
||||
PoolManager::LocalPoolConfig poolCfg = {
|
||||
{100, 16}, {50, 32}, {25, 64} , {15, 128}, {5, 1024}
|
||||
};
|
||||
new PoolManager(objects::IPC_STORE, poolCfg);
|
||||
}
|
||||
{
|
||||
PoolManager::LocalPoolConfig poolCfg = {{100, 16}, {50, 32}, {25, 64}, {15, 128}, {5, 1024}};
|
||||
new PoolManager(objects::IPC_STORE, poolCfg);
|
||||
}
|
||||
}
|
||||
|
||||
void Factory::setStaticFrameworkObjectIds() {
|
||||
PusServiceBase::packetSource = objects::NO_OBJECT;
|
||||
PusServiceBase::packetDestination = objects::NO_OBJECT;
|
||||
PusServiceBase::packetSource = objects::NO_OBJECT;
|
||||
PusServiceBase::packetDestination = objects::NO_OBJECT;
|
||||
|
||||
CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT;
|
||||
CommandingServiceBase::defaultPacketDestination = objects::NO_OBJECT;
|
||||
CommandingServiceBase::defaultPacketSource = objects::NO_OBJECT;
|
||||
CommandingServiceBase::defaultPacketDestination = objects::NO_OBJECT;
|
||||
|
||||
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
|
||||
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
|
||||
|
||||
DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
|
||||
DeviceHandlerBase::rawDataReceiverId = objects::PUS_SERVICE_2_DEVICE_ACCESS;
|
||||
DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
|
||||
DeviceHandlerBase::rawDataReceiverId = objects::PUS_SERVICE_2_DEVICE_ACCESS;
|
||||
|
||||
LocalDataPoolManager::defaultHkDestination = objects::HK_RECEIVER_MOCK;
|
||||
LocalDataPoolManager::defaultHkDestination = objects::HK_RECEIVER_MOCK;
|
||||
|
||||
DeviceHandlerFailureIsolation::powerConfirmationId = objects::NO_OBJECT;
|
||||
DeviceHandlerFailureIsolation::powerConfirmationId = objects::NO_OBJECT;
|
||||
|
||||
TmPacketBase::timeStamperId = objects::NO_OBJECT;
|
||||
TmPacketBase::timeStamperId = objects::NO_OBJECT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,23 +1,23 @@
|
||||
#ifndef FSFW_CATCHFACTORY_H_
|
||||
#define FSFW_CATCHFACTORY_H_
|
||||
|
||||
#include "tests/TestsConfig.h"
|
||||
#include "fsfw/objectmanager/SystemObjectIF.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/objectmanager/SystemObjectIF.h"
|
||||
#include "tests/TestsConfig.h"
|
||||
|
||||
// TODO: It is possible to solve this more cleanly using a special class which
|
||||
// is allowed to set the object IDs and has virtual functions.
|
||||
#if FSFW_ADD_DEFAULT_FACTORY_FUNCTIONS == 1
|
||||
|
||||
namespace Factory {
|
||||
/**
|
||||
* @brief Creates all SystemObject elements which are persistent
|
||||
* during execution.
|
||||
*/
|
||||
void produceFrameworkObjects(void* args);
|
||||
void setStaticFrameworkObjectIds();
|
||||
/**
|
||||
* @brief Creates all SystemObject elements which are persistent
|
||||
* during execution.
|
||||
*/
|
||||
void produceFrameworkObjects(void* args);
|
||||
void setStaticFrameworkObjectIds();
|
||||
|
||||
}
|
||||
} // namespace Factory
|
||||
|
||||
#endif /* FSFW_ADD_DEFAULT_FSFW_FACTORY == 1 */
|
||||
|
||||
|
@ -15,12 +15,11 @@
|
||||
extern int customSetup();
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
customSetup();
|
||||
customSetup();
|
||||
|
||||
// Catch internal function call
|
||||
int result = Catch::Session().run(argc, argv);
|
||||
// Catch internal function call
|
||||
int result = Catch::Session().run(argc, argv);
|
||||
|
||||
// global clean-up
|
||||
return result;
|
||||
// global clean-up
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,8 @@ namespace fsfwtest {
|
||||
* Can be called by upper level main() if default Catch2 main is overriden
|
||||
* @return
|
||||
*/
|
||||
//int customMain(int argc, char* argv[]);
|
||||
// int customMain(int argc, char* argv[]);
|
||||
|
||||
}
|
||||
} // namespace fsfwtest
|
||||
|
||||
#endif /* FSFW_TESTS_USER_UNITTEST_CORE_CATCHRUNNER_H_ */
|
||||
|
@ -1,14 +1,13 @@
|
||||
#include "CatchFactory.h"
|
||||
#include "CatchDefinitions.h"
|
||||
#include "CatchFactory.h"
|
||||
|
||||
#ifdef GCOV
|
||||
#include <gcov.h>
|
||||
#endif
|
||||
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
|
||||
/* Global instantiations normally done in main.cpp */
|
||||
/* Initialize Data Pool */
|
||||
@ -20,14 +19,13 @@ ServiceInterfaceStream debug("DEBUG");
|
||||
ServiceInterfaceStream info("INFO");
|
||||
ServiceInterfaceStream error("ERROR");
|
||||
ServiceInterfaceStream warning("WARNING");
|
||||
}
|
||||
} // namespace sif
|
||||
#endif
|
||||
|
||||
int customSetup() {
|
||||
// global setup
|
||||
ObjectManager* objMan = ObjectManager::instance();
|
||||
objMan->setObjectFactoryFunction(Factory::produceFrameworkObjects, nullptr);
|
||||
objMan->initialize();
|
||||
return 0;
|
||||
// global setup
|
||||
ObjectManager* objMan = ObjectManager::instance();
|
||||
objMan->setObjectFactoryFunction(Factory::produceFrameworkObjects, nullptr);
|
||||
objMan->initialize();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,110 +1,114 @@
|
||||
#include "TestActionHelper.h"
|
||||
#include "fsfw_tests/unit/mocks/MessageQueueMockBase.h"
|
||||
|
||||
#include <fsfw/action/ActionHelper.h>
|
||||
#include <fsfw/ipc/CommandMessage.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw_tests/unit/mocks/MessageQueueMockBase.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(¶mAddress, testParams.data(), 3);
|
||||
REQUIRE(actionHelper.initialize() == retval::CATCH_OK);
|
||||
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(¶mAddress, 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("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 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(false, 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 finish") {
|
||||
CHECK(not testMqMock.wasMessageSent());
|
||||
ReturnValue_t status = 0x9876;
|
||||
actionHelper.finish(false, 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("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("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"){
|
||||
|
||||
}
|
||||
SECTION("Data Reply") {}
|
||||
}
|
||||
|
@ -1,50 +1,49 @@
|
||||
#ifndef UNITTEST_HOSTED_TESTACTIONHELPER_H_
|
||||
#define UNITTEST_HOSTED_TESTACTIONHELPER_H_
|
||||
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
#include <fsfw/action/HasActionsIF.h>
|
||||
#include <fsfw/ipc/MessageQueueIF.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;
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
MessageQueueId_t getCommandQueue() const override {
|
||||
return tconst::testQueueId;
|
||||
}
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
MessageQueueId_t getCommandQueue() const override { return tconst::testQueueId; }
|
||||
|
||||
void clearBuffer(){
|
||||
this->size = 0;
|
||||
for(size_t i = 0; i<MAX_SIZE; i++){
|
||||
buffer[i] = 0;
|
||||
}
|
||||
}
|
||||
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 getBuffer(const uint8_t** ptr, size_t* size){
|
||||
if(size != nullptr){
|
||||
*size = this->size;
|
||||
}
|
||||
if(ptr != nullptr){
|
||||
*ptr = buffer;
|
||||
}
|
||||
}
|
||||
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_ */
|
||||
|
@ -1,101 +1,100 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/pdu/AckPduDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/AckPduSerializer.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
|
||||
#include <array>
|
||||
TEST_CASE("ACK PDU", "[AckPdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> buf = {};
|
||||
uint8_t* bufptr = buf.data();
|
||||
size_t maxsz = buf.size();
|
||||
size_t sz = 0;
|
||||
auto seqNum = TransactionSeqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
auto sourceId = EntityId(WidthInBytes::TWO_BYTES, 1);
|
||||
auto destId = EntityId(WidthInBytes::TWO_BYTES, 2);
|
||||
auto pduConf = PduConfig(TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId);
|
||||
AckInfo ackInfo(FileDirectives::EOF_DIRECTIVE, ConditionCode::NO_ERROR,
|
||||
AckTransactionStatus::ACTIVE);
|
||||
auto ackSerializer = AckPduSerializer(ackInfo, pduConf);
|
||||
result = ackSerializer.serialize(&bufptr, &sz, maxsz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
TEST_CASE( "ACK PDU" , "[AckPdu]") {
|
||||
SECTION("Serialize") {
|
||||
REQUIRE(buf.data()[sz - 3] == cfdp::FileDirectives::ACK);
|
||||
REQUIRE((buf.data()[sz - 2] >> 4) == FileDirectives::EOF_DIRECTIVE);
|
||||
REQUIRE((buf.data()[sz - 2] & 0x0f) == 0);
|
||||
REQUIRE(buf.data()[sz - 1] == AckTransactionStatus::ACTIVE);
|
||||
ackInfo.setAckedDirective(FileDirectives::FINISH);
|
||||
ackInfo.setAckedConditionCode(ConditionCode::FILESTORE_REJECTION);
|
||||
ackInfo.setTransactionStatus(AckTransactionStatus::TERMINATED);
|
||||
auto ackSerializer2 = AckPduSerializer(ackInfo, pduConf);
|
||||
bufptr = buf.data();
|
||||
sz = 0;
|
||||
result = ackSerializer2.serialize(&bufptr, &sz, maxsz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(buf.data()[sz - 3] == cfdp::FileDirectives::ACK);
|
||||
REQUIRE((buf.data()[sz - 2] >> 4) == FileDirectives::FINISH);
|
||||
REQUIRE((buf.data()[sz - 2] & 0x0f) == 0b0001);
|
||||
REQUIRE((buf.data()[sz - 1] >> 4) == ConditionCode::FILESTORE_REJECTION);
|
||||
REQUIRE((buf.data()[sz - 1] & 0b11) == AckTransactionStatus::TERMINATED);
|
||||
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> buf = {};
|
||||
uint8_t* bufptr = buf.data();
|
||||
size_t maxsz = buf.size();
|
||||
size_t sz = 0;
|
||||
auto seqNum = TransactionSeqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
auto sourceId = EntityId(WidthInBytes::TWO_BYTES, 1);
|
||||
auto destId = EntityId(WidthInBytes::TWO_BYTES, 2);
|
||||
auto pduConf = PduConfig(TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId);
|
||||
AckInfo ackInfo(FileDirectives::EOF_DIRECTIVE, ConditionCode::NO_ERROR, AckTransactionStatus::ACTIVE);
|
||||
auto ackSerializer = AckPduSerializer(ackInfo, pduConf);
|
||||
result = ackSerializer.serialize(&bufptr, &sz, maxsz, SerializeIF::Endianness::NETWORK);
|
||||
bufptr = buf.data();
|
||||
sz = 0;
|
||||
ackInfo.setAckedDirective(FileDirectives::KEEP_ALIVE);
|
||||
auto ackSerializer3 = AckPduSerializer(ackInfo, pduConf);
|
||||
result = ackSerializer3.serialize(&bufptr, &sz, maxsz, SerializeIF::Endianness::NETWORK);
|
||||
// Invalid file directive
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
ackInfo.setAckedDirective(FileDirectives::FINISH);
|
||||
// buffer too small
|
||||
result = ackSerializer.serialize(&bufptr, &sz, 8, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
|
||||
SECTION("Deserialize") {
|
||||
AckInfo ackInfo;
|
||||
auto reader = AckPduDeserializer(buf.data(), sz, ackInfo);
|
||||
result = reader.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(ackInfo.getAckedDirective() == FileDirectives::EOF_DIRECTIVE);
|
||||
REQUIRE(ackInfo.getAckedConditionCode() == ConditionCode::NO_ERROR);
|
||||
REQUIRE(ackInfo.getDirectiveSubtypeCode() == 0);
|
||||
REQUIRE(ackInfo.getTransactionStatus() == AckTransactionStatus::ACTIVE);
|
||||
|
||||
AckInfo newInfo = AckInfo(FileDirectives::FINISH, ConditionCode::FILESTORE_REJECTION,
|
||||
AckTransactionStatus::TERMINATED);
|
||||
auto ackSerializer2 = AckPduSerializer(newInfo, pduConf);
|
||||
bufptr = buf.data();
|
||||
sz = 0;
|
||||
result = ackSerializer2.serialize(&bufptr, &sz, maxsz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
SECTION("Serialize") {
|
||||
REQUIRE(buf.data()[sz - 3] == cfdp::FileDirectives::ACK);
|
||||
REQUIRE((buf.data()[sz - 2] >> 4) == FileDirectives::EOF_DIRECTIVE);
|
||||
REQUIRE((buf.data()[sz - 2] & 0x0f) == 0);
|
||||
REQUIRE(buf.data()[sz - 1] == AckTransactionStatus::ACTIVE);
|
||||
ackInfo.setAckedDirective(FileDirectives::FINISH);
|
||||
ackInfo.setAckedConditionCode(ConditionCode::FILESTORE_REJECTION);
|
||||
ackInfo.setTransactionStatus(AckTransactionStatus::TERMINATED);
|
||||
auto ackSerializer2 = AckPduSerializer(ackInfo, pduConf);
|
||||
bufptr = buf.data();
|
||||
sz = 0;
|
||||
result = ackSerializer2.serialize(&bufptr, &sz, maxsz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(buf.data()[sz - 3] == cfdp::FileDirectives::ACK);
|
||||
REQUIRE((buf.data()[sz - 2] >> 4) == FileDirectives::FINISH);
|
||||
REQUIRE((buf.data()[sz - 2] & 0x0f) == 0b0001);
|
||||
REQUIRE((buf.data()[sz - 1] >> 4) == ConditionCode::FILESTORE_REJECTION);
|
||||
REQUIRE((buf.data()[sz - 1] & 0b11) == AckTransactionStatus::TERMINATED);
|
||||
auto reader2 = AckPduDeserializer(buf.data(), sz, ackInfo);
|
||||
result = reader2.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(ackInfo.getAckedDirective() == FileDirectives::FINISH);
|
||||
REQUIRE(ackInfo.getAckedConditionCode() == ConditionCode::FILESTORE_REJECTION);
|
||||
REQUIRE(ackInfo.getDirectiveSubtypeCode() == 0b0001);
|
||||
REQUIRE(ackInfo.getTransactionStatus() == AckTransactionStatus::TERMINATED);
|
||||
|
||||
bufptr = buf.data();
|
||||
sz = 0;
|
||||
ackInfo.setAckedDirective(FileDirectives::KEEP_ALIVE);
|
||||
auto ackSerializer3 = AckPduSerializer(ackInfo, pduConf);
|
||||
result = ackSerializer3.serialize(&bufptr, &sz, maxsz, SerializeIF::Endianness::NETWORK);
|
||||
// Invalid file directive
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
ackInfo.setAckedDirective(FileDirectives::FINISH);
|
||||
// buffer too small
|
||||
result = ackSerializer.serialize(&bufptr, &sz, 8, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
|
||||
SECTION("Deserialize") {
|
||||
AckInfo ackInfo;
|
||||
auto reader = AckPduDeserializer(buf.data(), sz, ackInfo);
|
||||
result = reader.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(ackInfo.getAckedDirective() == FileDirectives::EOF_DIRECTIVE);
|
||||
REQUIRE(ackInfo.getAckedConditionCode() == ConditionCode::NO_ERROR);
|
||||
REQUIRE(ackInfo.getDirectiveSubtypeCode() == 0);
|
||||
REQUIRE(ackInfo.getTransactionStatus() == AckTransactionStatus::ACTIVE);
|
||||
|
||||
AckInfo newInfo = AckInfo(FileDirectives::FINISH,
|
||||
ConditionCode::FILESTORE_REJECTION, AckTransactionStatus::TERMINATED);
|
||||
auto ackSerializer2 = AckPduSerializer(newInfo, pduConf);
|
||||
bufptr = buf.data();
|
||||
sz = 0;
|
||||
result = ackSerializer2.serialize(&bufptr, &sz, maxsz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
auto reader2 = AckPduDeserializer(buf.data(), sz, ackInfo);
|
||||
result = reader2.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(ackInfo.getAckedDirective() == FileDirectives::FINISH);
|
||||
REQUIRE(ackInfo.getAckedConditionCode() == ConditionCode::FILESTORE_REJECTION);
|
||||
REQUIRE(ackInfo.getDirectiveSubtypeCode() == 0b0001);
|
||||
REQUIRE(ackInfo.getTransactionStatus() == AckTransactionStatus::TERMINATED);
|
||||
|
||||
uint8_t prevVal = buf[sz - 2];
|
||||
buf[sz - 2] = FileDirectives::INVALID_DIRECTIVE << 4;
|
||||
result = reader2.parseData();
|
||||
REQUIRE(result == cfdp::INVALID_ACK_DIRECTIVE_FIELDS);
|
||||
buf[sz - 2] = FileDirectives::FINISH << 4 | 0b1111;
|
||||
result = reader2.parseData();
|
||||
REQUIRE(result == cfdp::INVALID_ACK_DIRECTIVE_FIELDS);
|
||||
buf[sz - 2] = prevVal;
|
||||
buf[sz - 3] = cfdp::FileDirectives::INVALID_DIRECTIVE;
|
||||
result = reader2.parseData();
|
||||
REQUIRE(result == cfdp::INVALID_DIRECTIVE_FIELDS);
|
||||
buf[sz - 3] = cfdp::FileDirectives::ACK;
|
||||
auto maxSizeTooSmall = AckPduDeserializer(buf.data(), sz - 2, ackInfo);
|
||||
result = maxSizeTooSmall.parseData();
|
||||
REQUIRE(result == SerializeIF::STREAM_TOO_SHORT);
|
||||
}
|
||||
uint8_t prevVal = buf[sz - 2];
|
||||
buf[sz - 2] = FileDirectives::INVALID_DIRECTIVE << 4;
|
||||
result = reader2.parseData();
|
||||
REQUIRE(result == cfdp::INVALID_ACK_DIRECTIVE_FIELDS);
|
||||
buf[sz - 2] = FileDirectives::FINISH << 4 | 0b1111;
|
||||
result = reader2.parseData();
|
||||
REQUIRE(result == cfdp::INVALID_ACK_DIRECTIVE_FIELDS);
|
||||
buf[sz - 2] = prevVal;
|
||||
buf[sz - 3] = cfdp::FileDirectives::INVALID_DIRECTIVE;
|
||||
result = reader2.parseData();
|
||||
REQUIRE(result == cfdp::INVALID_DIRECTIVE_FIELDS);
|
||||
buf[sz - 3] = cfdp::FileDirectives::ACK;
|
||||
auto maxSizeTooSmall = AckPduDeserializer(buf.data(), sz - 2, ackInfo);
|
||||
result = maxSizeTooSmall.parseData();
|
||||
REQUIRE(result == SerializeIF::STREAM_TOO_SHORT);
|
||||
}
|
||||
}
|
||||
|
@ -1,372 +1,368 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <cstring>
|
||||
|
||||
#include "fsfw/cfdp/FileSize.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveSerializer.h"
|
||||
#include "fsfw/cfdp/pdu/HeaderDeserializer.h"
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
#include "fsfw/cfdp/FileSize.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
#include "fsfw/cfdp/pdu/HeaderSerializer.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
#include "fsfw/serialize/SerializeAdapter.h"
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <array>
|
||||
TEST_CASE("CFDP Base", "[CfdpBase]") {
|
||||
using namespace cfdp;
|
||||
std::array<uint8_t, 32> serBuf;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
cfdp::TransactionSeqNum seqNum = TransactionSeqNum(cfdp::WidthInBytes::ONE_BYTE, 2);
|
||||
cfdp::EntityId sourceId = EntityId(cfdp::WidthInBytes::ONE_BYTE, 0);
|
||||
cfdp::EntityId destId = EntityId(cfdp::WidthInBytes::ONE_BYTE, 1);
|
||||
PduConfig pduConf =
|
||||
PduConfig(cfdp::TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId, false);
|
||||
uint8_t* serTarget = serBuf.data();
|
||||
const uint8_t* deserTarget = serTarget;
|
||||
size_t serSize = 0;
|
||||
|
||||
TEST_CASE( "CFDP Base" , "[CfdpBase]") {
|
||||
using namespace cfdp;
|
||||
std::array<uint8_t, 32> serBuf;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
cfdp::TransactionSeqNum seqNum = TransactionSeqNum(cfdp::WidthInBytes::ONE_BYTE, 2);
|
||||
cfdp::EntityId sourceId = EntityId(cfdp::WidthInBytes::ONE_BYTE, 0);
|
||||
cfdp::EntityId destId = EntityId(cfdp::WidthInBytes::ONE_BYTE, 1);
|
||||
PduConfig pduConf = PduConfig(cfdp::TransmissionModes::ACKNOWLEDGED, seqNum, sourceId,
|
||||
destId, false);
|
||||
uint8_t* serTarget = serBuf.data();
|
||||
const uint8_t* deserTarget = serTarget;
|
||||
size_t serSize = 0;
|
||||
SECTION("Header Serialization") {
|
||||
auto headerSerializer = HeaderSerializer(pduConf, cfdp::PduType::FILE_DIRECTIVE, 0);
|
||||
const uint8_t** dummyPtr = nullptr;
|
||||
ReturnValue_t deserResult =
|
||||
headerSerializer.deSerialize(dummyPtr, &serSize, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(deserResult == retval::CATCH_FAILED);
|
||||
deserResult = headerSerializer.serialize(nullptr, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(deserResult == retval::CATCH_FAILED);
|
||||
REQUIRE(seqNum.getSerializedSize() == 1);
|
||||
|
||||
SECTION("Header Serialization") {
|
||||
auto headerSerializer = HeaderSerializer(pduConf, cfdp::PduType::FILE_DIRECTIVE, 0);
|
||||
const uint8_t** dummyPtr = nullptr;
|
||||
ReturnValue_t deserResult = headerSerializer.deSerialize(dummyPtr, &serSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(deserResult == retval::CATCH_FAILED);
|
||||
deserResult = headerSerializer.serialize(nullptr, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(deserResult == retval::CATCH_FAILED);
|
||||
REQUIRE(seqNum.getSerializedSize() == 1);
|
||||
REQUIRE(headerSerializer.getPduDataFieldLen() == 0);
|
||||
REQUIRE(headerSerializer.getSerializedSize() == 7);
|
||||
REQUIRE(headerSerializer.getWholePduSize() == 7);
|
||||
REQUIRE(headerSerializer.getCrcFlag() == false);
|
||||
REQUIRE(headerSerializer.getDirection() == cfdp::Direction::TOWARDS_RECEIVER);
|
||||
REQUIRE(headerSerializer.getLargeFileFlag() == false);
|
||||
REQUIRE(headerSerializer.getLenEntityIds() == 1);
|
||||
REQUIRE(headerSerializer.getLenSeqNum() == 1);
|
||||
REQUIRE(headerSerializer.getPduType() == cfdp::PduType::FILE_DIRECTIVE);
|
||||
REQUIRE(headerSerializer.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::NOT_PRESENT);
|
||||
REQUIRE(headerSerializer.getSegmentationControl() == false);
|
||||
REQUIRE(headerSerializer.getTransmissionMode() == cfdp::TransmissionModes::ACKNOWLEDGED);
|
||||
|
||||
REQUIRE(headerSerializer.getPduDataFieldLen() == 0);
|
||||
REQUIRE(headerSerializer.getSerializedSize() == 7);
|
||||
REQUIRE(headerSerializer.getWholePduSize() == 7);
|
||||
REQUIRE(headerSerializer.getCrcFlag() == false);
|
||||
REQUIRE(headerSerializer.getDirection() == cfdp::Direction::TOWARDS_RECEIVER);
|
||||
REQUIRE(headerSerializer.getLargeFileFlag() == false);
|
||||
REQUIRE(headerSerializer.getLenEntityIds() == 1);
|
||||
REQUIRE(headerSerializer.getLenSeqNum() == 1);
|
||||
REQUIRE(headerSerializer.getPduType() == cfdp::PduType::FILE_DIRECTIVE);
|
||||
REQUIRE(headerSerializer.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::NOT_PRESENT);
|
||||
REQUIRE(headerSerializer.getSegmentationControl() == false);
|
||||
REQUIRE(headerSerializer.getTransmissionMode() == cfdp::TransmissionModes::ACKNOWLEDGED);
|
||||
cfdp::TransactionSeqNum seqNumLocal;
|
||||
headerSerializer.getTransactionSeqNum(seqNumLocal);
|
||||
REQUIRE(seqNumLocal.getWidth() == cfdp::WidthInBytes::ONE_BYTE);
|
||||
REQUIRE(seqNumLocal.getValue() == 2);
|
||||
cfdp::EntityId sourceDestId;
|
||||
headerSerializer.getSourceId(sourceDestId);
|
||||
REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::ONE_BYTE);
|
||||
REQUIRE(sourceDestId.getValue() == 0);
|
||||
headerSerializer.getDestId(sourceDestId);
|
||||
REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::ONE_BYTE);
|
||||
REQUIRE(sourceDestId.getValue() == 1);
|
||||
|
||||
cfdp::TransactionSeqNum seqNumLocal;
|
||||
headerSerializer.getTransactionSeqNum(seqNumLocal);
|
||||
REQUIRE(seqNumLocal.getWidth() == cfdp::WidthInBytes::ONE_BYTE);
|
||||
REQUIRE(seqNumLocal.getValue() == 2);
|
||||
cfdp::EntityId sourceDestId;
|
||||
headerSerializer.getSourceId(sourceDestId);
|
||||
REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::ONE_BYTE);
|
||||
REQUIRE(sourceDestId.getValue() == 0);
|
||||
headerSerializer.getDestId(sourceDestId);
|
||||
REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::ONE_BYTE);
|
||||
REQUIRE(sourceDestId.getValue() == 1);
|
||||
result = headerSerializer.serialize(&serTarget, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
REQUIRE(serSize == 7);
|
||||
// Only version bits are set
|
||||
REQUIRE(serBuf[0] == 0b00100000);
|
||||
// PDU data field length is 0
|
||||
REQUIRE(serBuf[1] == 0);
|
||||
REQUIRE(serBuf[2] == 0);
|
||||
// Entity and Transaction Sequence number are 1 byte large
|
||||
REQUIRE(serBuf[3] == 0b00010001);
|
||||
// Source ID
|
||||
REQUIRE(serBuf[4] == 0);
|
||||
// Transaction Seq Number
|
||||
REQUIRE(serBuf[5] == 2);
|
||||
// Dest ID
|
||||
REQUIRE(serBuf[6] == 1);
|
||||
|
||||
result = headerSerializer.serialize(&serTarget, &serSize,
|
||||
serBuf.size(), SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
REQUIRE(serSize == 7);
|
||||
// Only version bits are set
|
||||
REQUIRE(serBuf[0] == 0b00100000);
|
||||
// PDU data field length is 0
|
||||
REQUIRE(serBuf[1] == 0);
|
||||
REQUIRE(serBuf[2] == 0);
|
||||
// Entity and Transaction Sequence number are 1 byte large
|
||||
REQUIRE(serBuf[3] == 0b00010001);
|
||||
// Source ID
|
||||
REQUIRE(serBuf[4] == 0);
|
||||
// Transaction Seq Number
|
||||
REQUIRE(serBuf[5] == 2);
|
||||
// Dest ID
|
||||
REQUIRE(serBuf[6] == 1);
|
||||
|
||||
for(uint8_t idx = 0; idx < 7; idx++) {
|
||||
ReturnValue_t result = headerSerializer.serialize(&serTarget, &serSize,
|
||||
idx, SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == static_cast<int>(SerializeIF::BUFFER_TOO_SHORT));
|
||||
}
|
||||
|
||||
// Set PDU data field len
|
||||
headerSerializer.setPduDataFieldLen(0x0ff0);
|
||||
REQUIRE(headerSerializer.getPduDataFieldLen() == 0x0ff0);
|
||||
REQUIRE(headerSerializer.getSerializedSize() == 7);
|
||||
REQUIRE(headerSerializer.getWholePduSize() == 7 + 0x0ff0);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
result = headerSerializer.serialize(&serTarget, &serSize,
|
||||
serBuf.size(), SerializeIF::Endianness::BIG);
|
||||
REQUIRE(serBuf[1] == 0x0f);
|
||||
REQUIRE(serBuf[2] == 0xf0);
|
||||
|
||||
pduConf.crcFlag = true;
|
||||
pduConf.largeFile = true;
|
||||
pduConf.direction = cfdp::Direction::TOWARDS_SENDER;
|
||||
pduConf.mode = cfdp::TransmissionModes::UNACKNOWLEDGED;
|
||||
headerSerializer.setSegmentationControl(
|
||||
cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION);
|
||||
headerSerializer.setPduType(cfdp::PduType::FILE_DATA);
|
||||
headerSerializer.setSegmentMetadataFlag(cfdp::SegmentMetadataFlag::PRESENT);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
result = headerSerializer.serialize(&serTarget, &serSize,
|
||||
serBuf.size(), SerializeIF::Endianness::BIG);
|
||||
|
||||
// Everything except version bit flipped to one now
|
||||
REQUIRE(serBuf[0] == 0x3f);
|
||||
REQUIRE(serBuf[3] == 0x99);
|
||||
pduConf.seqNum.setValue(cfdp::WidthInBytes::TWO_BYTES, 0x0fff);
|
||||
pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00);
|
||||
pduConf.destId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff);
|
||||
REQUIRE(pduConf.sourceId.getSerializedSize() == 4);
|
||||
REQUIRE(headerSerializer.getSerializedSize() == 14);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
result = headerSerializer.serialize(&serTarget, &serSize,
|
||||
serBuf.size(), SerializeIF::Endianness::BIG);
|
||||
|
||||
for(uint8_t idx = 0; idx < 14; idx++) {
|
||||
ReturnValue_t result = headerSerializer.serialize(&serTarget, &serSize,
|
||||
idx, SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == static_cast<int>(SerializeIF::BUFFER_TOO_SHORT));
|
||||
}
|
||||
REQUIRE(headerSerializer.getCrcFlag() == true);
|
||||
REQUIRE(headerSerializer.getDirection() == cfdp::Direction::TOWARDS_SENDER);
|
||||
REQUIRE(headerSerializer.getLargeFileFlag() == true);
|
||||
REQUIRE(headerSerializer.getLenEntityIds() == 4);
|
||||
REQUIRE(headerSerializer.getLenSeqNum() == 2);
|
||||
REQUIRE(headerSerializer.getPduType() == cfdp::PduType::FILE_DATA);
|
||||
REQUIRE(headerSerializer.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT);
|
||||
REQUIRE(headerSerializer.getTransmissionMode() == cfdp::TransmissionModes::UNACKNOWLEDGED);
|
||||
REQUIRE(headerSerializer.getSegmentationControl() == true);
|
||||
// Last three bits are 2 now (length of seq number) and bit 1 to bit 3 is 4 (len entity IDs)
|
||||
REQUIRE(serBuf[3] == 0b11001010);
|
||||
uint32_t entityId = 0;
|
||||
size_t deSerSize = 0;
|
||||
SerializeAdapter::deSerialize(&entityId, serBuf.data() + 4, &deSerSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(deSerSize == 4);
|
||||
REQUIRE(entityId == 0xff00ff00);
|
||||
uint16_t seqNum = 0;
|
||||
SerializeAdapter::deSerialize(&seqNum, serBuf.data() + 8, &deSerSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(deSerSize == 2);
|
||||
REQUIRE(seqNum == 0x0fff);
|
||||
SerializeAdapter::deSerialize(&entityId, serBuf.data() + 10, &deSerSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(deSerSize == 4);
|
||||
REQUIRE(entityId == 0x00ff00ff);
|
||||
|
||||
result = pduConf.sourceId.setValue(cfdp::WidthInBytes::ONE_BYTE, 0xfff);
|
||||
REQUIRE(result == retval::CATCH_FAILED);
|
||||
result = pduConf.sourceId.setValue(cfdp::WidthInBytes::TWO_BYTES, 0xfffff);
|
||||
REQUIRE(result == retval::CATCH_FAILED);
|
||||
result = pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xfffffffff);
|
||||
REQUIRE(result == retval::CATCH_FAILED);
|
||||
uint8_t oneByteSourceId = 32;
|
||||
serTarget = &oneByteSourceId;
|
||||
size_t deserLen = 1;
|
||||
pduConf.sourceId.deSerialize(cfdp::WidthInBytes::ONE_BYTE,
|
||||
const_cast<const uint8_t**>(&serTarget), &deserLen,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(pduConf.sourceId.getValue() == 32);
|
||||
|
||||
uint16_t twoByteSourceId = 0xf0f0;
|
||||
serTarget = reinterpret_cast<uint8_t*>(&twoByteSourceId);
|
||||
deserLen = 2;
|
||||
pduConf.sourceId.deSerialize(cfdp::WidthInBytes::TWO_BYTES,
|
||||
const_cast<const uint8_t**>(&serTarget), &deserLen,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(pduConf.sourceId.getValue() == 0xf0f0);
|
||||
|
||||
uint32_t fourByteSourceId = 0xf0f0f0f0;
|
||||
serTarget = reinterpret_cast<uint8_t*>(&fourByteSourceId);
|
||||
deserLen = 4;
|
||||
pduConf.sourceId.deSerialize(cfdp::WidthInBytes::FOUR_BYTES,
|
||||
const_cast<const uint8_t**>(&serTarget), &deserLen,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(pduConf.sourceId.getValue() == 0xf0f0f0f0);
|
||||
|
||||
pduConf.sourceId.setValue(cfdp::WidthInBytes::ONE_BYTE, 1);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 1;
|
||||
result = pduConf.sourceId.serialize(&serTarget, &serSize, 1,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(result == static_cast<int>(SerializeIF::BUFFER_TOO_SHORT));
|
||||
for (uint8_t idx = 0; idx < 7; idx++) {
|
||||
ReturnValue_t result =
|
||||
headerSerializer.serialize(&serTarget, &serSize, idx, SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == static_cast<int>(SerializeIF::BUFFER_TOO_SHORT));
|
||||
}
|
||||
|
||||
SECTION( "Header Deserialization" ) {
|
||||
// We unittested the serializer before, so we can use it now to generate valid raw CFDP
|
||||
// data
|
||||
auto headerSerializer = HeaderSerializer(pduConf, cfdp::PduType::FILE_DIRECTIVE, 0);
|
||||
ReturnValue_t result = headerSerializer.serialize(&serTarget, &serSize,
|
||||
serBuf.size(), SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
REQUIRE(serBuf[1] == 0);
|
||||
REQUIRE(serBuf[2] == 0);
|
||||
// Entity and Transaction Sequence number are 1 byte large
|
||||
REQUIRE(serBuf[3] == 0b00010001);
|
||||
REQUIRE(serSize == 7);
|
||||
// Deser call not strictly necessary
|
||||
auto headerDeser = HeaderDeserializer(serBuf.data(), serBuf.size());
|
||||
// Set PDU data field len
|
||||
headerSerializer.setPduDataFieldLen(0x0ff0);
|
||||
REQUIRE(headerSerializer.getPduDataFieldLen() == 0x0ff0);
|
||||
REQUIRE(headerSerializer.getSerializedSize() == 7);
|
||||
REQUIRE(headerSerializer.getWholePduSize() == 7 + 0x0ff0);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
result = headerSerializer.serialize(&serTarget, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::BIG);
|
||||
REQUIRE(serBuf[1] == 0x0f);
|
||||
REQUIRE(serBuf[2] == 0xf0);
|
||||
|
||||
ReturnValue_t serResult = headerDeser.parseData();
|
||||
REQUIRE(serResult == retval::CATCH_OK);
|
||||
REQUIRE(headerDeser.getPduDataFieldLen() == 0);
|
||||
REQUIRE(headerDeser.getHeaderSize() == 7);
|
||||
REQUIRE(headerDeser.getWholePduSize() == 7);
|
||||
REQUIRE(headerDeser.getCrcFlag() == false);
|
||||
REQUIRE(headerDeser.getDirection() == cfdp::Direction::TOWARDS_RECEIVER);
|
||||
REQUIRE(headerDeser.getLargeFileFlag() == false);
|
||||
REQUIRE(headerDeser.getLenEntityIds() == 1);
|
||||
REQUIRE(headerDeser.getLenSeqNum() == 1);
|
||||
REQUIRE(headerDeser.getPduType() == cfdp::PduType::FILE_DIRECTIVE);
|
||||
REQUIRE(headerDeser.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::NOT_PRESENT);
|
||||
REQUIRE(headerDeser.getSegmentationControl() == false);
|
||||
REQUIRE(headerDeser.getTransmissionMode() == cfdp::TransmissionModes::ACKNOWLEDGED);
|
||||
pduConf.crcFlag = true;
|
||||
pduConf.largeFile = true;
|
||||
pduConf.direction = cfdp::Direction::TOWARDS_SENDER;
|
||||
pduConf.mode = cfdp::TransmissionModes::UNACKNOWLEDGED;
|
||||
headerSerializer.setSegmentationControl(
|
||||
cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION);
|
||||
headerSerializer.setPduType(cfdp::PduType::FILE_DATA);
|
||||
headerSerializer.setSegmentMetadataFlag(cfdp::SegmentMetadataFlag::PRESENT);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
result = headerSerializer.serialize(&serTarget, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::BIG);
|
||||
|
||||
pduConf.crcFlag = true;
|
||||
pduConf.largeFile = true;
|
||||
pduConf.direction = cfdp::Direction::TOWARDS_SENDER;
|
||||
pduConf.mode = cfdp::TransmissionModes::UNACKNOWLEDGED;
|
||||
headerSerializer.setSegmentationControl(
|
||||
cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION);
|
||||
headerSerializer.setPduType(cfdp::PduType::FILE_DATA);
|
||||
headerSerializer.setSegmentMetadataFlag(cfdp::SegmentMetadataFlag::PRESENT);
|
||||
result = pduConf.seqNum.setValue(cfdp::WidthInBytes::TWO_BYTES, 0x0fff);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = pduConf.destId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
result = headerSerializer.serialize(&serTarget, &serSize,
|
||||
serBuf.size(), SerializeIF::Endianness::BIG);
|
||||
headerDeser = HeaderDeserializer(serBuf.data(), serBuf.size());
|
||||
// Everything except version bit flipped to one now
|
||||
REQUIRE(serBuf[0] == 0x3f);
|
||||
REQUIRE(serBuf[3] == 0x99);
|
||||
pduConf.seqNum.setValue(cfdp::WidthInBytes::TWO_BYTES, 0x0fff);
|
||||
pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00);
|
||||
pduConf.destId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff);
|
||||
REQUIRE(pduConf.sourceId.getSerializedSize() == 4);
|
||||
REQUIRE(headerSerializer.getSerializedSize() == 14);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
result = headerSerializer.serialize(&serTarget, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::BIG);
|
||||
|
||||
result = headerDeser.parseData();
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
// Everything except version bit flipped to one now
|
||||
REQUIRE(serBuf[0] == 0x3f);
|
||||
REQUIRE(serBuf[3] == 0b11001010);
|
||||
REQUIRE(headerDeser.getWholePduSize() == 14);
|
||||
for (uint8_t idx = 0; idx < 14; idx++) {
|
||||
ReturnValue_t result =
|
||||
headerSerializer.serialize(&serTarget, &serSize, idx, SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == static_cast<int>(SerializeIF::BUFFER_TOO_SHORT));
|
||||
}
|
||||
REQUIRE(headerSerializer.getCrcFlag() == true);
|
||||
REQUIRE(headerSerializer.getDirection() == cfdp::Direction::TOWARDS_SENDER);
|
||||
REQUIRE(headerSerializer.getLargeFileFlag() == true);
|
||||
REQUIRE(headerSerializer.getLenEntityIds() == 4);
|
||||
REQUIRE(headerSerializer.getLenSeqNum() == 2);
|
||||
REQUIRE(headerSerializer.getPduType() == cfdp::PduType::FILE_DATA);
|
||||
REQUIRE(headerSerializer.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT);
|
||||
REQUIRE(headerSerializer.getTransmissionMode() == cfdp::TransmissionModes::UNACKNOWLEDGED);
|
||||
REQUIRE(headerSerializer.getSegmentationControl() == true);
|
||||
// Last three bits are 2 now (length of seq number) and bit 1 to bit 3 is 4 (len entity IDs)
|
||||
REQUIRE(serBuf[3] == 0b11001010);
|
||||
uint32_t entityId = 0;
|
||||
size_t deSerSize = 0;
|
||||
SerializeAdapter::deSerialize(&entityId, serBuf.data() + 4, &deSerSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(deSerSize == 4);
|
||||
REQUIRE(entityId == 0xff00ff00);
|
||||
uint16_t seqNum = 0;
|
||||
SerializeAdapter::deSerialize(&seqNum, serBuf.data() + 8, &deSerSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(deSerSize == 2);
|
||||
REQUIRE(seqNum == 0x0fff);
|
||||
SerializeAdapter::deSerialize(&entityId, serBuf.data() + 10, &deSerSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(deSerSize == 4);
|
||||
REQUIRE(entityId == 0x00ff00ff);
|
||||
|
||||
REQUIRE(headerDeser.getCrcFlag() == true);
|
||||
REQUIRE(headerDeser.getDirection() == cfdp::Direction::TOWARDS_SENDER);
|
||||
REQUIRE(headerDeser.getLargeFileFlag() == true);
|
||||
REQUIRE(headerDeser.getLenEntityIds() == 4);
|
||||
REQUIRE(headerDeser.getLenSeqNum() == 2);
|
||||
REQUIRE(headerDeser.getPduType() == cfdp::PduType::FILE_DATA);
|
||||
REQUIRE(headerDeser.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT);
|
||||
REQUIRE(headerDeser.getSegmentationControl() == true);
|
||||
REQUIRE(headerDeser.getTransmissionMode() == cfdp::TransmissionModes::UNACKNOWLEDGED);
|
||||
result = pduConf.sourceId.setValue(cfdp::WidthInBytes::ONE_BYTE, 0xfff);
|
||||
REQUIRE(result == retval::CATCH_FAILED);
|
||||
result = pduConf.sourceId.setValue(cfdp::WidthInBytes::TWO_BYTES, 0xfffff);
|
||||
REQUIRE(result == retval::CATCH_FAILED);
|
||||
result = pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xfffffffff);
|
||||
REQUIRE(result == retval::CATCH_FAILED);
|
||||
uint8_t oneByteSourceId = 32;
|
||||
serTarget = &oneByteSourceId;
|
||||
size_t deserLen = 1;
|
||||
pduConf.sourceId.deSerialize(cfdp::WidthInBytes::ONE_BYTE,
|
||||
const_cast<const uint8_t**>(&serTarget), &deserLen,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(pduConf.sourceId.getValue() == 32);
|
||||
|
||||
cfdp::TransactionSeqNum seqNumLocal;
|
||||
headerDeser.getTransactionSeqNum(seqNumLocal);
|
||||
REQUIRE(seqNumLocal.getWidth() == cfdp::WidthInBytes::TWO_BYTES);
|
||||
REQUIRE(seqNumLocal.getValue() == 0x0fff);
|
||||
cfdp::EntityId sourceDestId;
|
||||
headerDeser.getSourceId(sourceDestId);
|
||||
REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::FOUR_BYTES);
|
||||
REQUIRE(sourceDestId.getValue() == 0xff00ff00);
|
||||
headerDeser.getDestId(sourceDestId);
|
||||
REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::FOUR_BYTES);
|
||||
REQUIRE(sourceDestId.getValue() == 0x00ff00ff);
|
||||
uint16_t twoByteSourceId = 0xf0f0;
|
||||
serTarget = reinterpret_cast<uint8_t*>(&twoByteSourceId);
|
||||
deserLen = 2;
|
||||
pduConf.sourceId.deSerialize(cfdp::WidthInBytes::TWO_BYTES,
|
||||
const_cast<const uint8_t**>(&serTarget), &deserLen,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(pduConf.sourceId.getValue() == 0xf0f0);
|
||||
|
||||
size_t deSerSize = headerDeser.getWholePduSize();
|
||||
serTarget = serBuf.data();
|
||||
const uint8_t** serTargetConst = const_cast<const uint8_t**>(&serTarget);
|
||||
result = headerDeser.parseData();
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
uint32_t fourByteSourceId = 0xf0f0f0f0;
|
||||
serTarget = reinterpret_cast<uint8_t*>(&fourByteSourceId);
|
||||
deserLen = 4;
|
||||
pduConf.sourceId.deSerialize(cfdp::WidthInBytes::FOUR_BYTES,
|
||||
const_cast<const uint8_t**>(&serTarget), &deserLen,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(pduConf.sourceId.getValue() == 0xf0f0f0f0);
|
||||
|
||||
headerDeser.setData(nullptr, -1);
|
||||
REQUIRE(headerDeser.getHeaderSize() == 0);
|
||||
headerDeser.setData(serBuf.data(), serBuf.size());
|
||||
pduConf.sourceId.setValue(cfdp::WidthInBytes::ONE_BYTE, 1);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 1;
|
||||
result = pduConf.sourceId.serialize(&serTarget, &serSize, 1, SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(result == static_cast<int>(SerializeIF::BUFFER_TOO_SHORT));
|
||||
}
|
||||
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
pduConf.sourceId.setValue(cfdp::WidthInBytes::ONE_BYTE, 22);
|
||||
pduConf.destId.setValue(cfdp::WidthInBytes::ONE_BYTE, 48);
|
||||
result = headerSerializer.serialize(&serTarget, &serSize,
|
||||
serBuf.size(), SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
REQUIRE(headerDeser.getWholePduSize() == 8);
|
||||
headerDeser.setData(serBuf.data(), serBuf.size());
|
||||
SECTION("Header Deserialization") {
|
||||
// We unittested the serializer before, so we can use it now to generate valid raw CFDP
|
||||
// data
|
||||
auto headerSerializer = HeaderSerializer(pduConf, cfdp::PduType::FILE_DIRECTIVE, 0);
|
||||
ReturnValue_t result = headerSerializer.serialize(&serTarget, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
REQUIRE(serBuf[1] == 0);
|
||||
REQUIRE(serBuf[2] == 0);
|
||||
// Entity and Transaction Sequence number are 1 byte large
|
||||
REQUIRE(serBuf[3] == 0b00010001);
|
||||
REQUIRE(serSize == 7);
|
||||
// Deser call not strictly necessary
|
||||
auto headerDeser = HeaderDeserializer(serBuf.data(), serBuf.size());
|
||||
|
||||
headerDeser.getSourceId(sourceDestId);
|
||||
REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::ONE_BYTE);
|
||||
REQUIRE(sourceDestId.getValue() == 22);
|
||||
ReturnValue_t serResult = headerDeser.parseData();
|
||||
REQUIRE(serResult == retval::CATCH_OK);
|
||||
REQUIRE(headerDeser.getPduDataFieldLen() == 0);
|
||||
REQUIRE(headerDeser.getHeaderSize() == 7);
|
||||
REQUIRE(headerDeser.getWholePduSize() == 7);
|
||||
REQUIRE(headerDeser.getCrcFlag() == false);
|
||||
REQUIRE(headerDeser.getDirection() == cfdp::Direction::TOWARDS_RECEIVER);
|
||||
REQUIRE(headerDeser.getLargeFileFlag() == false);
|
||||
REQUIRE(headerDeser.getLenEntityIds() == 1);
|
||||
REQUIRE(headerDeser.getLenSeqNum() == 1);
|
||||
REQUIRE(headerDeser.getPduType() == cfdp::PduType::FILE_DIRECTIVE);
|
||||
REQUIRE(headerDeser.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::NOT_PRESENT);
|
||||
REQUIRE(headerDeser.getSegmentationControl() == false);
|
||||
REQUIRE(headerDeser.getTransmissionMode() == cfdp::TransmissionModes::ACKNOWLEDGED);
|
||||
|
||||
pduConf.crcFlag = true;
|
||||
pduConf.largeFile = true;
|
||||
pduConf.direction = cfdp::Direction::TOWARDS_SENDER;
|
||||
pduConf.mode = cfdp::TransmissionModes::UNACKNOWLEDGED;
|
||||
headerSerializer.setSegmentationControl(
|
||||
cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION);
|
||||
headerSerializer.setPduType(cfdp::PduType::FILE_DATA);
|
||||
headerSerializer.setSegmentMetadataFlag(cfdp::SegmentMetadataFlag::PRESENT);
|
||||
result = pduConf.seqNum.setValue(cfdp::WidthInBytes::TWO_BYTES, 0x0fff);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = pduConf.destId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
result = headerSerializer.serialize(&serTarget, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::BIG);
|
||||
headerDeser = HeaderDeserializer(serBuf.data(), serBuf.size());
|
||||
|
||||
result = headerDeser.parseData();
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
// Everything except version bit flipped to one now
|
||||
REQUIRE(serBuf[0] == 0x3f);
|
||||
REQUIRE(serBuf[3] == 0b11001010);
|
||||
REQUIRE(headerDeser.getWholePduSize() == 14);
|
||||
|
||||
REQUIRE(headerDeser.getCrcFlag() == true);
|
||||
REQUIRE(headerDeser.getDirection() == cfdp::Direction::TOWARDS_SENDER);
|
||||
REQUIRE(headerDeser.getLargeFileFlag() == true);
|
||||
REQUIRE(headerDeser.getLenEntityIds() == 4);
|
||||
REQUIRE(headerDeser.getLenSeqNum() == 2);
|
||||
REQUIRE(headerDeser.getPduType() == cfdp::PduType::FILE_DATA);
|
||||
REQUIRE(headerDeser.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT);
|
||||
REQUIRE(headerDeser.getSegmentationControl() == true);
|
||||
REQUIRE(headerDeser.getTransmissionMode() == cfdp::TransmissionModes::UNACKNOWLEDGED);
|
||||
|
||||
cfdp::TransactionSeqNum seqNumLocal;
|
||||
headerDeser.getTransactionSeqNum(seqNumLocal);
|
||||
REQUIRE(seqNumLocal.getWidth() == cfdp::WidthInBytes::TWO_BYTES);
|
||||
REQUIRE(seqNumLocal.getValue() == 0x0fff);
|
||||
cfdp::EntityId sourceDestId;
|
||||
headerDeser.getSourceId(sourceDestId);
|
||||
REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::FOUR_BYTES);
|
||||
REQUIRE(sourceDestId.getValue() == 0xff00ff00);
|
||||
headerDeser.getDestId(sourceDestId);
|
||||
REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::FOUR_BYTES);
|
||||
REQUIRE(sourceDestId.getValue() == 0x00ff00ff);
|
||||
|
||||
size_t deSerSize = headerDeser.getWholePduSize();
|
||||
serTarget = serBuf.data();
|
||||
const uint8_t** serTargetConst = const_cast<const uint8_t**>(&serTarget);
|
||||
result = headerDeser.parseData();
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
|
||||
headerDeser.setData(nullptr, -1);
|
||||
REQUIRE(headerDeser.getHeaderSize() == 0);
|
||||
headerDeser.setData(serBuf.data(), serBuf.size());
|
||||
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
pduConf.sourceId.setValue(cfdp::WidthInBytes::ONE_BYTE, 22);
|
||||
pduConf.destId.setValue(cfdp::WidthInBytes::ONE_BYTE, 48);
|
||||
result = headerSerializer.serialize(&serTarget, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
REQUIRE(headerDeser.getWholePduSize() == 8);
|
||||
headerDeser.setData(serBuf.data(), serBuf.size());
|
||||
|
||||
headerDeser.getSourceId(sourceDestId);
|
||||
REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::ONE_BYTE);
|
||||
REQUIRE(sourceDestId.getValue() == 22);
|
||||
}
|
||||
|
||||
SECTION("File Directive") {
|
||||
auto fdSer = FileDirectiveSerializer(pduConf, FileDirectives::ACK, 4);
|
||||
REQUIRE(fdSer.getSerializedSize() == 8);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
result = fdSer.serialize(&serTarget, &serSize, serBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
// Only version bits are set
|
||||
REQUIRE(serBuf[0] == 0b00100000);
|
||||
// PDU data field length is 5 (4 + Directive code octet)
|
||||
REQUIRE(serBuf[1] == 0);
|
||||
REQUIRE(serBuf[2] == 5);
|
||||
// Entity and Transaction Sequence number are 1 byte large
|
||||
REQUIRE(serBuf[3] == 0b00010001);
|
||||
// Source ID
|
||||
REQUIRE(serBuf[4] == 0);
|
||||
// Transaction Seq Number
|
||||
REQUIRE(serBuf[5] == 2);
|
||||
// Dest ID
|
||||
REQUIRE(serBuf[6] == 1);
|
||||
REQUIRE(serBuf[7] == FileDirectives::ACK);
|
||||
|
||||
serTarget = serBuf.data();
|
||||
size_t deserSize = 20;
|
||||
serSize = 0;
|
||||
REQUIRE(fdSer.deSerialize(&deserTarget, &deserSize, SerializeIF::Endianness::NETWORK) ==
|
||||
HasReturnvaluesIF::RETURN_FAILED);
|
||||
REQUIRE(fdSer.serialize(nullptr, nullptr, 85, SerializeIF::Endianness::NETWORK) ==
|
||||
HasReturnvaluesIF::RETURN_FAILED);
|
||||
for (uint8_t idx = 0; idx < 8; idx++) {
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
REQUIRE(fdSer.serialize(&serTarget, &serSize, idx, SerializeIF::Endianness::NETWORK) ==
|
||||
SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
|
||||
SECTION("File Directive") {
|
||||
auto fdSer = FileDirectiveSerializer(pduConf, FileDirectives::ACK, 4);
|
||||
REQUIRE(fdSer.getSerializedSize() == 8);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
result = fdSer.serialize(&serTarget, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
// Only version bits are set
|
||||
REQUIRE(serBuf[0] == 0b00100000);
|
||||
// PDU data field length is 5 (4 + Directive code octet)
|
||||
REQUIRE(serBuf[1] == 0);
|
||||
REQUIRE(serBuf[2] == 5);
|
||||
// Entity and Transaction Sequence number are 1 byte large
|
||||
REQUIRE(serBuf[3] == 0b00010001);
|
||||
// Source ID
|
||||
REQUIRE(serBuf[4] == 0);
|
||||
// Transaction Seq Number
|
||||
REQUIRE(serBuf[5] == 2);
|
||||
// Dest ID
|
||||
REQUIRE(serBuf[6] == 1);
|
||||
REQUIRE(serBuf[7] == FileDirectives::ACK);
|
||||
deserTarget = serBuf.data();
|
||||
deserSize = 0;
|
||||
auto fdDeser = FileDirectiveDeserializer(deserTarget, serBuf.size());
|
||||
REQUIRE(fdDeser.getEndianness() == SerializeIF::Endianness::NETWORK);
|
||||
fdDeser.setEndianness(SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(fdDeser.getEndianness() == SerializeIF::Endianness::MACHINE);
|
||||
fdDeser.setEndianness(SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(fdDeser.parseData() == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(fdDeser.getFileDirective() == FileDirectives::ACK);
|
||||
REQUIRE(fdDeser.getPduDataFieldLen() == 5);
|
||||
REQUIRE(fdDeser.getHeaderSize() == 8);
|
||||
REQUIRE(fdDeser.getPduType() == cfdp::PduType::FILE_DIRECTIVE);
|
||||
|
||||
serTarget = serBuf.data();
|
||||
size_t deserSize = 20;
|
||||
serSize = 0;
|
||||
REQUIRE(fdSer.deSerialize(&deserTarget, &deserSize, SerializeIF::Endianness::NETWORK) ==
|
||||
HasReturnvaluesIF::RETURN_FAILED);
|
||||
REQUIRE(fdSer.serialize(nullptr, nullptr, 85, SerializeIF::Endianness::NETWORK) ==
|
||||
HasReturnvaluesIF::RETURN_FAILED);
|
||||
for(uint8_t idx = 0; idx < 8; idx++) {
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
REQUIRE(fdSer.serialize(&serTarget, &serSize, idx, SerializeIF::Endianness::NETWORK) ==
|
||||
SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
serBuf[7] = 0xff;
|
||||
// Invalid file directive
|
||||
REQUIRE(fdDeser.parseData() == cfdp::INVALID_DIRECTIVE_FIELDS);
|
||||
}
|
||||
|
||||
deserTarget = serBuf.data();
|
||||
deserSize = 0;
|
||||
auto fdDeser = FileDirectiveDeserializer(deserTarget, serBuf.size());
|
||||
REQUIRE(fdDeser.getEndianness() == SerializeIF::Endianness::NETWORK);
|
||||
fdDeser.setEndianness(SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(fdDeser.getEndianness() == SerializeIF::Endianness::MACHINE);
|
||||
fdDeser.setEndianness(SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(fdDeser.parseData() == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(fdDeser.getFileDirective() == FileDirectives::ACK);
|
||||
REQUIRE(fdDeser.getPduDataFieldLen() == 5);
|
||||
REQUIRE(fdDeser.getHeaderSize() == 8);
|
||||
REQUIRE(fdDeser.getPduType() == cfdp::PduType::FILE_DIRECTIVE);
|
||||
|
||||
serBuf[7] = 0xff;
|
||||
// Invalid file directive
|
||||
REQUIRE(fdDeser.parseData() == cfdp::INVALID_DIRECTIVE_FIELDS);
|
||||
}
|
||||
|
||||
SECTION("FileSize") {
|
||||
std::array<uint8_t, 8> fssBuf = {};
|
||||
uint8_t* buffer = fssBuf.data();
|
||||
size_t size = 0;
|
||||
cfdp::FileSize fss;
|
||||
REQUIRE(fss.getSize() == 0);
|
||||
fss.setFileSize(0x20, false);
|
||||
ReturnValue_t result = fss.serialize(&buffer, &size, fssBuf.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
uint32_t fileSize = 0;
|
||||
result = SerializeAdapter::deSerialize(&fileSize, fssBuf.data(), nullptr,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(fileSize == 0x20);
|
||||
|
||||
}
|
||||
SECTION("FileSize") {
|
||||
std::array<uint8_t, 8> fssBuf = {};
|
||||
uint8_t* buffer = fssBuf.data();
|
||||
size_t size = 0;
|
||||
cfdp::FileSize fss;
|
||||
REQUIRE(fss.getSize() == 0);
|
||||
fss.setFileSize(0x20, false);
|
||||
ReturnValue_t result =
|
||||
fss.serialize(&buffer, &size, fssBuf.size(), SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
uint32_t fileSize = 0;
|
||||
result = SerializeAdapter::deSerialize(&fileSize, fssBuf.data(), nullptr,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(fileSize == 0x20);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,124 +1,118 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/pdu/EofPduDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/EofPduSerializer.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
|
||||
#include <array>
|
||||
TEST_CASE("EOF PDU", "[EofPdu]") {
|
||||
using namespace cfdp;
|
||||
|
||||
TEST_CASE( "EOF PDU" , "[EofPdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 128> buf = {};
|
||||
uint8_t* bufPtr = buf.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
EntityIdTlv faultLoc(destId);
|
||||
FileSize fileSize(12);
|
||||
// We can already set the fault location, it will be ignored
|
||||
EofInfo eofInfo(cfdp::ConditionCode::NO_ERROR, 5, fileSize, &faultLoc);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 128> buf = {};
|
||||
uint8_t* bufPtr = buf.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
EntityIdTlv faultLoc(destId);
|
||||
FileSize fileSize(12);
|
||||
// We can already set the fault location, it will be ignored
|
||||
EofInfo eofInfo(cfdp::ConditionCode::NO_ERROR, 5, fileSize, &faultLoc);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId);
|
||||
|
||||
PduConfig pduConf(TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId);
|
||||
auto eofSerializer = EofPduSerializer(pduConf, eofInfo);
|
||||
SECTION("Serialize") {
|
||||
result = eofSerializer.serialize(&bufPtr, &sz, buf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(((buf[1] << 8) | buf[2]) == 10);
|
||||
uint32_t checksum = 0;
|
||||
result = SerializeAdapter::deSerialize(&checksum, buf.data() + sz - 8, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(checksum == 5);
|
||||
uint32_t fileSizeVal = 0;
|
||||
result = SerializeAdapter::deSerialize(&fileSizeVal, buf.data() + sz - 4, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(fileSizeVal == 12);
|
||||
REQUIRE(buf[sz - 10] == cfdp::FileDirectives::EOF_DIRECTIVE);
|
||||
REQUIRE(buf[sz - 9] == 0x00);
|
||||
REQUIRE(sz == 20);
|
||||
|
||||
auto eofSerializer = EofPduSerializer(pduConf, eofInfo);
|
||||
SECTION("Serialize") {
|
||||
result = eofSerializer.serialize(&bufPtr, &sz, buf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(((buf[1] << 8) | buf[2]) == 10);
|
||||
uint32_t checksum = 0;
|
||||
result = SerializeAdapter::deSerialize(&checksum, buf.data() + sz - 8, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(checksum == 5);
|
||||
uint32_t fileSizeVal = 0;
|
||||
result = SerializeAdapter::deSerialize(&fileSizeVal, buf.data() + sz - 4, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(fileSizeVal == 12);
|
||||
REQUIRE(buf[sz - 10] == cfdp::FileDirectives::EOF_DIRECTIVE);
|
||||
REQUIRE(buf[sz - 9] == 0x00);
|
||||
REQUIRE(sz == 20);
|
||||
|
||||
eofInfo.setConditionCode(cfdp::ConditionCode::FILESTORE_REJECTION);
|
||||
eofInfo.setFileSize(0x10ffffff10, true);
|
||||
pduConf.largeFile = true;
|
||||
// Should serialize with fault location now
|
||||
auto serializeWithFaultLocation = EofPduSerializer(pduConf, eofInfo);
|
||||
bufPtr = buf.data();
|
||||
sz = 0;
|
||||
result = serializeWithFaultLocation.serialize(&bufPtr, &sz, buf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(sz == 28);
|
||||
REQUIRE(buf[10] == cfdp::FileDirectives::EOF_DIRECTIVE);
|
||||
REQUIRE(buf[11] >> 4 == cfdp::ConditionCode::FILESTORE_REJECTION);
|
||||
uint64_t fileSizeLarge = 0;
|
||||
result = SerializeAdapter::deSerialize(&fileSizeLarge, buf.data() + 16, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(fileSizeLarge == 0x10ffffff10);
|
||||
REQUIRE(buf[sz - 4] == cfdp::TlvTypes::ENTITY_ID);
|
||||
// width of entity ID is 2
|
||||
REQUIRE(buf[sz - 3] == 2);
|
||||
uint16_t entityIdRaw = 0;
|
||||
result = SerializeAdapter::deSerialize(&entityIdRaw, buf.data() + sz - 2, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(entityIdRaw == 2);
|
||||
bufPtr = buf.data();
|
||||
sz = 0;
|
||||
for(size_t idx = 0; idx < 27; idx++) {
|
||||
result = serializeWithFaultLocation.serialize(&bufPtr, &sz, idx,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
bufPtr = buf.data();
|
||||
sz = 0;
|
||||
}
|
||||
eofInfo.setChecksum(16);
|
||||
eofInfo.setFaultLoc(nullptr);
|
||||
eofInfo.setConditionCode(cfdp::ConditionCode::FILESTORE_REJECTION);
|
||||
eofInfo.setFileSize(0x10ffffff10, true);
|
||||
pduConf.largeFile = true;
|
||||
// Should serialize with fault location now
|
||||
auto serializeWithFaultLocation = EofPduSerializer(pduConf, eofInfo);
|
||||
bufPtr = buf.data();
|
||||
sz = 0;
|
||||
result = serializeWithFaultLocation.serialize(&bufPtr, &sz, buf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(sz == 28);
|
||||
REQUIRE(buf[10] == cfdp::FileDirectives::EOF_DIRECTIVE);
|
||||
REQUIRE(buf[11] >> 4 == cfdp::ConditionCode::FILESTORE_REJECTION);
|
||||
uint64_t fileSizeLarge = 0;
|
||||
result = SerializeAdapter::deSerialize(&fileSizeLarge, buf.data() + 16, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(fileSizeLarge == 0x10ffffff10);
|
||||
REQUIRE(buf[sz - 4] == cfdp::TlvTypes::ENTITY_ID);
|
||||
// width of entity ID is 2
|
||||
REQUIRE(buf[sz - 3] == 2);
|
||||
uint16_t entityIdRaw = 0;
|
||||
result = SerializeAdapter::deSerialize(&entityIdRaw, buf.data() + sz - 2, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(entityIdRaw == 2);
|
||||
bufPtr = buf.data();
|
||||
sz = 0;
|
||||
for (size_t idx = 0; idx < 27; idx++) {
|
||||
result =
|
||||
serializeWithFaultLocation.serialize(&bufPtr, &sz, idx, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
bufPtr = buf.data();
|
||||
sz = 0;
|
||||
}
|
||||
eofInfo.setChecksum(16);
|
||||
eofInfo.setFaultLoc(nullptr);
|
||||
}
|
||||
|
||||
SECTION("Deserialize") {
|
||||
result = eofSerializer.serialize(&bufPtr, &sz, buf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
EntityIdTlv tlv(destId);
|
||||
EofInfo emptyInfo(&tlv);
|
||||
auto deserializer = EofPduDeserializer(buf.data(), buf.size(), emptyInfo);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(emptyInfo.getConditionCode() == cfdp::ConditionCode::NO_ERROR);
|
||||
REQUIRE(emptyInfo.getChecksum() == 5);
|
||||
REQUIRE(emptyInfo.getFileSize().getSize() == 12);
|
||||
SECTION("Deserialize") {
|
||||
result = eofSerializer.serialize(&bufPtr, &sz, buf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
EntityIdTlv tlv(destId);
|
||||
EofInfo emptyInfo(&tlv);
|
||||
auto deserializer = EofPduDeserializer(buf.data(), buf.size(), emptyInfo);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(emptyInfo.getConditionCode() == cfdp::ConditionCode::NO_ERROR);
|
||||
REQUIRE(emptyInfo.getChecksum() == 5);
|
||||
REQUIRE(emptyInfo.getFileSize().getSize() == 12);
|
||||
|
||||
eofInfo.setConditionCode(cfdp::ConditionCode::FILESTORE_REJECTION);
|
||||
eofInfo.setFileSize(0x10ffffff10, true);
|
||||
pduConf.largeFile = true;
|
||||
// Should serialize with fault location now
|
||||
auto serializeWithFaultLocation = EofPduSerializer(pduConf, eofInfo);
|
||||
bufPtr = buf.data();
|
||||
sz = 0;
|
||||
result = serializeWithFaultLocation.serialize(&bufPtr, &sz, buf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
auto deserializer2 = EofPduDeserializer(buf.data(), buf.size(), emptyInfo);
|
||||
result = deserializer2.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(emptyInfo.getConditionCode() == cfdp::ConditionCode::FILESTORE_REJECTION);
|
||||
REQUIRE(emptyInfo.getChecksum() == 5);
|
||||
REQUIRE(emptyInfo.getFileSize().getSize() == 0x10ffffff10);
|
||||
REQUIRE(emptyInfo.getFaultLoc()->getType() == cfdp::TlvTypes::ENTITY_ID);
|
||||
REQUIRE(emptyInfo.getFaultLoc()->getSerializedSize() == 4);
|
||||
uint16_t destId = emptyInfo.getFaultLoc()->getEntityId().getValue();
|
||||
REQUIRE(destId == 2);
|
||||
for(size_t maxSz = 0; maxSz < deserializer2.getWholePduSize() - 1; maxSz++) {
|
||||
auto invalidDeser = EofPduDeserializer(buf.data(), maxSz, emptyInfo);
|
||||
result = invalidDeser.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
eofInfo.setConditionCode(cfdp::ConditionCode::FILESTORE_REJECTION);
|
||||
eofInfo.setFileSize(0x10ffffff10, true);
|
||||
pduConf.largeFile = true;
|
||||
// Should serialize with fault location now
|
||||
auto serializeWithFaultLocation = EofPduSerializer(pduConf, eofInfo);
|
||||
bufPtr = buf.data();
|
||||
sz = 0;
|
||||
result = serializeWithFaultLocation.serialize(&bufPtr, &sz, buf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
auto deserializer2 = EofPduDeserializer(buf.data(), buf.size(), emptyInfo);
|
||||
result = deserializer2.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(emptyInfo.getConditionCode() == cfdp::ConditionCode::FILESTORE_REJECTION);
|
||||
REQUIRE(emptyInfo.getChecksum() == 5);
|
||||
REQUIRE(emptyInfo.getFileSize().getSize() == 0x10ffffff10);
|
||||
REQUIRE(emptyInfo.getFaultLoc()->getType() == cfdp::TlvTypes::ENTITY_ID);
|
||||
REQUIRE(emptyInfo.getFaultLoc()->getSerializedSize() == 4);
|
||||
uint16_t destId = emptyInfo.getFaultLoc()->getEntityId().getValue();
|
||||
REQUIRE(destId == 2);
|
||||
for (size_t maxSz = 0; maxSz < deserializer2.getWholePduSize() - 1; maxSz++) {
|
||||
auto invalidDeser = EofPduDeserializer(buf.data(), maxSz, emptyInfo);
|
||||
result = invalidDeser.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/pdu/FileDataDeserializer.h"
|
||||
@ -5,171 +6,166 @@
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
#include <array>
|
||||
TEST_CASE("File Data PDU", "[FileDataPdu]") {
|
||||
using namespace cfdp;
|
||||
|
||||
TEST_CASE( "File Data PDU" , "[FileDataPdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 128> fileBuffer = {};
|
||||
std::array<uint8_t, 256> fileDataBuffer = {};
|
||||
uint8_t* buffer = fileDataBuffer.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId);
|
||||
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 128> fileBuffer = {};
|
||||
std::array<uint8_t, 256> fileDataBuffer = {};
|
||||
uint8_t* buffer = fileDataBuffer.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId);
|
||||
for (uint8_t idx = 0; idx < 10; idx++) {
|
||||
fileBuffer[idx] = idx;
|
||||
}
|
||||
FileSize offset(50);
|
||||
FileDataInfo info(offset, fileBuffer.data(), 10);
|
||||
|
||||
for(uint8_t idx = 0; idx < 10; idx++) {
|
||||
fileBuffer[idx] = idx;
|
||||
}
|
||||
FileSize offset(50);
|
||||
FileDataInfo info(offset, fileBuffer.data(), 10);
|
||||
|
||||
SECTION("Serialization") {
|
||||
FileDataSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, fileDataBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(sz == 24);
|
||||
// 10 file bytes plus 4 byte offset
|
||||
REQUIRE(((fileDataBuffer[1] << 8) | fileDataBuffer[2]) == 14);
|
||||
// File Data -> Fourth bit is one
|
||||
REQUIRE(fileDataBuffer[0] == 0b00110000);
|
||||
uint32_t offsetRaw = 0;
|
||||
buffer = fileDataBuffer.data();
|
||||
result = SerializeAdapter::deSerialize(&offsetRaw, buffer + 10, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(offsetRaw == 50);
|
||||
buffer = fileDataBuffer.data() + 14;
|
||||
for(size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(buffer[idx] == idx);
|
||||
}
|
||||
|
||||
REQUIRE(info.hasSegmentMetadata() == false);
|
||||
info.addSegmentMetadataInfo(cfdp::RecordContinuationState::CONTAINS_START_AND_END,
|
||||
fileBuffer.data(), 10);
|
||||
REQUIRE(info.hasSegmentMetadata() == true);
|
||||
REQUIRE(info.getSegmentationControl() ==
|
||||
cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION);
|
||||
info.setSegmentationControl(cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION);
|
||||
serializer.update();
|
||||
REQUIRE(serializer.getSegmentationControl() ==
|
||||
cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION);
|
||||
buffer = fileDataBuffer.data();
|
||||
sz = 0;
|
||||
serializer.setSegmentationControl(cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION);
|
||||
|
||||
result = serializer.serialize(&buffer, &sz, fileDataBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(((fileDataBuffer[1] << 8) | fileDataBuffer[2]) == 25);
|
||||
// First bit: Seg Ctrl is set
|
||||
// Bits 1 to 3 length of enitity IDs is 2
|
||||
// Bit 4: Segment metadata flag is set
|
||||
// Bit 5 to seven: length of transaction seq num is 2
|
||||
REQUIRE(fileDataBuffer[3] == 0b10101010);
|
||||
REQUIRE((fileDataBuffer[10] >> 6) & 0b11 ==
|
||||
cfdp::RecordContinuationState::CONTAINS_START_AND_END);
|
||||
// Segment metadata length
|
||||
REQUIRE((fileDataBuffer[10] & 0x3f) == 10);
|
||||
buffer = fileDataBuffer.data() + 11;
|
||||
// Check segment metadata
|
||||
for(size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(buffer[idx] == idx);
|
||||
}
|
||||
// Check filedata
|
||||
buffer = fileDataBuffer.data() + 25;
|
||||
for(size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(buffer[idx] == idx);
|
||||
}
|
||||
|
||||
for(size_t invalidStartSz = 1; invalidStartSz < sz; invalidStartSz ++) {
|
||||
buffer = fileDataBuffer.data();
|
||||
sz = 0;
|
||||
result = serializer.serialize(&buffer, &invalidStartSz, sz,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
|
||||
info.setSegmentMetadataFlag(true);
|
||||
REQUIRE(info.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT);
|
||||
info.setSegmentMetadataFlag(false);
|
||||
REQUIRE(info.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::NOT_PRESENT);
|
||||
info.setRecordContinuationState(cfdp::RecordContinuationState::CONTAINS_END_NO_START);
|
||||
info.setSegmentMetadataLen(10);
|
||||
info.setSegmentMetadata(nullptr);
|
||||
info.setFileData(nullptr, 0);
|
||||
SECTION("Serialization") {
|
||||
FileDataSerializer serializer(pduConf, info);
|
||||
result =
|
||||
serializer.serialize(&buffer, &sz, fileDataBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(sz == 24);
|
||||
// 10 file bytes plus 4 byte offset
|
||||
REQUIRE(((fileDataBuffer[1] << 8) | fileDataBuffer[2]) == 14);
|
||||
// File Data -> Fourth bit is one
|
||||
REQUIRE(fileDataBuffer[0] == 0b00110000);
|
||||
uint32_t offsetRaw = 0;
|
||||
buffer = fileDataBuffer.data();
|
||||
result = SerializeAdapter::deSerialize(&offsetRaw, buffer + 10, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(offsetRaw == 50);
|
||||
buffer = fileDataBuffer.data() + 14;
|
||||
for (size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(buffer[idx] == idx);
|
||||
}
|
||||
|
||||
SECTION("Deserialization") {
|
||||
FileDataSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, fileDataBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
FileSize emptyOffset;
|
||||
FileDataInfo emptyInfo(emptyOffset);
|
||||
FileDataDeserializer deserializer(fileDataBuffer.data(), fileDataBuffer.size(), emptyInfo);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserializer.getWholePduSize() == 24);
|
||||
REQUIRE(deserializer.getPduDataFieldLen() == 14);
|
||||
REQUIRE(deserializer.getSegmentationControl() ==
|
||||
cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION);
|
||||
REQUIRE(deserializer.getSegmentMetadataFlag() ==
|
||||
cfdp::SegmentMetadataFlag::NOT_PRESENT);
|
||||
|
||||
REQUIRE(emptyInfo.getOffset().getSize() == 50);
|
||||
REQUIRE(emptyInfo.hasSegmentMetadata() == false);
|
||||
size_t emptyFileSize = 0;
|
||||
const uint8_t* fileData = emptyInfo.getFileData(&emptyFileSize);
|
||||
REQUIRE(emptyFileSize == 10);
|
||||
for(size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(fileData[idx] == idx);
|
||||
}
|
||||
|
||||
deserializer.setEndianness(SerializeIF::Endianness::NETWORK);
|
||||
|
||||
info.addSegmentMetadataInfo(cfdp::RecordContinuationState::CONTAINS_START_AND_END,
|
||||
fileBuffer.data(), 10);
|
||||
serializer.update();
|
||||
buffer = fileDataBuffer.data();
|
||||
sz = 0;
|
||||
result = serializer.serialize(&buffer, &sz, fileDataBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
REQUIRE(emptyInfo.getOffset().getSize() == 50);
|
||||
REQUIRE(emptyInfo.hasSegmentMetadata() == true);
|
||||
REQUIRE(emptyInfo.getRecordContinuationState() ==
|
||||
cfdp::RecordContinuationState::CONTAINS_START_AND_END);
|
||||
emptyFileSize = 0;
|
||||
fileData = emptyInfo.getFileData(&emptyFileSize);
|
||||
REQUIRE(emptyFileSize == 10);
|
||||
for(size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(fileData[idx] == idx);
|
||||
}
|
||||
size_t segmentMetadataLen = 0;
|
||||
fileData = emptyInfo.getSegmentMetadata(&segmentMetadataLen);
|
||||
REQUIRE(segmentMetadataLen == 10);
|
||||
for(size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(fileData[idx] == idx);
|
||||
}
|
||||
for(size_t invalidPduField = 0; invalidPduField < 24; invalidPduField++) {
|
||||
fileDataBuffer[1] = (invalidPduField >> 8) & 0xff;
|
||||
fileDataBuffer[2] = invalidPduField & 0xff;
|
||||
result = deserializer.parseData();
|
||||
// Starting at 15, the file data is parsed. There is not leading file data length
|
||||
// field to the parser can't check whether the remaining length is valid
|
||||
if(invalidPduField < 15) {
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
REQUIRE(info.hasSegmentMetadata() == false);
|
||||
info.addSegmentMetadataInfo(cfdp::RecordContinuationState::CONTAINS_START_AND_END,
|
||||
fileBuffer.data(), 10);
|
||||
REQUIRE(info.hasSegmentMetadata() == true);
|
||||
REQUIRE(info.getSegmentationControl() ==
|
||||
cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION);
|
||||
info.setSegmentationControl(cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION);
|
||||
serializer.update();
|
||||
REQUIRE(serializer.getSegmentationControl() ==
|
||||
cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION);
|
||||
buffer = fileDataBuffer.data();
|
||||
sz = 0;
|
||||
serializer.setSegmentationControl(cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION);
|
||||
|
||||
result =
|
||||
serializer.serialize(&buffer, &sz, fileDataBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(((fileDataBuffer[1] << 8) | fileDataBuffer[2]) == 25);
|
||||
// First bit: Seg Ctrl is set
|
||||
// Bits 1 to 3 length of enitity IDs is 2
|
||||
// Bit 4: Segment metadata flag is set
|
||||
// Bit 5 to seven: length of transaction seq num is 2
|
||||
REQUIRE(fileDataBuffer[3] == 0b10101010);
|
||||
REQUIRE((fileDataBuffer[10] >> 6) &
|
||||
0b11 == cfdp::RecordContinuationState::CONTAINS_START_AND_END);
|
||||
// Segment metadata length
|
||||
REQUIRE((fileDataBuffer[10] & 0x3f) == 10);
|
||||
buffer = fileDataBuffer.data() + 11;
|
||||
// Check segment metadata
|
||||
for (size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(buffer[idx] == idx);
|
||||
}
|
||||
// Check filedata
|
||||
buffer = fileDataBuffer.data() + 25;
|
||||
for (size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(buffer[idx] == idx);
|
||||
}
|
||||
|
||||
for (size_t invalidStartSz = 1; invalidStartSz < sz; invalidStartSz++) {
|
||||
buffer = fileDataBuffer.data();
|
||||
sz = 0;
|
||||
result = serializer.serialize(&buffer, &invalidStartSz, sz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
|
||||
info.setSegmentMetadataFlag(true);
|
||||
REQUIRE(info.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT);
|
||||
info.setSegmentMetadataFlag(false);
|
||||
REQUIRE(info.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::NOT_PRESENT);
|
||||
info.setRecordContinuationState(cfdp::RecordContinuationState::CONTAINS_END_NO_START);
|
||||
info.setSegmentMetadataLen(10);
|
||||
info.setSegmentMetadata(nullptr);
|
||||
info.setFileData(nullptr, 0);
|
||||
}
|
||||
|
||||
SECTION("Deserialization") {
|
||||
FileDataSerializer serializer(pduConf, info);
|
||||
result =
|
||||
serializer.serialize(&buffer, &sz, fileDataBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
FileSize emptyOffset;
|
||||
FileDataInfo emptyInfo(emptyOffset);
|
||||
FileDataDeserializer deserializer(fileDataBuffer.data(), fileDataBuffer.size(), emptyInfo);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserializer.getWholePduSize() == 24);
|
||||
REQUIRE(deserializer.getPduDataFieldLen() == 14);
|
||||
REQUIRE(deserializer.getSegmentationControl() ==
|
||||
cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION);
|
||||
REQUIRE(deserializer.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::NOT_PRESENT);
|
||||
|
||||
REQUIRE(emptyInfo.getOffset().getSize() == 50);
|
||||
REQUIRE(emptyInfo.hasSegmentMetadata() == false);
|
||||
size_t emptyFileSize = 0;
|
||||
const uint8_t* fileData = emptyInfo.getFileData(&emptyFileSize);
|
||||
REQUIRE(emptyFileSize == 10);
|
||||
for (size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(fileData[idx] == idx);
|
||||
}
|
||||
|
||||
deserializer.setEndianness(SerializeIF::Endianness::NETWORK);
|
||||
|
||||
info.addSegmentMetadataInfo(cfdp::RecordContinuationState::CONTAINS_START_AND_END,
|
||||
fileBuffer.data(), 10);
|
||||
serializer.update();
|
||||
buffer = fileDataBuffer.data();
|
||||
sz = 0;
|
||||
result =
|
||||
serializer.serialize(&buffer, &sz, fileDataBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
REQUIRE(emptyInfo.getOffset().getSize() == 50);
|
||||
REQUIRE(emptyInfo.hasSegmentMetadata() == true);
|
||||
REQUIRE(emptyInfo.getRecordContinuationState() ==
|
||||
cfdp::RecordContinuationState::CONTAINS_START_AND_END);
|
||||
emptyFileSize = 0;
|
||||
fileData = emptyInfo.getFileData(&emptyFileSize);
|
||||
REQUIRE(emptyFileSize == 10);
|
||||
for (size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(fileData[idx] == idx);
|
||||
}
|
||||
size_t segmentMetadataLen = 0;
|
||||
fileData = emptyInfo.getSegmentMetadata(&segmentMetadataLen);
|
||||
REQUIRE(segmentMetadataLen == 10);
|
||||
for (size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(fileData[idx] == idx);
|
||||
}
|
||||
for (size_t invalidPduField = 0; invalidPduField < 24; invalidPduField++) {
|
||||
fileDataBuffer[1] = (invalidPduField >> 8) & 0xff;
|
||||
fileDataBuffer[2] = invalidPduField & 0xff;
|
||||
result = deserializer.parseData();
|
||||
// Starting at 15, the file data is parsed. There is not leading file data length
|
||||
// field to the parser can't check whether the remaining length is valid
|
||||
if (invalidPduField < 15) {
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,196 +1,189 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
#include "fsfw/cfdp/pdu/FinishedPduDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/FinishedPduSerializer.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
|
||||
#include <array>
|
||||
TEST_CASE("Finished PDU", "[FinishedPdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> fnBuffer = {};
|
||||
uint8_t* buffer = fnBuffer.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId);
|
||||
|
||||
TEST_CASE( "Finished PDU" , "[FinishedPdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> fnBuffer = {};
|
||||
uint8_t* buffer = fnBuffer.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId);
|
||||
cfdp::Lv emptyFsMsg;
|
||||
FinishedInfo info(cfdp::ConditionCode::INACTIVITY_DETECTED,
|
||||
cfdp::FinishedDeliveryCode::DATA_INCOMPLETE,
|
||||
cfdp::FinishedFileStatus::DISCARDED_DELIBERATELY);
|
||||
|
||||
cfdp::Lv emptyFsMsg;
|
||||
FinishedInfo info(cfdp::ConditionCode::INACTIVITY_DETECTED,
|
||||
cfdp::FinishedDeliveryCode::DATA_INCOMPLETE,
|
||||
cfdp::FinishedFileStatus::DISCARDED_DELIBERATELY);
|
||||
SECTION("Serialize") {
|
||||
FinishPduSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getSerializedSize() == 12);
|
||||
REQUIRE(((fnBuffer[1] << 8) | fnBuffer[2]) == 2);
|
||||
REQUIRE(fnBuffer[10] == cfdp::FileDirectives::FINISH);
|
||||
REQUIRE(((fnBuffer[sz - 1] >> 4) & 0x0f) == cfdp::ConditionCode::INACTIVITY_DETECTED);
|
||||
REQUIRE(((fnBuffer[sz - 1] >> 2) & 0x01) == cfdp::FinishedDeliveryCode::DATA_INCOMPLETE);
|
||||
REQUIRE((fnBuffer[sz - 1] & 0b11) == cfdp::FinishedFileStatus::DISCARDED_DELIBERATELY);
|
||||
REQUIRE(sz == 12);
|
||||
|
||||
SECTION("Serialize") {
|
||||
FinishPduSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getSerializedSize() == 12);
|
||||
REQUIRE(((fnBuffer[1] << 8) | fnBuffer[2]) == 2);
|
||||
REQUIRE(fnBuffer[10] == cfdp::FileDirectives::FINISH);
|
||||
REQUIRE(((fnBuffer[sz - 1] >> 4) & 0x0f) == cfdp::ConditionCode::INACTIVITY_DETECTED);
|
||||
REQUIRE(((fnBuffer[sz - 1] >> 2) & 0x01) == cfdp::FinishedDeliveryCode::DATA_INCOMPLETE);
|
||||
REQUIRE((fnBuffer[sz - 1] & 0b11) == cfdp::FinishedFileStatus::DISCARDED_DELIBERATELY);
|
||||
REQUIRE(sz == 12);
|
||||
// Add a filestore response
|
||||
std::string firstName = "hello.txt";
|
||||
cfdp::Lv firstNameLv(reinterpret_cast<const uint8_t*>(firstName.data()), firstName.size());
|
||||
FilestoreResponseTlv response(cfdp::FilestoreActionCode::DELETE_FILE,
|
||||
cfdp::FSR_APPEND_FILE_1_NOT_EXISTS, firstNameLv, nullptr);
|
||||
FilestoreResponseTlv* responsePtr = &response;
|
||||
REQUIRE(response.getSerializedSize() == 14);
|
||||
size_t len = 1;
|
||||
info.setFilestoreResponsesArray(&responsePtr, &len, &len);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
REQUIRE(serializer.getSerializedSize() == 12 + 14);
|
||||
sz = 0;
|
||||
buffer = fnBuffer.data();
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getSerializedSize() == 12 + 14);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 16);
|
||||
|
||||
// Add a filestore response
|
||||
std::string firstName = "hello.txt";
|
||||
cfdp::Lv firstNameLv(reinterpret_cast<const uint8_t*>(firstName.data()), firstName.size());
|
||||
FilestoreResponseTlv response(cfdp::FilestoreActionCode::DELETE_FILE,
|
||||
cfdp::FSR_APPEND_FILE_1_NOT_EXISTS, firstNameLv, nullptr);
|
||||
FilestoreResponseTlv* responsePtr = &response;
|
||||
REQUIRE(response.getSerializedSize() == 14);
|
||||
size_t len = 1;
|
||||
info.setFilestoreResponsesArray(&responsePtr, &len, &len);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
REQUIRE(serializer.getSerializedSize() == 12 + 14);
|
||||
sz = 0;
|
||||
buffer = fnBuffer.data();
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getSerializedSize() == 12 + 14);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 16);
|
||||
// Add two filestore responses and a fault location parameter
|
||||
std::string secondName = "hello2.txt";
|
||||
cfdp::Lv secondNameLv(reinterpret_cast<const uint8_t*>(secondName.data()), secondName.size());
|
||||
FilestoreResponseTlv response2(cfdp::FilestoreActionCode::DENY_FILE, cfdp::FSR_SUCCESS,
|
||||
secondNameLv, nullptr);
|
||||
REQUIRE(response2.getSerializedSize() == 15);
|
||||
len = 2;
|
||||
std::array<FilestoreResponseTlv*, 2> responses{&response, &response2};
|
||||
info.setFilestoreResponsesArray(responses.data(), &len, &len);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
|
||||
// Add two filestore responses and a fault location parameter
|
||||
std::string secondName = "hello2.txt";
|
||||
cfdp::Lv secondNameLv(reinterpret_cast<const uint8_t*>(secondName.data()), secondName.size());
|
||||
FilestoreResponseTlv response2(cfdp::FilestoreActionCode::DENY_FILE ,
|
||||
cfdp::FSR_SUCCESS, secondNameLv, nullptr);
|
||||
REQUIRE(response2.getSerializedSize() == 15);
|
||||
len = 2;
|
||||
std::array<FilestoreResponseTlv*, 2> responses {&response, &response2};
|
||||
info.setFilestoreResponsesArray(responses.data(), &len, &len);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
|
||||
EntityIdTlv faultLoc(destId);
|
||||
REQUIRE(faultLoc.getSerializedSize() == 4);
|
||||
info.setFaultLocation(&faultLoc);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
sz = 0;
|
||||
buffer = fnBuffer.data();
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
info.setConditionCode(cfdp::ConditionCode::FILESTORE_REJECTION);
|
||||
REQUIRE(serializer.getSerializedSize() == 12 + 14 + 15 + 4);
|
||||
REQUIRE(sz == 12 + 14 + 15 + 4);
|
||||
info.setFileStatus(cfdp::FinishedFileStatus::DISCARDED_FILESTORE_REJECTION);
|
||||
REQUIRE(info.getFileStatus() == cfdp::FinishedFileStatus::DISCARDED_FILESTORE_REJECTION);
|
||||
info.setDeliveryCode(cfdp::FinishedDeliveryCode::DATA_INCOMPLETE);
|
||||
REQUIRE(info.getDeliveryCode() == cfdp::FinishedDeliveryCode::DATA_INCOMPLETE);
|
||||
for(size_t maxSz = 0; maxSz < 45; maxSz++) {
|
||||
sz = 0;
|
||||
buffer = fnBuffer.data();
|
||||
result = serializer.serialize(&buffer, &sz, maxSz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
EntityIdTlv faultLoc(destId);
|
||||
REQUIRE(faultLoc.getSerializedSize() == 4);
|
||||
info.setFaultLocation(&faultLoc);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
sz = 0;
|
||||
buffer = fnBuffer.data();
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
info.setConditionCode(cfdp::ConditionCode::FILESTORE_REJECTION);
|
||||
REQUIRE(serializer.getSerializedSize() == 12 + 14 + 15 + 4);
|
||||
REQUIRE(sz == 12 + 14 + 15 + 4);
|
||||
info.setFileStatus(cfdp::FinishedFileStatus::DISCARDED_FILESTORE_REJECTION);
|
||||
REQUIRE(info.getFileStatus() == cfdp::FinishedFileStatus::DISCARDED_FILESTORE_REJECTION);
|
||||
info.setDeliveryCode(cfdp::FinishedDeliveryCode::DATA_INCOMPLETE);
|
||||
REQUIRE(info.getDeliveryCode() == cfdp::FinishedDeliveryCode::DATA_INCOMPLETE);
|
||||
for (size_t maxSz = 0; maxSz < 45; maxSz++) {
|
||||
sz = 0;
|
||||
buffer = fnBuffer.data();
|
||||
result = serializer.serialize(&buffer, &sz, maxSz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Deserialize") {
|
||||
FinishedInfo emptyInfo;
|
||||
FinishPduSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
FinishPduDeserializer deserializer(fnBuffer.data(), fnBuffer.size(), emptyInfo);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(emptyInfo.getFileStatus() == cfdp::FinishedFileStatus::DISCARDED_DELIBERATELY);
|
||||
REQUIRE(emptyInfo.getConditionCode() == cfdp::ConditionCode::INACTIVITY_DETECTED);
|
||||
REQUIRE(emptyInfo.getDeliveryCode() == cfdp::FinishedDeliveryCode::DATA_INCOMPLETE);
|
||||
SECTION("Deserialize") {
|
||||
FinishedInfo emptyInfo;
|
||||
FinishPduSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
FinishPduDeserializer deserializer(fnBuffer.data(), fnBuffer.size(), emptyInfo);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(emptyInfo.getFileStatus() == cfdp::FinishedFileStatus::DISCARDED_DELIBERATELY);
|
||||
REQUIRE(emptyInfo.getConditionCode() == cfdp::ConditionCode::INACTIVITY_DETECTED);
|
||||
REQUIRE(emptyInfo.getDeliveryCode() == cfdp::FinishedDeliveryCode::DATA_INCOMPLETE);
|
||||
|
||||
// Add a filestore response
|
||||
sz = 0;
|
||||
buffer = fnBuffer.data();
|
||||
std::string firstName = "hello.txt";
|
||||
cfdp::Lv firstNameLv(reinterpret_cast<const uint8_t*>(firstName.data()), firstName.size());
|
||||
FilestoreResponseTlv response(cfdp::FilestoreActionCode::DELETE_FILE,
|
||||
cfdp::FSR_NOT_PERFORMED, firstNameLv, nullptr);
|
||||
FilestoreResponseTlv* responsePtr = &response;
|
||||
size_t len = 1;
|
||||
info.setFilestoreResponsesArray(&responsePtr, &len, &len);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 16);
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
FilestoreResponseTlv emptyResponse(firstNameLv, nullptr);
|
||||
responsePtr = &emptyResponse;
|
||||
emptyInfo.setFilestoreResponsesArray(&responsePtr, nullptr, &len);
|
||||
FinishPduDeserializer deserializer2(fnBuffer.data(), fnBuffer.size(), emptyInfo);
|
||||
result = deserializer2.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(emptyInfo.getFsResponsesLen() == 1);
|
||||
FilestoreResponseTlv** responseArray = nullptr;
|
||||
emptyInfo.getFilestoreResonses(&responseArray, nullptr, nullptr);
|
||||
REQUIRE(responseArray[0]->getActionCode() == cfdp::FilestoreActionCode::DELETE_FILE);
|
||||
REQUIRE(responseArray[0]->getStatusCode() == cfdp::FSR_NOT_PERFORMED);
|
||||
auto& fileNameRef = responseArray[0]->getFirstFileName();
|
||||
size_t stringSize = 0;
|
||||
const char* string = reinterpret_cast<const char*>(fileNameRef.getValue(&stringSize));
|
||||
std::string firstFileName(string, stringSize);
|
||||
REQUIRE(firstFileName == "hello.txt");
|
||||
// Add a filestore response
|
||||
sz = 0;
|
||||
buffer = fnBuffer.data();
|
||||
std::string firstName = "hello.txt";
|
||||
cfdp::Lv firstNameLv(reinterpret_cast<const uint8_t*>(firstName.data()), firstName.size());
|
||||
FilestoreResponseTlv response(cfdp::FilestoreActionCode::DELETE_FILE, cfdp::FSR_NOT_PERFORMED,
|
||||
firstNameLv, nullptr);
|
||||
FilestoreResponseTlv* responsePtr = &response;
|
||||
size_t len = 1;
|
||||
info.setFilestoreResponsesArray(&responsePtr, &len, &len);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 16);
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
FilestoreResponseTlv emptyResponse(firstNameLv, nullptr);
|
||||
responsePtr = &emptyResponse;
|
||||
emptyInfo.setFilestoreResponsesArray(&responsePtr, nullptr, &len);
|
||||
FinishPduDeserializer deserializer2(fnBuffer.data(), fnBuffer.size(), emptyInfo);
|
||||
result = deserializer2.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(emptyInfo.getFsResponsesLen() == 1);
|
||||
FilestoreResponseTlv** responseArray = nullptr;
|
||||
emptyInfo.getFilestoreResonses(&responseArray, nullptr, nullptr);
|
||||
REQUIRE(responseArray[0]->getActionCode() == cfdp::FilestoreActionCode::DELETE_FILE);
|
||||
REQUIRE(responseArray[0]->getStatusCode() == cfdp::FSR_NOT_PERFORMED);
|
||||
auto& fileNameRef = responseArray[0]->getFirstFileName();
|
||||
size_t stringSize = 0;
|
||||
const char* string = reinterpret_cast<const char*>(fileNameRef.getValue(&stringSize));
|
||||
std::string firstFileName(string, stringSize);
|
||||
REQUIRE(firstFileName == "hello.txt");
|
||||
|
||||
// Add two filestore responses and a fault location parameter
|
||||
std::string secondName = "hello2.txt";
|
||||
cfdp::Lv secondNameLv(reinterpret_cast<const uint8_t*>(secondName.data()), secondName.size());
|
||||
FilestoreResponseTlv response2(cfdp::FilestoreActionCode::DENY_FILE ,
|
||||
cfdp::FSR_SUCCESS, secondNameLv, nullptr);
|
||||
REQUIRE(response2.getSerializedSize() == 15);
|
||||
len = 2;
|
||||
std::array<FilestoreResponseTlv*, 2> responses {&response, &response2};
|
||||
info.setFilestoreResponsesArray(responses.data(), &len, &len);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
// Add two filestore responses and a fault location parameter
|
||||
std::string secondName = "hello2.txt";
|
||||
cfdp::Lv secondNameLv(reinterpret_cast<const uint8_t*>(secondName.data()), secondName.size());
|
||||
FilestoreResponseTlv response2(cfdp::FilestoreActionCode::DENY_FILE, cfdp::FSR_SUCCESS,
|
||||
secondNameLv, nullptr);
|
||||
REQUIRE(response2.getSerializedSize() == 15);
|
||||
len = 2;
|
||||
std::array<FilestoreResponseTlv*, 2> responses{&response, &response2};
|
||||
info.setFilestoreResponsesArray(responses.data(), &len, &len);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
|
||||
EntityIdTlv faultLoc(destId);
|
||||
info.setFaultLocation(&faultLoc);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
sz = 0;
|
||||
buffer = fnBuffer.data();
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
EntityId emptyId;
|
||||
EntityIdTlv emptyFaultLoc(emptyId);
|
||||
emptyInfo.setFaultLocation(&emptyFaultLoc);
|
||||
response.setFilestoreMessage(&emptyFsMsg);
|
||||
emptyInfo.setFilestoreResponsesArray(responses.data(), &len, &len);
|
||||
response2.setFilestoreMessage(&emptyFsMsg);
|
||||
FinishPduDeserializer deserializer3(fnBuffer.data(), fnBuffer.size(), emptyInfo);
|
||||
result = deserializer3.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
auto& infoRef = deserializer3.getInfo();
|
||||
REQUIRE(deserializer3.getWholePduSize() == 45);
|
||||
EntityIdTlv faultLoc(destId);
|
||||
info.setFaultLocation(&faultLoc);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
sz = 0;
|
||||
buffer = fnBuffer.data();
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
EntityId emptyId;
|
||||
EntityIdTlv emptyFaultLoc(emptyId);
|
||||
emptyInfo.setFaultLocation(&emptyFaultLoc);
|
||||
response.setFilestoreMessage(&emptyFsMsg);
|
||||
emptyInfo.setFilestoreResponsesArray(responses.data(), &len, &len);
|
||||
response2.setFilestoreMessage(&emptyFsMsg);
|
||||
FinishPduDeserializer deserializer3(fnBuffer.data(), fnBuffer.size(), emptyInfo);
|
||||
result = deserializer3.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
auto& infoRef = deserializer3.getInfo();
|
||||
REQUIRE(deserializer3.getWholePduSize() == 45);
|
||||
|
||||
size_t invalidMaxLen = 1;
|
||||
emptyInfo.setFilestoreResponsesArray(responses.data(), &len, &invalidMaxLen);
|
||||
result = deserializer3.parseData();
|
||||
REQUIRE(result == cfdp::FINISHED_CANT_PARSE_FS_RESPONSES);
|
||||
emptyInfo.setFilestoreResponsesArray(nullptr, nullptr, nullptr);
|
||||
result = deserializer3.parseData();
|
||||
REQUIRE(result == cfdp::FINISHED_CANT_PARSE_FS_RESPONSES);
|
||||
size_t invalidMaxLen = 1;
|
||||
emptyInfo.setFilestoreResponsesArray(responses.data(), &len, &invalidMaxLen);
|
||||
result = deserializer3.parseData();
|
||||
REQUIRE(result == cfdp::FINISHED_CANT_PARSE_FS_RESPONSES);
|
||||
emptyInfo.setFilestoreResponsesArray(nullptr, nullptr, nullptr);
|
||||
result = deserializer3.parseData();
|
||||
REQUIRE(result == cfdp::FINISHED_CANT_PARSE_FS_RESPONSES);
|
||||
|
||||
// Clear condition code
|
||||
auto tmp = fnBuffer[11];
|
||||
fnBuffer[11] = fnBuffer[11] & ~0xf0;
|
||||
fnBuffer[11] = fnBuffer[11] | (cfdp::ConditionCode::NO_ERROR << 4);
|
||||
emptyInfo.setFilestoreResponsesArray(responses.data(), &len, &len);
|
||||
result = deserializer3.parseData();
|
||||
REQUIRE(result == cfdp::INVALID_TLV_TYPE);
|
||||
// Clear condition code
|
||||
auto tmp = fnBuffer[11];
|
||||
fnBuffer[11] = fnBuffer[11] & ~0xf0;
|
||||
fnBuffer[11] = fnBuffer[11] | (cfdp::ConditionCode::NO_ERROR << 4);
|
||||
emptyInfo.setFilestoreResponsesArray(responses.data(), &len, &len);
|
||||
result = deserializer3.parseData();
|
||||
REQUIRE(result == cfdp::INVALID_TLV_TYPE);
|
||||
|
||||
fnBuffer[11] = tmp;
|
||||
// Invalid TLV type, should be entity ID
|
||||
fnBuffer[sz - 4] = cfdp::TlvTypes::FILESTORE_REQUEST;
|
||||
result = deserializer3.parseData();
|
||||
REQUIRE(result == cfdp::INVALID_TLV_TYPE);
|
||||
fnBuffer[11] = tmp;
|
||||
// Invalid TLV type, should be entity ID
|
||||
fnBuffer[sz - 4] = cfdp::TlvTypes::FILESTORE_REQUEST;
|
||||
result = deserializer3.parseData();
|
||||
REQUIRE(result == cfdp::INVALID_TLV_TYPE);
|
||||
|
||||
for(size_t maxSz = 0; maxSz < 45; maxSz++) {
|
||||
FinishPduDeserializer faultyDeser(fnBuffer.data(), maxSz, emptyInfo);
|
||||
result = faultyDeser.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
for (size_t maxSz = 0; maxSz < 45; maxSz++) {
|
||||
FinishPduDeserializer faultyDeser(fnBuffer.data(), maxSz, emptyInfo);
|
||||
result = faultyDeser.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,84 +1,79 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/pdu/KeepAlivePduDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/KeepAlivePduSerializer.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
|
||||
#include <array>
|
||||
TEST_CASE("Keep Alive PDU", "[KeepAlivePdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> kaBuffer = {};
|
||||
uint8_t* buffer = kaBuffer.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId);
|
||||
|
||||
TEST_CASE( "Keep Alive PDU" , "[KeepAlivePdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> kaBuffer = {};
|
||||
uint8_t* buffer = kaBuffer.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId);
|
||||
FileSize progress(0x50);
|
||||
|
||||
FileSize progress(0x50);
|
||||
SECTION("Serialize") {
|
||||
KeepAlivePduSerializer serializer(pduConf, progress);
|
||||
result = serializer.serialize(&buffer, &sz, kaBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(kaBuffer[10] == cfdp::FileDirectives::KEEP_ALIVE);
|
||||
uint32_t fsRaw = 0;
|
||||
result = SerializeAdapter::deSerialize(&fsRaw, kaBuffer.data() + 11, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(fsRaw == 0x50);
|
||||
REQUIRE(sz == 15);
|
||||
REQUIRE(serializer.getWholePduSize() == 15);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 5);
|
||||
|
||||
SECTION("Serialize") {
|
||||
KeepAlivePduSerializer serializer(pduConf, progress);
|
||||
result = serializer.serialize(&buffer, &sz, kaBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(kaBuffer[10] == cfdp::FileDirectives::KEEP_ALIVE);
|
||||
uint32_t fsRaw = 0;
|
||||
result = SerializeAdapter::deSerialize(&fsRaw, kaBuffer.data() + 11, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(fsRaw == 0x50);
|
||||
REQUIRE(sz == 15);
|
||||
REQUIRE(serializer.getWholePduSize() == 15);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 5);
|
||||
pduConf.largeFile = true;
|
||||
serializer.updateDirectiveFieldLen();
|
||||
buffer = kaBuffer.data();
|
||||
sz = 0;
|
||||
result = serializer.serialize(&buffer, &sz, kaBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getWholePduSize() == 19);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 9);
|
||||
uint64_t fsRawLarge = 0;
|
||||
result = SerializeAdapter::deSerialize(&fsRawLarge, kaBuffer.data() + 11, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(fsRawLarge == 0x50);
|
||||
|
||||
pduConf.largeFile = true;
|
||||
serializer.updateDirectiveFieldLen();
|
||||
buffer = kaBuffer.data();
|
||||
sz = 0;
|
||||
result = serializer.serialize(&buffer, &sz, kaBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getWholePduSize() == 19);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 9);
|
||||
uint64_t fsRawLarge = 0;
|
||||
result = SerializeAdapter::deSerialize(&fsRawLarge, kaBuffer.data() + 11, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(fsRawLarge == 0x50);
|
||||
|
||||
for(size_t invalidMaxSz = 0; invalidMaxSz < sz; invalidMaxSz++) {
|
||||
buffer = kaBuffer.data();
|
||||
sz = 0;
|
||||
result = serializer.serialize(&buffer, &sz, invalidMaxSz,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
for (size_t invalidMaxSz = 0; invalidMaxSz < sz; invalidMaxSz++) {
|
||||
buffer = kaBuffer.data();
|
||||
sz = 0;
|
||||
result = serializer.serialize(&buffer, &sz, invalidMaxSz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Deserialize") {
|
||||
KeepAlivePduSerializer serializer(pduConf, progress);
|
||||
result = serializer.serialize(&buffer, &sz, kaBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
SECTION("Deserialize") {
|
||||
KeepAlivePduSerializer serializer(pduConf, progress);
|
||||
result = serializer.serialize(&buffer, &sz, kaBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
// Set another file size
|
||||
progress.setFileSize(200, false);
|
||||
KeepAlivePduDeserializer deserializer(kaBuffer.data(), kaBuffer.size(), progress);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
auto& progRef = deserializer.getProgress();
|
||||
// Should have been overwritten
|
||||
REQUIRE(progRef.getSize() == 0x50);
|
||||
sz = deserializer.getWholePduSize();
|
||||
// Set another file size
|
||||
progress.setFileSize(200, false);
|
||||
KeepAlivePduDeserializer deserializer(kaBuffer.data(), kaBuffer.size(), progress);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
auto& progRef = deserializer.getProgress();
|
||||
// Should have been overwritten
|
||||
REQUIRE(progRef.getSize() == 0x50);
|
||||
sz = deserializer.getWholePduSize();
|
||||
|
||||
// invalid max size
|
||||
for(size_t invalidMaxSz = 0; invalidMaxSz < sz; invalidMaxSz++) {
|
||||
deserializer.setData(kaBuffer.data(), invalidMaxSz);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
// invalid max size
|
||||
for (size_t invalidMaxSz = 0; invalidMaxSz < sz; invalidMaxSz++) {
|
||||
deserializer.setData(kaBuffer.data(), invalidMaxSz);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,185 +1,179 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <fsfw/cfdp/tlv/MessageToUserTlv.h>
|
||||
|
||||
#include "fsfw/cfdp/tlv/FilestoreResponseTlv.h"
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/pdu/MetadataPduDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/MetadataPduSerializer.h"
|
||||
#include "fsfw/cfdp/tlv/FilestoreResponseTlv.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
|
||||
#include <array>
|
||||
TEST_CASE("Metadata PDU", "[MetadataPdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> mdBuffer = {};
|
||||
uint8_t* buffer = mdBuffer.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId);
|
||||
|
||||
TEST_CASE( "Metadata PDU" , "[MetadataPdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> mdBuffer = {};
|
||||
std::string firstFileName = "hello.txt";
|
||||
cfdp::Lv sourceFileName(reinterpret_cast<const uint8_t*>(firstFileName.data()),
|
||||
firstFileName.size());
|
||||
cfdp::Lv destFileName(nullptr, 0);
|
||||
FileSize fileSize(35);
|
||||
MetadataInfo info(false, ChecksumType::MODULAR, fileSize, sourceFileName, destFileName);
|
||||
|
||||
FilestoreResponseTlv response(FilestoreActionCode::CREATE_DIRECTORY, FSR_CREATE_NOT_ALLOWED,
|
||||
sourceFileName, nullptr);
|
||||
std::array<uint8_t, 3> msg = {0x41, 0x42, 0x43};
|
||||
cfdp::Tlv responseTlv;
|
||||
std::array<uint8_t, 64> responseBuf = {};
|
||||
uint8_t* responseBufPtr = responseBuf.data();
|
||||
response.convertToTlv(responseTlv, buffer, responseBuf.size(), SerializeIF::Endianness::MACHINE);
|
||||
MessageToUserTlv msgToUser(msg.data(), msg.size());
|
||||
std::array<Tlv*, 2> options{&responseTlv, &msgToUser};
|
||||
REQUIRE(options[0]->getSerializedSize() == 2 + 1 + 10 + 1);
|
||||
REQUIRE(options[1]->getSerializedSize() == 5);
|
||||
|
||||
SECTION("Serialize") {
|
||||
MetadataPduSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getWholePduSize() == 27);
|
||||
REQUIRE(info.getSourceFileName().getSerializedSize() == 10);
|
||||
REQUIRE(info.getDestFileName().getSerializedSize() == 1);
|
||||
REQUIRE(info.getSerializedSize() == 16);
|
||||
REQUIRE((mdBuffer[1] << 8 | mdBuffer[2]) == 17);
|
||||
REQUIRE(mdBuffer[10] == FileDirectives::METADATA);
|
||||
// no closure requested and checksum type is modular => 0x00
|
||||
REQUIRE(mdBuffer[11] == 0x00);
|
||||
uint32_t fileSizeRaw = 0;
|
||||
result = SerializeAdapter::deSerialize(&fileSizeRaw, mdBuffer.data() + 12, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(fileSizeRaw == 35);
|
||||
REQUIRE(mdBuffer[16] == 9);
|
||||
REQUIRE(mdBuffer[17] == 'h');
|
||||
REQUIRE(mdBuffer[18] == 'e');
|
||||
REQUIRE(mdBuffer[19] == 'l');
|
||||
REQUIRE(mdBuffer[20] == 'l');
|
||||
REQUIRE(mdBuffer[21] == 'o');
|
||||
REQUIRE(mdBuffer[22] == '.');
|
||||
REQUIRE(mdBuffer[23] == 't');
|
||||
REQUIRE(mdBuffer[24] == 'x');
|
||||
REQUIRE(mdBuffer[25] == 't');
|
||||
REQUIRE(mdBuffer[26] == 0);
|
||||
|
||||
std::string otherFileName = "hello2.txt";
|
||||
cfdp::Lv otherFileNameLv(reinterpret_cast<const uint8_t*>(otherFileName.data()),
|
||||
otherFileName.size());
|
||||
info.setSourceFileName(otherFileNameLv);
|
||||
size_t sizeOfOptions = options.size();
|
||||
info.setOptionsArray(options.data(), &sizeOfOptions, &sizeOfOptions);
|
||||
REQUIRE(info.getMaxOptionsLen() == 2);
|
||||
info.setMaxOptionsLen(3);
|
||||
REQUIRE(info.getMaxOptionsLen() == 3);
|
||||
info.setChecksumType(cfdp::ChecksumType::CRC_32C);
|
||||
info.setClosureRequested(true);
|
||||
uint8_t* buffer = mdBuffer.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
|
||||
std::string firstFileName = "hello.txt";
|
||||
cfdp::Lv sourceFileName(reinterpret_cast<const uint8_t*>(firstFileName.data()),
|
||||
firstFileName.size());
|
||||
cfdp::Lv destFileName(nullptr, 0);
|
||||
FileSize fileSize(35);
|
||||
MetadataInfo info(false, ChecksumType::MODULAR, fileSize, sourceFileName, destFileName);
|
||||
result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE((mdBuffer[1] << 8 | mdBuffer[2]) == 37);
|
||||
auto checksumType = static_cast<cfdp::ChecksumType>(mdBuffer[11] & 0x0f);
|
||||
REQUIRE(checksumType == cfdp::ChecksumType::CRC_32C);
|
||||
bool closureRequested = mdBuffer[11] >> 6 & 0x01;
|
||||
REQUIRE(closureRequested == true);
|
||||
// The size of the two options is 19. Summing up:
|
||||
// - 11 bytes of source file name
|
||||
// - 1 byte for dest file name
|
||||
// - 4 for FSS
|
||||
// - 1 leading byte.
|
||||
// - 1 byte for PDU type
|
||||
// PDU header has 10 bytes.
|
||||
// I am not going to check the options raw content, those are part of the dedicated
|
||||
// TLV unittests
|
||||
REQUIRE(sz == 10 + 37);
|
||||
for (size_t maxSz = 0; maxSz < sz; maxSz++) {
|
||||
uint8_t* buffer = mdBuffer.data();
|
||||
size_t sz = 0;
|
||||
result = serializer.serialize(&buffer, &sz, maxSz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
for (size_t initSz = 1; initSz < 47; initSz++) {
|
||||
uint8_t* buffer = mdBuffer.data();
|
||||
size_t sz = initSz;
|
||||
result = serializer.serialize(&buffer, &sz, 46, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
info.setDestFileName(destFileName);
|
||||
}
|
||||
|
||||
FilestoreResponseTlv response(FilestoreActionCode::CREATE_DIRECTORY, FSR_CREATE_NOT_ALLOWED,
|
||||
sourceFileName, nullptr);
|
||||
std::array<uint8_t, 3> msg = {0x41, 0x42, 0x43};
|
||||
cfdp::Tlv responseTlv;
|
||||
std::array<uint8_t, 64> responseBuf = {};
|
||||
uint8_t* responseBufPtr = responseBuf.data();
|
||||
response.convertToTlv(responseTlv, buffer, responseBuf.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
MessageToUserTlv msgToUser(msg.data(), msg.size());
|
||||
std::array<Tlv*, 2> options {&responseTlv, &msgToUser};
|
||||
REQUIRE(options[0]->getSerializedSize() == 2 + 1 + 10 + 1);
|
||||
SECTION("Deserialize") {
|
||||
MetadataPduSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
MetadataPduDeserializer deserializer(mdBuffer.data(), mdBuffer.size(), info);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
size_t fullSize = deserializer.getWholePduSize();
|
||||
for (size_t maxSz = 0; maxSz < fullSize; maxSz++) {
|
||||
MetadataPduDeserializer invalidSzDeser(mdBuffer.data(), maxSz, info);
|
||||
result = invalidSzDeser.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
size_t sizeOfOptions = options.size();
|
||||
size_t maxSize = 4;
|
||||
info.setOptionsArray(options.data(), &sizeOfOptions, &maxSize);
|
||||
REQUIRE(info.getOptionsLen() == 2);
|
||||
info.setChecksumType(cfdp::ChecksumType::CRC_32C);
|
||||
info.setClosureRequested(true);
|
||||
uint8_t* buffer = mdBuffer.data();
|
||||
size_t sz = 0;
|
||||
serializer.updateDirectiveFieldLen();
|
||||
|
||||
info.setSourceFileName(sourceFileName);
|
||||
result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
MetadataPduDeserializer deserializer2(mdBuffer.data(), mdBuffer.size(), info);
|
||||
result = deserializer2.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(options[0]->getType() == cfdp::TlvTypes::FILESTORE_RESPONSE);
|
||||
REQUIRE(options[0]->getSerializedSize() == 14);
|
||||
REQUIRE(options[1]->getType() == cfdp::TlvTypes::MSG_TO_USER);
|
||||
REQUIRE(options[1]->getSerializedSize() == 5);
|
||||
|
||||
SECTION("Serialize") {
|
||||
MetadataPduSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, mdBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getWholePduSize() == 27);
|
||||
REQUIRE(info.getSourceFileName().getSerializedSize() == 10);
|
||||
REQUIRE(info.getDestFileName().getSerializedSize() == 1);
|
||||
REQUIRE(info.getSerializedSize() == 16);
|
||||
REQUIRE((mdBuffer[1] << 8 | mdBuffer[2]) == 17);
|
||||
REQUIRE(mdBuffer[10] == FileDirectives::METADATA);
|
||||
// no closure requested and checksum type is modular => 0x00
|
||||
REQUIRE(mdBuffer[11] == 0x00);
|
||||
uint32_t fileSizeRaw = 0;
|
||||
result = SerializeAdapter::deSerialize(&fileSizeRaw, mdBuffer.data() + 12, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(fileSizeRaw == 35);
|
||||
REQUIRE(mdBuffer[16] == 9);
|
||||
REQUIRE(mdBuffer[17] == 'h');
|
||||
REQUIRE(mdBuffer[18] == 'e');
|
||||
REQUIRE(mdBuffer[19] == 'l');
|
||||
REQUIRE(mdBuffer[20] == 'l');
|
||||
REQUIRE(mdBuffer[21] == 'o');
|
||||
REQUIRE(mdBuffer[22] == '.');
|
||||
REQUIRE(mdBuffer[23] == 't');
|
||||
REQUIRE(mdBuffer[24] == 'x');
|
||||
REQUIRE(mdBuffer[25] == 't');
|
||||
REQUIRE(mdBuffer[26] == 0);
|
||||
|
||||
std::string otherFileName = "hello2.txt";
|
||||
cfdp::Lv otherFileNameLv(reinterpret_cast<const uint8_t*>(otherFileName.data()),
|
||||
otherFileName.size());
|
||||
info.setSourceFileName(otherFileNameLv);
|
||||
size_t sizeOfOptions = options.size();
|
||||
info.setOptionsArray(options.data(), &sizeOfOptions, &sizeOfOptions);
|
||||
REQUIRE(info.getMaxOptionsLen() == 2);
|
||||
info.setMaxOptionsLen(3);
|
||||
REQUIRE(info.getMaxOptionsLen() == 3);
|
||||
info.setChecksumType(cfdp::ChecksumType::CRC_32C);
|
||||
info.setClosureRequested(true);
|
||||
uint8_t* buffer = mdBuffer.data();
|
||||
size_t sz = 0;
|
||||
serializer.updateDirectiveFieldLen();
|
||||
|
||||
result = serializer.serialize(&buffer, &sz, mdBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE((mdBuffer[1] << 8 | mdBuffer[2]) == 37);
|
||||
auto checksumType = static_cast<cfdp::ChecksumType>(mdBuffer[11] & 0x0f);
|
||||
REQUIRE(checksumType == cfdp::ChecksumType::CRC_32C);
|
||||
bool closureRequested = mdBuffer[11] >> 6 & 0x01;
|
||||
REQUIRE(closureRequested == true);
|
||||
// The size of the two options is 19. Summing up:
|
||||
// - 11 bytes of source file name
|
||||
// - 1 byte for dest file name
|
||||
// - 4 for FSS
|
||||
// - 1 leading byte.
|
||||
// - 1 byte for PDU type
|
||||
// PDU header has 10 bytes.
|
||||
// I am not going to check the options raw content, those are part of the dedicated
|
||||
// TLV unittests
|
||||
REQUIRE(sz == 10 + 37);
|
||||
for(size_t maxSz = 0; maxSz < sz; maxSz++) {
|
||||
uint8_t* buffer = mdBuffer.data();
|
||||
size_t sz = 0;
|
||||
result = serializer.serialize(&buffer, &sz, maxSz,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
for(size_t initSz = 1; initSz < 47; initSz++) {
|
||||
uint8_t* buffer = mdBuffer.data();
|
||||
size_t sz = initSz;
|
||||
result = serializer.serialize(&buffer, &sz, 46, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
info.setDestFileName(destFileName);
|
||||
for (size_t invalidFieldLen = 0; invalidFieldLen < 36; invalidFieldLen++) {
|
||||
mdBuffer[1] = (invalidFieldLen >> 8) & 0xff;
|
||||
mdBuffer[2] = invalidFieldLen & 0xff;
|
||||
result = deserializer2.parseData();
|
||||
if (invalidFieldLen == 17) {
|
||||
REQUIRE(info.getOptionsLen() == 0);
|
||||
}
|
||||
if (invalidFieldLen == 31) {
|
||||
REQUIRE(info.getOptionsLen() == 1);
|
||||
}
|
||||
// This is the precise length where there are no options or one option
|
||||
if (invalidFieldLen != 17 and invalidFieldLen != 31) {
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Deserialize") {
|
||||
MetadataPduSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, mdBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
MetadataPduDeserializer deserializer(mdBuffer.data(), mdBuffer.size(), info);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
size_t fullSize = deserializer.getWholePduSize();
|
||||
for(size_t maxSz = 0; maxSz < fullSize; maxSz++) {
|
||||
MetadataPduDeserializer invalidSzDeser(mdBuffer.data(), maxSz, info);
|
||||
result = invalidSzDeser.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
size_t sizeOfOptions = options.size();
|
||||
size_t maxSize = 4;
|
||||
info.setOptionsArray(options.data(), &sizeOfOptions, &maxSize);
|
||||
REQUIRE(info.getOptionsLen() == 2);
|
||||
info.setChecksumType(cfdp::ChecksumType::CRC_32C);
|
||||
info.setClosureRequested(true);
|
||||
uint8_t* buffer = mdBuffer.data();
|
||||
size_t sz = 0;
|
||||
serializer.updateDirectiveFieldLen();
|
||||
|
||||
info.setSourceFileName(sourceFileName);
|
||||
result = serializer.serialize(&buffer, &sz, mdBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
MetadataPduDeserializer deserializer2(mdBuffer.data(), mdBuffer.size(), info);
|
||||
result = deserializer2.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(options[0]->getType() == cfdp::TlvTypes::FILESTORE_RESPONSE);
|
||||
REQUIRE(options[0]->getSerializedSize() == 14);
|
||||
REQUIRE(options[1]->getType() == cfdp::TlvTypes::MSG_TO_USER);
|
||||
REQUIRE(options[1]->getSerializedSize() == 5);
|
||||
|
||||
for(size_t invalidFieldLen = 0; invalidFieldLen < 36; invalidFieldLen++) {
|
||||
mdBuffer[1] = (invalidFieldLen >> 8) & 0xff;
|
||||
mdBuffer[2] = invalidFieldLen & 0xff;
|
||||
result = deserializer2.parseData();
|
||||
if(invalidFieldLen == 17) {
|
||||
REQUIRE(info.getOptionsLen() == 0);
|
||||
}
|
||||
if(invalidFieldLen == 31) {
|
||||
REQUIRE(info.getOptionsLen() == 1);
|
||||
}
|
||||
// This is the precise length where there are no options or one option
|
||||
if(invalidFieldLen != 17 and invalidFieldLen != 31) {
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
mdBuffer[1] = (36 >> 8) & 0xff;
|
||||
mdBuffer[2] = 36 & 0xff;
|
||||
info.setOptionsArray(nullptr, nullptr, nullptr);
|
||||
REQUIRE(deserializer2.parseData() == cfdp::METADATA_CANT_PARSE_OPTIONS);
|
||||
info.setOptionsArray(options.data(), &sizeOfOptions, nullptr);
|
||||
for(size_t maxSz = 0; maxSz < 46; maxSz++) {
|
||||
MetadataPduDeserializer invalidSzDeser(mdBuffer.data(), maxSz, info);
|
||||
result = invalidSzDeser.parseData();
|
||||
REQUIRE(result == SerializeIF::STREAM_TOO_SHORT);
|
||||
}
|
||||
mdBuffer[1] = (36 >> 8) & 0xff;
|
||||
mdBuffer[2] = 36 & 0xff;
|
||||
info.setOptionsArray(nullptr, nullptr, nullptr);
|
||||
REQUIRE(deserializer2.parseData() == cfdp::METADATA_CANT_PARSE_OPTIONS);
|
||||
info.setOptionsArray(options.data(), &sizeOfOptions, nullptr);
|
||||
for (size_t maxSz = 0; maxSz < 46; maxSz++) {
|
||||
MetadataPduDeserializer invalidSzDeser(mdBuffer.data(), maxSz, info);
|
||||
result = invalidSzDeser.parseData();
|
||||
REQUIRE(result == SerializeIF::STREAM_TOO_SHORT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,160 +1,152 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/pdu/PduConfig.h"
|
||||
#include "fsfw/cfdp/pdu/NakPduDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/NakPduSerializer.h"
|
||||
#include "fsfw/cfdp/pdu/PduConfig.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
|
||||
#include <array>
|
||||
TEST_CASE("NAK PDU", "[NakPdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> nakBuffer = {};
|
||||
uint8_t* buffer = nakBuffer.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId);
|
||||
|
||||
TEST_CASE( "NAK PDU" , "[NakPdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> nakBuffer = {};
|
||||
FileSize startOfScope(50);
|
||||
FileSize endOfScope(1050);
|
||||
NakInfo info(startOfScope, endOfScope);
|
||||
SECTION("Serializer") {
|
||||
NakPduSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, nakBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getSerializedSize() == 19);
|
||||
REQUIRE(serializer.FileDirectiveSerializer::getSerializedSize() == 11);
|
||||
REQUIRE(sz == 19);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 9);
|
||||
REQUIRE(((nakBuffer[1] << 8) | nakBuffer[2]) == 0x09);
|
||||
REQUIRE(nakBuffer[10] == cfdp::FileDirectives::NAK);
|
||||
uint32_t scope = 0;
|
||||
result = SerializeAdapter::deSerialize(&scope, nakBuffer.data() + 11, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(scope == 50);
|
||||
result = SerializeAdapter::deSerialize(&scope, nakBuffer.data() + 15, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(scope == 1050);
|
||||
|
||||
NakInfo::SegmentRequest segReq0(cfdp::FileSize(2020), cfdp::FileSize(2520));
|
||||
NakInfo::SegmentRequest segReq1(cfdp::FileSize(2932), cfdp::FileSize(3021));
|
||||
// Now add 2 segment requests to NAK info and serialize them as well
|
||||
std::array<NakInfo::SegmentRequest, 2> segReqs = {segReq0, segReq1};
|
||||
size_t segReqsLen = segReqs.size();
|
||||
info.setSegmentRequests(segReqs.data(), &segReqsLen, &segReqsLen);
|
||||
uint8_t* buffer = nakBuffer.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
result = serializer.serialize(&buffer, &sz, nakBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getSerializedSize() == 35);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 25);
|
||||
REQUIRE(((nakBuffer[1] << 8) | nakBuffer[2]) == 25);
|
||||
uint32_t segReqScopes = 0;
|
||||
result = SerializeAdapter::deSerialize(&segReqScopes, nakBuffer.data() + 19, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(segReqScopes == 2020);
|
||||
result = SerializeAdapter::deSerialize(&segReqScopes, nakBuffer.data() + 23, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(segReqScopes == 2520);
|
||||
result = SerializeAdapter::deSerialize(&segReqScopes, nakBuffer.data() + 27, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(segReqScopes == 2932);
|
||||
result = SerializeAdapter::deSerialize(&segReqScopes, nakBuffer.data() + 31, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(segReqScopes == 3021);
|
||||
|
||||
FileSize startOfScope(50);
|
||||
FileSize endOfScope(1050);
|
||||
NakInfo info(startOfScope, endOfScope);
|
||||
SECTION("Serializer") {
|
||||
NakPduSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, nakBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getSerializedSize() == 19);
|
||||
REQUIRE(serializer.FileDirectiveSerializer::getSerializedSize() == 11);
|
||||
REQUIRE(sz == 19);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 9);
|
||||
REQUIRE(((nakBuffer[1] << 8) | nakBuffer[2]) == 0x09);
|
||||
REQUIRE(nakBuffer[10] == cfdp::FileDirectives::NAK);
|
||||
uint32_t scope = 0;
|
||||
result = SerializeAdapter::deSerialize(&scope, nakBuffer.data() + 11, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(scope == 50);
|
||||
result = SerializeAdapter::deSerialize(&scope, nakBuffer.data() + 15, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(scope == 1050);
|
||||
|
||||
NakInfo::SegmentRequest segReq0(cfdp::FileSize(2020), cfdp::FileSize(2520));
|
||||
NakInfo::SegmentRequest segReq1(cfdp::FileSize(2932), cfdp::FileSize(3021));
|
||||
// Now add 2 segment requests to NAK info and serialize them as well
|
||||
std::array<NakInfo::SegmentRequest, 2> segReqs = { segReq0, segReq1 };
|
||||
size_t segReqsLen = segReqs.size();
|
||||
info.setSegmentRequests(segReqs.data(), &segReqsLen , &segReqsLen);
|
||||
uint8_t* buffer = nakBuffer.data();
|
||||
size_t sz = 0;
|
||||
serializer.updateDirectiveFieldLen();
|
||||
result = serializer.serialize(&buffer, &sz, nakBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getSerializedSize() == 35);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 25);
|
||||
REQUIRE(((nakBuffer[1] << 8) | nakBuffer[2]) == 25);
|
||||
uint32_t segReqScopes = 0;
|
||||
result = SerializeAdapter::deSerialize(&segReqScopes, nakBuffer.data() + 19, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(segReqScopes == 2020);
|
||||
result = SerializeAdapter::deSerialize(&segReqScopes, nakBuffer.data() + 23, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(segReqScopes == 2520);
|
||||
result = SerializeAdapter::deSerialize(&segReqScopes, nakBuffer.data() + 27, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(segReqScopes == 2932);
|
||||
result = SerializeAdapter::deSerialize(&segReqScopes, nakBuffer.data() + 31, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(segReqScopes == 3021);
|
||||
|
||||
for(size_t maxSz = 0; maxSz < 35; maxSz++) {
|
||||
uint8_t* buffer = nakBuffer.data();
|
||||
size_t sz = 0;
|
||||
result = serializer.serialize(&buffer, &sz, maxSz,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
for(size_t sz = 35; sz > 0; sz--) {
|
||||
uint8_t* buffer = nakBuffer.data();
|
||||
size_t locSize = sz;
|
||||
result = serializer.serialize(&buffer, &locSize, 35,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
for (size_t maxSz = 0; maxSz < 35; maxSz++) {
|
||||
uint8_t* buffer = nakBuffer.data();
|
||||
size_t sz = 0;
|
||||
result = serializer.serialize(&buffer, &sz, maxSz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
for (size_t sz = 35; sz > 0; sz--) {
|
||||
uint8_t* buffer = nakBuffer.data();
|
||||
size_t locSize = sz;
|
||||
result = serializer.serialize(&buffer, &locSize, 35, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Deserializer") {
|
||||
NakPduSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, nakBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
SECTION("Deserializer") {
|
||||
NakPduSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, nakBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
info.getStartOfScope().setFileSize(0, false);
|
||||
info.getEndOfScope().setFileSize(0, false);
|
||||
NakPduDeserializer deserializer(nakBuffer.data(), nakBuffer.size(), info);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserializer.getWholePduSize() == 19);
|
||||
REQUIRE(info.getStartOfScope().getSize() == 50);
|
||||
REQUIRE(info.getEndOfScope().getSize() == 1050);
|
||||
info.getStartOfScope().setFileSize(0, false);
|
||||
info.getEndOfScope().setFileSize(0, false);
|
||||
NakPduDeserializer deserializer(nakBuffer.data(), nakBuffer.size(), info);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserializer.getWholePduSize() == 19);
|
||||
REQUIRE(info.getStartOfScope().getSize() == 50);
|
||||
REQUIRE(info.getEndOfScope().getSize() == 1050);
|
||||
|
||||
NakInfo::SegmentRequest segReq0(cfdp::FileSize(2020), cfdp::FileSize(2520));
|
||||
NakInfo::SegmentRequest segReq1(cfdp::FileSize(2932), cfdp::FileSize(3021));
|
||||
// Now add 2 segment requests to NAK info and serialize them as well
|
||||
std::array<NakInfo::SegmentRequest, 2> segReqs = { segReq0, segReq1 };
|
||||
size_t segReqsLen = segReqs.size();
|
||||
info.setSegmentRequests(segReqs.data(), &segReqsLen, &segReqsLen);
|
||||
uint8_t* buffer = nakBuffer.data();
|
||||
size_t sz = 0;
|
||||
serializer.updateDirectiveFieldLen();
|
||||
result = serializer.serialize(&buffer, &sz, nakBuffer.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
NakInfo::SegmentRequest segReq0(cfdp::FileSize(2020), cfdp::FileSize(2520));
|
||||
NakInfo::SegmentRequest segReq1(cfdp::FileSize(2932), cfdp::FileSize(3021));
|
||||
// Now add 2 segment requests to NAK info and serialize them as well
|
||||
std::array<NakInfo::SegmentRequest, 2> segReqs = {segReq0, segReq1};
|
||||
size_t segReqsLen = segReqs.size();
|
||||
info.setSegmentRequests(segReqs.data(), &segReqsLen, &segReqsLen);
|
||||
uint8_t* buffer = nakBuffer.data();
|
||||
size_t sz = 0;
|
||||
serializer.updateDirectiveFieldLen();
|
||||
result = serializer.serialize(&buffer, &sz, nakBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
NakPduDeserializer deserializeWithSegReqs(nakBuffer.data(), nakBuffer.size(), info);
|
||||
result = deserializeWithSegReqs.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
NakInfo::SegmentRequest* segReqsPtr = nullptr;
|
||||
size_t readSegReqs = 0;
|
||||
info.getSegmentRequests(&segReqsPtr, &readSegReqs, nullptr);
|
||||
REQUIRE(readSegReqs == 2);
|
||||
REQUIRE(segReqsPtr[0].first.getSize() == 2020);
|
||||
REQUIRE(segReqsPtr[0].second.getSize() == 2520);
|
||||
REQUIRE(segReqsPtr[1].first.getSize() == 2932);
|
||||
REQUIRE(segReqsPtr[1].second.getSize() == 3021);
|
||||
REQUIRE(deserializeWithSegReqs.getPduDataFieldLen() == 25);
|
||||
NakPduDeserializer deserializeWithSegReqs(nakBuffer.data(), nakBuffer.size(), info);
|
||||
result = deserializeWithSegReqs.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
NakInfo::SegmentRequest* segReqsPtr = nullptr;
|
||||
size_t readSegReqs = 0;
|
||||
info.getSegmentRequests(&segReqsPtr, &readSegReqs, nullptr);
|
||||
REQUIRE(readSegReqs == 2);
|
||||
REQUIRE(segReqsPtr[0].first.getSize() == 2020);
|
||||
REQUIRE(segReqsPtr[0].second.getSize() == 2520);
|
||||
REQUIRE(segReqsPtr[1].first.getSize() == 2932);
|
||||
REQUIRE(segReqsPtr[1].second.getSize() == 3021);
|
||||
REQUIRE(deserializeWithSegReqs.getPduDataFieldLen() == 25);
|
||||
REQUIRE(info.getSegmentRequestsLen() == 2);
|
||||
for (size_t idx = 0; idx < 34; idx++) {
|
||||
NakPduDeserializer faultyDeserializer(nakBuffer.data(), idx, info);
|
||||
result = faultyDeserializer.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
for (size_t pduFieldLen = 0; pduFieldLen < 25; pduFieldLen++) {
|
||||
nakBuffer[1] = (pduFieldLen >> 8) & 0xff;
|
||||
nakBuffer[2] = pduFieldLen & 0xff;
|
||||
NakPduDeserializer faultyDeserializer(nakBuffer.data(), nakBuffer.size(), info);
|
||||
result = faultyDeserializer.parseData();
|
||||
if (pduFieldLen == 9) {
|
||||
REQUIRE(info.getSegmentRequestsLen() == 0);
|
||||
} else if (pduFieldLen == 17) {
|
||||
REQUIRE(info.getSegmentRequestsLen() == 1);
|
||||
} else if (pduFieldLen == 25) {
|
||||
REQUIRE(info.getSegmentRequestsLen() == 2);
|
||||
for(size_t idx = 0; idx < 34; idx ++) {
|
||||
NakPduDeserializer faultyDeserializer(nakBuffer.data(), idx, info);
|
||||
result = faultyDeserializer.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
for(size_t pduFieldLen = 0; pduFieldLen < 25; pduFieldLen++) {
|
||||
nakBuffer[1] = (pduFieldLen >> 8) & 0xff;
|
||||
nakBuffer[2] = pduFieldLen & 0xff;
|
||||
NakPduDeserializer faultyDeserializer(nakBuffer.data(), nakBuffer.size(), info);
|
||||
result = faultyDeserializer.parseData();
|
||||
if(pduFieldLen == 9) {
|
||||
REQUIRE(info.getSegmentRequestsLen() == 0);
|
||||
} else if(pduFieldLen == 17) {
|
||||
REQUIRE(info.getSegmentRequestsLen() == 1);
|
||||
} else if(pduFieldLen == 25) {
|
||||
REQUIRE(info.getSegmentRequestsLen() == 2);
|
||||
}
|
||||
if(pduFieldLen != 9 and pduFieldLen != 17 and pduFieldLen != 25) {
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
info.setMaxSegmentRequestLen(5);
|
||||
REQUIRE(info.getSegmentRequestsMaxLen() == 5);
|
||||
}
|
||||
if (pduFieldLen != 9 and pduFieldLen != 17 and pduFieldLen != 25) {
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
info.setMaxSegmentRequestLen(5);
|
||||
REQUIRE(info.getSegmentRequestsMaxLen() == 5);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,71 +1,65 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/pdu/PromptPduDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/PromptPduSerializer.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
|
||||
#include <array>
|
||||
TEST_CASE("Prompt PDU", "[PromptPdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> rawBuf = {};
|
||||
uint8_t* buffer = rawBuf.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId);
|
||||
|
||||
TEST_CASE( "Prompt PDU" , "[PromptPdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> rawBuf = {};
|
||||
uint8_t* buffer = rawBuf.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(TransmissionModes::ACKNOWLEDGED, seqNum, sourceId, destId);
|
||||
SECTION("Serialize") {
|
||||
PromptPduSerializer serializer(pduConf, cfdp::PromptResponseRequired::PROMPT_KEEP_ALIVE);
|
||||
result = serializer.serialize(&buffer, &sz, rawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getWholePduSize() == 12);
|
||||
REQUIRE(sz == 12);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 2);
|
||||
REQUIRE(rawBuf[10] == FileDirectives::PROMPT);
|
||||
REQUIRE((rawBuf[sz - 1] >> 7) & 0x01 == cfdp::PromptResponseRequired::PROMPT_KEEP_ALIVE);
|
||||
|
||||
SECTION("Serialize") {
|
||||
PromptPduSerializer serializer(pduConf, cfdp::PromptResponseRequired::PROMPT_KEEP_ALIVE);
|
||||
result = serializer.serialize(&buffer, &sz, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getWholePduSize() == 12);
|
||||
REQUIRE(sz == 12);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 2);
|
||||
REQUIRE(rawBuf[10] == FileDirectives::PROMPT);
|
||||
REQUIRE((rawBuf[sz - 1] >> 7) & 0x01 == cfdp::PromptResponseRequired::PROMPT_KEEP_ALIVE);
|
||||
|
||||
for(size_t invalidMaxSz = 0; invalidMaxSz < sz; invalidMaxSz++) {
|
||||
uint8_t* buffer = rawBuf.data();
|
||||
size_t sz = 0;
|
||||
result = serializer.serialize(&buffer, &sz, invalidMaxSz,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
for(size_t invalidSz = 1; invalidSz < sz; invalidSz++) {
|
||||
size_t locSz = invalidSz;
|
||||
uint8_t* buffer = rawBuf.data();
|
||||
result = serializer.serialize(&buffer, &locSz, sz,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
for (size_t invalidMaxSz = 0; invalidMaxSz < sz; invalidMaxSz++) {
|
||||
uint8_t* buffer = rawBuf.data();
|
||||
size_t sz = 0;
|
||||
result = serializer.serialize(&buffer, &sz, invalidMaxSz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
|
||||
SECTION("Deserialize") {
|
||||
PromptPduSerializer serializer(pduConf, cfdp::PromptResponseRequired::PROMPT_KEEP_ALIVE);
|
||||
result = serializer.serialize(&buffer, &sz, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
PromptPduDeserializer deserializer(rawBuf.data(), rawBuf.size());
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserializer.getPromptResponseRequired() ==
|
||||
cfdp::PromptResponseRequired::PROMPT_KEEP_ALIVE);
|
||||
sz = deserializer.getWholePduSize();
|
||||
rawBuf[2] = 1;
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == SerializeIF::STREAM_TOO_SHORT);
|
||||
rawBuf[2] = 2;
|
||||
|
||||
for(size_t invalidMaxSz = 0; invalidMaxSz < sz; invalidMaxSz++) {
|
||||
deserializer.setData(rawBuf.data(), invalidMaxSz);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
for (size_t invalidSz = 1; invalidSz < sz; invalidSz++) {
|
||||
size_t locSz = invalidSz;
|
||||
uint8_t* buffer = rawBuf.data();
|
||||
result = serializer.serialize(&buffer, &locSz, sz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Deserialize") {
|
||||
PromptPduSerializer serializer(pduConf, cfdp::PromptResponseRequired::PROMPT_KEEP_ALIVE);
|
||||
result = serializer.serialize(&buffer, &sz, rawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
PromptPduDeserializer deserializer(rawBuf.data(), rawBuf.size());
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserializer.getPromptResponseRequired() ==
|
||||
cfdp::PromptResponseRequired::PROMPT_KEEP_ALIVE);
|
||||
sz = deserializer.getWholePduSize();
|
||||
rawBuf[2] = 1;
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == SerializeIF::STREAM_TOO_SHORT);
|
||||
rawBuf[2] = 2;
|
||||
|
||||
for (size_t invalidMaxSz = 0; invalidMaxSz < sz; invalidMaxSz++) {
|
||||
deserializer.setData(rawBuf.data(), invalidMaxSz);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,334 +1,330 @@
|
||||
#include "fsfw/cfdp/pdu/PduConfig.h"
|
||||
#include "fsfw/cfdp/tlv/Tlv.h"
|
||||
#include "fsfw/cfdp/tlv/Lv.h"
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <fsfw/cfdp/tlv/EntityIdTlv.h>
|
||||
#include <fsfw/cfdp/tlv/FaultHandlerOverrideTlv.h>
|
||||
#include <fsfw/cfdp/tlv/FilestoreRequestTlv.h>
|
||||
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
#include <fsfw/cfdp/tlv/FilestoreResponseTlv.h>
|
||||
#include <fsfw/cfdp/tlv/FlowLabelTlv.h>
|
||||
#include <fsfw/cfdp/tlv/MessageToUserTlv.h>
|
||||
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <string>
|
||||
|
||||
TEST_CASE( "CFDP TLV LV" , "[CfdpTlvLv]") {
|
||||
using namespace cfdp;
|
||||
int result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 255> rawBuf;
|
||||
uint8_t* serPtr = rawBuf.data();
|
||||
const uint8_t* deserPtr = rawBuf.data();
|
||||
size_t deserSize = 0;
|
||||
cfdp::EntityId sourceId = EntityId(cfdp::WidthInBytes::TWO_BYTES, 0x0ff0);
|
||||
#include "fsfw/cfdp/pdu/PduConfig.h"
|
||||
#include "fsfw/cfdp/tlv/Lv.h"
|
||||
#include "fsfw/cfdp/tlv/Tlv.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
|
||||
SECTION("TLV Serialization") {
|
||||
std::array<uint8_t, 8> tlvRawBuf;
|
||||
serPtr = tlvRawBuf.data();
|
||||
result = sourceId.serialize(&serPtr, &deserSize, tlvRawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserSize == 2);
|
||||
auto tlv = Tlv(TlvTypes::ENTITY_ID, tlvRawBuf.data(), deserSize);
|
||||
REQUIRE(tlv.getSerializedSize() == 4);
|
||||
REQUIRE(tlv.getLengthField() == 2);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
result = tlv.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserSize == 4);
|
||||
REQUIRE(rawBuf[0] == TlvTypes::ENTITY_ID);
|
||||
REQUIRE(rawBuf[1] == 2);
|
||||
uint16_t entityId = 0;
|
||||
SerializeAdapter::deSerialize(&entityId, rawBuf.data() + 2, &deserSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(entityId == 0x0ff0);
|
||||
TEST_CASE("CFDP TLV LV", "[CfdpTlvLv]") {
|
||||
using namespace cfdp;
|
||||
int result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 255> rawBuf;
|
||||
uint8_t* serPtr = rawBuf.data();
|
||||
const uint8_t* deserPtr = rawBuf.data();
|
||||
size_t deserSize = 0;
|
||||
cfdp::EntityId sourceId = EntityId(cfdp::WidthInBytes::TWO_BYTES, 0x0ff0);
|
||||
|
||||
// Set new value
|
||||
sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 12);
|
||||
serPtr = tlvRawBuf.data();
|
||||
deserSize = 0;
|
||||
result = sourceId.serialize(&serPtr, &deserSize, tlvRawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
tlv.setValue(tlvRawBuf.data(), cfdp::WidthInBytes::FOUR_BYTES);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
result = tlv.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(rawBuf[0] == TlvTypes::ENTITY_ID);
|
||||
REQUIRE(rawBuf[1] == 4);
|
||||
SECTION("TLV Serialization") {
|
||||
std::array<uint8_t, 8> tlvRawBuf;
|
||||
serPtr = tlvRawBuf.data();
|
||||
result =
|
||||
sourceId.serialize(&serPtr, &deserSize, tlvRawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserSize == 2);
|
||||
auto tlv = Tlv(TlvTypes::ENTITY_ID, tlvRawBuf.data(), deserSize);
|
||||
REQUIRE(tlv.getSerializedSize() == 4);
|
||||
REQUIRE(tlv.getLengthField() == 2);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
result = tlv.serialize(&serPtr, &deserSize, rawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserSize == 4);
|
||||
REQUIRE(rawBuf[0] == TlvTypes::ENTITY_ID);
|
||||
REQUIRE(rawBuf[1] == 2);
|
||||
uint16_t entityId = 0;
|
||||
SerializeAdapter::deSerialize(&entityId, rawBuf.data() + 2, &deserSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(entityId == 0x0ff0);
|
||||
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
// Set new value
|
||||
sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 12);
|
||||
serPtr = tlvRawBuf.data();
|
||||
deserSize = 0;
|
||||
result =
|
||||
sourceId.serialize(&serPtr, &deserSize, tlvRawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
tlv.setValue(tlvRawBuf.data(), cfdp::WidthInBytes::FOUR_BYTES);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
result = tlv.serialize(&serPtr, &deserSize, rawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(rawBuf[0] == TlvTypes::ENTITY_ID);
|
||||
REQUIRE(rawBuf[1] == 4);
|
||||
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
auto tlvInvalid = Tlv(cfdp::TlvTypes::INVALID_TLV, tlvRawBuf.data(), 0);
|
||||
REQUIRE(tlvInvalid.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK) != HasReturnvaluesIF::RETURN_OK);
|
||||
tlvInvalid = Tlv(cfdp::TlvTypes::ENTITY_ID, nullptr, 3);
|
||||
REQUIRE(tlvInvalid.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK) != HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(tlvInvalid.serialize(&serPtr, &deserSize, 0,
|
||||
SerializeIF::Endianness::NETWORK) != HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(tlvInvalid.getSerializedSize() == 0);
|
||||
REQUIRE(tlvInvalid.serialize(nullptr, nullptr, 0,
|
||||
SerializeIF::Endianness::NETWORK) != HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
Tlv zeroLenField(TlvTypes::FAULT_HANDLER, nullptr, 0);
|
||||
REQUIRE(zeroLenField.getSerializedSize() == 2);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
REQUIRE(zeroLenField.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK) == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(rawBuf[0] == TlvTypes::FAULT_HANDLER);
|
||||
REQUIRE(rawBuf[1] == 0);
|
||||
}
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
auto tlvInvalid = Tlv(cfdp::TlvTypes::INVALID_TLV, tlvRawBuf.data(), 0);
|
||||
REQUIRE(tlvInvalid.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK) != HasReturnvaluesIF::RETURN_OK);
|
||||
tlvInvalid = Tlv(cfdp::TlvTypes::ENTITY_ID, nullptr, 3);
|
||||
REQUIRE(tlvInvalid.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK) != HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(tlvInvalid.serialize(&serPtr, &deserSize, 0, SerializeIF::Endianness::NETWORK) !=
|
||||
HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(tlvInvalid.getSerializedSize() == 0);
|
||||
REQUIRE(tlvInvalid.serialize(nullptr, nullptr, 0, SerializeIF::Endianness::NETWORK) !=
|
||||
HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
SECTION("TLV Deserialization") {
|
||||
// Serialization was tested before, generate raw data now
|
||||
std::array<uint8_t, 8> tlvRawBuf;
|
||||
serPtr = tlvRawBuf.data();
|
||||
result = sourceId.serialize(&serPtr, &deserSize, tlvRawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
auto tlvSerialization = Tlv(TlvTypes::ENTITY_ID, tlvRawBuf.data(), deserSize);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
result = tlvSerialization.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
Tlv tlv;
|
||||
deserPtr = rawBuf.data();
|
||||
result = tlv.deSerialize(&deserPtr, &deserSize, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(tlv.getSerializedSize() == 4);
|
||||
REQUIRE(tlv.getType() == TlvTypes::ENTITY_ID);
|
||||
deserPtr = tlv.getValue();
|
||||
uint16_t entityId = 0;
|
||||
deserSize = 0;
|
||||
SerializeAdapter::deSerialize(&entityId, deserPtr, &deserSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(entityId == 0x0ff0);
|
||||
Tlv zeroLenField(TlvTypes::FAULT_HANDLER, nullptr, 0);
|
||||
REQUIRE(zeroLenField.getSerializedSize() == 2);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
REQUIRE(zeroLenField.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK) ==
|
||||
HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(rawBuf[0] == TlvTypes::FAULT_HANDLER);
|
||||
REQUIRE(rawBuf[1] == 0);
|
||||
}
|
||||
|
||||
REQUIRE(tlv.deSerialize(nullptr, nullptr, SerializeIF::Endianness::NETWORK) !=
|
||||
HasReturnvaluesIF::RETURN_OK);
|
||||
deserPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
REQUIRE(tlv.deSerialize(&deserPtr, &deserSize, SerializeIF::Endianness::NETWORK) ==
|
||||
SerializeIF::STREAM_TOO_SHORT);
|
||||
// Set invalid TLV
|
||||
rawBuf[0] = TlvTypes::INVALID_TLV;
|
||||
deserSize = 4;
|
||||
REQUIRE(tlv.deSerialize(&deserPtr, &deserSize, SerializeIF::Endianness::NETWORK) !=
|
||||
HasReturnvaluesIF::RETURN_OK);
|
||||
SECTION("TLV Deserialization") {
|
||||
// Serialization was tested before, generate raw data now
|
||||
std::array<uint8_t, 8> tlvRawBuf;
|
||||
serPtr = tlvRawBuf.data();
|
||||
result =
|
||||
sourceId.serialize(&serPtr, &deserSize, tlvRawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
auto tlvSerialization = Tlv(TlvTypes::ENTITY_ID, tlvRawBuf.data(), deserSize);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
result = tlvSerialization.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
Tlv tlv;
|
||||
deserPtr = rawBuf.data();
|
||||
result = tlv.deSerialize(&deserPtr, &deserSize, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(tlv.getSerializedSize() == 4);
|
||||
REQUIRE(tlv.getType() == TlvTypes::ENTITY_ID);
|
||||
deserPtr = tlv.getValue();
|
||||
uint16_t entityId = 0;
|
||||
deserSize = 0;
|
||||
SerializeAdapter::deSerialize(&entityId, deserPtr, &deserSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(entityId == 0x0ff0);
|
||||
|
||||
Tlv zeroLenField(TlvTypes::FAULT_HANDLER, nullptr, 0);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
REQUIRE(zeroLenField.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK) == HasReturnvaluesIF::RETURN_OK);
|
||||
deserPtr = rawBuf.data();
|
||||
result = zeroLenField.deSerialize(&deserPtr, &deserSize, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(zeroLenField.getSerializedSize() == 2);
|
||||
REQUIRE(deserSize == 0);
|
||||
}
|
||||
REQUIRE(tlv.deSerialize(nullptr, nullptr, SerializeIF::Endianness::NETWORK) !=
|
||||
HasReturnvaluesIF::RETURN_OK);
|
||||
deserPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
REQUIRE(tlv.deSerialize(&deserPtr, &deserSize, SerializeIF::Endianness::NETWORK) ==
|
||||
SerializeIF::STREAM_TOO_SHORT);
|
||||
// Set invalid TLV
|
||||
rawBuf[0] = TlvTypes::INVALID_TLV;
|
||||
deserSize = 4;
|
||||
REQUIRE(tlv.deSerialize(&deserPtr, &deserSize, SerializeIF::Endianness::NETWORK) !=
|
||||
HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
SECTION("LV Serialization") {
|
||||
std::array<uint8_t, 8> lvRawBuf;
|
||||
serPtr = lvRawBuf.data();
|
||||
result = sourceId.serialize(&serPtr, &deserSize, lvRawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserSize == 2);
|
||||
auto lv = cfdp::Lv(lvRawBuf.data(), 2);
|
||||
auto lvCopy = cfdp::Lv(lv);
|
||||
REQUIRE(lv.getSerializedSize() == 3);
|
||||
REQUIRE(lvCopy.getSerializedSize() == 3);
|
||||
REQUIRE(lv.getValue(nullptr) == lvCopy.getValue(nullptr));
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
result = lv.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserSize == 3);
|
||||
REQUIRE(rawBuf[0] == 2);
|
||||
uint16_t sourceId = 0;
|
||||
result = SerializeAdapter::deSerialize(&sourceId, rawBuf.data() + 1, &deserSize,
|
||||
SerializeIF::Endianness::BIG);
|
||||
REQUIRE(sourceId == 0x0ff0);
|
||||
Tlv zeroLenField(TlvTypes::FAULT_HANDLER, nullptr, 0);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
REQUIRE(zeroLenField.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK) ==
|
||||
HasReturnvaluesIF::RETURN_OK);
|
||||
deserPtr = rawBuf.data();
|
||||
result = zeroLenField.deSerialize(&deserPtr, &deserSize, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(zeroLenField.getSerializedSize() == 2);
|
||||
REQUIRE(deserSize == 0);
|
||||
}
|
||||
|
||||
auto lvEmpty = Lv(nullptr, 0);
|
||||
REQUIRE(lvEmpty.getSerializedSize() == 1);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
result = lvEmpty.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserSize == 1);
|
||||
}
|
||||
SECTION("LV Serialization") {
|
||||
std::array<uint8_t, 8> lvRawBuf;
|
||||
serPtr = lvRawBuf.data();
|
||||
result =
|
||||
sourceId.serialize(&serPtr, &deserSize, lvRawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserSize == 2);
|
||||
auto lv = cfdp::Lv(lvRawBuf.data(), 2);
|
||||
auto lvCopy = cfdp::Lv(lv);
|
||||
REQUIRE(lv.getSerializedSize() == 3);
|
||||
REQUIRE(lvCopy.getSerializedSize() == 3);
|
||||
REQUIRE(lv.getValue(nullptr) == lvCopy.getValue(nullptr));
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
result = lv.serialize(&serPtr, &deserSize, rawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserSize == 3);
|
||||
REQUIRE(rawBuf[0] == 2);
|
||||
uint16_t sourceId = 0;
|
||||
result = SerializeAdapter::deSerialize(&sourceId, rawBuf.data() + 1, &deserSize,
|
||||
SerializeIF::Endianness::BIG);
|
||||
REQUIRE(sourceId == 0x0ff0);
|
||||
|
||||
SECTION("LV Deserialization") {
|
||||
std::array<uint8_t, 8> lvRawBuf;
|
||||
serPtr = lvRawBuf.data();
|
||||
result = sourceId.serialize(&serPtr, &deserSize, lvRawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
auto lv = cfdp::Lv(lvRawBuf.data(), 2);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
result = lv.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
auto lvEmpty = Lv(nullptr, 0);
|
||||
REQUIRE(lvEmpty.getSerializedSize() == 1);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
result =
|
||||
lvEmpty.serialize(&serPtr, &deserSize, rawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserSize == 1);
|
||||
}
|
||||
|
||||
Lv uninitLv;
|
||||
deserPtr = rawBuf.data();
|
||||
deserSize = 3;
|
||||
result = uninitLv.deSerialize(&deserPtr, &deserSize, SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(uninitLv.getSerializedSize() == 3);
|
||||
const uint8_t* storedValue = uninitLv.getValue(nullptr);
|
||||
uint16_t sourceId = 0;
|
||||
result = SerializeAdapter::deSerialize(&sourceId, storedValue, &deserSize,
|
||||
SerializeIF::Endianness::BIG);
|
||||
REQUIRE(sourceId == 0x0ff0);
|
||||
SECTION("LV Deserialization") {
|
||||
std::array<uint8_t, 8> lvRawBuf;
|
||||
serPtr = lvRawBuf.data();
|
||||
result =
|
||||
sourceId.serialize(&serPtr, &deserSize, lvRawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
auto lv = cfdp::Lv(lvRawBuf.data(), 2);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
result = lv.serialize(&serPtr, &deserSize, rawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
auto lvEmpty = Lv(nullptr, 0);
|
||||
REQUIRE(lvEmpty.getSerializedSize() == 1);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
result = lvEmpty.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserSize == 1);
|
||||
deserPtr = rawBuf.data();
|
||||
result = uninitLv.deSerialize(&deserPtr, &deserSize, SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(uninitLv.getSerializedSize() == 1);
|
||||
Lv uninitLv;
|
||||
deserPtr = rawBuf.data();
|
||||
deserSize = 3;
|
||||
result = uninitLv.deSerialize(&deserPtr, &deserSize, SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(uninitLv.getSerializedSize() == 3);
|
||||
const uint8_t* storedValue = uninitLv.getValue(nullptr);
|
||||
uint16_t sourceId = 0;
|
||||
result = SerializeAdapter::deSerialize(&sourceId, storedValue, &deserSize,
|
||||
SerializeIF::Endianness::BIG);
|
||||
REQUIRE(sourceId == 0x0ff0);
|
||||
|
||||
REQUIRE(uninitLv.deSerialize(nullptr, nullptr, SerializeIF::Endianness::BIG) ==
|
||||
HasReturnvaluesIF::RETURN_FAILED);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
REQUIRE(uninitLv.serialize(&serPtr, &deserSize, 0, SerializeIF::Endianness::BIG) ==
|
||||
SerializeIF::BUFFER_TOO_SHORT);
|
||||
REQUIRE(uninitLv.serialize(nullptr, nullptr, 12, SerializeIF::Endianness::BIG));
|
||||
deserSize = 0;
|
||||
REQUIRE(uninitLv.deSerialize(&deserPtr, &deserSize, SerializeIF::Endianness::BIG) ==
|
||||
SerializeIF::STREAM_TOO_SHORT);
|
||||
}
|
||||
auto lvEmpty = Lv(nullptr, 0);
|
||||
REQUIRE(lvEmpty.getSerializedSize() == 1);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
result =
|
||||
lvEmpty.serialize(&serPtr, &deserSize, rawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserSize == 1);
|
||||
deserPtr = rawBuf.data();
|
||||
result = uninitLv.deSerialize(&deserPtr, &deserSize, SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(uninitLv.getSerializedSize() == 1);
|
||||
|
||||
SECTION("Filestore Response TLV") {
|
||||
std::string name = "hello.txt";
|
||||
cfdp::Lv firstName(reinterpret_cast<const uint8_t*>(name.data()), name.size());
|
||||
std::string name2 = "hello2.txt";
|
||||
cfdp::Lv secondName(reinterpret_cast<const uint8_t*>(name2.data()), name2.size());
|
||||
std::string msg = "12345";
|
||||
cfdp::Lv fsMsg(reinterpret_cast<const uint8_t*>(msg.data()), msg.size());
|
||||
FilestoreResponseTlv response(cfdp::FilestoreActionCode::APPEND_FILE, cfdp::FSR_SUCCESS,
|
||||
firstName, &fsMsg);
|
||||
response.setSecondFileName(&secondName);
|
||||
REQUIRE(response.getLengthField() == 10 + 11 + 6 + 1);
|
||||
REQUIRE(response.getSerializedSize() == response.getLengthField() + 2);
|
||||
REQUIRE(uninitLv.deSerialize(nullptr, nullptr, SerializeIF::Endianness::BIG) ==
|
||||
HasReturnvaluesIF::RETURN_FAILED);
|
||||
serPtr = rawBuf.data();
|
||||
deserSize = 0;
|
||||
REQUIRE(uninitLv.serialize(&serPtr, &deserSize, 0, SerializeIF::Endianness::BIG) ==
|
||||
SerializeIF::BUFFER_TOO_SHORT);
|
||||
REQUIRE(uninitLv.serialize(nullptr, nullptr, 12, SerializeIF::Endianness::BIG));
|
||||
deserSize = 0;
|
||||
REQUIRE(uninitLv.deSerialize(&deserPtr, &deserSize, SerializeIF::Endianness::BIG) ==
|
||||
SerializeIF::STREAM_TOO_SHORT);
|
||||
}
|
||||
|
||||
cfdp::Tlv rawResponse;
|
||||
std::array<uint8_t, 128> serBuf = {};
|
||||
result = response.convertToTlv(rawResponse, serBuf.data(), serBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(rawResponse.getType() == cfdp::TlvTypes::FILESTORE_RESPONSE);
|
||||
cfdp::Lv emptyMsg;
|
||||
cfdp::Lv emptySecondName;
|
||||
FilestoreResponseTlv emptyTlv(firstName, &emptyMsg);
|
||||
emptyTlv.setSecondFileName(&emptySecondName);
|
||||
result = emptyTlv.deSerialize(rawResponse, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(emptyTlv.getActionCode() == cfdp::FilestoreActionCode::APPEND_FILE);
|
||||
REQUIRE(emptyTlv.getStatusCode() == cfdp::FSR_SUCCESS);
|
||||
size_t firstNameLen = 0;
|
||||
const char* firstNamePtr = reinterpret_cast<const char*>(
|
||||
emptyTlv.getFirstFileName().getValue(&firstNameLen));
|
||||
auto helloString = std::string(firstNamePtr, firstNameLen);
|
||||
REQUIRE(helloString == "hello.txt");
|
||||
}
|
||||
SECTION("Filestore Response TLV") {
|
||||
std::string name = "hello.txt";
|
||||
cfdp::Lv firstName(reinterpret_cast<const uint8_t*>(name.data()), name.size());
|
||||
std::string name2 = "hello2.txt";
|
||||
cfdp::Lv secondName(reinterpret_cast<const uint8_t*>(name2.data()), name2.size());
|
||||
std::string msg = "12345";
|
||||
cfdp::Lv fsMsg(reinterpret_cast<const uint8_t*>(msg.data()), msg.size());
|
||||
FilestoreResponseTlv response(cfdp::FilestoreActionCode::APPEND_FILE, cfdp::FSR_SUCCESS,
|
||||
firstName, &fsMsg);
|
||||
response.setSecondFileName(&secondName);
|
||||
REQUIRE(response.getLengthField() == 10 + 11 + 6 + 1);
|
||||
REQUIRE(response.getSerializedSize() == response.getLengthField() + 2);
|
||||
|
||||
SECTION("Filestore Request TLV") {
|
||||
std::string name = "hello.txt";
|
||||
cfdp::Lv firstName(reinterpret_cast<const uint8_t*>(name.data()), name.size());
|
||||
std::string name2 = "hello2.txt";
|
||||
cfdp::Lv secondName(reinterpret_cast<const uint8_t*>(name2.data()), name2.size());
|
||||
FilestoreRequestTlv request(cfdp::FilestoreActionCode::APPEND_FILE, firstName);
|
||||
cfdp::Tlv rawResponse;
|
||||
std::array<uint8_t, 128> serBuf = {};
|
||||
result = response.convertToTlv(rawResponse, serBuf.data(), serBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(rawResponse.getType() == cfdp::TlvTypes::FILESTORE_RESPONSE);
|
||||
cfdp::Lv emptyMsg;
|
||||
cfdp::Lv emptySecondName;
|
||||
FilestoreResponseTlv emptyTlv(firstName, &emptyMsg);
|
||||
emptyTlv.setSecondFileName(&emptySecondName);
|
||||
result = emptyTlv.deSerialize(rawResponse, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(emptyTlv.getActionCode() == cfdp::FilestoreActionCode::APPEND_FILE);
|
||||
REQUIRE(emptyTlv.getStatusCode() == cfdp::FSR_SUCCESS);
|
||||
size_t firstNameLen = 0;
|
||||
const char* firstNamePtr =
|
||||
reinterpret_cast<const char*>(emptyTlv.getFirstFileName().getValue(&firstNameLen));
|
||||
auto helloString = std::string(firstNamePtr, firstNameLen);
|
||||
REQUIRE(helloString == "hello.txt");
|
||||
}
|
||||
|
||||
// second name not set yet
|
||||
REQUIRE(request.getLengthField() == 10 + 1);
|
||||
REQUIRE(request.getSerializedSize() == request.getLengthField() + 2);
|
||||
SECTION("Filestore Request TLV") {
|
||||
std::string name = "hello.txt";
|
||||
cfdp::Lv firstName(reinterpret_cast<const uint8_t*>(name.data()), name.size());
|
||||
std::string name2 = "hello2.txt";
|
||||
cfdp::Lv secondName(reinterpret_cast<const uint8_t*>(name2.data()), name2.size());
|
||||
FilestoreRequestTlv request(cfdp::FilestoreActionCode::APPEND_FILE, firstName);
|
||||
|
||||
std::array<uint8_t, 128> serBuf = {};
|
||||
uint8_t* ptr = serBuf.data();
|
||||
size_t sz = 0;
|
||||
result = request.serialize(&ptr, &sz, serBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == cfdp::FILESTORE_REQUIRES_SECOND_FILE);
|
||||
// second name not set yet
|
||||
REQUIRE(request.getLengthField() == 10 + 1);
|
||||
REQUIRE(request.getSerializedSize() == request.getLengthField() + 2);
|
||||
|
||||
ptr = serBuf.data();
|
||||
sz = 0;
|
||||
request.setSecondFileName(&secondName);
|
||||
size_t expectedSz = request.getLengthField();
|
||||
REQUIRE(expectedSz == 10 + 11 + 1);
|
||||
REQUIRE(request.getSerializedSize() == expectedSz + 2);
|
||||
result = request.serialize(&ptr, &sz, serBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(sz == expectedSz + 2);
|
||||
std::array<uint8_t, 128> serBuf = {};
|
||||
uint8_t* ptr = serBuf.data();
|
||||
size_t sz = 0;
|
||||
result = request.serialize(&ptr, &sz, serBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == cfdp::FILESTORE_REQUIRES_SECOND_FILE);
|
||||
|
||||
FilestoreRequestTlv emptyRequest(firstName);
|
||||
emptyRequest.setSecondFileName(&secondName);
|
||||
const uint8_t* constptr = serBuf.data();
|
||||
result = emptyRequest.deSerialize(&constptr, &sz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
ptr = serBuf.data();
|
||||
sz = 0;
|
||||
request.setSecondFileName(&secondName);
|
||||
size_t expectedSz = request.getLengthField();
|
||||
REQUIRE(expectedSz == 10 + 11 + 1);
|
||||
REQUIRE(request.getSerializedSize() == expectedSz + 2);
|
||||
result = request.serialize(&ptr, &sz, serBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(sz == expectedSz + 2);
|
||||
|
||||
cfdp::Tlv rawRequest;
|
||||
ptr = serBuf.data();
|
||||
sz = 0;
|
||||
result = request.convertToTlv(rawRequest, serBuf.data(), serBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(rawRequest.getType() == cfdp::TlvTypes::FILESTORE_REQUEST);
|
||||
FilestoreRequestTlv emptyRequest(firstName);
|
||||
emptyRequest.setSecondFileName(&secondName);
|
||||
const uint8_t* constptr = serBuf.data();
|
||||
result = emptyRequest.deSerialize(&constptr, &sz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
emptyRequest.setActionCode(cfdp::FilestoreActionCode::DELETE_FILE);
|
||||
result = emptyRequest.deSerialize(rawRequest, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(emptyRequest.getType() == cfdp::TlvTypes::FILESTORE_REQUEST);
|
||||
REQUIRE(emptyRequest.getActionCode() == cfdp::FilestoreActionCode::APPEND_FILE);
|
||||
}
|
||||
cfdp::Tlv rawRequest;
|
||||
ptr = serBuf.data();
|
||||
sz = 0;
|
||||
result = request.convertToTlv(rawRequest, serBuf.data(), serBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(rawRequest.getType() == cfdp::TlvTypes::FILESTORE_REQUEST);
|
||||
|
||||
SECTION("Other") {
|
||||
MessageToUserTlv emptyTlv;
|
||||
uint8_t flowLabel = 1;
|
||||
FlowLabelTlv flowLabelTlv(&flowLabel, 1);
|
||||
emptyRequest.setActionCode(cfdp::FilestoreActionCode::DELETE_FILE);
|
||||
result = emptyRequest.deSerialize(rawRequest, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(emptyRequest.getType() == cfdp::TlvTypes::FILESTORE_REQUEST);
|
||||
REQUIRE(emptyRequest.getActionCode() == cfdp::FilestoreActionCode::APPEND_FILE);
|
||||
}
|
||||
|
||||
FaultHandlerOverrideTlv faultOverrideTlv(cfdp::ConditionCode::FILESTORE_REJECTION,
|
||||
cfdp::FaultHandlerCode::NOTICE_OF_CANCELLATION);
|
||||
size_t sz = 0;
|
||||
ReturnValue_t result = faultOverrideTlv.serialize(&serPtr, &sz, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(faultOverrideTlv.getSerializedSize() == 3);
|
||||
REQUIRE(sz == 3);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
SECTION("Other") {
|
||||
MessageToUserTlv emptyTlv;
|
||||
uint8_t flowLabel = 1;
|
||||
FlowLabelTlv flowLabelTlv(&flowLabel, 1);
|
||||
|
||||
FaultHandlerOverrideTlv emptyOverrideTlv;
|
||||
result = emptyOverrideTlv.deSerialize(&deserPtr, &sz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
FaultHandlerOverrideTlv faultOverrideTlv(cfdp::ConditionCode::FILESTORE_REJECTION,
|
||||
cfdp::FaultHandlerCode::NOTICE_OF_CANCELLATION);
|
||||
size_t sz = 0;
|
||||
ReturnValue_t result =
|
||||
faultOverrideTlv.serialize(&serPtr, &sz, rawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(faultOverrideTlv.getSerializedSize() == 3);
|
||||
REQUIRE(sz == 3);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
EntityId entId(cfdp::WidthInBytes::TWO_BYTES, 0x42);
|
||||
EntityId emptyId;
|
||||
EntityIdTlv idTlv(emptyId);
|
||||
serPtr = rawBuf.data();
|
||||
result = idTlv.serialize(&serPtr, &deserSize, rawBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
cfdp::Tlv rawTlv(cfdp::TlvTypes::ENTITY_ID, rawBuf.data() + 2, 2);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
deserPtr = rawBuf.data();
|
||||
result = idTlv.deSerialize(rawTlv, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
FaultHandlerOverrideTlv emptyOverrideTlv;
|
||||
result = emptyOverrideTlv.deSerialize(&deserPtr, &sz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
EntityId entId(cfdp::WidthInBytes::TWO_BYTES, 0x42);
|
||||
EntityId emptyId;
|
||||
EntityIdTlv idTlv(emptyId);
|
||||
serPtr = rawBuf.data();
|
||||
result = idTlv.serialize(&serPtr, &deserSize, rawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
cfdp::Tlv rawTlv(cfdp::TlvTypes::ENTITY_ID, rawBuf.data() + 2, 2);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
deserPtr = rawBuf.data();
|
||||
result = idTlv.deSerialize(rawTlv, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
|
@ -1,327 +1,321 @@
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
#include <fsfw/container/SimpleRingBuffer.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <cstring>
|
||||
|
||||
TEST_CASE("Ring Buffer Test" , "[RingBufferTest]") {
|
||||
uint8_t testData[13]= {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
uint8_t readBuffer[10] = {13, 13, 13, 13, 13, 13, 13, 13, 13, 13};
|
||||
SimpleRingBuffer ringBuffer(10, false, 5);
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
SECTION("Simple Test") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 9) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.writeData(testData, 3) == retval::CATCH_FAILED);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, true) == retval::CATCH_OK);
|
||||
for(uint8_t i = 0; i< 5; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 5);
|
||||
ringBuffer.clear();
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 4) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 4, true) == retval::CATCH_OK);
|
||||
for(uint8_t i = 0; i< 4; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
REQUIRE(ringBuffer.writeData(testData, 9) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 9, true) == retval::CATCH_OK);
|
||||
for(uint8_t i = 0; i< 9; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
TEST_CASE("Ring Buffer Test", "[RingBufferTest]") {
|
||||
uint8_t testData[13] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
uint8_t readBuffer[10] = {13, 13, 13, 13, 13, 13, 13, 13, 13, 13};
|
||||
SimpleRingBuffer ringBuffer(10, false, 5);
|
||||
|
||||
}
|
||||
SECTION("Simple Test") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 9) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.writeData(testData, 3) == retval::CATCH_FAILED);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, true) == retval::CATCH_OK);
|
||||
for (uint8_t i = 0; i < 5; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 5);
|
||||
ringBuffer.clear();
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 4) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 4, true) == retval::CATCH_OK);
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
REQUIRE(ringBuffer.writeData(testData, 9) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 9, true) == retval::CATCH_OK);
|
||||
for (uint8_t i = 0; i < 9; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Get Free Element Test") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 8) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 1);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 8, true) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
uint8_t *testPtr = nullptr;
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 10) == retval::CATCH_FAILED);
|
||||
SECTION("Get Free Element Test") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 8) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 1);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 8, true) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
uint8_t *testPtr = nullptr;
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 10) == retval::CATCH_FAILED);
|
||||
|
||||
REQUIRE(ringBuffer.writeTillWrap() == 2);
|
||||
// too many excess bytes.
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 8) == retval::CATCH_FAILED);
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 5) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getExcessBytes() == 3);
|
||||
std::memcpy(testPtr, testData, 5);
|
||||
ringBuffer.confirmBytesWritten(5);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 5);
|
||||
ringBuffer.readData(readBuffer, 5, true);
|
||||
for (uint8_t i = 0; i < 5; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
}
|
||||
|
||||
REQUIRE(ringBuffer.writeTillWrap() == 2);
|
||||
// too many excess bytes.
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 8) == retval::CATCH_FAILED);
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 5) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getExcessBytes() == 3);
|
||||
std::memcpy(testPtr, testData, 5);
|
||||
ringBuffer.confirmBytesWritten(5);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 5);
|
||||
ringBuffer.readData(readBuffer, 5, true);
|
||||
for(uint8_t i = 0; i< 5; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Read Remaining Test") {
|
||||
REQUIRE(ringBuffer.writeData(testData, 3) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 3);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, false, false, nullptr) == retval::CATCH_FAILED);
|
||||
size_t trueSize = 0;
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, false, true, &trueSize) == retval::CATCH_OK);
|
||||
REQUIRE(trueSize == 3);
|
||||
for(uint8_t i = 0; i< 3; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
trueSize = 0;
|
||||
REQUIRE(ringBuffer.deleteData(5, false, &trueSize) == retval::CATCH_FAILED);
|
||||
REQUIRE(trueSize == 0);
|
||||
REQUIRE(ringBuffer.deleteData(5, true, &trueSize) == retval::CATCH_OK);
|
||||
REQUIRE(trueSize == 3);
|
||||
}
|
||||
SECTION("Read Remaining Test") {
|
||||
REQUIRE(ringBuffer.writeData(testData, 3) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 3);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, false, false, nullptr) == retval::CATCH_FAILED);
|
||||
size_t trueSize = 0;
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, false, true, &trueSize) == retval::CATCH_OK);
|
||||
REQUIRE(trueSize == 3);
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
trueSize = 0;
|
||||
REQUIRE(ringBuffer.deleteData(5, false, &trueSize) == retval::CATCH_FAILED);
|
||||
REQUIRE(trueSize == 0);
|
||||
REQUIRE(ringBuffer.deleteData(5, true, &trueSize) == retval::CATCH_OK);
|
||||
REQUIRE(trueSize == 3);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Ring Buffer Test2" , "[RingBufferTest2]") {
|
||||
uint8_t testData[13]= {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
uint8_t readBuffer[10] = {13, 13, 13, 13, 13, 13, 13, 13, 13, 13};
|
||||
uint8_t* newBuffer = new uint8_t[15];
|
||||
SimpleRingBuffer ringBuffer(newBuffer, 10, true, 5);
|
||||
TEST_CASE("Ring Buffer Test2", "[RingBufferTest2]") {
|
||||
uint8_t testData[13] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
uint8_t readBuffer[10] = {13, 13, 13, 13, 13, 13, 13, 13, 13, 13};
|
||||
uint8_t *newBuffer = new uint8_t[15];
|
||||
SimpleRingBuffer ringBuffer(newBuffer, 10, true, 5);
|
||||
|
||||
SECTION("Simple Test") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 9) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, true) == retval::CATCH_OK);
|
||||
for(uint8_t i = 0; i< 5; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 5);
|
||||
ringBuffer.clear();
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 4) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 4, true) == retval::CATCH_OK);
|
||||
for(uint8_t i = 0; i< 4; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
REQUIRE(ringBuffer.writeData(testData, 9) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 9, true) == retval::CATCH_OK);
|
||||
for(uint8_t i = 0; i< 9; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
SECTION("Simple Test") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 9) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, true) == retval::CATCH_OK);
|
||||
for (uint8_t i = 0; i < 5; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 5);
|
||||
ringBuffer.clear();
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 4) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 4, true) == retval::CATCH_OK);
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
REQUIRE(ringBuffer.writeData(testData, 9) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 9, true) == retval::CATCH_OK);
|
||||
for (uint8_t i = 0; i < 9; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
SECTION("Get Free Element Test") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 8) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 1);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 8, true) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
uint8_t *testPtr = nullptr;
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 10) == retval::CATCH_FAILED);
|
||||
|
||||
SECTION("Get Free Element Test") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 8) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 1);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 8, true) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
uint8_t *testPtr = nullptr;
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 10) == retval::CATCH_FAILED);
|
||||
REQUIRE(ringBuffer.writeTillWrap() == 2);
|
||||
// too many excess bytes.
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 8) == retval::CATCH_FAILED);
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 5) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getExcessBytes() == 3);
|
||||
std::memcpy(testPtr, testData, 5);
|
||||
ringBuffer.confirmBytesWritten(5);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 5);
|
||||
ringBuffer.readData(readBuffer, 5, true);
|
||||
for (uint8_t i = 0; i < 5; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Read Remaining Test") {
|
||||
REQUIRE(ringBuffer.writeData(testData, 3) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 3);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, false, false, nullptr) == retval::CATCH_FAILED);
|
||||
size_t trueSize = 0;
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, false, true, &trueSize) == retval::CATCH_OK);
|
||||
REQUIRE(trueSize == 3);
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
trueSize = 0;
|
||||
REQUIRE(ringBuffer.deleteData(5, false, &trueSize) == retval::CATCH_FAILED);
|
||||
REQUIRE(trueSize == 0);
|
||||
REQUIRE(ringBuffer.deleteData(5, true, &trueSize) == retval::CATCH_OK);
|
||||
REQUIRE(trueSize == 3);
|
||||
}
|
||||
|
||||
REQUIRE(ringBuffer.writeTillWrap() == 2);
|
||||
// too many excess bytes.
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 8) == retval::CATCH_FAILED);
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 5) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getExcessBytes() == 3);
|
||||
std::memcpy(testPtr, testData, 5);
|
||||
ringBuffer.confirmBytesWritten(5);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 5);
|
||||
ringBuffer.readData(readBuffer, 5, true);
|
||||
for(uint8_t i = 0; i< 5; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Read Remaining Test") {
|
||||
REQUIRE(ringBuffer.writeData(testData, 3) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 3);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, false, false, nullptr) == retval::CATCH_FAILED);
|
||||
size_t trueSize = 0;
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, false, true, &trueSize) == retval::CATCH_OK);
|
||||
REQUIRE(trueSize == 3);
|
||||
for(uint8_t i = 0; i< 3; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
trueSize = 0;
|
||||
REQUIRE(ringBuffer.deleteData(5, false, &trueSize) == retval::CATCH_FAILED);
|
||||
REQUIRE(trueSize == 0);
|
||||
REQUIRE(ringBuffer.deleteData(5, true, &trueSize) == retval::CATCH_OK);
|
||||
REQUIRE(trueSize == 3);
|
||||
}
|
||||
|
||||
SECTION("Overflow"){
|
||||
REQUIRE(ringBuffer.availableWriteSpace()==9);
|
||||
//Writing more than the buffer is large, technically thats allowed
|
||||
//But it is senseless and has undesired impact on read call
|
||||
REQUIRE(ringBuffer.writeData(testData, 13) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getAvailableReadData()==3);
|
||||
ringBuffer.clear();
|
||||
uint8_t * ptr = nullptr;
|
||||
REQUIRE(ringBuffer.getFreeElement(&ptr, 13) == retval::CATCH_OK);
|
||||
REQUIRE(ptr != nullptr);
|
||||
memcpy(ptr, testData, 13);
|
||||
ringBuffer.confirmBytesWritten(13);
|
||||
REQUIRE(ringBuffer.getAvailableReadData()==3);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 3, true)== retval::CATCH_OK);
|
||||
for(auto i =0;i<3;i++){
|
||||
REQUIRE(readBuffer[i] == testData[i+10]);
|
||||
}
|
||||
}
|
||||
SECTION("Overflow") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
// Writing more than the buffer is large, technically thats allowed
|
||||
// But it is senseless and has undesired impact on read call
|
||||
REQUIRE(ringBuffer.writeData(testData, 13) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 3);
|
||||
ringBuffer.clear();
|
||||
uint8_t *ptr = nullptr;
|
||||
REQUIRE(ringBuffer.getFreeElement(&ptr, 13) == retval::CATCH_OK);
|
||||
REQUIRE(ptr != nullptr);
|
||||
memcpy(ptr, testData, 13);
|
||||
ringBuffer.confirmBytesWritten(13);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 3);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 3, true) == retval::CATCH_OK);
|
||||
for (auto i = 0; i < 3; i++) {
|
||||
REQUIRE(readBuffer[i] == testData[i + 10]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Ring Buffer Test3" , "[RingBufferTest3]") {
|
||||
uint8_t testData[13]= {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
uint8_t readBuffer[10] = {13, 13, 13, 13, 13, 13, 13, 13, 13, 13};
|
||||
uint8_t* newBuffer = new uint8_t[25];
|
||||
SimpleRingBuffer ringBuffer(newBuffer, 10, true, 15);
|
||||
TEST_CASE("Ring Buffer Test3", "[RingBufferTest3]") {
|
||||
uint8_t testData[13] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
uint8_t readBuffer[10] = {13, 13, 13, 13, 13, 13, 13, 13, 13, 13};
|
||||
uint8_t *newBuffer = new uint8_t[25];
|
||||
SimpleRingBuffer ringBuffer(newBuffer, 10, true, 15);
|
||||
|
||||
SECTION("Simple Test") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 9) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, true) == retval::CATCH_OK);
|
||||
for(uint8_t i = 0; i< 5; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 5);
|
||||
ringBuffer.clear();
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 4) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 4, true) == retval::CATCH_OK);
|
||||
for(uint8_t i = 0; i< 4; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
REQUIRE(ringBuffer.writeData(testData, 9) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 9, true) == retval::CATCH_OK);
|
||||
for(uint8_t i = 0; i< 9; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
SECTION("Simple Test") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 9) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, true) == retval::CATCH_OK);
|
||||
for (uint8_t i = 0; i < 5; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 5);
|
||||
ringBuffer.clear();
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 4) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 4, true) == retval::CATCH_OK);
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
REQUIRE(ringBuffer.writeData(testData, 9) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 9, true) == retval::CATCH_OK);
|
||||
for (uint8_t i = 0; i < 9; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
SECTION("Get Free Element Test") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 8) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 1);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 8, true) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
uint8_t *testPtr = nullptr;
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 10) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getExcessBytes() == 8);
|
||||
|
||||
SECTION("Get Free Element Test") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 8) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 1);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 8, true) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
uint8_t *testPtr = nullptr;
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 10) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getExcessBytes() == 8);
|
||||
REQUIRE(ringBuffer.writeTillWrap() == 2);
|
||||
// too many excess bytes.
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 8) == retval::CATCH_FAILED);
|
||||
// Less Execss bytes overwrites before
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 3) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getExcessBytes() == 1);
|
||||
std::memcpy(testPtr, testData, 3);
|
||||
ringBuffer.confirmBytesWritten(3);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 3);
|
||||
ringBuffer.readData(readBuffer, 3, true);
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
}
|
||||
|
||||
REQUIRE(ringBuffer.writeTillWrap() == 2);
|
||||
// too many excess bytes.
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 8) == retval::CATCH_FAILED);
|
||||
// Less Execss bytes overwrites before
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 3) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getExcessBytes() == 1);
|
||||
std::memcpy(testPtr, testData, 3);
|
||||
ringBuffer.confirmBytesWritten(3);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 3);
|
||||
ringBuffer.readData(readBuffer, 3, true);
|
||||
for(uint8_t i = 0; i< 3; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
}
|
||||
SECTION("Read Remaining Test") {
|
||||
REQUIRE(ringBuffer.writeData(testData, 3) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 3);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, false, false, nullptr) == retval::CATCH_FAILED);
|
||||
size_t trueSize = 0;
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, false, true, &trueSize) == retval::CATCH_OK);
|
||||
REQUIRE(trueSize == 3);
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
trueSize = 0;
|
||||
REQUIRE(ringBuffer.deleteData(5, false, &trueSize) == retval::CATCH_FAILED);
|
||||
REQUIRE(trueSize == 0);
|
||||
REQUIRE(ringBuffer.deleteData(5, true, &trueSize) == retval::CATCH_OK);
|
||||
REQUIRE(trueSize == 3);
|
||||
}
|
||||
|
||||
SECTION("Read Remaining Test") {
|
||||
REQUIRE(ringBuffer.writeData(testData, 3) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 3);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, false, false, nullptr) == retval::CATCH_FAILED);
|
||||
size_t trueSize = 0;
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, false, true, &trueSize) == retval::CATCH_OK);
|
||||
REQUIRE(trueSize == 3);
|
||||
for(uint8_t i = 0; i< 3; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
trueSize = 0;
|
||||
REQUIRE(ringBuffer.deleteData(5, false, &trueSize) == retval::CATCH_FAILED);
|
||||
REQUIRE(trueSize == 0);
|
||||
REQUIRE(ringBuffer.deleteData(5, true, &trueSize) == retval::CATCH_OK);
|
||||
REQUIRE(trueSize == 3);
|
||||
}
|
||||
|
||||
SECTION("Overflow"){
|
||||
REQUIRE(ringBuffer.availableWriteSpace()==9);
|
||||
//Writing more than the buffer is large, technically thats allowed
|
||||
//But it is senseless and has undesired impact on read call
|
||||
REQUIRE(ringBuffer.writeData(testData, 13) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getAvailableReadData()==3);
|
||||
ringBuffer.clear();
|
||||
uint8_t * ptr = nullptr;
|
||||
REQUIRE(ringBuffer.getFreeElement(&ptr, 13) == retval::CATCH_OK);
|
||||
REQUIRE(ptr != nullptr);
|
||||
memcpy(ptr, testData, 13);
|
||||
ringBuffer.confirmBytesWritten(13);
|
||||
REQUIRE(ringBuffer.getAvailableReadData()==3);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 3, true)== retval::CATCH_OK);
|
||||
for(auto i =0;i<3;i++){
|
||||
REQUIRE(readBuffer[i] == testData[i+10]);
|
||||
}
|
||||
}
|
||||
SECTION("Overflow") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
// Writing more than the buffer is large, technically thats allowed
|
||||
// But it is senseless and has undesired impact on read call
|
||||
REQUIRE(ringBuffer.writeData(testData, 13) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 3);
|
||||
ringBuffer.clear();
|
||||
uint8_t *ptr = nullptr;
|
||||
REQUIRE(ringBuffer.getFreeElement(&ptr, 13) == retval::CATCH_OK);
|
||||
REQUIRE(ptr != nullptr);
|
||||
memcpy(ptr, testData, 13);
|
||||
ringBuffer.confirmBytesWritten(13);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 3);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 3, true) == retval::CATCH_OK);
|
||||
for (auto i = 0; i < 3; i++) {
|
||||
REQUIRE(readBuffer[i] == testData[i + 10]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Ring Buffer Test4" , "[RingBufferTest4]") {
|
||||
uint8_t testData[13]= {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
uint8_t readBuffer[10] = {13, 13, 13, 13, 13, 13, 13, 13, 13, 13};
|
||||
SimpleRingBuffer ringBuffer(10, false, 15);
|
||||
TEST_CASE("Ring Buffer Test4", "[RingBufferTest4]") {
|
||||
uint8_t testData[13] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
|
||||
uint8_t readBuffer[10] = {13, 13, 13, 13, 13, 13, 13, 13, 13, 13};
|
||||
SimpleRingBuffer ringBuffer(10, false, 15);
|
||||
|
||||
SECTION("Simple Test") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 9) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.writeData(testData, 3) == retval::CATCH_FAILED);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, true) == retval::CATCH_OK);
|
||||
for(uint8_t i = 0; i< 5; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 5);
|
||||
ringBuffer.clear();
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 4) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 4, true) == retval::CATCH_OK);
|
||||
for(uint8_t i = 0; i< 4; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
REQUIRE(ringBuffer.writeData(testData, 9) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 9, true) == retval::CATCH_OK);
|
||||
for(uint8_t i = 0; i< 9; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
SECTION("Simple Test") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 9) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.writeData(testData, 3) == retval::CATCH_FAILED);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, true) == retval::CATCH_OK);
|
||||
for (uint8_t i = 0; i < 5; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 5);
|
||||
ringBuffer.clear();
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 4) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 4, true) == retval::CATCH_OK);
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
REQUIRE(ringBuffer.writeData(testData, 9) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 9, true) == retval::CATCH_OK);
|
||||
for (uint8_t i = 0; i < 9; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
SECTION("Get Free Element Test") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 8) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 1);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 8, true) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
uint8_t *testPtr = nullptr;
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 10) == retval::CATCH_FAILED);
|
||||
|
||||
SECTION("Get Free Element Test") {
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
REQUIRE(ringBuffer.writeData(testData, 8) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 1);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 8, true) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.availableWriteSpace() == 9);
|
||||
uint8_t *testPtr = nullptr;
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 10) == retval::CATCH_FAILED);
|
||||
REQUIRE(ringBuffer.writeTillWrap() == 2);
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 8) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 5) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getExcessBytes() == 3);
|
||||
std::memcpy(testPtr, testData, 5);
|
||||
ringBuffer.confirmBytesWritten(5);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 5);
|
||||
ringBuffer.readData(readBuffer, 5, true);
|
||||
for (uint8_t i = 0; i < 5; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
REQUIRE(ringBuffer.writeTillWrap() == 2);
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 8) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getFreeElement(&testPtr, 5) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getExcessBytes() == 3);
|
||||
std::memcpy(testPtr, testData, 5);
|
||||
ringBuffer.confirmBytesWritten(5);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 5);
|
||||
ringBuffer.readData(readBuffer, 5, true);
|
||||
for(uint8_t i = 0; i< 5; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Read Remaining Test") {
|
||||
REQUIRE(ringBuffer.writeData(testData, 3) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 3);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, false, false, nullptr) == retval::CATCH_FAILED);
|
||||
size_t trueSize = 0;
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, false, true, &trueSize) == retval::CATCH_OK);
|
||||
REQUIRE(trueSize == 3);
|
||||
for(uint8_t i = 0; i< 3; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
trueSize = 0;
|
||||
REQUIRE(ringBuffer.deleteData(5, false, &trueSize) == retval::CATCH_FAILED);
|
||||
REQUIRE(trueSize == 0);
|
||||
REQUIRE(ringBuffer.deleteData(5, true, &trueSize) == retval::CATCH_OK);
|
||||
REQUIRE(trueSize == 3);
|
||||
}
|
||||
SECTION("Read Remaining Test") {
|
||||
REQUIRE(ringBuffer.writeData(testData, 3) == retval::CATCH_OK);
|
||||
REQUIRE(ringBuffer.getAvailableReadData() == 3);
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, false, false, nullptr) == retval::CATCH_FAILED);
|
||||
size_t trueSize = 0;
|
||||
REQUIRE(ringBuffer.readData(readBuffer, 5, false, true, &trueSize) == retval::CATCH_OK);
|
||||
REQUIRE(trueSize == 3);
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
CHECK(readBuffer[i] == i);
|
||||
}
|
||||
trueSize = 0;
|
||||
REQUIRE(ringBuffer.deleteData(5, false, &trueSize) == retval::CATCH_FAILED);
|
||||
REQUIRE(trueSize == 0);
|
||||
REQUIRE(ringBuffer.deleteData(5, true, &trueSize) == retval::CATCH_OK);
|
||||
REQUIRE(trueSize == 3);
|
||||
}
|
||||
}
|
||||
|
@ -1,92 +1,92 @@
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <fsfw/container/ArrayList.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
/**
|
||||
* @brief Array List test
|
||||
*/
|
||||
TEST_CASE("Array List" , "[ArrayListTest]") {
|
||||
//perform set-up here
|
||||
ArrayList<uint16_t> list(20);
|
||||
struct TestClass{
|
||||
public:
|
||||
TestClass(){};
|
||||
TestClass(uint32_t number1, uint64_t number2):
|
||||
number1(number1), number2(number2){};
|
||||
uint32_t number1 = -1;
|
||||
uint64_t number2 = -1;
|
||||
bool operator==(const TestClass& other){
|
||||
return ((this->number1 == other.number1) and (this->number2 == other.number2));
|
||||
};
|
||||
};
|
||||
ArrayList<TestClass> complexList(20);
|
||||
SECTION("SimpleTest") {
|
||||
REQUIRE(list.maxSize()==20);
|
||||
REQUIRE(list.size == 0);
|
||||
REQUIRE(list.insert(10) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(list[0] == 10);
|
||||
REQUIRE(list.front() != nullptr);
|
||||
REQUIRE((*list.front()) == 10);
|
||||
REQUIRE(list.back() != nullptr);
|
||||
REQUIRE((*list.back()) == 10);
|
||||
// Need to test the const version of back as well
|
||||
const uint16_t* number = const_cast<const ArrayList<uint16_t>*>(&list)->back();
|
||||
REQUIRE(*number == 10);
|
||||
list.clear();
|
||||
REQUIRE(list.size == 0);
|
||||
}
|
||||
SECTION("Fill and check"){
|
||||
//This is an invalid element but its not a nullptr
|
||||
REQUIRE(list.back() != nullptr);
|
||||
for (auto i =0; i < 20; i++){
|
||||
REQUIRE(list.insert(i) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
}
|
||||
REQUIRE(list.insert(20) == static_cast<int>(ArrayList<uint16_t>::FULL));
|
||||
ArrayList<uint16_t>::Iterator it = list.begin();
|
||||
REQUIRE((*it) == 0);
|
||||
it++;
|
||||
REQUIRE((*it) == 1);
|
||||
it--;
|
||||
REQUIRE((*it) == 0);
|
||||
it++;
|
||||
for(auto it2 = list.begin(); it2!=list.end(); it2++){
|
||||
if (it == it2){
|
||||
REQUIRE((*it) == (*it2));
|
||||
break;
|
||||
}else{
|
||||
REQUIRE((*it2) == 0);
|
||||
REQUIRE(it2 != it);
|
||||
}
|
||||
}
|
||||
}
|
||||
SECTION("Const Iterator"){
|
||||
ArrayList<uint16_t>::Iterator it = list.begin();
|
||||
for (auto i =0; i < 10; i++){
|
||||
REQUIRE(list.insert(i) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
}
|
||||
it++;
|
||||
const uint16_t* number = it.value;
|
||||
REQUIRE(*number == 1);
|
||||
}
|
||||
TEST_CASE("Array List", "[ArrayListTest]") {
|
||||
// perform set-up here
|
||||
ArrayList<uint16_t> list(20);
|
||||
struct TestClass {
|
||||
public:
|
||||
TestClass(){};
|
||||
TestClass(uint32_t number1, uint64_t number2) : number1(number1), number2(number2){};
|
||||
uint32_t number1 = -1;
|
||||
uint64_t number2 = -1;
|
||||
bool operator==(const TestClass& other) {
|
||||
return ((this->number1 == other.number1) and (this->number2 == other.number2));
|
||||
};
|
||||
};
|
||||
ArrayList<TestClass> complexList(20);
|
||||
SECTION("SimpleTest") {
|
||||
REQUIRE(list.maxSize() == 20);
|
||||
REQUIRE(list.size == 0);
|
||||
REQUIRE(list.insert(10) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(list[0] == 10);
|
||||
REQUIRE(list.front() != nullptr);
|
||||
REQUIRE((*list.front()) == 10);
|
||||
REQUIRE(list.back() != nullptr);
|
||||
REQUIRE((*list.back()) == 10);
|
||||
// Need to test the const version of back as well
|
||||
const uint16_t* number = const_cast<const ArrayList<uint16_t>*>(&list)->back();
|
||||
REQUIRE(*number == 10);
|
||||
list.clear();
|
||||
REQUIRE(list.size == 0);
|
||||
}
|
||||
SECTION("Fill and check") {
|
||||
// This is an invalid element but its not a nullptr
|
||||
REQUIRE(list.back() != nullptr);
|
||||
for (auto i = 0; i < 20; i++) {
|
||||
REQUIRE(list.insert(i) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
}
|
||||
REQUIRE(list.insert(20) == static_cast<int>(ArrayList<uint16_t>::FULL));
|
||||
ArrayList<uint16_t>::Iterator it = list.begin();
|
||||
REQUIRE((*it) == 0);
|
||||
it++;
|
||||
REQUIRE((*it) == 1);
|
||||
it--;
|
||||
REQUIRE((*it) == 0);
|
||||
it++;
|
||||
for (auto it2 = list.begin(); it2 != list.end(); it2++) {
|
||||
if (it == it2) {
|
||||
REQUIRE((*it) == (*it2));
|
||||
break;
|
||||
} else {
|
||||
REQUIRE((*it2) == 0);
|
||||
REQUIRE(it2 != it);
|
||||
}
|
||||
}
|
||||
}
|
||||
SECTION("Const Iterator") {
|
||||
ArrayList<uint16_t>::Iterator it = list.begin();
|
||||
for (auto i = 0; i < 10; i++) {
|
||||
REQUIRE(list.insert(i) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
}
|
||||
it++;
|
||||
const uint16_t* number = it.value;
|
||||
REQUIRE(*number == 1);
|
||||
}
|
||||
|
||||
SECTION("Const Iterator"){
|
||||
ArrayList<TestClass>::Iterator it = complexList.begin();
|
||||
for (auto i =0; i < 10; i++){
|
||||
REQUIRE(complexList.insert(TestClass(i, i+1)) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
}
|
||||
it++;
|
||||
const TestClass* secondTest = it.value;
|
||||
bool compare = TestClass(1, 2) == *secondTest;
|
||||
REQUIRE(compare);
|
||||
it++;
|
||||
REQUIRE(it->number1 == 2);
|
||||
REQUIRE(it->number2 == 3);
|
||||
const ArrayList<TestClass>::Iterator it4(&(complexList[2]));
|
||||
REQUIRE(it4->number1 == 2);
|
||||
REQUIRE((*it4).number2 == 3);
|
||||
REQUIRE(complexList.remaining()==10);
|
||||
}
|
||||
SECTION("Const Iterator") {
|
||||
ArrayList<TestClass>::Iterator it = complexList.begin();
|
||||
for (auto i = 0; i < 10; i++) {
|
||||
REQUIRE(complexList.insert(TestClass(i, i + 1)) ==
|
||||
static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
}
|
||||
it++;
|
||||
const TestClass* secondTest = it.value;
|
||||
bool compare = TestClass(1, 2) == *secondTest;
|
||||
REQUIRE(compare);
|
||||
it++;
|
||||
REQUIRE(it->number1 == 2);
|
||||
REQUIRE(it->number2 == 3);
|
||||
const ArrayList<TestClass>::Iterator it4(&(complexList[2]));
|
||||
REQUIRE(it4->number1 == 2);
|
||||
REQUIRE((*it4).number2 == 3);
|
||||
REQUIRE(complexList.remaining() == 10);
|
||||
}
|
||||
}
|
||||
|
@ -1,149 +1,145 @@
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <fsfw/container/DynamicFIFO.h>
|
||||
#include <fsfw/container/FIFO.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
TEST_CASE( "Dynamic Fifo Tests", "[TestDynamicFifo]") {
|
||||
INFO("Dynamic Fifo Tests");
|
||||
struct Test{
|
||||
uint64_t number1;
|
||||
uint32_t number2;
|
||||
uint8_t number3;
|
||||
bool operator==(struct Test& other){
|
||||
if ((other.number1 == this->number1) and
|
||||
(other.number1 == this->number1) and
|
||||
(other.number1 == this->number1)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
DynamicFIFO<Test> fifo(3);
|
||||
std::vector<Test> list;
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
struct Test structOne({UINT64_MAX, UINT32_MAX, UINT8_MAX});
|
||||
struct Test structTwo({0, 1, 2});
|
||||
struct Test structThree({42, 43, 44});
|
||||
list.push_back(structThree);
|
||||
list.push_back(structTwo);
|
||||
list.push_back(structOne);
|
||||
SECTION("Insert, retrieval test"){
|
||||
REQUIRE(fifo.getMaxCapacity()==3);
|
||||
REQUIRE(fifo.size()==0);
|
||||
REQUIRE(fifo.empty());
|
||||
REQUIRE(not fifo.full());
|
||||
TEST_CASE("Dynamic Fifo Tests", "[TestDynamicFifo]") {
|
||||
INFO("Dynamic Fifo Tests");
|
||||
struct Test {
|
||||
uint64_t number1;
|
||||
uint32_t number2;
|
||||
uint8_t number3;
|
||||
bool operator==(struct Test& other) {
|
||||
if ((other.number1 == this->number1) and (other.number1 == this->number1) and
|
||||
(other.number1 == this->number1)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
DynamicFIFO<Test> fifo(3);
|
||||
std::vector<Test> list;
|
||||
|
||||
REQUIRE(fifo.insert(structOne)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structThree)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo)==static_cast<int>(FIFOBase<Test>::FULL));
|
||||
struct Test structOne({UINT64_MAX, UINT32_MAX, UINT8_MAX});
|
||||
struct Test structTwo({0, 1, 2});
|
||||
struct Test structThree({42, 43, 44});
|
||||
list.push_back(structThree);
|
||||
list.push_back(structTwo);
|
||||
list.push_back(structOne);
|
||||
SECTION("Insert, retrieval test") {
|
||||
REQUIRE(fifo.getMaxCapacity() == 3);
|
||||
REQUIRE(fifo.size() == 0);
|
||||
REQUIRE(fifo.empty());
|
||||
REQUIRE(not fifo.full());
|
||||
|
||||
struct Test testptr;
|
||||
REQUIRE(fifo.peek(&testptr)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
bool equal = testptr == structOne;
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo.size()==3);
|
||||
REQUIRE(fifo.full());
|
||||
REQUIRE(not fifo.empty());
|
||||
REQUIRE(fifo.insert(structOne) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structThree) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo) == static_cast<int>(FIFOBase<Test>::FULL));
|
||||
|
||||
for(size_t i=2;i<3;i--){
|
||||
testptr.number1 = 0;
|
||||
testptr.number2 = 0;
|
||||
testptr.number3 = 0;
|
||||
REQUIRE(fifo.retrieve(&testptr)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
equal = testptr == list[i];
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo.size()==i);
|
||||
}
|
||||
testptr.number1 = 0;
|
||||
testptr.number2 = 0;
|
||||
testptr.number3 = 0;
|
||||
REQUIRE(fifo.retrieve(&testptr)==static_cast<int>(FIFOBase<Test>::EMPTY));
|
||||
REQUIRE(fifo.peek(&testptr)==static_cast<int>(FIFOBase<Test>::EMPTY));
|
||||
REQUIRE(not fifo.full());
|
||||
REQUIRE(fifo.empty());
|
||||
REQUIRE(fifo.pop()==static_cast<int>(FIFOBase<Test>::EMPTY));
|
||||
struct Test testptr;
|
||||
REQUIRE(fifo.peek(&testptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
bool equal = testptr == structOne;
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo.size() == 3);
|
||||
REQUIRE(fifo.full());
|
||||
REQUIRE(not fifo.empty());
|
||||
|
||||
REQUIRE(fifo.insert(structOne)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size()==1);
|
||||
REQUIRE(fifo.insert(structTwo)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size()==2);
|
||||
REQUIRE(fifo.pop()==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size()==1);
|
||||
testptr.number1 = 0;
|
||||
testptr.number2 = 0;
|
||||
testptr.number3 = 0;
|
||||
REQUIRE(fifo.peek(&testptr)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
equal = testptr == structTwo;
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo.pop()==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size()==0);
|
||||
REQUIRE(fifo.empty());
|
||||
//struct Test* ptr = nullptr;
|
||||
//REQUIRE(fifo.retrieve(ptr) == static_cast<int>(HasReturnvaluesIF::RETURN_FAILED));
|
||||
//REQUIRE(fifo.peek(ptr) == static_cast<int>(HasReturnvaluesIF::RETURN_FAILED));
|
||||
};
|
||||
SECTION("Copy Test"){
|
||||
REQUIRE(fifo.insert(structOne)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structThree)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size()==3);
|
||||
REQUIRE(fifo.full());
|
||||
REQUIRE(not fifo.empty());
|
||||
for (size_t i = 2; i < 3; i--) {
|
||||
testptr.number1 = 0;
|
||||
testptr.number2 = 0;
|
||||
testptr.number3 = 0;
|
||||
REQUIRE(fifo.retrieve(&testptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
equal = testptr == list[i];
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo.size() == i);
|
||||
}
|
||||
testptr.number1 = 0;
|
||||
testptr.number2 = 0;
|
||||
testptr.number3 = 0;
|
||||
REQUIRE(fifo.retrieve(&testptr) == static_cast<int>(FIFOBase<Test>::EMPTY));
|
||||
REQUIRE(fifo.peek(&testptr) == static_cast<int>(FIFOBase<Test>::EMPTY));
|
||||
REQUIRE(not fifo.full());
|
||||
REQUIRE(fifo.empty());
|
||||
REQUIRE(fifo.pop() == static_cast<int>(FIFOBase<Test>::EMPTY));
|
||||
|
||||
DynamicFIFO<Test> fifo2(fifo);
|
||||
REQUIRE(fifo2.size()==3);
|
||||
REQUIRE(fifo2.full());
|
||||
REQUIRE(not fifo2.empty());
|
||||
REQUIRE(fifo.insert(structOne) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size() == 1);
|
||||
REQUIRE(fifo.insert(structTwo) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size() == 2);
|
||||
REQUIRE(fifo.pop() == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size() == 1);
|
||||
testptr.number1 = 0;
|
||||
testptr.number2 = 0;
|
||||
testptr.number3 = 0;
|
||||
REQUIRE(fifo.peek(&testptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
equal = testptr == structTwo;
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo.pop() == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size() == 0);
|
||||
REQUIRE(fifo.empty());
|
||||
// struct Test* ptr = nullptr;
|
||||
// REQUIRE(fifo.retrieve(ptr) == static_cast<int>(HasReturnvaluesIF::RETURN_FAILED));
|
||||
// REQUIRE(fifo.peek(ptr) == static_cast<int>(HasReturnvaluesIF::RETURN_FAILED));
|
||||
};
|
||||
SECTION("Copy Test") {
|
||||
REQUIRE(fifo.insert(structOne) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structThree) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size() == 3);
|
||||
REQUIRE(fifo.full());
|
||||
REQUIRE(not fifo.empty());
|
||||
|
||||
};
|
||||
DynamicFIFO<Test> fifo2(fifo);
|
||||
REQUIRE(fifo2.size() == 3);
|
||||
REQUIRE(fifo2.full());
|
||||
REQUIRE(not fifo2.empty());
|
||||
};
|
||||
|
||||
SECTION("Assignment Test"){
|
||||
REQUIRE(fifo.insert(structOne)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structThree)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size()==3);
|
||||
REQUIRE(fifo.full());
|
||||
REQUIRE(not fifo.empty());
|
||||
SECTION("Assignment Test") {
|
||||
REQUIRE(fifo.insert(structOne) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structThree) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size() == 3);
|
||||
REQUIRE(fifo.full());
|
||||
REQUIRE(not fifo.empty());
|
||||
|
||||
DynamicFIFO<Test> fifo2(6);
|
||||
fifo2 = fifo;
|
||||
REQUIRE(fifo2.size()==3);
|
||||
REQUIRE(fifo2.full());
|
||||
REQUIRE(not fifo2.empty());
|
||||
for(size_t i=2;i<3;i--){
|
||||
struct Test testptr = {0, 0, 0};
|
||||
REQUIRE(fifo2.retrieve(&testptr)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
bool equal = testptr == list[i];
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo2.size()==i);
|
||||
}
|
||||
DynamicFIFO<Test> fifo2(6);
|
||||
fifo2 = fifo;
|
||||
REQUIRE(fifo2.size() == 3);
|
||||
REQUIRE(fifo2.full());
|
||||
REQUIRE(not fifo2.empty());
|
||||
for (size_t i = 2; i < 3; i--) {
|
||||
struct Test testptr = {0, 0, 0};
|
||||
REQUIRE(fifo2.retrieve(&testptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
bool equal = testptr == list[i];
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo2.size() == i);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
SECTION("Assignment Test Smaller"){
|
||||
REQUIRE(fifo.insert(structOne)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structThree)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size()==3);
|
||||
REQUIRE(fifo.full());
|
||||
REQUIRE(not fifo.empty());
|
||||
|
||||
DynamicFIFO<Test> fifo2(2);
|
||||
fifo2 = fifo;
|
||||
REQUIRE(fifo2.size()==3);
|
||||
REQUIRE(fifo2.full());
|
||||
REQUIRE(not fifo2.empty());
|
||||
for(size_t i=2;i<3;i--){
|
||||
struct Test testptr = {0, 0, 0};
|
||||
REQUIRE(fifo2.retrieve(&testptr)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
bool equal = testptr == list[i];
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo2.size()==i);
|
||||
}
|
||||
};
|
||||
SECTION("Assignment Test Smaller") {
|
||||
REQUIRE(fifo.insert(structOne) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structThree) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size() == 3);
|
||||
REQUIRE(fifo.full());
|
||||
REQUIRE(not fifo.empty());
|
||||
|
||||
DynamicFIFO<Test> fifo2(2);
|
||||
fifo2 = fifo;
|
||||
REQUIRE(fifo2.size() == 3);
|
||||
REQUIRE(fifo2.full());
|
||||
REQUIRE(not fifo2.empty());
|
||||
for (size_t i = 2; i < 3; i--) {
|
||||
struct Test testptr = {0, 0, 0};
|
||||
REQUIRE(fifo2.retrieve(&testptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
bool equal = testptr == list[i];
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo2.size() == i);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -1,138 +1,133 @@
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <fsfw/container/DynamicFIFO.h>
|
||||
#include <fsfw/container/FIFO.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
TEST_CASE( "Static Fifo Tests", "[TestFifo]") {
|
||||
INFO("Fifo Tests");
|
||||
struct Test{
|
||||
uint64_t number1;
|
||||
uint32_t number2;
|
||||
uint8_t number3;
|
||||
bool operator==(struct Test& other){
|
||||
if ((other.number1 == this->number1) and
|
||||
(other.number1 == this->number1) and
|
||||
(other.number1 == this->number1)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
FIFO<Test, 3> fifo;
|
||||
std::vector<Test> list;
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
struct Test structOne({UINT64_MAX, UINT32_MAX, UINT8_MAX});
|
||||
struct Test structTwo({0, 1, 2});
|
||||
struct Test structThree({42, 43, 44});
|
||||
list.push_back(structThree);
|
||||
list.push_back(structTwo);
|
||||
list.push_back(structOne);
|
||||
SECTION("Insert, retrieval test"){
|
||||
REQUIRE(fifo.getMaxCapacity()==3);
|
||||
REQUIRE(fifo.size()==0);
|
||||
REQUIRE(fifo.empty());
|
||||
REQUIRE(not fifo.full());
|
||||
TEST_CASE("Static Fifo Tests", "[TestFifo]") {
|
||||
INFO("Fifo Tests");
|
||||
struct Test {
|
||||
uint64_t number1;
|
||||
uint32_t number2;
|
||||
uint8_t number3;
|
||||
bool operator==(struct Test& other) {
|
||||
if ((other.number1 == this->number1) and (other.number1 == this->number1) and
|
||||
(other.number1 == this->number1)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
FIFO<Test, 3> fifo;
|
||||
std::vector<Test> list;
|
||||
|
||||
REQUIRE(fifo.insert(structOne)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structThree)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo)==static_cast<int>(FIFOBase<Test>::FULL));
|
||||
struct Test structOne({UINT64_MAX, UINT32_MAX, UINT8_MAX});
|
||||
struct Test structTwo({0, 1, 2});
|
||||
struct Test structThree({42, 43, 44});
|
||||
list.push_back(structThree);
|
||||
list.push_back(structTwo);
|
||||
list.push_back(structOne);
|
||||
SECTION("Insert, retrieval test") {
|
||||
REQUIRE(fifo.getMaxCapacity() == 3);
|
||||
REQUIRE(fifo.size() == 0);
|
||||
REQUIRE(fifo.empty());
|
||||
REQUIRE(not fifo.full());
|
||||
|
||||
struct Test testptr;
|
||||
REQUIRE(fifo.peek(&testptr)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
bool equal = testptr == structOne;
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo.size()==3);
|
||||
REQUIRE(fifo.full());
|
||||
REQUIRE(not fifo.empty());
|
||||
REQUIRE(fifo.insert(structOne) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structThree) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo) == static_cast<int>(FIFOBase<Test>::FULL));
|
||||
|
||||
for(size_t i=2;i<3;i--){
|
||||
testptr.number1 = 0;
|
||||
testptr.number2 = 0;
|
||||
testptr.number3 = 0;
|
||||
REQUIRE(fifo.retrieve(&testptr)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
equal = testptr == list[i];
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo.size()==i);
|
||||
}
|
||||
testptr.number1 = 0;
|
||||
testptr.number2 = 0;
|
||||
testptr.number3 = 0;
|
||||
REQUIRE(fifo.retrieve(&testptr)==static_cast<int>(FIFOBase<Test>::EMPTY));
|
||||
REQUIRE(fifo.peek(&testptr)==static_cast<int>(FIFOBase<Test>::EMPTY));
|
||||
REQUIRE(not fifo.full());
|
||||
REQUIRE(fifo.empty());
|
||||
REQUIRE(fifo.pop()==static_cast<int>(FIFOBase<Test>::EMPTY));
|
||||
struct Test testptr;
|
||||
REQUIRE(fifo.peek(&testptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
bool equal = testptr == structOne;
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo.size() == 3);
|
||||
REQUIRE(fifo.full());
|
||||
REQUIRE(not fifo.empty());
|
||||
|
||||
REQUIRE(fifo.insert(structOne)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size()==1);
|
||||
REQUIRE(fifo.insert(structTwo)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size()==2);
|
||||
REQUIRE(fifo.pop()==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size()==1);
|
||||
testptr.number1 = 0;
|
||||
testptr.number2 = 0;
|
||||
testptr.number3 = 0;
|
||||
for (size_t i = 2; i < 3; i--) {
|
||||
testptr.number1 = 0;
|
||||
testptr.number2 = 0;
|
||||
testptr.number3 = 0;
|
||||
REQUIRE(fifo.retrieve(&testptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
equal = testptr == list[i];
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo.size() == i);
|
||||
}
|
||||
testptr.number1 = 0;
|
||||
testptr.number2 = 0;
|
||||
testptr.number3 = 0;
|
||||
REQUIRE(fifo.retrieve(&testptr) == static_cast<int>(FIFOBase<Test>::EMPTY));
|
||||
REQUIRE(fifo.peek(&testptr) == static_cast<int>(FIFOBase<Test>::EMPTY));
|
||||
REQUIRE(not fifo.full());
|
||||
REQUIRE(fifo.empty());
|
||||
REQUIRE(fifo.pop() == static_cast<int>(FIFOBase<Test>::EMPTY));
|
||||
|
||||
// Test that retrieve and peek will not cause a nullptr dereference
|
||||
struct Test* ptr = nullptr;
|
||||
REQUIRE(fifo.retrieve(ptr) == static_cast<int>(HasReturnvaluesIF::RETURN_FAILED));
|
||||
REQUIRE(fifo.peek(ptr) == static_cast<int>(HasReturnvaluesIF::RETURN_FAILED));
|
||||
REQUIRE(fifo.insert(structOne) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size() == 1);
|
||||
REQUIRE(fifo.insert(structTwo) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size() == 2);
|
||||
REQUIRE(fifo.pop() == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size() == 1);
|
||||
testptr.number1 = 0;
|
||||
testptr.number2 = 0;
|
||||
testptr.number3 = 0;
|
||||
|
||||
// Test that retrieve and peek will not cause a nullptr dereference
|
||||
struct Test* ptr = nullptr;
|
||||
REQUIRE(fifo.retrieve(ptr) == static_cast<int>(HasReturnvaluesIF::RETURN_FAILED));
|
||||
REQUIRE(fifo.peek(ptr) == static_cast<int>(HasReturnvaluesIF::RETURN_FAILED));
|
||||
|
||||
REQUIRE(fifo.peek(&testptr)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
equal = testptr == structTwo;
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo.pop()==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size()==0);
|
||||
REQUIRE(fifo.empty());
|
||||
REQUIRE(fifo.peek(&testptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
equal = testptr == structTwo;
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo.pop() == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size() == 0);
|
||||
REQUIRE(fifo.empty());
|
||||
};
|
||||
SECTION("Copy Test") {
|
||||
REQUIRE(fifo.insert(structOne) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structThree) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size() == 3);
|
||||
REQUIRE(fifo.full());
|
||||
REQUIRE(not fifo.empty());
|
||||
|
||||
FIFO<Test, 3> fifo2(fifo);
|
||||
REQUIRE(fifo2.size() == 3);
|
||||
REQUIRE(fifo2.full());
|
||||
REQUIRE(not fifo2.empty());
|
||||
for (size_t i = 2; i < 3; i--) {
|
||||
struct Test testptr = {0, 0, 0};
|
||||
REQUIRE(fifo2.retrieve(&testptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
bool equal = testptr == list[i];
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo2.size() == i);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
SECTION("Copy Test"){
|
||||
REQUIRE(fifo.insert(structOne)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structThree)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size()==3);
|
||||
REQUIRE(fifo.full());
|
||||
REQUIRE(not fifo.empty());
|
||||
SECTION("Assignment Test") {
|
||||
REQUIRE(fifo.insert(structOne) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structThree) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size() == 3);
|
||||
REQUIRE(fifo.full());
|
||||
REQUIRE(not fifo.empty());
|
||||
|
||||
FIFO<Test, 3> fifo2(fifo);
|
||||
REQUIRE(fifo2.size()==3);
|
||||
REQUIRE(fifo2.full());
|
||||
REQUIRE(not fifo2.empty());
|
||||
for(size_t i=2;i<3;i--){
|
||||
struct Test testptr = {0, 0, 0};
|
||||
REQUIRE(fifo2.retrieve(&testptr)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
bool equal = testptr == list[i];
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo2.size()==i);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
SECTION("Assignment Test"){
|
||||
REQUIRE(fifo.insert(structOne)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structTwo)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.insert(structThree)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(fifo.size()==3);
|
||||
REQUIRE(fifo.full());
|
||||
REQUIRE(not fifo.empty());
|
||||
|
||||
FIFO<Test, 3> fifo2;
|
||||
fifo2 = fifo;
|
||||
REQUIRE(fifo2.size()==3);
|
||||
REQUIRE(fifo2.full());
|
||||
REQUIRE(not fifo2.empty());
|
||||
for(size_t i=2;i<3;i--){
|
||||
struct Test testptr = {0, 0, 0};
|
||||
REQUIRE(fifo2.retrieve(&testptr)==static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
bool equal = testptr == list[i];
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo2.size()==i);
|
||||
}
|
||||
};
|
||||
FIFO<Test, 3> fifo2;
|
||||
fifo2 = fifo;
|
||||
REQUIRE(fifo2.size() == 3);
|
||||
REQUIRE(fifo2.full());
|
||||
REQUIRE(not fifo2.empty());
|
||||
for (size_t i = 2; i < 3; i--) {
|
||||
struct Test testptr = {0, 0, 0};
|
||||
REQUIRE(fifo2.retrieve(&testptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
bool equal = testptr == list[i];
|
||||
REQUIRE(equal);
|
||||
REQUIRE(fifo2.size() == i);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -1,42 +1,38 @@
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <fsfw/container/FixedArrayList.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
TEST_CASE( "FixedArrayList Tests", "[TestFixedArrayList]") {
|
||||
INFO("FixedArrayList Tests");
|
||||
using testList = FixedArrayList<uint32_t, 260, uint16_t>;
|
||||
testList list;
|
||||
REQUIRE(list.size==0);
|
||||
REQUIRE(list.insert(10) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(list.size==1);
|
||||
REQUIRE(list.maxSize()==260);
|
||||
SECTION("Copy Constructor"){
|
||||
testList list2(list);
|
||||
REQUIRE(list2.size==1);
|
||||
REQUIRE(list2[0] == 10);
|
||||
REQUIRE(list.maxSize()==260);
|
||||
};
|
||||
SECTION("Assignment copy"){
|
||||
testList list2;
|
||||
REQUIRE(list2.size==0);
|
||||
list2 = list;
|
||||
REQUIRE(list2.size==1);
|
||||
REQUIRE(list2[0] == 10);
|
||||
REQUIRE(list.maxSize()==260);
|
||||
};
|
||||
SECTION("Fill"){
|
||||
for(auto i=1;i<260;i++){
|
||||
REQUIRE(list.insert(i) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
}
|
||||
REQUIRE(list.insert(260) == static_cast<int>(ArrayList<uint32_t, uint16_t>::FULL));
|
||||
list.clear();
|
||||
REQUIRE(list.size == 0);
|
||||
}
|
||||
TEST_CASE("FixedArrayList Tests", "[TestFixedArrayList]") {
|
||||
INFO("FixedArrayList Tests");
|
||||
using testList = FixedArrayList<uint32_t, 260, uint16_t>;
|
||||
testList list;
|
||||
REQUIRE(list.size == 0);
|
||||
REQUIRE(list.insert(10) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(list.size == 1);
|
||||
REQUIRE(list.maxSize() == 260);
|
||||
SECTION("Copy Constructor") {
|
||||
testList list2(list);
|
||||
REQUIRE(list2.size == 1);
|
||||
REQUIRE(list2[0] == 10);
|
||||
REQUIRE(list.maxSize() == 260);
|
||||
};
|
||||
SECTION("Assignment copy") {
|
||||
testList list2;
|
||||
REQUIRE(list2.size == 0);
|
||||
list2 = list;
|
||||
REQUIRE(list2.size == 1);
|
||||
REQUIRE(list2[0] == 10);
|
||||
REQUIRE(list.maxSize() == 260);
|
||||
};
|
||||
SECTION("Fill") {
|
||||
for (auto i = 1; i < 260; i++) {
|
||||
REQUIRE(list.insert(i) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
}
|
||||
REQUIRE(list.insert(260) == static_cast<int>(ArrayList<uint32_t, uint16_t>::FULL));
|
||||
list.clear();
|
||||
REQUIRE(list.size == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,173 +1,166 @@
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <fsfw/container/FixedMap.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
template class FixedMap<unsigned int, unsigned short>;
|
||||
|
||||
TEST_CASE( "FixedMap Tests", "[TestFixedMap]") {
|
||||
INFO("FixedMap Tests");
|
||||
TEST_CASE("FixedMap Tests", "[TestFixedMap]") {
|
||||
INFO("FixedMap Tests");
|
||||
|
||||
FixedMap<unsigned int, unsigned short> map(30);
|
||||
REQUIRE(map.size() == 0);
|
||||
REQUIRE(map.maxSize() == 30);
|
||||
REQUIRE(map.getSerializedSize() == sizeof(uint32_t));
|
||||
REQUIRE(map.empty());
|
||||
REQUIRE(not map.full());
|
||||
FixedMap<unsigned int, unsigned short> map(30);
|
||||
REQUIRE(map.size() == 0);
|
||||
REQUIRE(map.maxSize() == 30);
|
||||
REQUIRE(map.getSerializedSize() == sizeof(uint32_t));
|
||||
REQUIRE(map.empty());
|
||||
REQUIRE(not map.full());
|
||||
|
||||
SECTION("Fill and erase"){
|
||||
for (uint16_t i=0;i<30;i++){
|
||||
REQUIRE(map.insert(std::make_pair(i, i+1))== static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.exists(i) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.find(i)->second==i+1);
|
||||
REQUIRE(not map.empty());
|
||||
}
|
||||
REQUIRE(map.insert(0, 0) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_ALREADY_EXISTS));
|
||||
REQUIRE(map.insert(31, 0) == static_cast<int>(FixedMap<uint32_t, uint16_t>::MAP_FULL));
|
||||
REQUIRE(map.exists(31) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.size() == 30);
|
||||
REQUIRE(map.full());
|
||||
{
|
||||
uint16_t* ptr;
|
||||
REQUIRE(map.find(5,&ptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(*ptr == 6);
|
||||
REQUIRE(*(map.findValue(6)) == 7);
|
||||
REQUIRE(map.find(31,&ptr) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
}
|
||||
SECTION("Fill and erase") {
|
||||
for (uint16_t i = 0; i < 30; i++) {
|
||||
REQUIRE(map.insert(std::make_pair(i, i + 1)) ==
|
||||
static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.exists(i) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.find(i)->second == i + 1);
|
||||
REQUIRE(not map.empty());
|
||||
}
|
||||
REQUIRE(map.insert(0, 0) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_ALREADY_EXISTS));
|
||||
REQUIRE(map.insert(31, 0) == static_cast<int>(FixedMap<uint32_t, uint16_t>::MAP_FULL));
|
||||
REQUIRE(map.exists(31) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.size() == 30);
|
||||
REQUIRE(map.full());
|
||||
{
|
||||
uint16_t* ptr;
|
||||
REQUIRE(map.find(5, &ptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(*ptr == 6);
|
||||
REQUIRE(*(map.findValue(6)) == 7);
|
||||
REQUIRE(map.find(31, &ptr) ==
|
||||
static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
}
|
||||
|
||||
REQUIRE(map.getSerializedSize() == (sizeof(uint32_t)+ 30*(sizeof(uint32_t) + sizeof(uint16_t))));
|
||||
REQUIRE(map.erase(2) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.erase(31) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.exists(2) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.size() == 29);
|
||||
REQUIRE(map.getSerializedSize() ==
|
||||
(sizeof(uint32_t) + 30 * (sizeof(uint32_t) + sizeof(uint16_t))));
|
||||
REQUIRE(map.erase(2) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.erase(31) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.exists(2) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.size() == 29);
|
||||
|
||||
for (auto element: map){
|
||||
if (element.first == 5){
|
||||
REQUIRE(element.second == 6);
|
||||
}
|
||||
}
|
||||
for (auto element : map) {
|
||||
if (element.first == 5) {
|
||||
REQUIRE(element.second == 6);
|
||||
}
|
||||
}
|
||||
|
||||
for (FixedMap<uint32_t, uint16_t>::Iterator it = map.begin(); it != map.end(); it++){
|
||||
REQUIRE(it->second == it->first + 1);
|
||||
REQUIRE((*it).second == (*it).first + 1);
|
||||
it->second = it->second + 1;
|
||||
REQUIRE(it->second == it->first + 2);
|
||||
}
|
||||
for (FixedMap<uint32_t, uint16_t>::Iterator it = map.begin(); it != map.end(); it++) {
|
||||
REQUIRE(it->second == it->first + 1);
|
||||
REQUIRE((*it).second == (*it).first + 1);
|
||||
it->second = it->second + 1;
|
||||
REQUIRE(it->second == it->first + 2);
|
||||
}
|
||||
|
||||
for (FixedMap<uint32_t, uint16_t>::Iterator it = map.begin(); it != map.end(); it++){
|
||||
REQUIRE(map.erase(&it) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
}
|
||||
for (FixedMap<uint32_t, uint16_t>::Iterator it = map.begin(); it != map.end(); it++) {
|
||||
REQUIRE(map.erase(&it) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
}
|
||||
|
||||
REQUIRE(map.size() == 0);
|
||||
REQUIRE(map.size() == 0);
|
||||
|
||||
for (FixedMap<uint32_t, uint16_t>::Iterator it = map.begin(); it != map.end(); it++){
|
||||
// This line should never executed if begin and end is correct
|
||||
FAIL("Should never be reached, Iterators invalid");
|
||||
}
|
||||
};
|
||||
for (FixedMap<uint32_t, uint16_t>::Iterator it = map.begin(); it != map.end(); it++) {
|
||||
// This line should never executed if begin and end is correct
|
||||
FAIL("Should never be reached, Iterators invalid");
|
||||
}
|
||||
};
|
||||
|
||||
SECTION("Insert variants"){
|
||||
FixedMap<uint32_t, uint16_t>::Iterator it = map.end();
|
||||
REQUIRE(map.insert(36, 37, &it) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(it->first == 36);
|
||||
REQUIRE(it->second == 37);
|
||||
REQUIRE(map.size() == 1);
|
||||
REQUIRE(map.insert(37, 38, nullptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.find(37)->second == 38);
|
||||
REQUIRE(map.size() == 2);
|
||||
REQUIRE(map.insert(37, 24, nullptr) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_ALREADY_EXISTS));
|
||||
REQUIRE(map.find(37)->second != 24);
|
||||
REQUIRE(map.size() == 2);
|
||||
};
|
||||
SECTION("Serialize and DeSerialize") {
|
||||
REQUIRE(map.insert(36, 37, nullptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.insert(37, 38, nullptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
uint8_t buffer[sizeof(uint32_t)
|
||||
+ 2 * (sizeof(uint32_t) + sizeof(uint16_t))];
|
||||
REQUIRE(
|
||||
map.getSerializedSize()
|
||||
== (sizeof(uint32_t)
|
||||
+ 2 * (sizeof(uint32_t) + sizeof(uint16_t))));
|
||||
uint8_t *loc_ptr = buffer;
|
||||
size_t size = 0;
|
||||
REQUIRE(
|
||||
map.serialize(&loc_ptr, &size, 10, SerializeIF::Endianness::BIG)
|
||||
== static_cast<int>(SerializeIF::BUFFER_TOO_SHORT));
|
||||
loc_ptr = buffer;
|
||||
size = 0;
|
||||
REQUIRE(
|
||||
map.serialize(&loc_ptr, &size,
|
||||
sizeof(uint32_t)
|
||||
+ 2 * (sizeof(uint32_t) + sizeof(uint16_t)),
|
||||
SerializeIF::Endianness::BIG)
|
||||
== static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(size == 16);
|
||||
SECTION("Insert variants") {
|
||||
FixedMap<uint32_t, uint16_t>::Iterator it = map.end();
|
||||
REQUIRE(map.insert(36, 37, &it) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(it->first == 36);
|
||||
REQUIRE(it->second == 37);
|
||||
REQUIRE(map.size() == 1);
|
||||
REQUIRE(map.insert(37, 38, nullptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.find(37)->second == 38);
|
||||
REQUIRE(map.size() == 2);
|
||||
REQUIRE(map.insert(37, 24, nullptr) ==
|
||||
static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_ALREADY_EXISTS));
|
||||
REQUIRE(map.find(37)->second != 24);
|
||||
REQUIRE(map.size() == 2);
|
||||
};
|
||||
SECTION("Serialize and DeSerialize") {
|
||||
REQUIRE(map.insert(36, 37, nullptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.insert(37, 38, nullptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
uint8_t buffer[sizeof(uint32_t) + 2 * (sizeof(uint32_t) + sizeof(uint16_t))];
|
||||
REQUIRE(map.getSerializedSize() ==
|
||||
(sizeof(uint32_t) + 2 * (sizeof(uint32_t) + sizeof(uint16_t))));
|
||||
uint8_t* loc_ptr = buffer;
|
||||
size_t size = 0;
|
||||
REQUIRE(map.serialize(&loc_ptr, &size, 10, SerializeIF::Endianness::BIG) ==
|
||||
static_cast<int>(SerializeIF::BUFFER_TOO_SHORT));
|
||||
loc_ptr = buffer;
|
||||
size = 0;
|
||||
REQUIRE(map.serialize(
|
||||
&loc_ptr, &size, sizeof(uint32_t) + 2 * (sizeof(uint32_t) + sizeof(uint16_t)),
|
||||
SerializeIF::Endianness::BIG) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(size == 16);
|
||||
|
||||
uint32_t internal_size = 0;
|
||||
const uint8_t *ptr2 = buffer;
|
||||
REQUIRE(
|
||||
SerializeAdapter::deSerialize(&internal_size, &ptr2, &size,
|
||||
SerializeIF::Endianness::BIG)
|
||||
== static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(internal_size == 2);
|
||||
for (uint8_t i = 36; i < 38; i++) {
|
||||
uint32_t first_element = 0;
|
||||
REQUIRE(
|
||||
SerializeAdapter::deSerialize(&first_element, &ptr2, &size,
|
||||
SerializeIF::Endianness::BIG)
|
||||
== static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(first_element == i);
|
||||
uint16_t second_element = 0;
|
||||
REQUIRE(
|
||||
SerializeAdapter::deSerialize(&second_element, &ptr2, &size,
|
||||
SerializeIF::Endianness::BIG)
|
||||
== static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(second_element == i + 1);
|
||||
}
|
||||
REQUIRE(size == 0);
|
||||
map.clear();
|
||||
const uint8_t* constPtr = buffer;
|
||||
size = 16;
|
||||
REQUIRE(map.size() == 0);
|
||||
REQUIRE(map.deSerialize(&constPtr, &size,
|
||||
SerializeIF::Endianness::BIG) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.size() == 2);
|
||||
REQUIRE(map.find(36)->second == 37);
|
||||
for(auto& element: map){
|
||||
REQUIRE((element.first+1) == element.second);
|
||||
}
|
||||
};
|
||||
uint32_t internal_size = 0;
|
||||
const uint8_t* ptr2 = buffer;
|
||||
REQUIRE(
|
||||
SerializeAdapter::deSerialize(&internal_size, &ptr2, &size, SerializeIF::Endianness::BIG) ==
|
||||
static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(internal_size == 2);
|
||||
for (uint8_t i = 36; i < 38; i++) {
|
||||
uint32_t first_element = 0;
|
||||
REQUIRE(SerializeAdapter::deSerialize(&first_element, &ptr2, &size,
|
||||
SerializeIF::Endianness::BIG) ==
|
||||
static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(first_element == i);
|
||||
uint16_t second_element = 0;
|
||||
REQUIRE(SerializeAdapter::deSerialize(&second_element, &ptr2, &size,
|
||||
SerializeIF::Endianness::BIG) ==
|
||||
static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(second_element == i + 1);
|
||||
}
|
||||
REQUIRE(size == 0);
|
||||
map.clear();
|
||||
const uint8_t* constPtr = buffer;
|
||||
size = 16;
|
||||
REQUIRE(map.size() == 0);
|
||||
REQUIRE(map.deSerialize(&constPtr, &size, SerializeIF::Endianness::BIG) ==
|
||||
static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.size() == 2);
|
||||
REQUIRE(map.find(36)->second == 37);
|
||||
for (auto& element : map) {
|
||||
REQUIRE((element.first + 1) == element.second);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
SECTION("Failed erase and deSerialize"){
|
||||
FixedMap<uint32_t, uint16_t>::Iterator it;
|
||||
std::pair<uint32_t, uint16_t> pair = std::make_pair(44, 43);
|
||||
it = FixedMap<uint32_t, uint16_t>::Iterator(&pair);
|
||||
REQUIRE(map.erase(&it) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.find(45) == map.end());
|
||||
size_t toLargeMap = 100;
|
||||
const uint8_t* ptr = reinterpret_cast<uint8_t*>(&toLargeMap);
|
||||
size_t size = sizeof(size_t);
|
||||
REQUIRE(map.deSerialize(&ptr, &size, SerializeIF::Endianness::BIG) ==
|
||||
static_cast<int>(SerializeIF::TOO_MANY_ELEMENTS));
|
||||
};
|
||||
SECTION("Little Endianess"){
|
||||
map.clear();
|
||||
map.insert(10,20, nullptr);
|
||||
uint8_t newBuffer[sizeof(uint32_t)+ 1*(sizeof(uint32_t) + sizeof(uint16_t))];
|
||||
uint8_t* ptr = newBuffer;
|
||||
size_t size = 0;
|
||||
size_t max_size = sizeof(uint32_t)+ 1*(sizeof(uint32_t) + sizeof(uint16_t));
|
||||
REQUIRE(map.serialize(&ptr, &size, max_size,
|
||||
SerializeIF::Endianness::LITTLE) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
map.clear();
|
||||
REQUIRE(map.size()==0);
|
||||
const uint8_t* ptr2 = newBuffer;
|
||||
REQUIRE(map.deSerialize(&ptr2, &size,
|
||||
SerializeIF::Endianness::LITTLE) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.size()==1);
|
||||
REQUIRE(map.find(10)->second == 20);
|
||||
};
|
||||
SECTION("Failed erase and deSerialize") {
|
||||
FixedMap<uint32_t, uint16_t>::Iterator it;
|
||||
std::pair<uint32_t, uint16_t> pair = std::make_pair(44, 43);
|
||||
it = FixedMap<uint32_t, uint16_t>::Iterator(&pair);
|
||||
REQUIRE(map.erase(&it) == static_cast<int>(FixedMap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.find(45) == map.end());
|
||||
size_t toLargeMap = 100;
|
||||
const uint8_t* ptr = reinterpret_cast<uint8_t*>(&toLargeMap);
|
||||
size_t size = sizeof(size_t);
|
||||
REQUIRE(map.deSerialize(&ptr, &size, SerializeIF::Endianness::BIG) ==
|
||||
static_cast<int>(SerializeIF::TOO_MANY_ELEMENTS));
|
||||
};
|
||||
SECTION("Little Endianess") {
|
||||
map.clear();
|
||||
map.insert(10, 20, nullptr);
|
||||
uint8_t newBuffer[sizeof(uint32_t) + 1 * (sizeof(uint32_t) + sizeof(uint16_t))];
|
||||
uint8_t* ptr = newBuffer;
|
||||
size_t size = 0;
|
||||
size_t max_size = sizeof(uint32_t) + 1 * (sizeof(uint32_t) + sizeof(uint16_t));
|
||||
REQUIRE(map.serialize(&ptr, &size, max_size, SerializeIF::Endianness::LITTLE) ==
|
||||
static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
map.clear();
|
||||
REQUIRE(map.size() == 0);
|
||||
const uint8_t* ptr2 = newBuffer;
|
||||
REQUIRE(map.deSerialize(&ptr2, &size, SerializeIF::Endianness::LITTLE) ==
|
||||
static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.size() == 1);
|
||||
REQUIRE(map.find(10)->second == 20);
|
||||
};
|
||||
}
|
||||
|
@ -1,204 +1,221 @@
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <fsfw/container/FixedOrderedMultimap.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
TEST_CASE( "FixedOrderedMultimap Tests", "[TestFixedOrderedMultimap]") {
|
||||
INFO("FixedOrderedMultimap Tests");
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
FixedOrderedMultimap<unsigned int, unsigned short> map(30);
|
||||
REQUIRE(map.size() == 0);
|
||||
REQUIRE(map.maxSize() == 30);
|
||||
TEST_CASE("FixedOrderedMultimap Tests", "[TestFixedOrderedMultimap]") {
|
||||
INFO("FixedOrderedMultimap Tests");
|
||||
|
||||
SECTION("Test insert, find, exists"){
|
||||
for (uint16_t i=0;i<30;i++){
|
||||
REQUIRE(map.insert(std::make_pair(i, i+1))== static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.exists(i) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.find(i)->second==i+1);
|
||||
}
|
||||
REQUIRE(map.insert(0, 0) == static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::MAP_FULL));
|
||||
REQUIRE(map.exists(31) == static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.size() == 30);
|
||||
{
|
||||
uint16_t* ptr;
|
||||
REQUIRE(map.find(5,&ptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(*ptr == 6);
|
||||
REQUIRE(map.find(31,&ptr) == static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
}
|
||||
REQUIRE(map.erase(2) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.erase(31) == static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.exists(2) == static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.size() == 29);
|
||||
FixedOrderedMultimap<unsigned int, unsigned short> map(30);
|
||||
REQUIRE(map.size() == 0);
|
||||
REQUIRE(map.maxSize() == 30);
|
||||
|
||||
for (auto element: map){
|
||||
if (element.first == 5){
|
||||
REQUIRE(element.second == 6);
|
||||
}
|
||||
}
|
||||
SECTION("Test insert, find, exists") {
|
||||
for (uint16_t i = 0; i < 30; i++) {
|
||||
REQUIRE(map.insert(std::make_pair(i, i + 1)) ==
|
||||
static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.exists(i) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.find(i)->second == i + 1);
|
||||
}
|
||||
REQUIRE(map.insert(0, 0) ==
|
||||
static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::MAP_FULL));
|
||||
REQUIRE(map.exists(31) ==
|
||||
static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.size() == 30);
|
||||
{
|
||||
uint16_t* ptr;
|
||||
REQUIRE(map.find(5, &ptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(*ptr == 6);
|
||||
REQUIRE(map.find(31, &ptr) ==
|
||||
static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
}
|
||||
REQUIRE(map.erase(2) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.erase(31) ==
|
||||
static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.exists(2) ==
|
||||
static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.size() == 29);
|
||||
|
||||
for (FixedOrderedMultimap<uint32_t, uint16_t>::Iterator it = map.begin(); it != map.end(); it++){
|
||||
REQUIRE(it->second == it->first + 1);
|
||||
REQUIRE((*it).second == (*it).first + 1);
|
||||
it->second = it->second + 1;
|
||||
REQUIRE(it->second == it->first + 2);
|
||||
}
|
||||
for (auto element : map) {
|
||||
if (element.first == 5) {
|
||||
REQUIRE(element.second == 6);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
FixedOrderedMultimap<uint32_t, uint16_t>::Iterator it = map.begin();
|
||||
while(it != map.end()){
|
||||
REQUIRE(map.erase(&it) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
}
|
||||
REQUIRE(map.size() == 0);
|
||||
}
|
||||
for (FixedOrderedMultimap<uint32_t, uint16_t>::Iterator it = map.begin(); it != map.end();
|
||||
it++) {
|
||||
REQUIRE(it->second == it->first + 1);
|
||||
REQUIRE((*it).second == (*it).first + 1);
|
||||
it->second = it->second + 1;
|
||||
REQUIRE(it->second == it->first + 2);
|
||||
}
|
||||
|
||||
for (FixedOrderedMultimap<uint32_t, uint16_t>::Iterator it = map.begin(); it != map.end(); it++){
|
||||
// This line should never executed if begin and end is correct
|
||||
FAIL("Should never be reached, Iterators invalid");
|
||||
}
|
||||
};
|
||||
{
|
||||
FixedOrderedMultimap<uint32_t, uint16_t>::Iterator it = map.begin();
|
||||
while (it != map.end()) {
|
||||
REQUIRE(map.erase(&it) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
}
|
||||
REQUIRE(map.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("Test different insert variants")
|
||||
{
|
||||
FixedOrderedMultimap<uint32_t, uint16_t>::Iterator it = map.end();
|
||||
REQUIRE(map.insert(36, 37, &it) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(it->first == 36);
|
||||
REQUIRE(it->second == 37);
|
||||
REQUIRE(map.size() == 1);
|
||||
REQUIRE(map.insert(37, 38, nullptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.find(37)->second == 38);
|
||||
REQUIRE(map.size() == 2);
|
||||
REQUIRE(map.insert(37, 24, nullptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.find(37)->second == 38);
|
||||
REQUIRE(map.insert(0, 1, nullptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.find(0)->second == 1);
|
||||
REQUIRE(map.size() == 4);
|
||||
map.clear();
|
||||
REQUIRE(map.size() == 0);
|
||||
}
|
||||
SECTION("Test different erase and find with no entries"){
|
||||
FixedOrderedMultimap<uint32_t, uint16_t>::Iterator it;
|
||||
it = map.end();
|
||||
REQUIRE(map.erase(&it) == static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.find(1)== map.end());
|
||||
}
|
||||
for (FixedOrderedMultimap<uint32_t, uint16_t>::Iterator it = map.begin(); it != map.end();
|
||||
it++) {
|
||||
// This line should never executed if begin and end is correct
|
||||
FAIL("Should never be reached, Iterators invalid");
|
||||
}
|
||||
};
|
||||
|
||||
SECTION("Test different insert variants") {
|
||||
FixedOrderedMultimap<uint32_t, uint16_t>::Iterator it = map.end();
|
||||
REQUIRE(map.insert(36, 37, &it) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(it->first == 36);
|
||||
REQUIRE(it->second == 37);
|
||||
REQUIRE(map.size() == 1);
|
||||
REQUIRE(map.insert(37, 38, nullptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.find(37)->second == 38);
|
||||
REQUIRE(map.size() == 2);
|
||||
REQUIRE(map.insert(37, 24, nullptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.find(37)->second == 38);
|
||||
REQUIRE(map.insert(0, 1, nullptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.find(0)->second == 1);
|
||||
REQUIRE(map.size() == 4);
|
||||
map.clear();
|
||||
REQUIRE(map.size() == 0);
|
||||
}
|
||||
SECTION("Test different erase and find with no entries") {
|
||||
FixedOrderedMultimap<uint32_t, uint16_t>::Iterator it;
|
||||
it = map.end();
|
||||
REQUIRE(map.erase(&it) ==
|
||||
static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.find(1) == map.end());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE( "FixedOrderedMultimap Non Trivial Type", "[TestFixedOrderedMultimapNonTrivial]") {
|
||||
INFO("FixedOrderedMultimap Non Trivial Type");
|
||||
TEST_CASE("FixedOrderedMultimap Non Trivial Type", "[TestFixedOrderedMultimapNonTrivial]") {
|
||||
INFO("FixedOrderedMultimap Non Trivial Type");
|
||||
|
||||
class TestClass{
|
||||
public:
|
||||
TestClass(){};
|
||||
TestClass(uint32_t number1, uint64_t number2):
|
||||
number1(number1),number2(number2){};
|
||||
~TestClass(){};
|
||||
class TestClass {
|
||||
public:
|
||||
TestClass(){};
|
||||
TestClass(uint32_t number1, uint64_t number2) : number1(number1), number2(number2){};
|
||||
~TestClass(){};
|
||||
|
||||
bool operator==(const TestClass& lhs){
|
||||
return ((this->number1 == lhs.number1) and (this->number2 == lhs.number2));
|
||||
}
|
||||
bool operator!=(const TestClass& lhs){
|
||||
return not(this->operator ==(lhs));
|
||||
}
|
||||
bool operator==(const TestClass& lhs) {
|
||||
return ((this->number1 == lhs.number1) and (this->number2 == lhs.number2));
|
||||
}
|
||||
bool operator!=(const TestClass& lhs) { return not(this->operator==(lhs)); }
|
||||
|
||||
TestClass(const TestClass& other){
|
||||
this->number1 = other.number1;
|
||||
this->number2 = other.number2;
|
||||
};
|
||||
TestClass& operator=(const TestClass& other){
|
||||
this->number1 = other.number1;
|
||||
this->number2 = other.number2;
|
||||
return *this;
|
||||
};
|
||||
TestClass(const TestClass& other) {
|
||||
this->number1 = other.number1;
|
||||
this->number2 = other.number2;
|
||||
};
|
||||
TestClass& operator=(const TestClass& other) {
|
||||
this->number1 = other.number1;
|
||||
this->number2 = other.number2;
|
||||
return *this;
|
||||
};
|
||||
|
||||
private:
|
||||
uint32_t number1 = 0;
|
||||
uint64_t number2 = 5;
|
||||
};
|
||||
FixedOrderedMultimap<unsigned int, TestClass> map(30);
|
||||
REQUIRE(map.size() == 0);
|
||||
REQUIRE(map.maxSize() == 30);
|
||||
private:
|
||||
uint32_t number1 = 0;
|
||||
uint64_t number2 = 5;
|
||||
};
|
||||
FixedOrderedMultimap<unsigned int, TestClass> map(30);
|
||||
REQUIRE(map.size() == 0);
|
||||
REQUIRE(map.maxSize() == 30);
|
||||
|
||||
SECTION("Test insert, find, exists"){
|
||||
for (uint16_t i=0;i<30;i++){
|
||||
REQUIRE(map.insert(std::make_pair(i, TestClass(i+1,i)))== static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.exists(i) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
bool compare = map.find(i)->second == TestClass(i+1,i);
|
||||
REQUIRE(compare);
|
||||
}
|
||||
REQUIRE(map.insert(0, TestClass()) == static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::MAP_FULL));
|
||||
REQUIRE(map.exists(31) == static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.size() == 30);
|
||||
{
|
||||
TestClass* ptr = nullptr;
|
||||
REQUIRE(map.find(5,&ptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
bool compare = *ptr == TestClass(6, 5);
|
||||
REQUIRE(compare);
|
||||
REQUIRE(map.find(31,&ptr) == static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
}
|
||||
REQUIRE(map.erase(2) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.erase(31) == static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.exists(2) == static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.size() == 29);
|
||||
SECTION("Test insert, find, exists") {
|
||||
for (uint16_t i = 0; i < 30; i++) {
|
||||
REQUIRE(map.insert(std::make_pair(i, TestClass(i + 1, i))) ==
|
||||
static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.exists(i) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
bool compare = map.find(i)->second == TestClass(i + 1, i);
|
||||
REQUIRE(compare);
|
||||
}
|
||||
REQUIRE(map.insert(0, TestClass()) ==
|
||||
static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::MAP_FULL));
|
||||
REQUIRE(map.exists(31) ==
|
||||
static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.size() == 30);
|
||||
{
|
||||
TestClass* ptr = nullptr;
|
||||
REQUIRE(map.find(5, &ptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
bool compare = *ptr == TestClass(6, 5);
|
||||
REQUIRE(compare);
|
||||
REQUIRE(map.find(31, &ptr) ==
|
||||
static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
}
|
||||
REQUIRE(map.erase(2) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(map.erase(31) ==
|
||||
static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.exists(2) ==
|
||||
static_cast<int>(FixedOrderedMultimap<uint32_t, uint16_t>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.size() == 29);
|
||||
|
||||
for (auto element: map){
|
||||
if (element.first == 5){
|
||||
bool compare = element.second == TestClass(6, 5);
|
||||
REQUIRE(compare);
|
||||
}
|
||||
}
|
||||
for (auto element : map) {
|
||||
if (element.first == 5) {
|
||||
bool compare = element.second == TestClass(6, 5);
|
||||
REQUIRE(compare);
|
||||
}
|
||||
}
|
||||
|
||||
for (FixedOrderedMultimap<uint32_t, TestClass>::Iterator it = map.begin(); it != map.end(); it++){
|
||||
bool compare = it->second == TestClass(it->first + 1, it->first);
|
||||
REQUIRE(compare);
|
||||
compare = (*it).second == TestClass((*it).first + 1, (*it).first);
|
||||
REQUIRE(compare);
|
||||
it->second = TestClass(it->first + 2, it->first);
|
||||
compare = it->second == TestClass(it->first + 2, it->first);
|
||||
REQUIRE(compare);
|
||||
}
|
||||
for (FixedOrderedMultimap<uint32_t, TestClass>::Iterator it = map.begin(); it != map.end();
|
||||
it++) {
|
||||
bool compare = it->second == TestClass(it->first + 1, it->first);
|
||||
REQUIRE(compare);
|
||||
compare = (*it).second == TestClass((*it).first + 1, (*it).first);
|
||||
REQUIRE(compare);
|
||||
it->second = TestClass(it->first + 2, it->first);
|
||||
compare = it->second == TestClass(it->first + 2, it->first);
|
||||
REQUIRE(compare);
|
||||
}
|
||||
|
||||
{
|
||||
FixedOrderedMultimap<uint32_t, TestClass>::Iterator it = map.begin();
|
||||
while(it != map.end()){
|
||||
REQUIRE(map.erase(&it) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
}
|
||||
REQUIRE(map.size() == 0);
|
||||
}
|
||||
{
|
||||
FixedOrderedMultimap<uint32_t, TestClass>::Iterator it = map.begin();
|
||||
while (it != map.end()) {
|
||||
REQUIRE(map.erase(&it) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
}
|
||||
REQUIRE(map.size() == 0);
|
||||
}
|
||||
|
||||
for (FixedOrderedMultimap<uint32_t, TestClass>::Iterator it = map.begin(); it != map.end(); it++){
|
||||
// This line should never executed if begin and end is correct
|
||||
FAIL("Should never be reached, Iterators invalid");
|
||||
}
|
||||
};
|
||||
for (FixedOrderedMultimap<uint32_t, TestClass>::Iterator it = map.begin(); it != map.end();
|
||||
it++) {
|
||||
// This line should never executed if begin and end is correct
|
||||
FAIL("Should never be reached, Iterators invalid");
|
||||
}
|
||||
};
|
||||
|
||||
SECTION("Test different insert variants")
|
||||
{
|
||||
FixedOrderedMultimap<uint32_t, TestClass>::Iterator it = map.end();
|
||||
REQUIRE(map.insert(36, TestClass(37, 36), &it) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(it->first == 36);
|
||||
bool compare = it->second == TestClass(37, 36);
|
||||
REQUIRE(compare);
|
||||
REQUIRE(map.size() == 1);
|
||||
REQUIRE(map.insert(37, TestClass(38, 37), nullptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
compare = map.find(37)->second == TestClass(38, 37);
|
||||
REQUIRE(compare);
|
||||
REQUIRE(map.size() == 2);
|
||||
REQUIRE(map.insert(37, TestClass(24, 37), nullptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
compare = map.find(37)->second == TestClass(38, 37);
|
||||
REQUIRE(compare);
|
||||
REQUIRE(map.insert(0, TestClass(1, 0), nullptr) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
compare = map.find(0)->second == TestClass(1, 0);
|
||||
REQUIRE(compare);
|
||||
REQUIRE(map.size() == 4);
|
||||
map.clear();
|
||||
REQUIRE(map.size() == 0);
|
||||
}
|
||||
SECTION("Test different erase and find with no entries"){
|
||||
FixedOrderedMultimap<uint32_t, TestClass>::Iterator it;
|
||||
it = map.end();
|
||||
REQUIRE(map.erase(&it) == static_cast<int>(FixedOrderedMultimap<uint32_t, TestClass>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.find(1)== map.end());
|
||||
}
|
||||
SECTION("Test different insert variants") {
|
||||
FixedOrderedMultimap<uint32_t, TestClass>::Iterator it = map.end();
|
||||
REQUIRE(map.insert(36, TestClass(37, 36), &it) ==
|
||||
static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(it->first == 36);
|
||||
bool compare = it->second == TestClass(37, 36);
|
||||
REQUIRE(compare);
|
||||
REQUIRE(map.size() == 1);
|
||||
REQUIRE(map.insert(37, TestClass(38, 37), nullptr) ==
|
||||
static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
compare = map.find(37)->second == TestClass(38, 37);
|
||||
REQUIRE(compare);
|
||||
REQUIRE(map.size() == 2);
|
||||
REQUIRE(map.insert(37, TestClass(24, 37), nullptr) ==
|
||||
static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
compare = map.find(37)->second == TestClass(38, 37);
|
||||
REQUIRE(compare);
|
||||
REQUIRE(map.insert(0, TestClass(1, 0), nullptr) ==
|
||||
static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
compare = map.find(0)->second == TestClass(1, 0);
|
||||
REQUIRE(compare);
|
||||
REQUIRE(map.size() == 4);
|
||||
map.clear();
|
||||
REQUIRE(map.size() == 0);
|
||||
}
|
||||
SECTION("Test different erase and find with no entries") {
|
||||
FixedOrderedMultimap<uint32_t, TestClass>::Iterator it;
|
||||
it = map.end();
|
||||
REQUIRE(map.erase(&it) ==
|
||||
static_cast<int>(FixedOrderedMultimap<uint32_t, TestClass>::KEY_DOES_NOT_EXIST));
|
||||
REQUIRE(map.find(1) == map.end());
|
||||
}
|
||||
}
|
||||
|
@ -1,49 +1,48 @@
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <fsfw/container/PlacementFactory.h>
|
||||
#include <fsfw/storagemanager/LocalPool.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <fsfw/container/ArrayList.h>
|
||||
#include <fsfw/container/PlacementFactory.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <fsfw/storagemanager/LocalPool.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
TEST_CASE( "PlacementFactory Tests", "[TestPlacementFactory]") {
|
||||
INFO("PlacementFactory Tests");
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
LocalPool::LocalPoolConfig poolCfg= {{1, sizeof(uint16_t)},
|
||||
{1, sizeof(uint32_t)}, {1, sizeof(uint64_t)}
|
||||
};
|
||||
//const uint16_t element_sizes[3] = {sizeof(uint16_t), sizeof(uint32_t), sizeof(uint64_t)};
|
||||
//const uint16_t n_elements[3] = {1, 1, 1};
|
||||
LocalPool storagePool(0x1, poolCfg, false, true);
|
||||
PlacementFactory factory(&storagePool);
|
||||
TEST_CASE("PlacementFactory Tests", "[TestPlacementFactory]") {
|
||||
INFO("PlacementFactory Tests");
|
||||
|
||||
SECTION("Pool overload"){
|
||||
store_address_t address;
|
||||
uint8_t* ptr = nullptr;
|
||||
REQUIRE(storagePool.getFreeElement(&address, sizeof(ArrayList<uint32_t, uint16_t>), &ptr)
|
||||
== static_cast<int>(StorageManagerIF::DATA_TOO_LARGE));
|
||||
ArrayList<uint32_t, uint16_t>* list2 = factory.generate<ArrayList<uint32_t, uint16_t> >(80);
|
||||
REQUIRE(list2 == nullptr);
|
||||
}
|
||||
LocalPool::LocalPoolConfig poolCfg = {
|
||||
{1, sizeof(uint16_t)}, {1, sizeof(uint32_t)}, {1, sizeof(uint64_t)}};
|
||||
// const uint16_t element_sizes[3] = {sizeof(uint16_t), sizeof(uint32_t), sizeof(uint64_t)};
|
||||
// const uint16_t n_elements[3] = {1, 1, 1};
|
||||
LocalPool storagePool(0x1, poolCfg, false, true);
|
||||
PlacementFactory factory(&storagePool);
|
||||
|
||||
SECTION("Test generate and destroy"){
|
||||
uint64_t* number = factory.generate<uint64_t>(32000);
|
||||
REQUIRE(number != nullptr);
|
||||
REQUIRE(*number == 32000);
|
||||
store_address_t address;
|
||||
uint8_t* ptr = nullptr;
|
||||
REQUIRE(storagePool.getFreeElement(&address, sizeof(uint64_t), &ptr)
|
||||
== static_cast<int>(StorageManagerIF::DATA_TOO_LARGE));
|
||||
uint64_t* number2 = factory.generate<uint64_t>(12345);
|
||||
REQUIRE(number2 == nullptr);
|
||||
REQUIRE(factory.destroy(number) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(storagePool.getFreeElement(&address, sizeof(uint64_t), &ptr)
|
||||
== static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(storagePool.deleteData(address) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
SECTION("Pool overload") {
|
||||
store_address_t address;
|
||||
uint8_t* ptr = nullptr;
|
||||
REQUIRE(storagePool.getFreeElement(&address, sizeof(ArrayList<uint32_t, uint16_t>), &ptr) ==
|
||||
static_cast<int>(StorageManagerIF::DATA_TOO_LARGE));
|
||||
ArrayList<uint32_t, uint16_t>* list2 = factory.generate<ArrayList<uint32_t, uint16_t> >(80);
|
||||
REQUIRE(list2 == nullptr);
|
||||
}
|
||||
|
||||
//Check that PlacementFactory checks for nullptr
|
||||
ptr = nullptr;
|
||||
REQUIRE(factory.destroy(ptr) == static_cast<int>(HasReturnvaluesIF::RETURN_FAILED));
|
||||
}
|
||||
SECTION("Test generate and destroy") {
|
||||
uint64_t* number = factory.generate<uint64_t>(32000);
|
||||
REQUIRE(number != nullptr);
|
||||
REQUIRE(*number == 32000);
|
||||
store_address_t address;
|
||||
uint8_t* ptr = nullptr;
|
||||
REQUIRE(storagePool.getFreeElement(&address, sizeof(uint64_t), &ptr) ==
|
||||
static_cast<int>(StorageManagerIF::DATA_TOO_LARGE));
|
||||
uint64_t* number2 = factory.generate<uint64_t>(12345);
|
||||
REQUIRE(number2 == nullptr);
|
||||
REQUIRE(factory.destroy(number) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(storagePool.getFreeElement(&address, sizeof(uint64_t), &ptr) ==
|
||||
static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(storagePool.deleteData(address) == static_cast<int>(HasReturnvaluesIF::RETURN_OK));
|
||||
|
||||
// Check that PlacementFactory checks for nullptr
|
||||
ptr = nullptr;
|
||||
REQUIRE(factory.destroy(ptr) == static_cast<int>(HasReturnvaluesIF::RETURN_FAILED));
|
||||
}
|
||||
}
|
||||
|
@ -1,295 +1,286 @@
|
||||
#include "LocalPoolOwnerBase.h"
|
||||
#include "tests/TestsConfig.h"
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/datapoollocal/HasLocalDataPoolIF.h>
|
||||
#include <fsfw/datapoollocal/SharedLocalDataSet.h>
|
||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/globalfunctions/bitutility.h>
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/catch_approx.hpp>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
TEST_CASE("DataSetTest" , "[DataSetTest]") {
|
||||
LocalPoolOwnerBase* poolOwner = ObjectManager::instance()->
|
||||
get<LocalPoolOwnerBase>(objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
REQUIRE(poolOwner != nullptr);
|
||||
REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK);
|
||||
REQUIRE(poolOwner->initializeHkManagerAfterTaskCreation()
|
||||
== retval::CATCH_OK);
|
||||
LocalPoolStaticTestDataSet localSet;
|
||||
#include "LocalPoolOwnerBase.h"
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
#include "tests/TestsConfig.h"
|
||||
|
||||
SECTION("BasicTest") {
|
||||
/* Test some basic functions */
|
||||
CHECK(localSet.getReportingEnabled() == false);
|
||||
CHECK(localSet.getLocalPoolIdsSerializedSize(false) == 3 * sizeof(lp_id_t));
|
||||
CHECK(localSet.getLocalPoolIdsSerializedSize(true) ==
|
||||
3 * sizeof(lp_id_t) + sizeof(uint8_t));
|
||||
CHECK(localSet.getSid() == lpool::testSid);
|
||||
CHECK(localSet.getCreatorObjectId() == objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
size_t maxSize = localSet.getLocalPoolIdsSerializedSize(true);
|
||||
uint8_t localPoolIdBuff[maxSize];
|
||||
/* Skip size field */
|
||||
lp_id_t* lpIds = reinterpret_cast<lp_id_t*>(localPoolIdBuff + 1);
|
||||
size_t serSize = 0;
|
||||
uint8_t *localPoolIdBuffPtr = reinterpret_cast<uint8_t*>(localPoolIdBuff);
|
||||
TEST_CASE("DataSetTest", "[DataSetTest]") {
|
||||
LocalPoolOwnerBase* poolOwner =
|
||||
ObjectManager::instance()->get<LocalPoolOwnerBase>(objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
REQUIRE(poolOwner != nullptr);
|
||||
REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK);
|
||||
REQUIRE(poolOwner->initializeHkManagerAfterTaskCreation() == retval::CATCH_OK);
|
||||
LocalPoolStaticTestDataSet localSet;
|
||||
|
||||
/* Test local pool ID serialization */
|
||||
CHECK(localSet.serializeLocalPoolIds(&localPoolIdBuffPtr, &serSize,
|
||||
maxSize, SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
CHECK(serSize == maxSize);
|
||||
CHECK(localPoolIdBuff[0] == 3);
|
||||
CHECK(lpIds[0] == localSet.localPoolVarUint8.getDataPoolId());
|
||||
CHECK(lpIds[1] == localSet.localPoolVarFloat.getDataPoolId());
|
||||
CHECK(lpIds[2] == localSet.localPoolUint16Vec.getDataPoolId());
|
||||
/* Now serialize without fill count */
|
||||
lpIds = reinterpret_cast<lp_id_t*>(localPoolIdBuff);
|
||||
localPoolIdBuffPtr = localPoolIdBuff;
|
||||
serSize = 0;
|
||||
CHECK(localSet.serializeLocalPoolIds(&localPoolIdBuffPtr, &serSize,
|
||||
maxSize, SerializeIF::Endianness::MACHINE, false) == retval::CATCH_OK);
|
||||
CHECK(serSize == maxSize - sizeof(uint8_t));
|
||||
CHECK(lpIds[0] == localSet.localPoolVarUint8.getDataPoolId());
|
||||
CHECK(lpIds[1] == localSet.localPoolVarFloat.getDataPoolId());
|
||||
CHECK(lpIds[2] == localSet.localPoolUint16Vec.getDataPoolId());
|
||||
SECTION("BasicTest") {
|
||||
/* Test some basic functions */
|
||||
CHECK(localSet.getReportingEnabled() == false);
|
||||
CHECK(localSet.getLocalPoolIdsSerializedSize(false) == 3 * sizeof(lp_id_t));
|
||||
CHECK(localSet.getLocalPoolIdsSerializedSize(true) == 3 * sizeof(lp_id_t) + sizeof(uint8_t));
|
||||
CHECK(localSet.getSid() == lpool::testSid);
|
||||
CHECK(localSet.getCreatorObjectId() == objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
size_t maxSize = localSet.getLocalPoolIdsSerializedSize(true);
|
||||
uint8_t localPoolIdBuff[maxSize];
|
||||
/* Skip size field */
|
||||
lp_id_t* lpIds = reinterpret_cast<lp_id_t*>(localPoolIdBuff + 1);
|
||||
size_t serSize = 0;
|
||||
uint8_t* localPoolIdBuffPtr = reinterpret_cast<uint8_t*>(localPoolIdBuff);
|
||||
|
||||
{
|
||||
/* Test read operation. Values should be all zeros */
|
||||
PoolReadGuard readHelper(&localSet);
|
||||
REQUIRE(readHelper.getReadResult() == retval::CATCH_OK);
|
||||
CHECK(not localSet.isValid());
|
||||
CHECK(localSet.localPoolVarUint8.value == 0);
|
||||
CHECK(not localSet.localPoolVarUint8.isValid());
|
||||
CHECK(localSet.localPoolVarFloat.value == Catch::Approx(0.0));
|
||||
CHECK(not localSet.localPoolVarUint8.isValid());
|
||||
CHECK(localSet.localPoolUint16Vec.value[0] == 0);
|
||||
CHECK(localSet.localPoolUint16Vec.value[1] == 0);
|
||||
CHECK(localSet.localPoolUint16Vec.value[2] == 0);
|
||||
CHECK(not localSet.localPoolVarUint8.isValid());
|
||||
/* Test local pool ID serialization */
|
||||
CHECK(localSet.serializeLocalPoolIds(&localPoolIdBuffPtr, &serSize, maxSize,
|
||||
SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
CHECK(serSize == maxSize);
|
||||
CHECK(localPoolIdBuff[0] == 3);
|
||||
CHECK(lpIds[0] == localSet.localPoolVarUint8.getDataPoolId());
|
||||
CHECK(lpIds[1] == localSet.localPoolVarFloat.getDataPoolId());
|
||||
CHECK(lpIds[2] == localSet.localPoolUint16Vec.getDataPoolId());
|
||||
/* Now serialize without fill count */
|
||||
lpIds = reinterpret_cast<lp_id_t*>(localPoolIdBuff);
|
||||
localPoolIdBuffPtr = localPoolIdBuff;
|
||||
serSize = 0;
|
||||
CHECK(localSet.serializeLocalPoolIds(&localPoolIdBuffPtr, &serSize, maxSize,
|
||||
SerializeIF::Endianness::MACHINE,
|
||||
false) == retval::CATCH_OK);
|
||||
CHECK(serSize == maxSize - sizeof(uint8_t));
|
||||
CHECK(lpIds[0] == localSet.localPoolVarUint8.getDataPoolId());
|
||||
CHECK(lpIds[1] == localSet.localPoolVarFloat.getDataPoolId());
|
||||
CHECK(lpIds[2] == localSet.localPoolUint16Vec.getDataPoolId());
|
||||
|
||||
/* Now set new values, commit should be done by read helper automatically */
|
||||
localSet.localPoolVarUint8 = 232;
|
||||
localSet.localPoolVarFloat = -2324.322;
|
||||
localSet.localPoolUint16Vec.value[0] = 232;
|
||||
localSet.localPoolUint16Vec.value[1] = 23923;
|
||||
localSet.localPoolUint16Vec.value[2] = 1;
|
||||
localSet.setValidity(true, true);
|
||||
}
|
||||
|
||||
/* Zero out some values for next test */
|
||||
localSet.localPoolVarUint8 = 0;
|
||||
localSet.localPoolVarFloat = 0;
|
||||
|
||||
localSet.setAllVariablesReadOnly();
|
||||
CHECK(localSet.localPoolUint16Vec.getReadWriteMode() == pool_rwm_t::VAR_READ);
|
||||
CHECK(localSet.localPoolVarUint8.getReadWriteMode() == pool_rwm_t::VAR_READ);
|
||||
CHECK(localSet.localPoolVarFloat.getReadWriteMode() == pool_rwm_t::VAR_READ);
|
||||
|
||||
{
|
||||
/* Now we read again and check whether our zeroed values were overwritten with
|
||||
the values in the pool */
|
||||
PoolReadGuard readHelper(&localSet);
|
||||
REQUIRE(readHelper.getReadResult() == retval::CATCH_OK);
|
||||
CHECK(localSet.isValid());
|
||||
CHECK(localSet.localPoolVarUint8.value == 232);
|
||||
CHECK(localSet.localPoolVarUint8.isValid());
|
||||
CHECK(localSet.localPoolVarFloat.value == Catch::Approx(-2324.322));
|
||||
CHECK(localSet.localPoolVarFloat.isValid());
|
||||
CHECK(localSet.localPoolUint16Vec.value[0] == 232);
|
||||
CHECK(localSet.localPoolUint16Vec.value[1] == 23923);
|
||||
CHECK(localSet.localPoolUint16Vec.value[2] == 1);
|
||||
CHECK(localSet.localPoolUint16Vec.isValid());
|
||||
|
||||
/* Now we serialize these values into a buffer without the validity buffer */
|
||||
localSet.setValidityBufferGeneration(false);
|
||||
maxSize = localSet.getSerializedSize();
|
||||
CHECK(maxSize == sizeof(uint8_t) + sizeof(uint16_t) * 3 + sizeof(float));
|
||||
serSize = 0;
|
||||
/* Already reserve additional space for validity buffer, will be needed later */
|
||||
uint8_t buffer[maxSize + 1];
|
||||
uint8_t* buffPtr = buffer;
|
||||
CHECK(localSet.serialize(&buffPtr, &serSize, maxSize,
|
||||
SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
uint8_t rawUint8 = buffer[0];
|
||||
CHECK(rawUint8 == 232);
|
||||
float rawFloat = 0.0;
|
||||
std::memcpy(&rawFloat, buffer + sizeof(uint8_t), sizeof(float));
|
||||
CHECK(rawFloat == Catch::Approx(-2324.322));
|
||||
|
||||
uint16_t rawUint16Vec[3];
|
||||
std::memcpy(&rawUint16Vec, buffer + sizeof(uint8_t) + sizeof(float),
|
||||
3 * sizeof(uint16_t));
|
||||
CHECK(rawUint16Vec[0] == 232);
|
||||
CHECK(rawUint16Vec[1] == 23923);
|
||||
CHECK(rawUint16Vec[2] == 1);
|
||||
|
||||
size_t sizeToDeserialize = maxSize;
|
||||
/* Now we zeros out the raw entries and deserialize back into the dataset */
|
||||
std::memset(buffer, 0, sizeof(buffer));
|
||||
const uint8_t* constBuffPtr = buffer;
|
||||
CHECK(localSet.deSerialize(&constBuffPtr, &sizeToDeserialize,
|
||||
SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
/* Check whether deserialization was successfull */
|
||||
CHECK(localSet.localPoolVarUint8.value == 0);
|
||||
CHECK(localSet.localPoolVarFloat.value == Catch::Approx(0.0));
|
||||
CHECK(localSet.localPoolVarUint8.value == 0);
|
||||
CHECK(localSet.localPoolUint16Vec.value[0] == 0);
|
||||
CHECK(localSet.localPoolUint16Vec.value[1] == 0);
|
||||
CHECK(localSet.localPoolUint16Vec.value[2] == 0);
|
||||
/* Validity should be unchanged */
|
||||
CHECK(localSet.localPoolVarUint8.isValid());
|
||||
CHECK(localSet.localPoolVarFloat.isValid());
|
||||
CHECK(localSet.localPoolUint16Vec.isValid());
|
||||
|
||||
/* Now we do the same process but with the validity buffer */
|
||||
localSet.localPoolVarUint8 = 232;
|
||||
localSet.localPoolVarFloat = -2324.322;
|
||||
localSet.localPoolUint16Vec.value[0] = 232;
|
||||
localSet.localPoolUint16Vec.value[1] = 23923;
|
||||
localSet.localPoolUint16Vec.value[2] = 1;
|
||||
localSet.localPoolVarUint8.setValid(true);
|
||||
localSet.localPoolVarFloat.setValid(false);
|
||||
localSet.localPoolUint16Vec.setValid(true);
|
||||
localSet.setValidityBufferGeneration(true);
|
||||
maxSize = localSet.getSerializedSize();
|
||||
CHECK(maxSize == sizeof(uint8_t) + sizeof(uint16_t) * 3 + sizeof(float) + 1);
|
||||
serSize = 0;
|
||||
buffPtr = buffer;
|
||||
CHECK(localSet.serialize(&buffPtr, &serSize, maxSize,
|
||||
SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
CHECK(rawUint8 == 232);
|
||||
std::memcpy(&rawFloat, buffer + sizeof(uint8_t), sizeof(float));
|
||||
CHECK(rawFloat == Catch::Approx(-2324.322));
|
||||
|
||||
std::memcpy(&rawUint16Vec, buffer + sizeof(uint8_t) + sizeof(float),
|
||||
3 * sizeof(uint16_t));
|
||||
CHECK(rawUint16Vec[0] == 232);
|
||||
CHECK(rawUint16Vec[1] == 23923);
|
||||
CHECK(rawUint16Vec[2] == 1);
|
||||
/* We can do it like this because the buffer only has one byte for
|
||||
less than 8 variables */
|
||||
uint8_t* validityByte = buffer + sizeof(buffer) - 1;
|
||||
bool bitSet = false;
|
||||
bitutil::get(validityByte, 0, bitSet);
|
||||
|
||||
CHECK(bitSet == true);
|
||||
bitutil::get(validityByte, 1, bitSet);
|
||||
CHECK(bitSet == false);
|
||||
bitutil::get(validityByte, 2, bitSet);
|
||||
CHECK(bitSet == true);
|
||||
|
||||
/* Now we manipulate the validity buffer for the deserialization */
|
||||
bitutil::clear(validityByte, 0);
|
||||
bitutil::set(validityByte, 1);
|
||||
bitutil::clear(validityByte, 2);
|
||||
/* Zero out everything except validity buffer */
|
||||
std::memset(buffer, 0, sizeof(buffer) - 1);
|
||||
sizeToDeserialize = maxSize;
|
||||
constBuffPtr = buffer;
|
||||
CHECK(localSet.deSerialize(&constBuffPtr, &sizeToDeserialize,
|
||||
SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
/* Check whether deserialization was successfull */
|
||||
CHECK(localSet.localPoolVarUint8.value == 0);
|
||||
CHECK(localSet.localPoolVarFloat.value == Catch::Approx(0.0));
|
||||
CHECK(localSet.localPoolVarUint8.value == 0);
|
||||
CHECK(localSet.localPoolUint16Vec.value[0] == 0);
|
||||
CHECK(localSet.localPoolUint16Vec.value[1] == 0);
|
||||
CHECK(localSet.localPoolUint16Vec.value[2] == 0);
|
||||
CHECK(not localSet.localPoolVarUint8.isValid());
|
||||
CHECK(localSet.localPoolVarFloat.isValid());
|
||||
CHECK(not localSet.localPoolUint16Vec.isValid());
|
||||
|
||||
}
|
||||
|
||||
/* Common fault test cases */
|
||||
LocalPoolObjectBase* variableHandle = poolOwner->getPoolObjectHandle(lpool::uint32VarId);
|
||||
CHECK(variableHandle != nullptr);
|
||||
CHECK(localSet.registerVariable(variableHandle) ==
|
||||
static_cast<int>(DataSetIF::DATA_SET_FULL));
|
||||
variableHandle = nullptr;
|
||||
REQUIRE(localSet.registerVariable(variableHandle) ==
|
||||
static_cast<int>(DataSetIF::POOL_VAR_NULL));
|
||||
{
|
||||
/* Test read operation. Values should be all zeros */
|
||||
PoolReadGuard readHelper(&localSet);
|
||||
REQUIRE(readHelper.getReadResult() == retval::CATCH_OK);
|
||||
CHECK(not localSet.isValid());
|
||||
CHECK(localSet.localPoolVarUint8.value == 0);
|
||||
CHECK(not localSet.localPoolVarUint8.isValid());
|
||||
CHECK(localSet.localPoolVarFloat.value == Catch::Approx(0.0));
|
||||
CHECK(not localSet.localPoolVarUint8.isValid());
|
||||
CHECK(localSet.localPoolUint16Vec.value[0] == 0);
|
||||
CHECK(localSet.localPoolUint16Vec.value[1] == 0);
|
||||
CHECK(localSet.localPoolUint16Vec.value[2] == 0);
|
||||
CHECK(not localSet.localPoolVarUint8.isValid());
|
||||
|
||||
/* Now set new values, commit should be done by read helper automatically */
|
||||
localSet.localPoolVarUint8 = 232;
|
||||
localSet.localPoolVarFloat = -2324.322;
|
||||
localSet.localPoolUint16Vec.value[0] = 232;
|
||||
localSet.localPoolUint16Vec.value[1] = 23923;
|
||||
localSet.localPoolUint16Vec.value[2] = 1;
|
||||
localSet.setValidity(true, true);
|
||||
}
|
||||
|
||||
SECTION("MorePoolVariables") {
|
||||
LocalDataSet set(poolOwner, 2, 10);
|
||||
/* Zero out some values for next test */
|
||||
localSet.localPoolVarUint8 = 0;
|
||||
localSet.localPoolVarFloat = 0;
|
||||
|
||||
/* Register same variables again to get more than 8 registered variables */
|
||||
for(uint8_t idx = 0; idx < 8; idx ++) {
|
||||
REQUIRE(set.registerVariable(&localSet.localPoolVarUint8) == retval::CATCH_OK);
|
||||
}
|
||||
REQUIRE(set.registerVariable(&localSet.localPoolVarUint8) == retval::CATCH_OK);
|
||||
REQUIRE(set.registerVariable(&localSet.localPoolUint16Vec) == retval::CATCH_OK);
|
||||
localSet.setAllVariablesReadOnly();
|
||||
CHECK(localSet.localPoolUint16Vec.getReadWriteMode() == pool_rwm_t::VAR_READ);
|
||||
CHECK(localSet.localPoolVarUint8.getReadWriteMode() == pool_rwm_t::VAR_READ);
|
||||
CHECK(localSet.localPoolVarFloat.getReadWriteMode() == pool_rwm_t::VAR_READ);
|
||||
|
||||
set.setValidityBufferGeneration(true);
|
||||
{
|
||||
PoolReadGuard readHelper(&localSet);
|
||||
localSet.localPoolVarUint8.value = 42;
|
||||
localSet.localPoolVarUint8.setValid(true);
|
||||
localSet.localPoolUint16Vec.setValid(false);
|
||||
}
|
||||
{
|
||||
/* Now we read again and check whether our zeroed values were overwritten with
|
||||
the values in the pool */
|
||||
PoolReadGuard readHelper(&localSet);
|
||||
REQUIRE(readHelper.getReadResult() == retval::CATCH_OK);
|
||||
CHECK(localSet.isValid());
|
||||
CHECK(localSet.localPoolVarUint8.value == 232);
|
||||
CHECK(localSet.localPoolVarUint8.isValid());
|
||||
CHECK(localSet.localPoolVarFloat.value == Catch::Approx(-2324.322));
|
||||
CHECK(localSet.localPoolVarFloat.isValid());
|
||||
CHECK(localSet.localPoolUint16Vec.value[0] == 232);
|
||||
CHECK(localSet.localPoolUint16Vec.value[1] == 23923);
|
||||
CHECK(localSet.localPoolUint16Vec.value[2] == 1);
|
||||
CHECK(localSet.localPoolUint16Vec.isValid());
|
||||
|
||||
size_t maxSize = set.getSerializedSize();
|
||||
CHECK(maxSize == 9 + sizeof(uint16_t) * 3 + 2);
|
||||
size_t serSize = 0;
|
||||
/* Already reserve additional space for validity buffer, will be needed later */
|
||||
uint8_t buffer[maxSize + 1];
|
||||
uint8_t* buffPtr = buffer;
|
||||
CHECK(set.serialize(&buffPtr, &serSize, maxSize,
|
||||
SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
std::array<uint8_t, 2> validityBuffer;
|
||||
std::memcpy(validityBuffer.data(), buffer + 9 + sizeof(uint16_t) * 3, 2);
|
||||
/* The first 9 variables should be valid */
|
||||
CHECK(validityBuffer[0] == 0xff);
|
||||
bool bitSet = false;
|
||||
bitutil::get(validityBuffer.data() + 1, 0, bitSet);
|
||||
CHECK(bitSet == true);
|
||||
bitutil::get(validityBuffer.data() + 1, 1, bitSet);
|
||||
CHECK(bitSet == false);
|
||||
/* Now we serialize these values into a buffer without the validity buffer */
|
||||
localSet.setValidityBufferGeneration(false);
|
||||
maxSize = localSet.getSerializedSize();
|
||||
CHECK(maxSize == sizeof(uint8_t) + sizeof(uint16_t) * 3 + sizeof(float));
|
||||
serSize = 0;
|
||||
/* Already reserve additional space for validity buffer, will be needed later */
|
||||
uint8_t buffer[maxSize + 1];
|
||||
uint8_t* buffPtr = buffer;
|
||||
CHECK(localSet.serialize(&buffPtr, &serSize, maxSize, SerializeIF::Endianness::MACHINE) ==
|
||||
retval::CATCH_OK);
|
||||
uint8_t rawUint8 = buffer[0];
|
||||
CHECK(rawUint8 == 232);
|
||||
float rawFloat = 0.0;
|
||||
std::memcpy(&rawFloat, buffer + sizeof(uint8_t), sizeof(float));
|
||||
CHECK(rawFloat == Catch::Approx(-2324.322));
|
||||
|
||||
/* Now we invert the validity */
|
||||
validityBuffer[0] = 0;
|
||||
validityBuffer[1] = 0b0100'0000;
|
||||
std::memcpy(buffer + 9 + sizeof(uint16_t) * 3, validityBuffer.data(), 2);
|
||||
const uint8_t* constBuffPtr = buffer;
|
||||
size_t sizeToDeSerialize = serSize;
|
||||
CHECK(set.deSerialize(&constBuffPtr, &sizeToDeSerialize, SerializeIF::Endianness::MACHINE)
|
||||
== retval::CATCH_OK);
|
||||
CHECK(localSet.localPoolVarUint8.isValid() == false);
|
||||
CHECK(localSet.localPoolUint16Vec.isValid() == true);
|
||||
uint16_t rawUint16Vec[3];
|
||||
std::memcpy(&rawUint16Vec, buffer + sizeof(uint8_t) + sizeof(float), 3 * sizeof(uint16_t));
|
||||
CHECK(rawUint16Vec[0] == 232);
|
||||
CHECK(rawUint16Vec[1] == 23923);
|
||||
CHECK(rawUint16Vec[2] == 1);
|
||||
|
||||
size_t sizeToDeserialize = maxSize;
|
||||
/* Now we zeros out the raw entries and deserialize back into the dataset */
|
||||
std::memset(buffer, 0, sizeof(buffer));
|
||||
const uint8_t* constBuffPtr = buffer;
|
||||
CHECK(localSet.deSerialize(&constBuffPtr, &sizeToDeserialize,
|
||||
SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
/* Check whether deserialization was successfull */
|
||||
CHECK(localSet.localPoolVarUint8.value == 0);
|
||||
CHECK(localSet.localPoolVarFloat.value == Catch::Approx(0.0));
|
||||
CHECK(localSet.localPoolVarUint8.value == 0);
|
||||
CHECK(localSet.localPoolUint16Vec.value[0] == 0);
|
||||
CHECK(localSet.localPoolUint16Vec.value[1] == 0);
|
||||
CHECK(localSet.localPoolUint16Vec.value[2] == 0);
|
||||
/* Validity should be unchanged */
|
||||
CHECK(localSet.localPoolVarUint8.isValid());
|
||||
CHECK(localSet.localPoolVarFloat.isValid());
|
||||
CHECK(localSet.localPoolUint16Vec.isValid());
|
||||
|
||||
/* Now we do the same process but with the validity buffer */
|
||||
localSet.localPoolVarUint8 = 232;
|
||||
localSet.localPoolVarFloat = -2324.322;
|
||||
localSet.localPoolUint16Vec.value[0] = 232;
|
||||
localSet.localPoolUint16Vec.value[1] = 23923;
|
||||
localSet.localPoolUint16Vec.value[2] = 1;
|
||||
localSet.localPoolVarUint8.setValid(true);
|
||||
localSet.localPoolVarFloat.setValid(false);
|
||||
localSet.localPoolUint16Vec.setValid(true);
|
||||
localSet.setValidityBufferGeneration(true);
|
||||
maxSize = localSet.getSerializedSize();
|
||||
CHECK(maxSize == sizeof(uint8_t) + sizeof(uint16_t) * 3 + sizeof(float) + 1);
|
||||
serSize = 0;
|
||||
buffPtr = buffer;
|
||||
CHECK(localSet.serialize(&buffPtr, &serSize, maxSize, SerializeIF::Endianness::MACHINE) ==
|
||||
retval::CATCH_OK);
|
||||
CHECK(rawUint8 == 232);
|
||||
std::memcpy(&rawFloat, buffer + sizeof(uint8_t), sizeof(float));
|
||||
CHECK(rawFloat == Catch::Approx(-2324.322));
|
||||
|
||||
std::memcpy(&rawUint16Vec, buffer + sizeof(uint8_t) + sizeof(float), 3 * sizeof(uint16_t));
|
||||
CHECK(rawUint16Vec[0] == 232);
|
||||
CHECK(rawUint16Vec[1] == 23923);
|
||||
CHECK(rawUint16Vec[2] == 1);
|
||||
/* We can do it like this because the buffer only has one byte for
|
||||
less than 8 variables */
|
||||
uint8_t* validityByte = buffer + sizeof(buffer) - 1;
|
||||
bool bitSet = false;
|
||||
bitutil::get(validityByte, 0, bitSet);
|
||||
|
||||
CHECK(bitSet == true);
|
||||
bitutil::get(validityByte, 1, bitSet);
|
||||
CHECK(bitSet == false);
|
||||
bitutil::get(validityByte, 2, bitSet);
|
||||
CHECK(bitSet == true);
|
||||
|
||||
/* Now we manipulate the validity buffer for the deserialization */
|
||||
bitutil::clear(validityByte, 0);
|
||||
bitutil::set(validityByte, 1);
|
||||
bitutil::clear(validityByte, 2);
|
||||
/* Zero out everything except validity buffer */
|
||||
std::memset(buffer, 0, sizeof(buffer) - 1);
|
||||
sizeToDeserialize = maxSize;
|
||||
constBuffPtr = buffer;
|
||||
CHECK(localSet.deSerialize(&constBuffPtr, &sizeToDeserialize,
|
||||
SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
/* Check whether deserialization was successfull */
|
||||
CHECK(localSet.localPoolVarUint8.value == 0);
|
||||
CHECK(localSet.localPoolVarFloat.value == Catch::Approx(0.0));
|
||||
CHECK(localSet.localPoolVarUint8.value == 0);
|
||||
CHECK(localSet.localPoolUint16Vec.value[0] == 0);
|
||||
CHECK(localSet.localPoolUint16Vec.value[1] == 0);
|
||||
CHECK(localSet.localPoolUint16Vec.value[2] == 0);
|
||||
CHECK(not localSet.localPoolVarUint8.isValid());
|
||||
CHECK(localSet.localPoolVarFloat.isValid());
|
||||
CHECK(not localSet.localPoolUint16Vec.isValid());
|
||||
}
|
||||
|
||||
SECTION("SharedDataSet") {
|
||||
object_id_t sharedSetId = objects::SHARED_SET_ID;
|
||||
SharedLocalDataSet sharedSet(sharedSetId, poolOwner, lpool::testSetId, 5);
|
||||
localSet.localPoolVarUint8.setReadWriteMode(pool_rwm_t::VAR_WRITE);
|
||||
localSet.localPoolUint16Vec.setReadWriteMode(pool_rwm_t::VAR_WRITE);
|
||||
CHECK(sharedSet.registerVariable(&localSet.localPoolVarUint8) == retval::CATCH_OK);
|
||||
CHECK(sharedSet.registerVariable(&localSet.localPoolUint16Vec) == retval::CATCH_OK);
|
||||
CHECK(sharedSet.initialize() == retval::CATCH_OK);
|
||||
CHECK(sharedSet.lockDataset() == retval::CATCH_OK);
|
||||
CHECK(sharedSet.unlockDataset() == retval::CATCH_OK);
|
||||
/* Common fault test cases */
|
||||
LocalPoolObjectBase* variableHandle = poolOwner->getPoolObjectHandle(lpool::uint32VarId);
|
||||
CHECK(variableHandle != nullptr);
|
||||
CHECK(localSet.registerVariable(variableHandle) == static_cast<int>(DataSetIF::DATA_SET_FULL));
|
||||
variableHandle = nullptr;
|
||||
REQUIRE(localSet.registerVariable(variableHandle) ==
|
||||
static_cast<int>(DataSetIF::POOL_VAR_NULL));
|
||||
}
|
||||
|
||||
{
|
||||
//PoolReadGuard rg(&sharedSet);
|
||||
//CHECK(rg.getReadResult() == retval::CATCH_OK);
|
||||
localSet.localPoolVarUint8.value = 5;
|
||||
localSet.localPoolUint16Vec.value[0] = 1;
|
||||
localSet.localPoolUint16Vec.value[1] = 2;
|
||||
localSet.localPoolUint16Vec.value[2] = 3;
|
||||
CHECK(sharedSet.commit() == retval::CATCH_OK);
|
||||
}
|
||||
SECTION("MorePoolVariables") {
|
||||
LocalDataSet set(poolOwner, 2, 10);
|
||||
|
||||
sharedSet.setReadCommitProtectionBehaviour(true);
|
||||
/* Register same variables again to get more than 8 registered variables */
|
||||
for (uint8_t idx = 0; idx < 8; idx++) {
|
||||
REQUIRE(set.registerVariable(&localSet.localPoolVarUint8) == retval::CATCH_OK);
|
||||
}
|
||||
REQUIRE(set.registerVariable(&localSet.localPoolVarUint8) == retval::CATCH_OK);
|
||||
REQUIRE(set.registerVariable(&localSet.localPoolUint16Vec) == retval::CATCH_OK);
|
||||
|
||||
set.setValidityBufferGeneration(true);
|
||||
{
|
||||
PoolReadGuard readHelper(&localSet);
|
||||
localSet.localPoolVarUint8.value = 42;
|
||||
localSet.localPoolVarUint8.setValid(true);
|
||||
localSet.localPoolUint16Vec.setValid(false);
|
||||
}
|
||||
|
||||
/* we need to reset the subscription list because the pool owner
|
||||
is a global object. */
|
||||
CHECK(poolOwner->reset() == retval::CATCH_OK);
|
||||
size_t maxSize = set.getSerializedSize();
|
||||
CHECK(maxSize == 9 + sizeof(uint16_t) * 3 + 2);
|
||||
size_t serSize = 0;
|
||||
/* Already reserve additional space for validity buffer, will be needed later */
|
||||
uint8_t buffer[maxSize + 1];
|
||||
uint8_t* buffPtr = buffer;
|
||||
CHECK(set.serialize(&buffPtr, &serSize, maxSize, SerializeIF::Endianness::MACHINE) ==
|
||||
retval::CATCH_OK);
|
||||
std::array<uint8_t, 2> validityBuffer;
|
||||
std::memcpy(validityBuffer.data(), buffer + 9 + sizeof(uint16_t) * 3, 2);
|
||||
/* The first 9 variables should be valid */
|
||||
CHECK(validityBuffer[0] == 0xff);
|
||||
bool bitSet = false;
|
||||
bitutil::get(validityBuffer.data() + 1, 0, bitSet);
|
||||
CHECK(bitSet == true);
|
||||
bitutil::get(validityBuffer.data() + 1, 1, bitSet);
|
||||
CHECK(bitSet == false);
|
||||
|
||||
/* Now we invert the validity */
|
||||
validityBuffer[0] = 0;
|
||||
validityBuffer[1] = 0b0100'0000;
|
||||
std::memcpy(buffer + 9 + sizeof(uint16_t) * 3, validityBuffer.data(), 2);
|
||||
const uint8_t* constBuffPtr = buffer;
|
||||
size_t sizeToDeSerialize = serSize;
|
||||
CHECK(set.deSerialize(&constBuffPtr, &sizeToDeSerialize, SerializeIF::Endianness::MACHINE) ==
|
||||
retval::CATCH_OK);
|
||||
CHECK(localSet.localPoolVarUint8.isValid() == false);
|
||||
CHECK(localSet.localPoolUint16Vec.isValid() == true);
|
||||
}
|
||||
|
||||
SECTION("SharedDataSet") {
|
||||
object_id_t sharedSetId = objects::SHARED_SET_ID;
|
||||
SharedLocalDataSet sharedSet(sharedSetId, poolOwner, lpool::testSetId, 5);
|
||||
localSet.localPoolVarUint8.setReadWriteMode(pool_rwm_t::VAR_WRITE);
|
||||
localSet.localPoolUint16Vec.setReadWriteMode(pool_rwm_t::VAR_WRITE);
|
||||
CHECK(sharedSet.registerVariable(&localSet.localPoolVarUint8) == retval::CATCH_OK);
|
||||
CHECK(sharedSet.registerVariable(&localSet.localPoolUint16Vec) == retval::CATCH_OK);
|
||||
CHECK(sharedSet.initialize() == retval::CATCH_OK);
|
||||
CHECK(sharedSet.lockDataset() == retval::CATCH_OK);
|
||||
CHECK(sharedSet.unlockDataset() == retval::CATCH_OK);
|
||||
|
||||
{
|
||||
// PoolReadGuard rg(&sharedSet);
|
||||
// CHECK(rg.getReadResult() == retval::CATCH_OK);
|
||||
localSet.localPoolVarUint8.value = 5;
|
||||
localSet.localPoolUint16Vec.value[0] = 1;
|
||||
localSet.localPoolUint16Vec.value[1] = 2;
|
||||
localSet.localPoolUint16Vec.value[2] = 3;
|
||||
CHECK(sharedSet.commit() == retval::CATCH_OK);
|
||||
}
|
||||
|
||||
sharedSet.setReadCommitProtectionBehaviour(true);
|
||||
}
|
||||
|
||||
/* we need to reset the subscription list because the pool owner
|
||||
is a global object. */
|
||||
CHECK(poolOwner->reset() == retval::CATCH_OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,428 +1,419 @@
|
||||
#include "LocalPoolOwnerBase.h"
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/datapoollocal/HasLocalDataPoolIF.h>
|
||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
||||
#include <fsfw/housekeeping/HousekeepingSnapshot.h>
|
||||
#include <fsfw/ipc/CommandMessageCleaner.h>
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
#include <fsfw/timemanager/CCSDSTime.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/catch_approx.hpp>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include "LocalPoolOwnerBase.h"
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
TEST_CASE("LocalPoolManagerTest" , "[LocManTest]") {
|
||||
LocalPoolOwnerBase* poolOwner = ObjectManager::instance()->
|
||||
get<LocalPoolOwnerBase>(objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
REQUIRE(poolOwner != nullptr);
|
||||
REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK);
|
||||
REQUIRE(poolOwner->initializeHkManagerAfterTaskCreation()
|
||||
== retval::CATCH_OK);
|
||||
TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
||||
LocalPoolOwnerBase* poolOwner =
|
||||
ObjectManager::instance()->get<LocalPoolOwnerBase>(objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
REQUIRE(poolOwner != nullptr);
|
||||
REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK);
|
||||
REQUIRE(poolOwner->initializeHkManagerAfterTaskCreation() == retval::CATCH_OK);
|
||||
|
||||
MessageQueueMockBase* mqMock = poolOwner->getMockQueueHandle();
|
||||
REQUIRE(mqMock != nullptr);
|
||||
CommandMessage messageSent;
|
||||
uint8_t messagesSent = 0;
|
||||
MessageQueueMockBase* mqMock = poolOwner->getMockQueueHandle();
|
||||
REQUIRE(mqMock != nullptr);
|
||||
CommandMessage messageSent;
|
||||
uint8_t messagesSent = 0;
|
||||
|
||||
SECTION("BasicTest") {
|
||||
{
|
||||
/* For code coverage, should not crash */
|
||||
LocalDataPoolManager manager(nullptr, nullptr);
|
||||
}
|
||||
auto owner = poolOwner->poolManager.getOwner();
|
||||
REQUIRE(owner != nullptr);
|
||||
CHECK(owner->getObjectId() == objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
SECTION("BasicTest") {
|
||||
{
|
||||
/* For code coverage, should not crash */
|
||||
LocalDataPoolManager manager(nullptr, nullptr);
|
||||
}
|
||||
auto owner = poolOwner->poolManager.getOwner();
|
||||
REQUIRE(owner != nullptr);
|
||||
CHECK(owner->getObjectId() == objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
|
||||
/* Subscribe for message generation on update. */
|
||||
REQUIRE(poolOwner->subscribeWrapperSetUpdate() == retval::CATCH_OK);
|
||||
/* Subscribe for an update message. */
|
||||
poolOwner->dataset.setChanged(true);
|
||||
/* Now the update message should be generated. */
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent() == true);
|
||||
/* Subscribe for message generation on update. */
|
||||
REQUIRE(poolOwner->subscribeWrapperSetUpdate() == retval::CATCH_OK);
|
||||
/* Subscribe for an update message. */
|
||||
poolOwner->dataset.setChanged(true);
|
||||
/* Now the update message should be generated. */
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent() == true);
|
||||
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() == static_cast<int>(
|
||||
HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() ==
|
||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||
|
||||
/* Should have been reset. */
|
||||
CHECK(poolOwner->dataset.hasChanged() == false);
|
||||
/* Set changed again, result should be the same. */
|
||||
poolOwner->dataset.setChanged(true);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
/* Should have been reset. */
|
||||
CHECK(poolOwner->dataset.hasChanged() == false);
|
||||
/* Set changed again, result should be the same. */
|
||||
poolOwner->dataset.setChanged(true);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() == static_cast<int>(
|
||||
HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() ==
|
||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||
|
||||
/* Now subscribe for set update HK as well. */
|
||||
REQUIRE(poolOwner->subscribeWrapperSetUpdateHk() == retval::CATCH_OK);
|
||||
poolOwner->dataset.setChanged(true);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 2);
|
||||
/* first message sent should be the update notification, considering
|
||||
the internal list is a vector checked in insertion order. */
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() == static_cast<int>(
|
||||
HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||
/* Now subscribe for set update HK as well. */
|
||||
REQUIRE(poolOwner->subscribeWrapperSetUpdateHk() == retval::CATCH_OK);
|
||||
poolOwner->dataset.setChanged(true);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 2);
|
||||
/* first message sent should be the update notification, considering
|
||||
the internal list is a vector checked in insertion order. */
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() ==
|
||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() == static_cast<int>(
|
||||
HousekeepingMessage::HK_REPORT));
|
||||
/* Clear message to avoid memory leak, our mock won't do it for us (yet) */
|
||||
CommandMessageCleaner::clearCommandMessage(&messageSent);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() == static_cast<int>(HousekeepingMessage::HK_REPORT));
|
||||
/* Clear message to avoid memory leak, our mock won't do it for us (yet) */
|
||||
CommandMessageCleaner::clearCommandMessage(&messageSent);
|
||||
}
|
||||
|
||||
SECTION("SetSnapshotUpdateTest") {
|
||||
/* Set the variables in the set to certain values. These are checked later. */
|
||||
{
|
||||
PoolReadGuard readHelper(&poolOwner->dataset);
|
||||
REQUIRE(readHelper.getReadResult() == retval::CATCH_OK);
|
||||
poolOwner->dataset.localPoolVarUint8.value = 5;
|
||||
poolOwner->dataset.localPoolVarFloat.value = -12.242;
|
||||
poolOwner->dataset.localPoolUint16Vec.value[0] = 2;
|
||||
poolOwner->dataset.localPoolUint16Vec.value[1] = 32;
|
||||
poolOwner->dataset.localPoolUint16Vec.value[2] = 42932;
|
||||
}
|
||||
|
||||
SECTION("SetSnapshotUpdateTest") {
|
||||
/* Set the variables in the set to certain values. These are checked later. */
|
||||
{
|
||||
PoolReadGuard readHelper(&poolOwner->dataset);
|
||||
REQUIRE(readHelper.getReadResult() == retval::CATCH_OK);
|
||||
poolOwner->dataset.localPoolVarUint8.value = 5;
|
||||
poolOwner->dataset.localPoolVarFloat.value = -12.242;
|
||||
poolOwner->dataset.localPoolUint16Vec.value[0] = 2;
|
||||
poolOwner->dataset.localPoolUint16Vec.value[1] = 32;
|
||||
poolOwner->dataset.localPoolUint16Vec.value[2] = 42932;
|
||||
}
|
||||
/* Subscribe for snapshot generation on update. */
|
||||
REQUIRE(poolOwner->subscribeWrapperSetUpdateSnapshot() == retval::CATCH_OK);
|
||||
poolOwner->dataset.setChanged(true);
|
||||
|
||||
/* Subscribe for snapshot generation on update. */
|
||||
REQUIRE(poolOwner->subscribeWrapperSetUpdateSnapshot() == retval::CATCH_OK);
|
||||
poolOwner->dataset.setChanged(true);
|
||||
/* Store current time, we are going to check the (approximate) time equality later */
|
||||
CCSDSTime::CDS_short timeCdsNow;
|
||||
timeval now;
|
||||
Clock::getClock_timeval(&now);
|
||||
CCSDSTime::convertToCcsds(&timeCdsNow, &now);
|
||||
|
||||
/* Store current time, we are going to check the (approximate) time equality later */
|
||||
CCSDSTime::CDS_short timeCdsNow;
|
||||
timeval now;
|
||||
Clock::getClock_timeval(&now);
|
||||
CCSDSTime::convertToCcsds(&timeCdsNow, &now);
|
||||
/* Trigger generation of snapshot */
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
/* Check that snapshot was generated */
|
||||
CHECK(messageSent.getCommand() == static_cast<int>(HousekeepingMessage::UPDATE_SNAPSHOT_SET));
|
||||
/* Now we deserialize the snapshot into a new dataset instance */
|
||||
CCSDSTime::CDS_short cdsShort;
|
||||
LocalPoolTestDataSet newSet;
|
||||
HousekeepingSnapshot snapshot(&cdsShort, &newSet);
|
||||
store_address_t storeId;
|
||||
HousekeepingMessage::getUpdateSnapshotSetCommand(&messageSent, &storeId);
|
||||
ConstAccessorPair accessorPair = tglob::getIpcStoreHandle()->getData(storeId);
|
||||
REQUIRE(accessorPair.first == retval::CATCH_OK);
|
||||
const uint8_t* readOnlyPtr = accessorPair.second.data();
|
||||
size_t sizeToDeserialize = accessorPair.second.size();
|
||||
CHECK(newSet.localPoolVarFloat.value == 0);
|
||||
CHECK(newSet.localPoolVarUint8 == 0);
|
||||
CHECK(newSet.localPoolUint16Vec.value[0] == 0);
|
||||
CHECK(newSet.localPoolUint16Vec.value[1] == 0);
|
||||
CHECK(newSet.localPoolUint16Vec.value[2] == 0);
|
||||
/* Fill the dataset and timestamp */
|
||||
REQUIRE(snapshot.deSerialize(&readOnlyPtr, &sizeToDeserialize,
|
||||
SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
/* Now we check that the snapshot is actually correct */
|
||||
CHECK(newSet.localPoolVarFloat.value == Catch::Approx(-12.242));
|
||||
CHECK(newSet.localPoolVarUint8 == 5);
|
||||
CHECK(newSet.localPoolUint16Vec.value[0] == 2);
|
||||
CHECK(newSet.localPoolUint16Vec.value[1] == 32);
|
||||
CHECK(newSet.localPoolUint16Vec.value[2] == 42932);
|
||||
|
||||
/* Trigger generation of snapshot */
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
/* Check that snapshot was generated */
|
||||
CHECK(messageSent.getCommand() == static_cast<int>(
|
||||
HousekeepingMessage::UPDATE_SNAPSHOT_SET));
|
||||
/* Now we deserialize the snapshot into a new dataset instance */
|
||||
CCSDSTime::CDS_short cdsShort;
|
||||
LocalPoolTestDataSet newSet;
|
||||
HousekeepingSnapshot snapshot(&cdsShort, &newSet);
|
||||
store_address_t storeId;
|
||||
HousekeepingMessage::getUpdateSnapshotSetCommand(&messageSent, &storeId);
|
||||
ConstAccessorPair accessorPair = tglob::getIpcStoreHandle()->getData(storeId);
|
||||
REQUIRE(accessorPair.first == retval::CATCH_OK);
|
||||
const uint8_t* readOnlyPtr = accessorPair.second.data();
|
||||
size_t sizeToDeserialize = accessorPair.second.size();
|
||||
CHECK(newSet.localPoolVarFloat.value == 0);
|
||||
CHECK(newSet.localPoolVarUint8 == 0);
|
||||
CHECK(newSet.localPoolUint16Vec.value[0] == 0);
|
||||
CHECK(newSet.localPoolUint16Vec.value[1] == 0);
|
||||
CHECK(newSet.localPoolUint16Vec.value[2] == 0);
|
||||
/* Fill the dataset and timestamp */
|
||||
REQUIRE(snapshot.deSerialize(&readOnlyPtr, &sizeToDeserialize,
|
||||
SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
/* Now we check that the snapshot is actually correct */
|
||||
CHECK(newSet.localPoolVarFloat.value == Catch::Approx(-12.242));
|
||||
CHECK(newSet.localPoolVarUint8 == 5);
|
||||
CHECK(newSet.localPoolUint16Vec.value[0] == 2);
|
||||
CHECK(newSet.localPoolUint16Vec.value[1] == 32);
|
||||
CHECK(newSet.localPoolUint16Vec.value[2] == 42932);
|
||||
/* Now we check that both times are equal */
|
||||
CHECK(cdsShort.pField == timeCdsNow.pField);
|
||||
CHECK(cdsShort.dayLSB == Catch::Approx(timeCdsNow.dayLSB).margin(1));
|
||||
CHECK(cdsShort.dayMSB == Catch::Approx(timeCdsNow.dayMSB).margin(1));
|
||||
CHECK(cdsShort.msDay_h == Catch::Approx(timeCdsNow.msDay_h).margin(1));
|
||||
CHECK(cdsShort.msDay_hh == Catch::Approx(timeCdsNow.msDay_hh).margin(1));
|
||||
CHECK(cdsShort.msDay_l == Catch::Approx(timeCdsNow.msDay_l).margin(1));
|
||||
CHECK(cdsShort.msDay_ll == Catch::Approx(timeCdsNow.msDay_ll).margin(5));
|
||||
}
|
||||
|
||||
/* Now we check that both times are equal */
|
||||
CHECK(cdsShort.pField == timeCdsNow.pField);
|
||||
CHECK(cdsShort.dayLSB == Catch::Approx(timeCdsNow.dayLSB).margin(1));
|
||||
CHECK(cdsShort.dayMSB == Catch::Approx(timeCdsNow.dayMSB).margin(1));
|
||||
CHECK(cdsShort.msDay_h == Catch::Approx(timeCdsNow.msDay_h).margin(1));
|
||||
CHECK(cdsShort.msDay_hh == Catch::Approx(timeCdsNow.msDay_hh).margin(1));
|
||||
CHECK(cdsShort.msDay_l == Catch::Approx(timeCdsNow.msDay_l).margin(1));
|
||||
CHECK(cdsShort.msDay_ll == Catch::Approx(timeCdsNow.msDay_ll).margin(5));
|
||||
SECTION("VariableSnapshotTest") {
|
||||
/* Acquire subscription interface */
|
||||
ProvidesDataPoolSubscriptionIF* subscriptionIF = poolOwner->getSubscriptionInterface();
|
||||
REQUIRE(subscriptionIF != nullptr);
|
||||
|
||||
/* Subscribe for variable snapshot */
|
||||
REQUIRE(poolOwner->subscribeWrapperVariableSnapshot(lpool::uint8VarId) == retval::CATCH_OK);
|
||||
auto poolVar =
|
||||
dynamic_cast<lp_var_t<uint8_t>*>(poolOwner->getPoolObjectHandle(lpool::uint8VarId));
|
||||
REQUIRE(poolVar != nullptr);
|
||||
|
||||
{
|
||||
PoolReadGuard rg(poolVar);
|
||||
CHECK(rg.getReadResult() == retval::CATCH_OK);
|
||||
poolVar->value = 25;
|
||||
}
|
||||
|
||||
SECTION("VariableSnapshotTest") {
|
||||
/* Acquire subscription interface */
|
||||
ProvidesDataPoolSubscriptionIF* subscriptionIF = poolOwner->getSubscriptionInterface();
|
||||
REQUIRE(subscriptionIF != nullptr);
|
||||
poolVar->setChanged(true);
|
||||
|
||||
/* Subscribe for variable snapshot */
|
||||
REQUIRE(poolOwner->subscribeWrapperVariableSnapshot(lpool::uint8VarId) == retval::CATCH_OK);
|
||||
auto poolVar = dynamic_cast<lp_var_t<uint8_t>*>(
|
||||
poolOwner->getPoolObjectHandle(lpool::uint8VarId));
|
||||
REQUIRE(poolVar != nullptr);
|
||||
/* Store current time, we are going to check the (approximate) time equality later */
|
||||
CCSDSTime::CDS_short timeCdsNow;
|
||||
timeval now;
|
||||
Clock::getClock_timeval(&now);
|
||||
CCSDSTime::convertToCcsds(&timeCdsNow, &now);
|
||||
|
||||
{
|
||||
PoolReadGuard rg(poolVar);
|
||||
CHECK(rg.getReadResult() == retval::CATCH_OK);
|
||||
poolVar->value = 25;
|
||||
}
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
|
||||
poolVar->setChanged(true);
|
||||
/* Check update snapshot was sent. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
|
||||
/* Store current time, we are going to check the (approximate) time equality later */
|
||||
CCSDSTime::CDS_short timeCdsNow;
|
||||
timeval now;
|
||||
Clock::getClock_timeval(&now);
|
||||
CCSDSTime::convertToCcsds(&timeCdsNow, &now);
|
||||
/* Should have been reset. */
|
||||
CHECK(poolVar->hasChanged() == false);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() ==
|
||||
static_cast<int>(HousekeepingMessage::UPDATE_SNAPSHOT_VARIABLE));
|
||||
/* Now we deserialize the snapshot into a new dataset instance */
|
||||
CCSDSTime::CDS_short cdsShort;
|
||||
lp_var_t<uint8_t> varCopy = lp_var_t<uint8_t>(lpool::uint8VarGpid);
|
||||
HousekeepingSnapshot snapshot(&cdsShort, &varCopy);
|
||||
store_address_t storeId;
|
||||
HousekeepingMessage::getUpdateSnapshotVariableCommand(&messageSent, &storeId);
|
||||
ConstAccessorPair accessorPair = tglob::getIpcStoreHandle()->getData(storeId);
|
||||
REQUIRE(accessorPair.first == retval::CATCH_OK);
|
||||
const uint8_t* readOnlyPtr = accessorPair.second.data();
|
||||
size_t sizeToDeserialize = accessorPair.second.size();
|
||||
CHECK(varCopy.value == 0);
|
||||
/* Fill the dataset and timestamp */
|
||||
REQUIRE(snapshot.deSerialize(&readOnlyPtr, &sizeToDeserialize,
|
||||
SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
CHECK(varCopy.value == 25);
|
||||
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
/* Now we check that both times are equal */
|
||||
CHECK(cdsShort.pField == timeCdsNow.pField);
|
||||
CHECK(cdsShort.dayLSB == Catch::Approx(timeCdsNow.dayLSB).margin(1));
|
||||
CHECK(cdsShort.dayMSB == Catch::Approx(timeCdsNow.dayMSB).margin(1));
|
||||
CHECK(cdsShort.msDay_h == Catch::Approx(timeCdsNow.msDay_h).margin(1));
|
||||
CHECK(cdsShort.msDay_hh == Catch::Approx(timeCdsNow.msDay_hh).margin(1));
|
||||
CHECK(cdsShort.msDay_l == Catch::Approx(timeCdsNow.msDay_l).margin(1));
|
||||
CHECK(cdsShort.msDay_ll == Catch::Approx(timeCdsNow.msDay_ll).margin(5));
|
||||
}
|
||||
|
||||
/* Check update snapshot was sent. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
SECTION("VariableNotificationTest") {
|
||||
/* Acquire subscription interface */
|
||||
ProvidesDataPoolSubscriptionIF* subscriptionIF = poolOwner->getSubscriptionInterface();
|
||||
REQUIRE(subscriptionIF != nullptr);
|
||||
|
||||
/* Should have been reset. */
|
||||
CHECK(poolVar->hasChanged() == false);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() == static_cast<int>(
|
||||
HousekeepingMessage::UPDATE_SNAPSHOT_VARIABLE));
|
||||
/* Now we deserialize the snapshot into a new dataset instance */
|
||||
CCSDSTime::CDS_short cdsShort;
|
||||
lp_var_t<uint8_t> varCopy = lp_var_t<uint8_t>(lpool::uint8VarGpid);
|
||||
HousekeepingSnapshot snapshot(&cdsShort, &varCopy);
|
||||
store_address_t storeId;
|
||||
HousekeepingMessage::getUpdateSnapshotVariableCommand(&messageSent, &storeId);
|
||||
ConstAccessorPair accessorPair = tglob::getIpcStoreHandle()->getData(storeId);
|
||||
REQUIRE(accessorPair.first == retval::CATCH_OK);
|
||||
const uint8_t* readOnlyPtr = accessorPair.second.data();
|
||||
size_t sizeToDeserialize = accessorPair.second.size();
|
||||
CHECK(varCopy.value == 0);
|
||||
/* Fill the dataset and timestamp */
|
||||
REQUIRE(snapshot.deSerialize(&readOnlyPtr, &sizeToDeserialize,
|
||||
SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
CHECK(varCopy.value == 25);
|
||||
/* Subscribe for variable update */
|
||||
REQUIRE(poolOwner->subscribeWrapperVariableUpdate(lpool::uint8VarId) == retval::CATCH_OK);
|
||||
lp_var_t<uint8_t>* poolVar =
|
||||
dynamic_cast<lp_var_t<uint8_t>*>(poolOwner->getPoolObjectHandle(lpool::uint8VarId));
|
||||
REQUIRE(poolVar != nullptr);
|
||||
poolVar->setChanged(true);
|
||||
REQUIRE(poolVar->hasChanged() == true);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
|
||||
/* Now we check that both times are equal */
|
||||
CHECK(cdsShort.pField == timeCdsNow.pField);
|
||||
CHECK(cdsShort.dayLSB == Catch::Approx(timeCdsNow.dayLSB).margin(1));
|
||||
CHECK(cdsShort.dayMSB == Catch::Approx(timeCdsNow.dayMSB).margin(1));
|
||||
CHECK(cdsShort.msDay_h == Catch::Approx(timeCdsNow.msDay_h).margin(1));
|
||||
CHECK(cdsShort.msDay_hh == Catch::Approx(timeCdsNow.msDay_hh).margin(1));
|
||||
CHECK(cdsShort.msDay_l == Catch::Approx(timeCdsNow.msDay_l).margin(1));
|
||||
CHECK(cdsShort.msDay_ll == Catch::Approx(timeCdsNow.msDay_ll).margin(5));
|
||||
}
|
||||
/* Check update notification was sent. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
/* Should have been reset. */
|
||||
CHECK(poolVar->hasChanged() == false);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() ==
|
||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE));
|
||||
/* Now subscribe for the dataset update (HK and update) again with subscription interface */
|
||||
REQUIRE(subscriptionIF->subscribeForSetUpdateMessage(lpool::testSetId, objects::NO_OBJECT,
|
||||
objects::HK_RECEIVER_MOCK,
|
||||
false) == retval::CATCH_OK);
|
||||
REQUIRE(poolOwner->subscribeWrapperSetUpdateHk() == retval::CATCH_OK);
|
||||
|
||||
SECTION("VariableNotificationTest") {
|
||||
/* Acquire subscription interface */
|
||||
ProvidesDataPoolSubscriptionIF* subscriptionIF = poolOwner->getSubscriptionInterface();
|
||||
REQUIRE(subscriptionIF != nullptr);
|
||||
|
||||
/* Subscribe for variable update */
|
||||
REQUIRE(poolOwner->subscribeWrapperVariableUpdate(lpool::uint8VarId) ==
|
||||
retval::CATCH_OK);
|
||||
lp_var_t<uint8_t>* poolVar = dynamic_cast<lp_var_t<uint8_t>*>(
|
||||
poolOwner->getPoolObjectHandle(lpool::uint8VarId));
|
||||
REQUIRE(poolVar != nullptr);
|
||||
poolVar->setChanged(true);
|
||||
REQUIRE(poolVar->hasChanged() == true);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
|
||||
/* Check update notification was sent. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
/* Should have been reset. */
|
||||
CHECK(poolVar->hasChanged() == false);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() == static_cast<int>(
|
||||
HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE));
|
||||
/* Now subscribe for the dataset update (HK and update) again with subscription interface */
|
||||
REQUIRE(subscriptionIF->subscribeForSetUpdateMessage(lpool::testSetId,
|
||||
objects::NO_OBJECT, objects::HK_RECEIVER_MOCK, false) == retval::CATCH_OK);
|
||||
REQUIRE(poolOwner->subscribeWrapperSetUpdateHk() == retval::CATCH_OK);
|
||||
|
||||
poolOwner->dataset.setChanged(true);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
/* Now two messages should be sent. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 2);
|
||||
mqMock->clearMessages(true);
|
||||
|
||||
poolOwner->dataset.setChanged(true);
|
||||
poolVar->setChanged(true);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
/* Now three messages should be sent. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 3);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() == static_cast<int>(
|
||||
HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE));
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() == static_cast<int>(
|
||||
HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() == static_cast<int>(
|
||||
HousekeepingMessage::HK_REPORT));
|
||||
CommandMessageCleaner::clearCommandMessage(&messageSent);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == static_cast<int>(MessageQueueIF::EMPTY));
|
||||
}
|
||||
|
||||
SECTION("PeriodicHKAndMessaging") {
|
||||
/* Now we subcribe for a HK periodic generation. Even when it's difficult to simulate
|
||||
the temporal behaviour correctly the HK manager should generate a HK packet
|
||||
immediately and the periodic helper depends on HK op function calls anyway instead of
|
||||
using the clock, so we could also just call performHkOperation multiple times */
|
||||
REQUIRE(poolOwner->subscribePeriodicHk(true) == retval::CATCH_OK);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
/* Now HK packet should be sent as message immediately. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
LocalPoolDataSetBase* setHandle = poolOwner->getDataSetHandle(lpool::testSid);
|
||||
REQUIRE(setHandle != nullptr);
|
||||
CHECK(poolOwner->poolManager.generateHousekeepingPacket(lpool::testSid,
|
||||
setHandle, false) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
CHECK(setHandle->getReportingEnabled() == true);
|
||||
CommandMessage hkCmd;
|
||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
CHECK(setHandle->getReportingEnabled() == false);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
CHECK(setHandle->getReportingEnabled() == true);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
CHECK(setHandle->getReportingEnabled() == false);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd,
|
||||
lpool::testSid, 0.4, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
/* For non-diagnostics and a specified minimum frequency of 0.2 seconds, the
|
||||
resulting collection interval should be 1.0 second */
|
||||
CHECK(poolOwner->dataset.getCollectionInterval() == 1.0);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
/* Now HK packet should be sent as message. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setUpdateNotificationSetCommand(&hkCmd, lpool::testSid);
|
||||
sid_t sidToCheck;
|
||||
store_address_t storeId;
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
CHECK(poolOwner->changedDataSetCallbackWasCalled(sidToCheck, storeId) == true);
|
||||
CHECK(sidToCheck == lpool::testSid);
|
||||
|
||||
/* Now we test the handling is the dataset is set to diagnostic */
|
||||
poolOwner->dataset.setDiagnostic(true);
|
||||
|
||||
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
||||
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
||||
/* We still expect a failure message being sent */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd,
|
||||
lpool::testSid, 0.4, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
||||
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
||||
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, true);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4,
|
||||
true);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, true);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, true);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
||||
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, true);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setUpdateNotificationVariableCommand(&hkCmd, lpool::uint8VarGpid);
|
||||
gp_id_t gpidToCheck;
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
CHECK(poolOwner->changedVariableCallbackWasCalled(gpidToCheck, storeId) == true);
|
||||
CHECK(gpidToCheck == lpool::uint8VarGpid);
|
||||
|
||||
HousekeepingMessage::setUpdateSnapshotSetCommand(&hkCmd, lpool::testSid,
|
||||
storeId::INVALID_STORE_ADDRESS);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
CHECK(poolOwner->changedDataSetCallbackWasCalled(sidToCheck, storeId) == true);
|
||||
CHECK(sidToCheck == lpool::testSid);
|
||||
|
||||
HousekeepingMessage::setUpdateSnapshotVariableCommand(&hkCmd, lpool::uint8VarGpid,
|
||||
storeId::INVALID_STORE_ADDRESS);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
CHECK(poolOwner->changedVariableCallbackWasCalled(gpidToCheck, storeId) == true);
|
||||
CHECK(gpidToCheck == lpool::uint8VarGpid);
|
||||
|
||||
poolOwner->poolManager.printPoolEntry(lpool::uint8VarId);
|
||||
|
||||
}
|
||||
|
||||
/* we need to reset the subscription list because the pool owner
|
||||
is a global object. */
|
||||
CHECK(poolOwner->reset() == retval::CATCH_OK);
|
||||
poolOwner->dataset.setChanged(true);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
/* Now two messages should be sent. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 2);
|
||||
mqMock->clearMessages(true);
|
||||
}
|
||||
|
||||
poolOwner->dataset.setChanged(true);
|
||||
poolVar->setChanged(true);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
/* Now three messages should be sent. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 3);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() ==
|
||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE));
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() ==
|
||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() == static_cast<int>(HousekeepingMessage::HK_REPORT));
|
||||
CommandMessageCleaner::clearCommandMessage(&messageSent);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == static_cast<int>(MessageQueueIF::EMPTY));
|
||||
}
|
||||
|
||||
SECTION("PeriodicHKAndMessaging") {
|
||||
/* Now we subcribe for a HK periodic generation. Even when it's difficult to simulate
|
||||
the temporal behaviour correctly the HK manager should generate a HK packet
|
||||
immediately and the periodic helper depends on HK op function calls anyway instead of
|
||||
using the clock, so we could also just call performHkOperation multiple times */
|
||||
REQUIRE(poolOwner->subscribePeriodicHk(true) == retval::CATCH_OK);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
/* Now HK packet should be sent as message immediately. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
LocalPoolDataSetBase* setHandle = poolOwner->getDataSetHandle(lpool::testSid);
|
||||
REQUIRE(setHandle != nullptr);
|
||||
CHECK(poolOwner->poolManager.generateHousekeepingPacket(lpool::testSid, setHandle, false) ==
|
||||
retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
CHECK(setHandle->getReportingEnabled() == true);
|
||||
CommandMessage hkCmd;
|
||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
CHECK(setHandle->getReportingEnabled() == false);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
CHECK(setHandle->getReportingEnabled() == true);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
CHECK(setHandle->getReportingEnabled() == false);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4,
|
||||
false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
/* For non-diagnostics and a specified minimum frequency of 0.2 seconds, the
|
||||
resulting collection interval should be 1.0 second */
|
||||
CHECK(poolOwner->dataset.getCollectionInterval() == 1.0);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
/* Now HK packet should be sent as message. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setUpdateNotificationSetCommand(&hkCmd, lpool::testSid);
|
||||
sid_t sidToCheck;
|
||||
store_address_t storeId;
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
CHECK(poolOwner->changedDataSetCallbackWasCalled(sidToCheck, storeId) == true);
|
||||
CHECK(sidToCheck == lpool::testSid);
|
||||
|
||||
/* Now we test the handling is the dataset is set to diagnostic */
|
||||
poolOwner->dataset.setDiagnostic(true);
|
||||
|
||||
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
||||
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
||||
/* We still expect a failure message being sent */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4,
|
||||
false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
||||
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
||||
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, true);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4,
|
||||
true);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, true);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, true);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
||||
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, true);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setUpdateNotificationVariableCommand(&hkCmd, lpool::uint8VarGpid);
|
||||
gp_id_t gpidToCheck;
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
CHECK(poolOwner->changedVariableCallbackWasCalled(gpidToCheck, storeId) == true);
|
||||
CHECK(gpidToCheck == lpool::uint8VarGpid);
|
||||
|
||||
HousekeepingMessage::setUpdateSnapshotSetCommand(&hkCmd, lpool::testSid,
|
||||
storeId::INVALID_STORE_ADDRESS);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
CHECK(poolOwner->changedDataSetCallbackWasCalled(sidToCheck, storeId) == true);
|
||||
CHECK(sidToCheck == lpool::testSid);
|
||||
|
||||
HousekeepingMessage::setUpdateSnapshotVariableCommand(&hkCmd, lpool::uint8VarGpid,
|
||||
storeId::INVALID_STORE_ADDRESS);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
CHECK(poolOwner->changedVariableCallbackWasCalled(gpidToCheck, storeId) == true);
|
||||
CHECK(gpidToCheck == lpool::uint8VarGpid);
|
||||
|
||||
poolOwner->poolManager.printPoolEntry(lpool::uint8VarId);
|
||||
}
|
||||
|
||||
/* we need to reset the subscription list because the pool owner
|
||||
is a global object. */
|
||||
CHECK(poolOwner->reset() == retval::CATCH_OK);
|
||||
mqMock->clearMessages(true);
|
||||
}
|
||||
|
@ -1,141 +1,127 @@
|
||||
#include "LocalPoolOwnerBase.h"
|
||||
|
||||
LocalPoolOwnerBase::LocalPoolOwnerBase(object_id_t objectId):
|
||||
SystemObject(objectId), poolManager(this, messageQueue),
|
||||
dataset(this, lpool::testSetId) {
|
||||
messageQueue = new MessageQueueMockBase();
|
||||
LocalPoolOwnerBase::LocalPoolOwnerBase(object_id_t objectId)
|
||||
: SystemObject(objectId), poolManager(this, messageQueue), dataset(this, lpool::testSetId) {
|
||||
messageQueue = new MessageQueueMockBase();
|
||||
}
|
||||
|
||||
LocalPoolOwnerBase::~LocalPoolOwnerBase() {
|
||||
QueueFactory::instance()->deleteMessageQueue(messageQueue);
|
||||
QueueFactory::instance()->deleteMessageQueue(messageQueue);
|
||||
}
|
||||
|
||||
ReturnValue_t LocalPoolOwnerBase::initializeHkManager() {
|
||||
if(not initialized) {
|
||||
initialized = true;
|
||||
return poolManager.initialize(messageQueue);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
if (not initialized) {
|
||||
initialized = true;
|
||||
return poolManager.initialize(messageQueue);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t LocalPoolOwnerBase::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) {
|
||||
LocalDataPoolManager &poolManager) {
|
||||
// Default initialization empty for now.
|
||||
localDataPoolMap.emplace(lpool::uint8VarId, new PoolEntry<uint8_t>({0}));
|
||||
localDataPoolMap.emplace(lpool::floatVarId, new PoolEntry<float>({0}));
|
||||
localDataPoolMap.emplace(lpool::uint32VarId, new PoolEntry<uint32_t>({0}));
|
||||
|
||||
// Default initialization empty for now.
|
||||
localDataPoolMap.emplace(lpool::uint8VarId,
|
||||
new PoolEntry<uint8_t>({0}));
|
||||
localDataPoolMap.emplace(lpool::floatVarId,
|
||||
new PoolEntry<float>({0}));
|
||||
localDataPoolMap.emplace(lpool::uint32VarId,
|
||||
new PoolEntry<uint32_t>({0}));
|
||||
|
||||
localDataPoolMap.emplace(lpool::uint16Vec3Id,
|
||||
new PoolEntry<uint16_t>({0, 0, 0}));
|
||||
localDataPoolMap.emplace(lpool::int64Vec2Id,
|
||||
new PoolEntry<int64_t>({0, 0}));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
localDataPoolMap.emplace(lpool::uint16Vec3Id, new PoolEntry<uint16_t>({0, 0, 0}));
|
||||
localDataPoolMap.emplace(lpool::int64Vec2Id, new PoolEntry<int64_t>({0, 0}));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
LocalPoolObjectBase* LocalPoolOwnerBase::getPoolObjectHandle(lp_id_t localPoolId) {
|
||||
if(localPoolId == lpool::uint8VarId) {
|
||||
return &testUint8;
|
||||
}
|
||||
else if(localPoolId == lpool::uint16Vec3Id) {
|
||||
return &testUint16Vec;
|
||||
}
|
||||
else if(localPoolId == lpool::floatVarId) {
|
||||
return &testFloat;
|
||||
}
|
||||
else if(localPoolId == lpool::int64Vec2Id) {
|
||||
return &testInt64Vec;
|
||||
}
|
||||
else if(localPoolId == lpool::uint32VarId) {
|
||||
return &testUint32;
|
||||
}
|
||||
else {
|
||||
return &testUint8;
|
||||
}
|
||||
LocalPoolObjectBase *LocalPoolOwnerBase::getPoolObjectHandle(lp_id_t localPoolId) {
|
||||
if (localPoolId == lpool::uint8VarId) {
|
||||
return &testUint8;
|
||||
} else if (localPoolId == lpool::uint16Vec3Id) {
|
||||
return &testUint16Vec;
|
||||
} else if (localPoolId == lpool::floatVarId) {
|
||||
return &testFloat;
|
||||
} else if (localPoolId == lpool::int64Vec2Id) {
|
||||
return &testInt64Vec;
|
||||
} else if (localPoolId == lpool::uint32VarId) {
|
||||
return &testUint32;
|
||||
} else {
|
||||
return &testUint8;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t LocalPoolOwnerBase::reset() {
|
||||
resetSubscriptionList();
|
||||
ReturnValue_t status = HasReturnvaluesIF::RETURN_OK;
|
||||
{
|
||||
PoolReadGuard readHelper(&dataset);
|
||||
if(readHelper.getReadResult() != HasReturnvaluesIF::RETURN_OK) {
|
||||
status = readHelper.getReadResult();
|
||||
}
|
||||
dataset.localPoolVarUint8.value = 0;
|
||||
dataset.localPoolVarFloat.value = 0.0;
|
||||
dataset.localPoolUint16Vec.value[0] = 0;
|
||||
dataset.localPoolUint16Vec.value[1] = 0;
|
||||
dataset.localPoolUint16Vec.value[2] = 0;
|
||||
dataset.setValidity(false, true);
|
||||
resetSubscriptionList();
|
||||
ReturnValue_t status = HasReturnvaluesIF::RETURN_OK;
|
||||
{
|
||||
PoolReadGuard readHelper(&dataset);
|
||||
if (readHelper.getReadResult() != HasReturnvaluesIF::RETURN_OK) {
|
||||
status = readHelper.getReadResult();
|
||||
}
|
||||
dataset.localPoolVarUint8.value = 0;
|
||||
dataset.localPoolVarFloat.value = 0.0;
|
||||
dataset.localPoolUint16Vec.value[0] = 0;
|
||||
dataset.localPoolUint16Vec.value[1] = 0;
|
||||
dataset.localPoolUint16Vec.value[2] = 0;
|
||||
dataset.setValidity(false, true);
|
||||
}
|
||||
|
||||
{
|
||||
PoolReadGuard readHelper(&testUint32);
|
||||
if(readHelper.getReadResult() != HasReturnvaluesIF::RETURN_OK) {
|
||||
status = readHelper.getReadResult();
|
||||
}
|
||||
testUint32.value = 0;
|
||||
testUint32.setValid(false);
|
||||
{
|
||||
PoolReadGuard readHelper(&testUint32);
|
||||
if (readHelper.getReadResult() != HasReturnvaluesIF::RETURN_OK) {
|
||||
status = readHelper.getReadResult();
|
||||
}
|
||||
testUint32.value = 0;
|
||||
testUint32.setValid(false);
|
||||
}
|
||||
|
||||
{
|
||||
PoolReadGuard readHelper(&testInt64Vec);
|
||||
if(readHelper.getReadResult() != HasReturnvaluesIF::RETURN_OK) {
|
||||
status = readHelper.getReadResult();
|
||||
}
|
||||
testInt64Vec.value[0] = 0;
|
||||
testInt64Vec.value[1] = 0;
|
||||
testInt64Vec.setValid(false);
|
||||
{
|
||||
PoolReadGuard readHelper(&testInt64Vec);
|
||||
if (readHelper.getReadResult() != HasReturnvaluesIF::RETURN_OK) {
|
||||
status = readHelper.getReadResult();
|
||||
}
|
||||
return status;
|
||||
testInt64Vec.value[0] = 0;
|
||||
testInt64Vec.value[1] = 0;
|
||||
testInt64Vec.setValid(false);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
bool LocalPoolOwnerBase::changedDataSetCallbackWasCalled(sid_t &sid, store_address_t &storeId) {
|
||||
bool condition = false;
|
||||
if(not this->changedDatasetSid.notSet()) {
|
||||
condition = true;
|
||||
}
|
||||
sid = changedDatasetSid;
|
||||
storeId = storeIdForChangedSet;
|
||||
this->changedDatasetSid.raw = sid_t::INVALID_SID;
|
||||
this->storeIdForChangedSet = storeId::INVALID_STORE_ADDRESS;
|
||||
return condition;
|
||||
bool condition = false;
|
||||
if (not this->changedDatasetSid.notSet()) {
|
||||
condition = true;
|
||||
}
|
||||
sid = changedDatasetSid;
|
||||
storeId = storeIdForChangedSet;
|
||||
this->changedDatasetSid.raw = sid_t::INVALID_SID;
|
||||
this->storeIdForChangedSet = storeId::INVALID_STORE_ADDRESS;
|
||||
return condition;
|
||||
}
|
||||
|
||||
void LocalPoolOwnerBase::handleChangedDataset(sid_t sid, store_address_t storeId,
|
||||
bool* clearMessage) {
|
||||
this->changedDatasetSid = sid;
|
||||
this->storeIdForChangedSet = storeId;
|
||||
bool *clearMessage) {
|
||||
this->changedDatasetSid = sid;
|
||||
this->storeIdForChangedSet = storeId;
|
||||
}
|
||||
|
||||
bool LocalPoolOwnerBase::changedVariableCallbackWasCalled(gp_id_t &gpid, store_address_t &storeId) {
|
||||
bool condition = false;
|
||||
if(not this->changedPoolVariableGpid.notSet()) {
|
||||
condition = true;
|
||||
}
|
||||
gpid = changedPoolVariableGpid;
|
||||
storeId = storeIdForChangedVariable;
|
||||
this->changedPoolVariableGpid.raw = gp_id_t::INVALID_GPID;
|
||||
this->storeIdForChangedVariable = storeId::INVALID_STORE_ADDRESS;
|
||||
return condition;
|
||||
bool condition = false;
|
||||
if (not this->changedPoolVariableGpid.notSet()) {
|
||||
condition = true;
|
||||
}
|
||||
gpid = changedPoolVariableGpid;
|
||||
storeId = storeIdForChangedVariable;
|
||||
this->changedPoolVariableGpid.raw = gp_id_t::INVALID_GPID;
|
||||
this->storeIdForChangedVariable = storeId::INVALID_STORE_ADDRESS;
|
||||
return condition;
|
||||
}
|
||||
|
||||
ReturnValue_t LocalPoolOwnerBase::initializeHkManagerAfterTaskCreation() {
|
||||
if(not initializedAfterTaskCreation) {
|
||||
initializedAfterTaskCreation = true;
|
||||
return poolManager.initializeAfterTaskCreation();
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
|
||||
if (not initializedAfterTaskCreation) {
|
||||
initializedAfterTaskCreation = true;
|
||||
return poolManager.initializeAfterTaskCreation();
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
void LocalPoolOwnerBase::handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId,
|
||||
bool* clearMessage) {
|
||||
this->changedPoolVariableGpid = globPoolId;
|
||||
this->storeIdForChangedVariable = storeId;
|
||||
bool *clearMessage) {
|
||||
this->changedPoolVariableGpid = globPoolId;
|
||||
this->storeIdForChangedVariable = storeId;
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,17 @@
|
||||
#ifndef FSFW_UNITTEST_TESTS_DATAPOOLLOCAL_LOCALPOOLOWNERBASE_H_
|
||||
#define FSFW_UNITTEST_TESTS_DATAPOOLLOCAL_LOCALPOOLOWNERBASE_H_
|
||||
|
||||
#include "tests/TestsConfig.h"
|
||||
#include "../mocks/MessageQueueMockBase.h"
|
||||
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/datapoollocal/HasLocalDataPoolIF.h>
|
||||
#include <fsfw/datapoollocal/LocalDataSet.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw/datapoollocal/LocalPoolVariable.h>
|
||||
#include <fsfw/datapoollocal/LocalPoolVector.h>
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
|
||||
#include "../mocks/MessageQueueMockBase.h"
|
||||
#include "tests/TestsConfig.h"
|
||||
|
||||
namespace lpool {
|
||||
static constexpr lp_id_t uint8VarId = 0;
|
||||
@ -30,159 +30,135 @@ static const gp_id_t floatVarGpid = gp_id_t(objects::TEST_LOCAL_POOL_OWNER_BASE,
|
||||
static const gp_id_t uint32Gpid = gp_id_t(objects::TEST_LOCAL_POOL_OWNER_BASE, uint32VarId);
|
||||
static const gp_id_t uint16Vec3Gpid = gp_id_t(objects::TEST_LOCAL_POOL_OWNER_BASE, uint16Vec3Id);
|
||||
static const gp_id_t uint64Vec2Id = gp_id_t(objects::TEST_LOCAL_POOL_OWNER_BASE, int64Vec2Id);
|
||||
}
|
||||
} // namespace lpool
|
||||
|
||||
class LocalPoolStaticTestDataSet : public StaticLocalDataSet<3> {
|
||||
public:
|
||||
LocalPoolStaticTestDataSet() : StaticLocalDataSet(lpool::testSid) {}
|
||||
|
||||
class LocalPoolStaticTestDataSet: public StaticLocalDataSet<3> {
|
||||
public:
|
||||
LocalPoolStaticTestDataSet():
|
||||
StaticLocalDataSet(lpool::testSid) {
|
||||
LocalPoolStaticTestDataSet(HasLocalDataPoolIF* owner, uint32_t setId)
|
||||
: StaticLocalDataSet(owner, setId) {}
|
||||
|
||||
}
|
||||
lp_var_t<uint8_t> localPoolVarUint8 = lp_var_t<uint8_t>(lpool::uint8VarGpid, this);
|
||||
lp_var_t<float> localPoolVarFloat = lp_var_t<float>(lpool::floatVarGpid, this);
|
||||
lp_vec_t<uint16_t, 3> localPoolUint16Vec = lp_vec_t<uint16_t, 3>(lpool::uint16Vec3Gpid, this);
|
||||
|
||||
LocalPoolStaticTestDataSet(HasLocalDataPoolIF* owner, uint32_t setId):
|
||||
StaticLocalDataSet(owner, setId) {
|
||||
}
|
||||
|
||||
lp_var_t<uint8_t> localPoolVarUint8 = lp_var_t<uint8_t>(lpool::uint8VarGpid, this);
|
||||
lp_var_t<float> localPoolVarFloat = lp_var_t<float>(lpool::floatVarGpid, this);
|
||||
lp_vec_t<uint16_t, 3> localPoolUint16Vec = lp_vec_t<uint16_t, 3>(lpool::uint16Vec3Gpid, this);
|
||||
|
||||
private:
|
||||
private:
|
||||
};
|
||||
|
||||
class LocalPoolTestDataSet: public LocalDataSet {
|
||||
public:
|
||||
LocalPoolTestDataSet():
|
||||
LocalDataSet(lpool::testSid, lpool::dataSetMaxVariables) {}
|
||||
class LocalPoolTestDataSet : public LocalDataSet {
|
||||
public:
|
||||
LocalPoolTestDataSet() : LocalDataSet(lpool::testSid, lpool::dataSetMaxVariables) {}
|
||||
|
||||
LocalPoolTestDataSet(HasLocalDataPoolIF* owner, uint32_t setId):
|
||||
LocalDataSet(owner, setId, lpool::dataSetMaxVariables) {
|
||||
}
|
||||
LocalPoolTestDataSet(HasLocalDataPoolIF* owner, uint32_t setId)
|
||||
: LocalDataSet(owner, setId, lpool::dataSetMaxVariables) {}
|
||||
|
||||
lp_var_t<uint8_t> localPoolVarUint8 = lp_var_t<uint8_t>(lpool::uint8VarGpid, this);
|
||||
lp_var_t<float> localPoolVarFloat = lp_var_t<float>(lpool::floatVarGpid, this);
|
||||
lp_vec_t<uint16_t, 3> localPoolUint16Vec = lp_vec_t<uint16_t, 3>(lpool::uint16Vec3Gpid, this);
|
||||
lp_var_t<uint8_t> localPoolVarUint8 = lp_var_t<uint8_t>(lpool::uint8VarGpid, this);
|
||||
lp_var_t<float> localPoolVarFloat = lp_var_t<float>(lpool::floatVarGpid, this);
|
||||
lp_vec_t<uint16_t, 3> localPoolUint16Vec = lp_vec_t<uint16_t, 3>(lpool::uint16Vec3Gpid, this);
|
||||
|
||||
void setDiagnostic(bool isDiagnostic) {
|
||||
LocalPoolDataSetBase::setDiagnostic(isDiagnostic);
|
||||
}
|
||||
private:
|
||||
void setDiagnostic(bool isDiagnostic) { LocalPoolDataSetBase::setDiagnostic(isDiagnostic); }
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class LocalPoolOwnerBase : public SystemObject, public HasLocalDataPoolIF {
|
||||
public:
|
||||
LocalPoolOwnerBase(object_id_t objectId = objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
|
||||
class LocalPoolOwnerBase: public SystemObject, public HasLocalDataPoolIF {
|
||||
public:
|
||||
LocalPoolOwnerBase(object_id_t objectId = objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
~LocalPoolOwnerBase();
|
||||
|
||||
~LocalPoolOwnerBase();
|
||||
object_id_t getObjectId() const override { return SystemObject::getObjectId(); }
|
||||
|
||||
object_id_t getObjectId() const override {
|
||||
return SystemObject::getObjectId();
|
||||
}
|
||||
ReturnValue_t initializeHkManager();
|
||||
|
||||
ReturnValue_t initializeHkManager();
|
||||
ReturnValue_t initializeHkManagerAfterTaskCreation();
|
||||
|
||||
ReturnValue_t initializeHkManagerAfterTaskCreation();
|
||||
/** Command queue for housekeeping messages. */
|
||||
MessageQueueId_t getCommandQueue() const override { return messageQueue->getId(); }
|
||||
|
||||
/** Command queue for housekeeping messages. */
|
||||
MessageQueueId_t getCommandQueue() const override {
|
||||
return messageQueue->getId();
|
||||
}
|
||||
// This is called by initializeAfterTaskCreation of the HK manager.
|
||||
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
|
||||
// This is called by initializeAfterTaskCreation of the HK manager.
|
||||
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
LocalDataPoolManager* getHkManagerHandle() override { return &poolManager; }
|
||||
|
||||
LocalDataPoolManager* getHkManagerHandle() override {
|
||||
return &poolManager;
|
||||
}
|
||||
dur_millis_t getPeriodicOperationFrequency() const override { return 200; }
|
||||
|
||||
dur_millis_t getPeriodicOperationFrequency() const override {
|
||||
return 200;
|
||||
}
|
||||
/**
|
||||
* This function is used by the pool manager to get a valid dataset
|
||||
* from a SID
|
||||
* @param sid Corresponding structure ID
|
||||
* @return
|
||||
*/
|
||||
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override { return &dataset; }
|
||||
|
||||
/**
|
||||
* This function is used by the pool manager to get a valid dataset
|
||||
* from a SID
|
||||
* @param sid Corresponding structure ID
|
||||
* @return
|
||||
*/
|
||||
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override {
|
||||
return &dataset;
|
||||
}
|
||||
virtual LocalPoolObjectBase* getPoolObjectHandle(lp_id_t localPoolId) override;
|
||||
|
||||
virtual LocalPoolObjectBase* getPoolObjectHandle(lp_id_t localPoolId) override;
|
||||
MessageQueueMockBase* getMockQueueHandle() const {
|
||||
return dynamic_cast<MessageQueueMockBase*>(messageQueue);
|
||||
}
|
||||
|
||||
MessageQueueMockBase* getMockQueueHandle() const {
|
||||
return dynamic_cast<MessageQueueMockBase*>(messageQueue);
|
||||
}
|
||||
ReturnValue_t subscribePeriodicHk(bool enableReporting) {
|
||||
return poolManager.subscribeForPeriodicPacket(lpool::testSid, enableReporting, 0.2, false);
|
||||
}
|
||||
|
||||
ReturnValue_t subscribePeriodicHk(bool enableReporting) {
|
||||
return poolManager.subscribeForPeriodicPacket(lpool::testSid, enableReporting, 0.2, false);
|
||||
}
|
||||
ReturnValue_t subscribeWrapperSetUpdate() {
|
||||
return poolManager.subscribeForSetUpdateMessage(lpool::testSetId, objects::NO_OBJECT,
|
||||
objects::HK_RECEIVER_MOCK, false);
|
||||
}
|
||||
|
||||
ReturnValue_t subscribeWrapperSetUpdate() {
|
||||
return poolManager.subscribeForSetUpdateMessage(lpool::testSetId,
|
||||
objects::NO_OBJECT, objects::HK_RECEIVER_MOCK, false);
|
||||
}
|
||||
ReturnValue_t subscribeWrapperSetUpdateSnapshot() {
|
||||
return poolManager.subscribeForSetUpdateMessage(lpool::testSetId, objects::NO_OBJECT,
|
||||
objects::HK_RECEIVER_MOCK, true);
|
||||
}
|
||||
|
||||
ReturnValue_t subscribeWrapperSetUpdateSnapshot() {
|
||||
return poolManager.subscribeForSetUpdateMessage(lpool::testSetId,
|
||||
objects::NO_OBJECT, objects::HK_RECEIVER_MOCK, true);
|
||||
}
|
||||
ReturnValue_t subscribeWrapperSetUpdateHk(bool diagnostics = false) {
|
||||
return poolManager.subscribeForUpdatePacket(lpool::testSid, diagnostics, false,
|
||||
objects::HK_RECEIVER_MOCK);
|
||||
}
|
||||
|
||||
ReturnValue_t subscribeWrapperSetUpdateHk(bool diagnostics = false) {
|
||||
return poolManager.subscribeForUpdatePacket(lpool::testSid, diagnostics,
|
||||
false, objects::HK_RECEIVER_MOCK);
|
||||
}
|
||||
ReturnValue_t subscribeWrapperVariableUpdate(lp_id_t localPoolId) {
|
||||
return poolManager.subscribeForVariableUpdateMessage(localPoolId, MessageQueueIF::NO_QUEUE,
|
||||
objects::HK_RECEIVER_MOCK, false);
|
||||
}
|
||||
|
||||
ReturnValue_t subscribeWrapperVariableUpdate(lp_id_t localPoolId) {
|
||||
return poolManager.subscribeForVariableUpdateMessage(localPoolId,
|
||||
MessageQueueIF::NO_QUEUE, objects::HK_RECEIVER_MOCK, false);
|
||||
}
|
||||
ReturnValue_t subscribeWrapperVariableSnapshot(lp_id_t localPoolId) {
|
||||
return poolManager.subscribeForVariableUpdateMessage(localPoolId, MessageQueueIF::NO_QUEUE,
|
||||
objects::HK_RECEIVER_MOCK, true);
|
||||
}
|
||||
|
||||
ReturnValue_t subscribeWrapperVariableSnapshot(lp_id_t localPoolId) {
|
||||
return poolManager.subscribeForVariableUpdateMessage(localPoolId,
|
||||
MessageQueueIF::NO_QUEUE, objects::HK_RECEIVER_MOCK, true);
|
||||
}
|
||||
ReturnValue_t reset();
|
||||
|
||||
ReturnValue_t reset();
|
||||
void resetSubscriptionList() { poolManager.clearReceiversList(); }
|
||||
|
||||
void resetSubscriptionList() {
|
||||
poolManager.clearReceiversList();
|
||||
}
|
||||
bool changedDataSetCallbackWasCalled(sid_t& sid, store_address_t& storeId);
|
||||
bool changedVariableCallbackWasCalled(gp_id_t& gpid, store_address_t& storeId);
|
||||
|
||||
bool changedDataSetCallbackWasCalled(sid_t& sid, store_address_t& storeId);
|
||||
bool changedVariableCallbackWasCalled(gp_id_t& gpid, store_address_t& storeId);
|
||||
LocalDataPoolManager poolManager;
|
||||
LocalPoolTestDataSet dataset;
|
||||
|
||||
LocalDataPoolManager poolManager;
|
||||
LocalPoolTestDataSet dataset;
|
||||
private:
|
||||
private:
|
||||
void handleChangedDataset(sid_t sid, store_address_t storeId, bool* clearMessage) override;
|
||||
sid_t changedDatasetSid;
|
||||
store_address_t storeIdForChangedSet;
|
||||
|
||||
void handleChangedDataset(sid_t sid, store_address_t storeId, bool* clearMessage) override;
|
||||
sid_t changedDatasetSid;
|
||||
store_address_t storeIdForChangedSet;
|
||||
void handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId,
|
||||
bool* clearMessage) override;
|
||||
gp_id_t changedPoolVariableGpid;
|
||||
store_address_t storeIdForChangedVariable;
|
||||
|
||||
void handleChangedPoolVariable(gp_id_t globPoolId, store_address_t storeId,
|
||||
bool* clearMessage) override;
|
||||
gp_id_t changedPoolVariableGpid;
|
||||
store_address_t storeIdForChangedVariable;
|
||||
lp_var_t<uint8_t> testUint8 = lp_var_t<uint8_t>(this, lpool::uint8VarId);
|
||||
lp_var_t<float> testFloat = lp_var_t<float>(this, lpool::floatVarId);
|
||||
lp_var_t<uint32_t> testUint32 = lp_var_t<uint32_t>(this, lpool::uint32VarId);
|
||||
|
||||
lp_var_t<uint8_t> testUint8 = lp_var_t<uint8_t>(this, lpool::uint8VarId);
|
||||
lp_var_t<float> testFloat = lp_var_t<float>(this, lpool::floatVarId);
|
||||
lp_var_t<uint32_t> testUint32 = lp_var_t<uint32_t>(this, lpool::uint32VarId);
|
||||
lp_vec_t<uint16_t, 3> testUint16Vec = lp_vec_t<uint16_t, 3>(this, lpool::uint16Vec3Id);
|
||||
lp_vec_t<int64_t, 2> testInt64Vec = lp_vec_t<int64_t, 2>(this, lpool::int64Vec2Id);
|
||||
|
||||
lp_vec_t<uint16_t, 3> testUint16Vec = lp_vec_t<uint16_t, 3>(this,
|
||||
lpool::uint16Vec3Id);
|
||||
lp_vec_t<int64_t, 2> testInt64Vec = lp_vec_t<int64_t, 2>(this,
|
||||
lpool::int64Vec2Id);
|
||||
|
||||
MessageQueueIF* messageQueue = nullptr;
|
||||
|
||||
bool initialized = false;
|
||||
bool initializedAfterTaskCreation = false;
|
||||
MessageQueueIF* messageQueue = nullptr;
|
||||
|
||||
bool initialized = false;
|
||||
bool initializedAfterTaskCreation = false;
|
||||
};
|
||||
|
||||
#endif /* FSFW_UNITTEST_TESTS_DATAPOOLLOCAL_LOCALPOOLOWNERBASE_H_ */
|
||||
|
@ -1,126 +1,111 @@
|
||||
#include "LocalPoolOwnerBase.h"
|
||||
#include "tests/TestsConfig.h"
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
#include <fsfw/datapoollocal/HasLocalDataPoolIF.h>
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
TEST_CASE("LocalPoolVariable" , "[LocPoolVarTest]") {
|
||||
LocalPoolOwnerBase* poolOwner = ObjectManager::instance()->
|
||||
get<LocalPoolOwnerBase>(objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
REQUIRE(poolOwner != nullptr);
|
||||
REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK);
|
||||
REQUIRE(poolOwner->initializeHkManagerAfterTaskCreation() == retval::CATCH_OK);
|
||||
#include "LocalPoolOwnerBase.h"
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
#include "tests/TestsConfig.h"
|
||||
|
||||
SECTION("Basic Tests") {
|
||||
/* very basic test. */
|
||||
lp_var_t<uint8_t> testVariable = lp_var_t<uint8_t>(
|
||||
objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint8VarId);
|
||||
REQUIRE(testVariable.read() == retval::CATCH_OK);
|
||||
CHECK(testVariable.value == 0);
|
||||
testVariable.value = 5;
|
||||
REQUIRE(testVariable.commit() == retval::CATCH_OK);
|
||||
REQUIRE(testVariable.read() == retval::CATCH_OK);
|
||||
REQUIRE(testVariable.value == 5);
|
||||
CHECK(not testVariable.isValid());
|
||||
testVariable.setValid(true);
|
||||
CHECK(testVariable.isValid());
|
||||
CHECK(testVariable.commit(true) == retval::CATCH_OK);
|
||||
TEST_CASE("LocalPoolVariable", "[LocPoolVarTest]") {
|
||||
LocalPoolOwnerBase* poolOwner =
|
||||
ObjectManager::instance()->get<LocalPoolOwnerBase>(objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
REQUIRE(poolOwner != nullptr);
|
||||
REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK);
|
||||
REQUIRE(poolOwner->initializeHkManagerAfterTaskCreation() == retval::CATCH_OK);
|
||||
|
||||
testVariable.setReadWriteMode(pool_rwm_t::VAR_READ);
|
||||
CHECK(testVariable.getReadWriteMode() == pool_rwm_t::VAR_READ);
|
||||
testVariable.setReadWriteMode(pool_rwm_t::VAR_READ_WRITE);
|
||||
SECTION("Basic Tests") {
|
||||
/* very basic test. */
|
||||
lp_var_t<uint8_t> testVariable =
|
||||
lp_var_t<uint8_t>(objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint8VarId);
|
||||
REQUIRE(testVariable.read() == retval::CATCH_OK);
|
||||
CHECK(testVariable.value == 0);
|
||||
testVariable.value = 5;
|
||||
REQUIRE(testVariable.commit() == retval::CATCH_OK);
|
||||
REQUIRE(testVariable.read() == retval::CATCH_OK);
|
||||
REQUIRE(testVariable.value == 5);
|
||||
CHECK(not testVariable.isValid());
|
||||
testVariable.setValid(true);
|
||||
CHECK(testVariable.isValid());
|
||||
CHECK(testVariable.commit(true) == retval::CATCH_OK);
|
||||
|
||||
testVariable.setDataPoolId(22);
|
||||
CHECK(testVariable.getDataPoolId() == 22);
|
||||
testVariable.setDataPoolId(lpool::uint8VarId);
|
||||
testVariable.setReadWriteMode(pool_rwm_t::VAR_READ);
|
||||
CHECK(testVariable.getReadWriteMode() == pool_rwm_t::VAR_READ);
|
||||
testVariable.setReadWriteMode(pool_rwm_t::VAR_READ_WRITE);
|
||||
|
||||
testVariable.setChanged(true);
|
||||
CHECK(testVariable.hasChanged());
|
||||
testVariable.setChanged(false);
|
||||
testVariable.setDataPoolId(22);
|
||||
CHECK(testVariable.getDataPoolId() == 22);
|
||||
testVariable.setDataPoolId(lpool::uint8VarId);
|
||||
|
||||
gp_id_t globPoolId(objects::TEST_LOCAL_POOL_OWNER_BASE,
|
||||
lpool::uint8VarId);
|
||||
lp_var_t<uint8_t> testVariable2 = lp_var_t<uint8_t>(globPoolId);
|
||||
REQUIRE(testVariable2.read() == retval::CATCH_OK);
|
||||
CHECK(testVariable2 == 5);
|
||||
CHECK(testVariable == testVariable2);
|
||||
testVariable = 10;
|
||||
CHECK(testVariable != 5);
|
||||
//CHECK(not testVariable != testVariable2);
|
||||
uint8_t variableRaw = 0;
|
||||
uint8_t* varPtr = &variableRaw;
|
||||
size_t maxSize = testVariable.getSerializedSize();
|
||||
CHECK(maxSize == 1);
|
||||
size_t serSize = 0;
|
||||
CHECK(testVariable.serialize(&varPtr, &serSize, maxSize,
|
||||
SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
CHECK(variableRaw == 10);
|
||||
const uint8_t* varConstPtr = &variableRaw;
|
||||
testVariable = 5;
|
||||
CHECK(testVariable.deSerialize(&varConstPtr, &serSize,
|
||||
SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
CHECK(testVariable == 10);
|
||||
CHECK(testVariable != testVariable2);
|
||||
CHECK(testVariable2 < testVariable);
|
||||
CHECK(testVariable2 < 10);
|
||||
CHECK(testVariable > 5);
|
||||
CHECK(testVariable > testVariable2);
|
||||
variableRaw = static_cast<uint8_t>(testVariable2);
|
||||
CHECK(variableRaw == 5);
|
||||
testVariable.setChanged(true);
|
||||
CHECK(testVariable.hasChanged());
|
||||
testVariable.setChanged(false);
|
||||
|
||||
CHECK(testVariable == 10);
|
||||
testVariable = testVariable2;
|
||||
CHECK(testVariable == 5);
|
||||
}
|
||||
gp_id_t globPoolId(objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint8VarId);
|
||||
lp_var_t<uint8_t> testVariable2 = lp_var_t<uint8_t>(globPoolId);
|
||||
REQUIRE(testVariable2.read() == retval::CATCH_OK);
|
||||
CHECK(testVariable2 == 5);
|
||||
CHECK(testVariable == testVariable2);
|
||||
testVariable = 10;
|
||||
CHECK(testVariable != 5);
|
||||
// CHECK(not testVariable != testVariable2);
|
||||
uint8_t variableRaw = 0;
|
||||
uint8_t* varPtr = &variableRaw;
|
||||
size_t maxSize = testVariable.getSerializedSize();
|
||||
CHECK(maxSize == 1);
|
||||
size_t serSize = 0;
|
||||
CHECK(testVariable.serialize(&varPtr, &serSize, maxSize, SerializeIF::Endianness::MACHINE) ==
|
||||
retval::CATCH_OK);
|
||||
CHECK(variableRaw == 10);
|
||||
const uint8_t* varConstPtr = &variableRaw;
|
||||
testVariable = 5;
|
||||
CHECK(testVariable.deSerialize(&varConstPtr, &serSize, SerializeIF::Endianness::MACHINE) ==
|
||||
retval::CATCH_OK);
|
||||
CHECK(testVariable == 10);
|
||||
CHECK(testVariable != testVariable2);
|
||||
CHECK(testVariable2 < testVariable);
|
||||
CHECK(testVariable2 < 10);
|
||||
CHECK(testVariable > 5);
|
||||
CHECK(testVariable > testVariable2);
|
||||
variableRaw = static_cast<uint8_t>(testVariable2);
|
||||
CHECK(variableRaw == 5);
|
||||
|
||||
SECTION("ErrorHandling") {
|
||||
CHECK(testVariable == 10);
|
||||
testVariable = testVariable2;
|
||||
CHECK(testVariable == 5);
|
||||
}
|
||||
|
||||
/* now try to use a local pool variable which does not exist */
|
||||
lp_var_t<uint8_t> invalidVariable = lp_var_t<uint8_t>(
|
||||
objects::TEST_LOCAL_POOL_OWNER_BASE, 0xffffffff);
|
||||
REQUIRE(invalidVariable.read() ==
|
||||
static_cast<int>(localpool::POOL_ENTRY_NOT_FOUND));
|
||||
SECTION("ErrorHandling") {
|
||||
/* now try to use a local pool variable which does not exist */
|
||||
lp_var_t<uint8_t> invalidVariable =
|
||||
lp_var_t<uint8_t>(objects::TEST_LOCAL_POOL_OWNER_BASE, 0xffffffff);
|
||||
REQUIRE(invalidVariable.read() == static_cast<int>(localpool::POOL_ENTRY_NOT_FOUND));
|
||||
|
||||
REQUIRE(invalidVariable.commit() ==
|
||||
static_cast<int>(localpool::POOL_ENTRY_NOT_FOUND));
|
||||
/* now try to access with wrong type */
|
||||
lp_var_t<int8_t> invalidVariable2 = lp_var_t<int8_t>(
|
||||
objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint8VarId);
|
||||
REQUIRE(invalidVariable2.read() ==
|
||||
static_cast<int>(localpool::POOL_ENTRY_TYPE_CONFLICT));
|
||||
REQUIRE(invalidVariable.commit() == static_cast<int>(localpool::POOL_ENTRY_NOT_FOUND));
|
||||
/* now try to access with wrong type */
|
||||
lp_var_t<int8_t> invalidVariable2 =
|
||||
lp_var_t<int8_t>(objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint8VarId);
|
||||
REQUIRE(invalidVariable2.read() == static_cast<int>(localpool::POOL_ENTRY_TYPE_CONFLICT));
|
||||
|
||||
lp_var_t<uint8_t> readOnlyVar = lp_var_t<uint8_t>(
|
||||
objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint8VarId,
|
||||
nullptr, pool_rwm_t::VAR_READ);
|
||||
REQUIRE(readOnlyVar.commit() ==
|
||||
static_cast<int>(PoolVariableIF::INVALID_READ_WRITE_MODE));
|
||||
lp_var_t<uint8_t> writeOnlyVar = lp_var_t<uint8_t>(
|
||||
objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint8VarId,
|
||||
nullptr, pool_rwm_t::VAR_WRITE);
|
||||
REQUIRE(writeOnlyVar.read() == static_cast<int>(
|
||||
PoolVariableIF::INVALID_READ_WRITE_MODE));
|
||||
lp_var_t<uint8_t> readOnlyVar = lp_var_t<uint8_t>(
|
||||
objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint8VarId, nullptr, pool_rwm_t::VAR_READ);
|
||||
REQUIRE(readOnlyVar.commit() == static_cast<int>(PoolVariableIF::INVALID_READ_WRITE_MODE));
|
||||
lp_var_t<uint8_t> writeOnlyVar = lp_var_t<uint8_t>(
|
||||
objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint8VarId, nullptr, pool_rwm_t::VAR_WRITE);
|
||||
REQUIRE(writeOnlyVar.read() == static_cast<int>(PoolVariableIF::INVALID_READ_WRITE_MODE));
|
||||
|
||||
lp_var_t<uint32_t> uint32tVar = lp_var_t<uint32_t>(
|
||||
objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint32VarId);
|
||||
lp_var_t<uint32_t> uint32tVar =
|
||||
lp_var_t<uint32_t>(objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint32VarId);
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "LocalPoolVariable printout: " <<uint32tVar << std::endl;
|
||||
sif::info << "LocalPoolVariable printout: " << uint32tVar << std::endl;
|
||||
#endif
|
||||
|
||||
/* for code coverage. If program does not crash -> OK */
|
||||
lp_var_t<uint8_t> invalidObjectVar = lp_var_t<uint8_t>(
|
||||
0xffffffff, lpool::uint8VarId);
|
||||
gp_id_t globPoolId(0xffffffff,
|
||||
lpool::uint8VarId);
|
||||
lp_var_t<uint8_t> invalidObjectVar2 = lp_var_t<uint8_t>(globPoolId);
|
||||
lp_var_t<uint8_t> invalidObjectVar3 = lp_var_t<uint8_t>(nullptr,
|
||||
lpool::uint8VarId);
|
||||
}
|
||||
|
||||
CHECK(poolOwner->reset() == retval::CATCH_OK);
|
||||
/* for code coverage. If program does not crash -> OK */
|
||||
lp_var_t<uint8_t> invalidObjectVar = lp_var_t<uint8_t>(0xffffffff, lpool::uint8VarId);
|
||||
gp_id_t globPoolId(0xffffffff, lpool::uint8VarId);
|
||||
lp_var_t<uint8_t> invalidObjectVar2 = lp_var_t<uint8_t>(globPoolId);
|
||||
lp_var_t<uint8_t> invalidObjectVar3 = lp_var_t<uint8_t>(nullptr, lpool::uint8VarId);
|
||||
}
|
||||
|
||||
CHECK(poolOwner->reset() == retval::CATCH_OK);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,124 +1,110 @@
|
||||
#include "LocalPoolOwnerBase.h"
|
||||
#include "tests/TestsConfig.h"
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
#include <fsfw/datapoollocal/HasLocalDataPoolIF.h>
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
#include <fsfw/datapoollocal/HasLocalDataPoolIF.h>
|
||||
|
||||
#include "LocalPoolOwnerBase.h"
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
#include "tests/TestsConfig.h"
|
||||
|
||||
TEST_CASE("LocalPoolVector" , "[LocPoolVecTest]") {
|
||||
LocalPoolOwnerBase* poolOwner = ObjectManager::instance()->
|
||||
get<LocalPoolOwnerBase>(objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
REQUIRE(poolOwner != nullptr);
|
||||
REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK);
|
||||
REQUIRE(poolOwner->initializeHkManagerAfterTaskCreation()
|
||||
== retval::CATCH_OK);
|
||||
TEST_CASE("LocalPoolVector", "[LocPoolVecTest]") {
|
||||
LocalPoolOwnerBase* poolOwner =
|
||||
ObjectManager::instance()->get<LocalPoolOwnerBase>(objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
REQUIRE(poolOwner != nullptr);
|
||||
REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK);
|
||||
REQUIRE(poolOwner->initializeHkManagerAfterTaskCreation() == retval::CATCH_OK);
|
||||
|
||||
SECTION("BasicTest") {
|
||||
// very basic test.
|
||||
lp_vec_t<uint16_t, 3> testVector = lp_vec_t<uint16_t, 3>(
|
||||
objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint16Vec3Id);
|
||||
REQUIRE(testVector.read() == retval::CATCH_OK);
|
||||
testVector.value[0] = 5;
|
||||
testVector.value[1] = 232;
|
||||
testVector.value[2] = 32023;
|
||||
SECTION("BasicTest") {
|
||||
// very basic test.
|
||||
lp_vec_t<uint16_t, 3> testVector =
|
||||
lp_vec_t<uint16_t, 3>(objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint16Vec3Id);
|
||||
REQUIRE(testVector.read() == retval::CATCH_OK);
|
||||
testVector.value[0] = 5;
|
||||
testVector.value[1] = 232;
|
||||
testVector.value[2] = 32023;
|
||||
|
||||
REQUIRE(testVector.commit(true) == retval::CATCH_OK);
|
||||
CHECK(testVector.isValid());
|
||||
REQUIRE(testVector.commit(true) == retval::CATCH_OK);
|
||||
CHECK(testVector.isValid());
|
||||
|
||||
testVector.value[0] = 0;
|
||||
testVector.value[1] = 0;
|
||||
testVector.value[2] = 0;
|
||||
testVector.value[0] = 0;
|
||||
testVector.value[1] = 0;
|
||||
testVector.value[2] = 0;
|
||||
|
||||
CHECK(testVector.read() == retval::CATCH_OK);
|
||||
CHECK(testVector.value[0] == 5);
|
||||
CHECK(testVector.value[1] == 232);
|
||||
CHECK(testVector.value[2] == 32023);
|
||||
CHECK(testVector.read() == retval::CATCH_OK);
|
||||
CHECK(testVector.value[0] == 5);
|
||||
CHECK(testVector.value[1] == 232);
|
||||
CHECK(testVector.value[2] == 32023);
|
||||
|
||||
CHECK(testVector[0] == 5);
|
||||
CHECK(testVector[0] == 5);
|
||||
|
||||
/* This is invalid access, so the last value will be set instead.
|
||||
(we can't throw exceptions) */
|
||||
testVector[4] = 12;
|
||||
CHECK(testVector[2] == 12);
|
||||
CHECK(testVector.commit() == retval::CATCH_OK);
|
||||
/* This is invalid access, so the last value will be set instead.
|
||||
(we can't throw exceptions) */
|
||||
testVector[4] = 12;
|
||||
CHECK(testVector[2] == 12);
|
||||
CHECK(testVector.commit() == retval::CATCH_OK);
|
||||
|
||||
/* Use read-only reference. */
|
||||
const lp_vec_t<uint16_t, 3>& roTestVec = testVector;
|
||||
uint16_t valueOne = roTestVec[0];
|
||||
CHECK(valueOne == 5);
|
||||
/* Use read-only reference. */
|
||||
const lp_vec_t<uint16_t, 3>& roTestVec = testVector;
|
||||
uint16_t valueOne = roTestVec[0];
|
||||
CHECK(valueOne == 5);
|
||||
|
||||
uint16_t lastVal = roTestVec[25];
|
||||
CHECK(lastVal == 12);
|
||||
uint16_t lastVal = roTestVec[25];
|
||||
CHECK(lastVal == 12);
|
||||
|
||||
size_t maxSize = testVector.getSerializedSize();
|
||||
CHECK(maxSize == 6);
|
||||
size_t maxSize = testVector.getSerializedSize();
|
||||
CHECK(maxSize == 6);
|
||||
|
||||
uint16_t serializedVector[3];
|
||||
uint8_t* vecPtr = reinterpret_cast<uint8_t*>(serializedVector);
|
||||
size_t serSize = 0;
|
||||
REQUIRE(testVector.serialize(&vecPtr, &serSize,
|
||||
maxSize, SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
uint16_t serializedVector[3];
|
||||
uint8_t* vecPtr = reinterpret_cast<uint8_t*>(serializedVector);
|
||||
size_t serSize = 0;
|
||||
REQUIRE(testVector.serialize(&vecPtr, &serSize, maxSize, SerializeIF::Endianness::MACHINE) ==
|
||||
retval::CATCH_OK);
|
||||
|
||||
CHECK(serSize == 6);
|
||||
CHECK(serializedVector[0] == 5);
|
||||
CHECK(serializedVector[1] == 232);
|
||||
CHECK(serializedVector[2] == 12);
|
||||
CHECK(serSize == 6);
|
||||
CHECK(serializedVector[0] == 5);
|
||||
CHECK(serializedVector[1] == 232);
|
||||
CHECK(serializedVector[2] == 12);
|
||||
|
||||
maxSize = 1;
|
||||
REQUIRE(testVector.serialize(&vecPtr, &serSize,
|
||||
maxSize, SerializeIF::Endianness::MACHINE) ==
|
||||
static_cast<int>(SerializeIF::BUFFER_TOO_SHORT));
|
||||
maxSize = 1;
|
||||
REQUIRE(testVector.serialize(&vecPtr, &serSize, maxSize, SerializeIF::Endianness::MACHINE) ==
|
||||
static_cast<int>(SerializeIF::BUFFER_TOO_SHORT));
|
||||
|
||||
serializedVector[0] = 16;
|
||||
serializedVector[1] = 7832;
|
||||
serializedVector[2] = 39232;
|
||||
serializedVector[0] = 16;
|
||||
serializedVector[1] = 7832;
|
||||
serializedVector[2] = 39232;
|
||||
|
||||
const uint8_t* constVecPtr = reinterpret_cast<const uint8_t*>(
|
||||
serializedVector);
|
||||
REQUIRE(testVector.deSerialize(&constVecPtr, &serSize,
|
||||
SerializeIF::Endianness::MACHINE) == retval::CATCH_OK);
|
||||
CHECK(testVector[0] == 16);
|
||||
CHECK(testVector[1] == 7832);
|
||||
CHECK(testVector[2] == 39232);
|
||||
const uint8_t* constVecPtr = reinterpret_cast<const uint8_t*>(serializedVector);
|
||||
REQUIRE(testVector.deSerialize(&constVecPtr, &serSize, SerializeIF::Endianness::MACHINE) ==
|
||||
retval::CATCH_OK);
|
||||
CHECK(testVector[0] == 16);
|
||||
CHECK(testVector[1] == 7832);
|
||||
CHECK(testVector[2] == 39232);
|
||||
|
||||
serSize = 1;
|
||||
REQUIRE(testVector.deSerialize(&constVecPtr, &serSize,
|
||||
SerializeIF::Endianness::MACHINE) ==
|
||||
static_cast<int>(SerializeIF::STREAM_TOO_SHORT));
|
||||
}
|
||||
serSize = 1;
|
||||
REQUIRE(testVector.deSerialize(&constVecPtr, &serSize, SerializeIF::Endianness::MACHINE) ==
|
||||
static_cast<int>(SerializeIF::STREAM_TOO_SHORT));
|
||||
}
|
||||
|
||||
SECTION("ErrorHandling") {
|
||||
/* Now try to use a local pool variable which does not exist */
|
||||
lp_vec_t<uint16_t, 3> invalidVector = lp_vec_t<uint16_t, 3>(
|
||||
objects::TEST_LOCAL_POOL_OWNER_BASE, 0xffffffff);
|
||||
REQUIRE(invalidVector.read() ==
|
||||
static_cast<int>(localpool::POOL_ENTRY_NOT_FOUND));
|
||||
REQUIRE(invalidVector.commit() ==
|
||||
static_cast<int>(localpool::POOL_ENTRY_NOT_FOUND));
|
||||
SECTION("ErrorHandling") {
|
||||
/* Now try to use a local pool variable which does not exist */
|
||||
lp_vec_t<uint16_t, 3> invalidVector =
|
||||
lp_vec_t<uint16_t, 3>(objects::TEST_LOCAL_POOL_OWNER_BASE, 0xffffffff);
|
||||
REQUIRE(invalidVector.read() == static_cast<int>(localpool::POOL_ENTRY_NOT_FOUND));
|
||||
REQUIRE(invalidVector.commit() == static_cast<int>(localpool::POOL_ENTRY_NOT_FOUND));
|
||||
|
||||
/* Now try to access with wrong type */
|
||||
lp_vec_t<uint32_t, 3> invalidVector2 = lp_vec_t<uint32_t, 3>(
|
||||
objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint16Vec3Id);
|
||||
REQUIRE(invalidVector2.read() ==
|
||||
static_cast<int>(localpool::POOL_ENTRY_TYPE_CONFLICT));
|
||||
REQUIRE(invalidVector2.commit() ==
|
||||
static_cast<int>(localpool::POOL_ENTRY_TYPE_CONFLICT));
|
||||
/* Now try to access with wrong type */
|
||||
lp_vec_t<uint32_t, 3> invalidVector2 =
|
||||
lp_vec_t<uint32_t, 3>(objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint16Vec3Id);
|
||||
REQUIRE(invalidVector2.read() == static_cast<int>(localpool::POOL_ENTRY_TYPE_CONFLICT));
|
||||
REQUIRE(invalidVector2.commit() == static_cast<int>(localpool::POOL_ENTRY_TYPE_CONFLICT));
|
||||
|
||||
lp_vec_t<uint16_t, 3> writeOnlyVec = lp_vec_t<uint16_t, 3>(
|
||||
objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint16Vec3Id,
|
||||
nullptr, pool_rwm_t::VAR_WRITE);
|
||||
REQUIRE(writeOnlyVec.read() ==
|
||||
static_cast<int>(PoolVariableIF::INVALID_READ_WRITE_MODE));
|
||||
lp_vec_t<uint16_t, 3> writeOnlyVec = lp_vec_t<uint16_t, 3>(
|
||||
objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint16Vec3Id, nullptr, pool_rwm_t::VAR_WRITE);
|
||||
REQUIRE(writeOnlyVec.read() == static_cast<int>(PoolVariableIF::INVALID_READ_WRITE_MODE));
|
||||
|
||||
lp_vec_t<uint16_t, 3> readOnlyVec = lp_vec_t<uint16_t, 3>(
|
||||
objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint16Vec3Id,
|
||||
nullptr, pool_rwm_t::VAR_READ);
|
||||
REQUIRE(readOnlyVec.commit() ==
|
||||
static_cast<int>(PoolVariableIF::INVALID_READ_WRITE_MODE));
|
||||
}
|
||||
poolOwner->reset();
|
||||
lp_vec_t<uint16_t, 3> readOnlyVec = lp_vec_t<uint16_t, 3>(
|
||||
objects::TEST_LOCAL_POOL_OWNER_BASE, lpool::uint16Vec3Id, nullptr, pool_rwm_t::VAR_READ);
|
||||
REQUIRE(readOnlyVec.commit() == static_cast<int>(PoolVariableIF::INVALID_READ_WRITE_MODE));
|
||||
}
|
||||
poolOwner->reset();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,64 +1,61 @@
|
||||
#include "fsfw/globalfunctions/bitutility.h"
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
TEST_CASE("Bitutility" , "[Bitutility]") {
|
||||
uint8_t dummyByte = 0;
|
||||
bool bitSet = false;
|
||||
for(uint8_t pos = 0; pos < 8; pos++) {
|
||||
bitutil::set(&dummyByte, pos);
|
||||
REQUIRE(dummyByte == (1 << (7 - pos)));
|
||||
bitutil::get(&dummyByte, pos, bitSet);
|
||||
REQUIRE(bitSet == 1);
|
||||
dummyByte = 0;
|
||||
}
|
||||
|
||||
dummyByte = 0xff;
|
||||
for(uint8_t pos = 0; pos < 8; pos++) {
|
||||
bitutil::get(&dummyByte, pos, bitSet);
|
||||
REQUIRE(bitSet == 1);
|
||||
bitutil::clear(&dummyByte, pos);
|
||||
bitutil::get(&dummyByte, pos, bitSet);
|
||||
REQUIRE(bitSet == 0);
|
||||
dummyByte = 0xff;
|
||||
}
|
||||
|
||||
dummyByte = 0xf0;
|
||||
for(uint8_t pos = 0; pos < 8; pos++) {
|
||||
if(pos < 4) {
|
||||
bitutil::get(&dummyByte, pos, bitSet);
|
||||
REQUIRE(bitSet == 1);
|
||||
bitutil::toggle(&dummyByte, pos);
|
||||
bitutil::get(&dummyByte, pos, bitSet);
|
||||
REQUIRE(bitSet == 0);
|
||||
}
|
||||
else {
|
||||
bitutil::get(&dummyByte, pos, bitSet);
|
||||
REQUIRE(bitSet == false);
|
||||
bitutil::toggle(&dummyByte, pos);
|
||||
bitutil::get(&dummyByte, pos, bitSet);
|
||||
REQUIRE(bitSet == true);
|
||||
}
|
||||
}
|
||||
REQUIRE(dummyByte == 0x0f);
|
||||
#include "fsfw/globalfunctions/bitutility.h"
|
||||
|
||||
TEST_CASE("Bitutility", "[Bitutility]") {
|
||||
uint8_t dummyByte = 0;
|
||||
bool bitSet = false;
|
||||
for (uint8_t pos = 0; pos < 8; pos++) {
|
||||
bitutil::set(&dummyByte, pos);
|
||||
REQUIRE(dummyByte == (1 << (7 - pos)));
|
||||
bitutil::get(&dummyByte, pos, bitSet);
|
||||
REQUIRE(bitSet == 1);
|
||||
dummyByte = 0;
|
||||
bitutil::set(&dummyByte, 8);
|
||||
REQUIRE(dummyByte == 0);
|
||||
bitutil::set(&dummyByte, -1);
|
||||
REQUIRE(dummyByte == 0);
|
||||
}
|
||||
|
||||
dummyByte = 0xff;
|
||||
for (uint8_t pos = 0; pos < 8; pos++) {
|
||||
bitutil::get(&dummyByte, pos, bitSet);
|
||||
REQUIRE(bitSet == 1);
|
||||
bitutil::clear(&dummyByte, pos);
|
||||
bitutil::get(&dummyByte, pos, bitSet);
|
||||
REQUIRE(bitSet == 0);
|
||||
dummyByte = 0xff;
|
||||
bitutil::clear(&dummyByte, 8);
|
||||
REQUIRE(dummyByte == 0xff);
|
||||
bitutil::clear(&dummyByte, -1);
|
||||
REQUIRE(dummyByte == 0xff);
|
||||
dummyByte = 0x00;
|
||||
bitutil::toggle(&dummyByte, 8);
|
||||
REQUIRE(dummyByte == 0x00);
|
||||
bitutil::toggle(&dummyByte, -1);
|
||||
REQUIRE(dummyByte == 0x00);
|
||||
}
|
||||
|
||||
REQUIRE(bitutil::get(&dummyByte, 8, bitSet) == false);
|
||||
dummyByte = 0xf0;
|
||||
for (uint8_t pos = 0; pos < 8; pos++) {
|
||||
if (pos < 4) {
|
||||
bitutil::get(&dummyByte, pos, bitSet);
|
||||
REQUIRE(bitSet == 1);
|
||||
bitutil::toggle(&dummyByte, pos);
|
||||
bitutil::get(&dummyByte, pos, bitSet);
|
||||
REQUIRE(bitSet == 0);
|
||||
} else {
|
||||
bitutil::get(&dummyByte, pos, bitSet);
|
||||
REQUIRE(bitSet == false);
|
||||
bitutil::toggle(&dummyByte, pos);
|
||||
bitutil::get(&dummyByte, pos, bitSet);
|
||||
REQUIRE(bitSet == true);
|
||||
}
|
||||
}
|
||||
REQUIRE(dummyByte == 0x0f);
|
||||
|
||||
dummyByte = 0;
|
||||
bitutil::set(&dummyByte, 8);
|
||||
REQUIRE(dummyByte == 0);
|
||||
bitutil::set(&dummyByte, -1);
|
||||
REQUIRE(dummyByte == 0);
|
||||
dummyByte = 0xff;
|
||||
bitutil::clear(&dummyByte, 8);
|
||||
REQUIRE(dummyByte == 0xff);
|
||||
bitutil::clear(&dummyByte, -1);
|
||||
REQUIRE(dummyByte == 0xff);
|
||||
dummyByte = 0x00;
|
||||
bitutil::toggle(&dummyByte, 8);
|
||||
REQUIRE(dummyByte == 0x00);
|
||||
bitutil::toggle(&dummyByte, -1);
|
||||
REQUIRE(dummyByte == 0x00);
|
||||
|
||||
REQUIRE(bitutil::get(&dummyByte, 8, bitSet) == false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,227 +1,212 @@
|
||||
#include "fsfw/globalfunctions/DleEncoder.h"
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
#include "catch2/catch_test_macros.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
const std::vector<uint8_t> TEST_ARRAY_0 = { 0, 0, 0, 0, 0 };
|
||||
const std::vector<uint8_t> TEST_ARRAY_1 = { 0, DleEncoder::DLE_CHAR, 5};
|
||||
const std::vector<uint8_t> TEST_ARRAY_2 = { 0, DleEncoder::STX_CHAR, 5};
|
||||
const std::vector<uint8_t> TEST_ARRAY_3 = { 0, DleEncoder::CARRIAGE_RETURN, DleEncoder::ETX_CHAR};
|
||||
const std::vector<uint8_t> TEST_ARRAY_4 = { DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR,
|
||||
DleEncoder::STX_CHAR };
|
||||
#include "catch2/catch_test_macros.hpp"
|
||||
#include "fsfw/globalfunctions/DleEncoder.h"
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
const std::vector<uint8_t> TEST_ARRAY_0_ENCODED_ESCAPED = {
|
||||
DleEncoder::STX_CHAR, 0, 0, 0, 0, 0, DleEncoder::ETX_CHAR
|
||||
};
|
||||
const std::vector<uint8_t> TEST_ARRAY_0 = {0, 0, 0, 0, 0};
|
||||
const std::vector<uint8_t> TEST_ARRAY_1 = {0, DleEncoder::DLE_CHAR, 5};
|
||||
const std::vector<uint8_t> TEST_ARRAY_2 = {0, DleEncoder::STX_CHAR, 5};
|
||||
const std::vector<uint8_t> TEST_ARRAY_3 = {0, DleEncoder::CARRIAGE_RETURN, DleEncoder::ETX_CHAR};
|
||||
const std::vector<uint8_t> TEST_ARRAY_4 = {DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR,
|
||||
DleEncoder::STX_CHAR};
|
||||
|
||||
const std::vector<uint8_t> TEST_ARRAY_0_ENCODED_ESCAPED = {DleEncoder::STX_CHAR, 0, 0, 0, 0, 0,
|
||||
DleEncoder::ETX_CHAR};
|
||||
const std::vector<uint8_t> TEST_ARRAY_0_ENCODED_NON_ESCAPED = {
|
||||
DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR, 0, 0, 0, 0, 0,
|
||||
DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR
|
||||
};
|
||||
DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR, 0, 0, 0, 0, 0,
|
||||
DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR};
|
||||
|
||||
const std::vector<uint8_t> TEST_ARRAY_1_ENCODED_ESCAPED = {
|
||||
DleEncoder::STX_CHAR, 0, DleEncoder::DLE_CHAR, DleEncoder::DLE_CHAR, 5, DleEncoder::ETX_CHAR
|
||||
};
|
||||
DleEncoder::STX_CHAR, 0, DleEncoder::DLE_CHAR, DleEncoder::DLE_CHAR, 5, DleEncoder::ETX_CHAR};
|
||||
const std::vector<uint8_t> TEST_ARRAY_1_ENCODED_NON_ESCAPED = {
|
||||
DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR, 0, DleEncoder::DLE_CHAR, DleEncoder::DLE_CHAR,
|
||||
5, DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR
|
||||
};
|
||||
DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR, 0, DleEncoder::DLE_CHAR, DleEncoder::DLE_CHAR, 5,
|
||||
DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR};
|
||||
|
||||
const std::vector<uint8_t> TEST_ARRAY_2_ENCODED_ESCAPED = {
|
||||
DleEncoder::STX_CHAR, 0, DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR + 0x40,
|
||||
5, DleEncoder::ETX_CHAR
|
||||
};
|
||||
DleEncoder::STX_CHAR, 0, DleEncoder::DLE_CHAR,
|
||||
DleEncoder::STX_CHAR + 0x40, 5, DleEncoder::ETX_CHAR};
|
||||
const std::vector<uint8_t> TEST_ARRAY_2_ENCODED_NON_ESCAPED = {
|
||||
DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR, 0,
|
||||
DleEncoder::STX_CHAR, 5, DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR
|
||||
};
|
||||
DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR, 0, DleEncoder::STX_CHAR, 5,
|
||||
DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR};
|
||||
|
||||
const std::vector<uint8_t> TEST_ARRAY_3_ENCODED_ESCAPED = {
|
||||
DleEncoder::STX_CHAR, 0, DleEncoder::CARRIAGE_RETURN,
|
||||
DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR + 0x40, DleEncoder::ETX_CHAR
|
||||
};
|
||||
DleEncoder::STX_CHAR, 0,
|
||||
DleEncoder::CARRIAGE_RETURN, DleEncoder::DLE_CHAR,
|
||||
DleEncoder::ETX_CHAR + 0x40, DleEncoder::ETX_CHAR};
|
||||
const std::vector<uint8_t> TEST_ARRAY_3_ENCODED_NON_ESCAPED = {
|
||||
DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR, 0,
|
||||
DleEncoder::CARRIAGE_RETURN, DleEncoder::ETX_CHAR, DleEncoder::DLE_CHAR,
|
||||
DleEncoder::ETX_CHAR
|
||||
};
|
||||
DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR, 0,
|
||||
DleEncoder::CARRIAGE_RETURN, DleEncoder::ETX_CHAR, DleEncoder::DLE_CHAR,
|
||||
DleEncoder::ETX_CHAR};
|
||||
|
||||
const std::vector<uint8_t> TEST_ARRAY_4_ENCODED_ESCAPED = {
|
||||
DleEncoder::STX_CHAR, DleEncoder::DLE_CHAR, DleEncoder::DLE_CHAR,
|
||||
DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR + 0x40, DleEncoder::DLE_CHAR,
|
||||
DleEncoder::STX_CHAR + 0x40, DleEncoder::ETX_CHAR
|
||||
};
|
||||
DleEncoder::STX_CHAR, DleEncoder::DLE_CHAR, DleEncoder::DLE_CHAR,
|
||||
DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR + 0x40, DleEncoder::DLE_CHAR,
|
||||
DleEncoder::STX_CHAR + 0x40, DleEncoder::ETX_CHAR};
|
||||
const std::vector<uint8_t> TEST_ARRAY_4_ENCODED_NON_ESCAPED = {
|
||||
DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR, DleEncoder::DLE_CHAR, DleEncoder::DLE_CHAR,
|
||||
DleEncoder::ETX_CHAR, DleEncoder::STX_CHAR, DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR
|
||||
};
|
||||
DleEncoder::DLE_CHAR, DleEncoder::STX_CHAR, DleEncoder::DLE_CHAR, DleEncoder::DLE_CHAR,
|
||||
DleEncoder::ETX_CHAR, DleEncoder::STX_CHAR, DleEncoder::DLE_CHAR, DleEncoder::ETX_CHAR};
|
||||
|
||||
TEST_CASE("DleEncoder", "[DleEncoder]") {
|
||||
DleEncoder dleEncoder;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 32> buffer;
|
||||
|
||||
TEST_CASE("DleEncoder" , "[DleEncoder]") {
|
||||
DleEncoder dleEncoder;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 32> buffer;
|
||||
size_t encodedLen = 0;
|
||||
size_t readLen = 0;
|
||||
size_t decodedLen = 0;
|
||||
|
||||
size_t encodedLen = 0;
|
||||
size_t readLen = 0;
|
||||
size_t decodedLen = 0;
|
||||
auto testLambdaEncode = [&](DleEncoder& encoder, const std::vector<uint8_t>& vecToEncode,
|
||||
const std::vector<uint8_t>& expectedVec) {
|
||||
result = encoder.encode(vecToEncode.data(), vecToEncode.size(), buffer.data(), buffer.size(),
|
||||
&encodedLen);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
for (size_t idx = 0; idx < expectedVec.size(); idx++) {
|
||||
REQUIRE(buffer[idx] == expectedVec[idx]);
|
||||
}
|
||||
REQUIRE(encodedLen == expectedVec.size());
|
||||
};
|
||||
|
||||
auto testLambdaEncode = [&](DleEncoder& encoder, const std::vector<uint8_t>& vecToEncode,
|
||||
const std::vector<uint8_t>& expectedVec) {
|
||||
result = encoder.encode(vecToEncode.data(), vecToEncode.size(),
|
||||
buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
for(size_t idx = 0; idx < expectedVec.size(); idx++) {
|
||||
REQUIRE(buffer[idx] == expectedVec[idx]);
|
||||
}
|
||||
REQUIRE(encodedLen == expectedVec.size());
|
||||
auto testLambdaDecode = [&](DleEncoder& encoder, const std::vector<uint8_t>& testVecEncoded,
|
||||
const std::vector<uint8_t>& expectedVec) {
|
||||
result = encoder.decode(testVecEncoded.data(), testVecEncoded.size(), &readLen, buffer.data(),
|
||||
buffer.size(), &decodedLen);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
REQUIRE(readLen == testVecEncoded.size());
|
||||
REQUIRE(decodedLen == expectedVec.size());
|
||||
for (size_t idx = 0; idx < decodedLen; idx++) {
|
||||
REQUIRE(buffer[idx] == expectedVec[idx]);
|
||||
}
|
||||
};
|
||||
|
||||
SECTION("Encoding") {
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_0, TEST_ARRAY_0_ENCODED_ESCAPED);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_1, TEST_ARRAY_1_ENCODED_ESCAPED);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_2, TEST_ARRAY_2_ENCODED_ESCAPED);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_3, TEST_ARRAY_3_ENCODED_ESCAPED);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_4, TEST_ARRAY_4_ENCODED_ESCAPED);
|
||||
|
||||
auto testFaultyEncoding = [&](const std::vector<uint8_t>& vecToEncode,
|
||||
const std::vector<uint8_t>& expectedVec) {
|
||||
for (size_t faultyDestSize = 0; faultyDestSize < expectedVec.size(); faultyDestSize++) {
|
||||
result = dleEncoder.encode(vecToEncode.data(), vecToEncode.size(), buffer.data(),
|
||||
faultyDestSize, &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::STREAM_TOO_SHORT));
|
||||
}
|
||||
};
|
||||
|
||||
auto testLambdaDecode = [&](DleEncoder& encoder, const std::vector<uint8_t>& testVecEncoded,
|
||||
const std::vector<uint8_t>& expectedVec) {
|
||||
result = encoder.decode(testVecEncoded.data(),
|
||||
testVecEncoded.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &decodedLen);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
REQUIRE(readLen == testVecEncoded.size());
|
||||
REQUIRE(decodedLen == expectedVec.size());
|
||||
for(size_t idx = 0; idx < decodedLen; idx++) {
|
||||
REQUIRE(buffer[idx] == expectedVec[idx]);
|
||||
}
|
||||
testFaultyEncoding(TEST_ARRAY_0, TEST_ARRAY_0_ENCODED_ESCAPED);
|
||||
testFaultyEncoding(TEST_ARRAY_1, TEST_ARRAY_1_ENCODED_ESCAPED);
|
||||
testFaultyEncoding(TEST_ARRAY_2, TEST_ARRAY_2_ENCODED_ESCAPED);
|
||||
testFaultyEncoding(TEST_ARRAY_3, TEST_ARRAY_3_ENCODED_ESCAPED);
|
||||
testFaultyEncoding(TEST_ARRAY_4, TEST_ARRAY_4_ENCODED_ESCAPED);
|
||||
|
||||
dleEncoder.setEscapeMode(false);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_0, TEST_ARRAY_0_ENCODED_NON_ESCAPED);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_1, TEST_ARRAY_1_ENCODED_NON_ESCAPED);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_2, TEST_ARRAY_2_ENCODED_NON_ESCAPED);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_3, TEST_ARRAY_3_ENCODED_NON_ESCAPED);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_4, TEST_ARRAY_4_ENCODED_NON_ESCAPED);
|
||||
|
||||
testFaultyEncoding(TEST_ARRAY_0, TEST_ARRAY_0_ENCODED_NON_ESCAPED);
|
||||
testFaultyEncoding(TEST_ARRAY_1, TEST_ARRAY_1_ENCODED_NON_ESCAPED);
|
||||
testFaultyEncoding(TEST_ARRAY_2, TEST_ARRAY_2_ENCODED_NON_ESCAPED);
|
||||
testFaultyEncoding(TEST_ARRAY_3, TEST_ARRAY_3_ENCODED_NON_ESCAPED);
|
||||
testFaultyEncoding(TEST_ARRAY_4, TEST_ARRAY_4_ENCODED_NON_ESCAPED);
|
||||
dleEncoder.setEscapeMode(true);
|
||||
}
|
||||
|
||||
SECTION("Decoding") {
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_0_ENCODED_ESCAPED, TEST_ARRAY_0);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_1_ENCODED_ESCAPED, TEST_ARRAY_1);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_2_ENCODED_ESCAPED, TEST_ARRAY_2);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_3_ENCODED_ESCAPED, TEST_ARRAY_3);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_4_ENCODED_ESCAPED, TEST_ARRAY_4);
|
||||
|
||||
// Faulty source data
|
||||
auto testArray1EncodedFaulty = TEST_ARRAY_1_ENCODED_ESCAPED;
|
||||
testArray1EncodedFaulty[3] = 0;
|
||||
result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
auto testArray2EncodedFaulty = TEST_ARRAY_2_ENCODED_ESCAPED;
|
||||
testArray2EncodedFaulty[5] = 0;
|
||||
result = dleEncoder.decode(testArray2EncodedFaulty.data(), testArray2EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
auto testArray4EncodedFaulty = TEST_ARRAY_4_ENCODED_ESCAPED;
|
||||
testArray4EncodedFaulty[2] = 0;
|
||||
result = dleEncoder.decode(testArray4EncodedFaulty.data(), testArray4EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
auto testArray4EncodedFaulty2 = TEST_ARRAY_4_ENCODED_ESCAPED;
|
||||
testArray4EncodedFaulty2[4] = 0;
|
||||
result = dleEncoder.decode(testArray4EncodedFaulty2.data(), testArray4EncodedFaulty2.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
|
||||
auto testFaultyDecoding = [&](const std::vector<uint8_t>& vecToDecode,
|
||||
const std::vector<uint8_t>& expectedVec) {
|
||||
for (size_t faultyDestSizes = 0; faultyDestSizes < expectedVec.size(); faultyDestSizes++) {
|
||||
result = dleEncoder.decode(vecToDecode.data(), vecToDecode.size(), &readLen, buffer.data(),
|
||||
faultyDestSizes, &decodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::STREAM_TOO_SHORT));
|
||||
}
|
||||
};
|
||||
|
||||
SECTION("Encoding") {
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_0, TEST_ARRAY_0_ENCODED_ESCAPED);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_1, TEST_ARRAY_1_ENCODED_ESCAPED);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_2, TEST_ARRAY_2_ENCODED_ESCAPED);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_3, TEST_ARRAY_3_ENCODED_ESCAPED);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_4, TEST_ARRAY_4_ENCODED_ESCAPED);
|
||||
testFaultyDecoding(TEST_ARRAY_0_ENCODED_ESCAPED, TEST_ARRAY_0);
|
||||
testFaultyDecoding(TEST_ARRAY_1_ENCODED_ESCAPED, TEST_ARRAY_1);
|
||||
testFaultyDecoding(TEST_ARRAY_2_ENCODED_ESCAPED, TEST_ARRAY_2);
|
||||
testFaultyDecoding(TEST_ARRAY_3_ENCODED_ESCAPED, TEST_ARRAY_3);
|
||||
testFaultyDecoding(TEST_ARRAY_4_ENCODED_ESCAPED, TEST_ARRAY_4);
|
||||
|
||||
auto testFaultyEncoding = [&](const std::vector<uint8_t>& vecToEncode,
|
||||
const std::vector<uint8_t>& expectedVec) {
|
||||
dleEncoder.setEscapeMode(false);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_0_ENCODED_NON_ESCAPED, TEST_ARRAY_0);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_1_ENCODED_NON_ESCAPED, TEST_ARRAY_1);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_2_ENCODED_NON_ESCAPED, TEST_ARRAY_2);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_3_ENCODED_NON_ESCAPED, TEST_ARRAY_3);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_4_ENCODED_NON_ESCAPED, TEST_ARRAY_4);
|
||||
|
||||
for(size_t faultyDestSize = 0; faultyDestSize < expectedVec.size(); faultyDestSize ++) {
|
||||
result = dleEncoder.encode(vecToEncode.data(), vecToEncode.size(),
|
||||
buffer.data(), faultyDestSize, &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::STREAM_TOO_SHORT));
|
||||
}
|
||||
};
|
||||
testFaultyDecoding(TEST_ARRAY_0_ENCODED_NON_ESCAPED, TEST_ARRAY_0);
|
||||
testFaultyDecoding(TEST_ARRAY_1_ENCODED_NON_ESCAPED, TEST_ARRAY_1);
|
||||
testFaultyDecoding(TEST_ARRAY_2_ENCODED_NON_ESCAPED, TEST_ARRAY_2);
|
||||
testFaultyDecoding(TEST_ARRAY_3_ENCODED_NON_ESCAPED, TEST_ARRAY_3);
|
||||
testFaultyDecoding(TEST_ARRAY_4_ENCODED_NON_ESCAPED, TEST_ARRAY_4);
|
||||
|
||||
testFaultyEncoding(TEST_ARRAY_0, TEST_ARRAY_0_ENCODED_ESCAPED);
|
||||
testFaultyEncoding(TEST_ARRAY_1, TEST_ARRAY_1_ENCODED_ESCAPED);
|
||||
testFaultyEncoding(TEST_ARRAY_2, TEST_ARRAY_2_ENCODED_ESCAPED);
|
||||
testFaultyEncoding(TEST_ARRAY_3, TEST_ARRAY_3_ENCODED_ESCAPED);
|
||||
testFaultyEncoding(TEST_ARRAY_4, TEST_ARRAY_4_ENCODED_ESCAPED);
|
||||
// Faulty source data
|
||||
testArray1EncodedFaulty = TEST_ARRAY_1_ENCODED_NON_ESCAPED;
|
||||
auto prevVal = testArray1EncodedFaulty[0];
|
||||
testArray1EncodedFaulty[0] = 0;
|
||||
result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
testArray1EncodedFaulty[0] = prevVal;
|
||||
testArray1EncodedFaulty[1] = 0;
|
||||
result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
|
||||
dleEncoder.setEscapeMode(false);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_0, TEST_ARRAY_0_ENCODED_NON_ESCAPED);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_1, TEST_ARRAY_1_ENCODED_NON_ESCAPED);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_2, TEST_ARRAY_2_ENCODED_NON_ESCAPED);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_3, TEST_ARRAY_3_ENCODED_NON_ESCAPED);
|
||||
testLambdaEncode(dleEncoder, TEST_ARRAY_4, TEST_ARRAY_4_ENCODED_NON_ESCAPED);
|
||||
testArray1EncodedFaulty = TEST_ARRAY_1_ENCODED_NON_ESCAPED;
|
||||
testArray1EncodedFaulty[6] = 0;
|
||||
result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
testArray1EncodedFaulty = TEST_ARRAY_1_ENCODED_NON_ESCAPED;
|
||||
testArray1EncodedFaulty[7] = 0;
|
||||
result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
testArray4EncodedFaulty = TEST_ARRAY_4_ENCODED_NON_ESCAPED;
|
||||
testArray4EncodedFaulty[3] = 0;
|
||||
result = dleEncoder.decode(testArray4EncodedFaulty.data(), testArray4EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
|
||||
testFaultyEncoding(TEST_ARRAY_0, TEST_ARRAY_0_ENCODED_NON_ESCAPED);
|
||||
testFaultyEncoding(TEST_ARRAY_1, TEST_ARRAY_1_ENCODED_NON_ESCAPED);
|
||||
testFaultyEncoding(TEST_ARRAY_2, TEST_ARRAY_2_ENCODED_NON_ESCAPED);
|
||||
testFaultyEncoding(TEST_ARRAY_3, TEST_ARRAY_3_ENCODED_NON_ESCAPED);
|
||||
testFaultyEncoding(TEST_ARRAY_4, TEST_ARRAY_4_ENCODED_NON_ESCAPED);
|
||||
dleEncoder.setEscapeMode(true);
|
||||
}
|
||||
|
||||
SECTION("Decoding") {
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_0_ENCODED_ESCAPED, TEST_ARRAY_0);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_1_ENCODED_ESCAPED, TEST_ARRAY_1);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_2_ENCODED_ESCAPED, TEST_ARRAY_2);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_3_ENCODED_ESCAPED, TEST_ARRAY_3);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_4_ENCODED_ESCAPED, TEST_ARRAY_4);
|
||||
|
||||
// Faulty source data
|
||||
auto testArray1EncodedFaulty = TEST_ARRAY_1_ENCODED_ESCAPED;
|
||||
testArray1EncodedFaulty[3] = 0;
|
||||
result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
auto testArray2EncodedFaulty = TEST_ARRAY_2_ENCODED_ESCAPED;
|
||||
testArray2EncodedFaulty[5] = 0;
|
||||
result = dleEncoder.decode(testArray2EncodedFaulty.data(), testArray2EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
auto testArray4EncodedFaulty = TEST_ARRAY_4_ENCODED_ESCAPED;
|
||||
testArray4EncodedFaulty[2] = 0;
|
||||
result = dleEncoder.decode(testArray4EncodedFaulty.data(), testArray4EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
auto testArray4EncodedFaulty2 = TEST_ARRAY_4_ENCODED_ESCAPED;
|
||||
testArray4EncodedFaulty2[4] = 0;
|
||||
result = dleEncoder.decode(testArray4EncodedFaulty2.data(), testArray4EncodedFaulty2.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
|
||||
auto testFaultyDecoding = [&](const std::vector<uint8_t>& vecToDecode,
|
||||
const std::vector<uint8_t>& expectedVec) {
|
||||
for(size_t faultyDestSizes = 0;
|
||||
faultyDestSizes < expectedVec.size();
|
||||
faultyDestSizes ++) {
|
||||
result = dleEncoder.decode(vecToDecode.data(),
|
||||
vecToDecode.size(), &readLen,
|
||||
buffer.data(), faultyDestSizes, &decodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::STREAM_TOO_SHORT));
|
||||
}
|
||||
};
|
||||
|
||||
testFaultyDecoding(TEST_ARRAY_0_ENCODED_ESCAPED, TEST_ARRAY_0);
|
||||
testFaultyDecoding(TEST_ARRAY_1_ENCODED_ESCAPED, TEST_ARRAY_1);
|
||||
testFaultyDecoding(TEST_ARRAY_2_ENCODED_ESCAPED, TEST_ARRAY_2);
|
||||
testFaultyDecoding(TEST_ARRAY_3_ENCODED_ESCAPED, TEST_ARRAY_3);
|
||||
testFaultyDecoding(TEST_ARRAY_4_ENCODED_ESCAPED, TEST_ARRAY_4);
|
||||
|
||||
dleEncoder.setEscapeMode(false);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_0_ENCODED_NON_ESCAPED, TEST_ARRAY_0);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_1_ENCODED_NON_ESCAPED, TEST_ARRAY_1);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_2_ENCODED_NON_ESCAPED, TEST_ARRAY_2);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_3_ENCODED_NON_ESCAPED, TEST_ARRAY_3);
|
||||
testLambdaDecode(dleEncoder, TEST_ARRAY_4_ENCODED_NON_ESCAPED, TEST_ARRAY_4);
|
||||
|
||||
testFaultyDecoding(TEST_ARRAY_0_ENCODED_NON_ESCAPED, TEST_ARRAY_0);
|
||||
testFaultyDecoding(TEST_ARRAY_1_ENCODED_NON_ESCAPED, TEST_ARRAY_1);
|
||||
testFaultyDecoding(TEST_ARRAY_2_ENCODED_NON_ESCAPED, TEST_ARRAY_2);
|
||||
testFaultyDecoding(TEST_ARRAY_3_ENCODED_NON_ESCAPED, TEST_ARRAY_3);
|
||||
testFaultyDecoding(TEST_ARRAY_4_ENCODED_NON_ESCAPED, TEST_ARRAY_4);
|
||||
|
||||
// Faulty source data
|
||||
testArray1EncodedFaulty = TEST_ARRAY_1_ENCODED_NON_ESCAPED;
|
||||
auto prevVal = testArray1EncodedFaulty[0];
|
||||
testArray1EncodedFaulty[0] = 0;
|
||||
result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
testArray1EncodedFaulty[0] = prevVal;
|
||||
testArray1EncodedFaulty[1] = 0;
|
||||
result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
|
||||
testArray1EncodedFaulty = TEST_ARRAY_1_ENCODED_NON_ESCAPED;
|
||||
testArray1EncodedFaulty[6] = 0;
|
||||
result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
testArray1EncodedFaulty = TEST_ARRAY_1_ENCODED_NON_ESCAPED;
|
||||
testArray1EncodedFaulty[7] = 0;
|
||||
result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
testArray4EncodedFaulty = TEST_ARRAY_4_ENCODED_NON_ESCAPED;
|
||||
testArray4EncodedFaulty[3] = 0;
|
||||
result = dleEncoder.decode(testArray4EncodedFaulty.data(), testArray4EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
|
||||
dleEncoder.setEscapeMode(true);
|
||||
testArray1EncodedFaulty = TEST_ARRAY_1_ENCODED_ESCAPED;
|
||||
testArray1EncodedFaulty[5] = 0;
|
||||
result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
}
|
||||
dleEncoder.setEscapeMode(true);
|
||||
testArray1EncodedFaulty = TEST_ARRAY_1_ENCODED_ESCAPED;
|
||||
testArray1EncodedFaulty[5] = 0;
|
||||
result = dleEncoder.decode(testArray1EncodedFaulty.data(), testArray1EncodedFaulty.size(),
|
||||
&readLen, buffer.data(), buffer.size(), &encodedLen);
|
||||
REQUIRE(result == static_cast<int>(DleEncoder::DECODING_ERROR));
|
||||
}
|
||||
}
|
||||
|
@ -1,64 +1,65 @@
|
||||
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
TEST_CASE("OpDivider" , "[OpDivider]") {
|
||||
auto opDivider = PeriodicOperationDivider(1);
|
||||
REQUIRE(opDivider.getDivider() == 1);
|
||||
REQUIRE(opDivider.getCounter() == 1);
|
||||
REQUIRE(opDivider.check() == true);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
REQUIRE(opDivider.getCounter() == 1);
|
||||
REQUIRE(opDivider.check() == true);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
||||
|
||||
opDivider.setDivider(0);
|
||||
REQUIRE(opDivider.getCounter() == 1);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
REQUIRE(opDivider.getCounter() == 1);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
TEST_CASE("OpDivider", "[OpDivider]") {
|
||||
auto opDivider = PeriodicOperationDivider(1);
|
||||
REQUIRE(opDivider.getDivider() == 1);
|
||||
REQUIRE(opDivider.getCounter() == 1);
|
||||
REQUIRE(opDivider.check() == true);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
REQUIRE(opDivider.getCounter() == 1);
|
||||
REQUIRE(opDivider.check() == true);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
|
||||
opDivider.setDivider(2);
|
||||
opDivider.resetCounter();
|
||||
REQUIRE(opDivider.getDivider() == 2);
|
||||
REQUIRE(opDivider.getCounter() == 1);
|
||||
REQUIRE(opDivider.check() == false);
|
||||
REQUIRE(opDivider.checkAndIncrement() == false);
|
||||
REQUIRE(opDivider.getCounter() == 2);
|
||||
REQUIRE(opDivider.check() == true);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
REQUIRE(opDivider.getCounter() == 1);
|
||||
REQUIRE(opDivider.check() == false);
|
||||
REQUIRE(opDivider.checkAndIncrement() == false);
|
||||
REQUIRE(opDivider.getCounter() == 2);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
REQUIRE(opDivider.checkAndIncrement() == false);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
REQUIRE(opDivider.checkAndIncrement() == false);
|
||||
opDivider.setDivider(0);
|
||||
REQUIRE(opDivider.getCounter() == 1);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
REQUIRE(opDivider.getCounter() == 1);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
|
||||
opDivider.setDivider(3);
|
||||
opDivider.resetCounter();
|
||||
REQUIRE(opDivider.checkAndIncrement() == false);
|
||||
REQUIRE(opDivider.checkAndIncrement() == false);
|
||||
REQUIRE(opDivider.getCounter() == 3);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
REQUIRE(opDivider.getCounter() == 1);
|
||||
REQUIRE(opDivider.checkAndIncrement() == false);
|
||||
opDivider.setDivider(2);
|
||||
opDivider.resetCounter();
|
||||
REQUIRE(opDivider.getDivider() == 2);
|
||||
REQUIRE(opDivider.getCounter() == 1);
|
||||
REQUIRE(opDivider.check() == false);
|
||||
REQUIRE(opDivider.checkAndIncrement() == false);
|
||||
REQUIRE(opDivider.getCounter() == 2);
|
||||
REQUIRE(opDivider.check() == true);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
REQUIRE(opDivider.getCounter() == 1);
|
||||
REQUIRE(opDivider.check() == false);
|
||||
REQUIRE(opDivider.checkAndIncrement() == false);
|
||||
REQUIRE(opDivider.getCounter() == 2);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
REQUIRE(opDivider.checkAndIncrement() == false);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
REQUIRE(opDivider.checkAndIncrement() == false);
|
||||
|
||||
auto opDividerNonResetting = PeriodicOperationDivider(2, false);
|
||||
REQUIRE(opDividerNonResetting.getCounter() == 1);
|
||||
REQUIRE(opDividerNonResetting.check() == false);
|
||||
REQUIRE(opDividerNonResetting.checkAndIncrement() == false);
|
||||
REQUIRE(opDividerNonResetting.getCounter() == 2);
|
||||
REQUIRE(opDividerNonResetting.check() == true);
|
||||
REQUIRE(opDividerNonResetting.checkAndIncrement() == true);
|
||||
REQUIRE(opDividerNonResetting.getCounter() == 3);
|
||||
REQUIRE(opDividerNonResetting.checkAndIncrement() == true);
|
||||
REQUIRE(opDividerNonResetting.getCounter() == 4);
|
||||
opDividerNonResetting.resetCounter();
|
||||
REQUIRE(opDividerNonResetting.getCounter() == 1);
|
||||
REQUIRE(opDividerNonResetting.check() == false);
|
||||
REQUIRE(opDividerNonResetting.checkAndIncrement() == false);
|
||||
REQUIRE(opDividerNonResetting.getCounter() == 2);
|
||||
opDivider.setDivider(3);
|
||||
opDivider.resetCounter();
|
||||
REQUIRE(opDivider.checkAndIncrement() == false);
|
||||
REQUIRE(opDivider.checkAndIncrement() == false);
|
||||
REQUIRE(opDivider.getCounter() == 3);
|
||||
REQUIRE(opDivider.checkAndIncrement() == true);
|
||||
REQUIRE(opDivider.getCounter() == 1);
|
||||
REQUIRE(opDivider.checkAndIncrement() == false);
|
||||
|
||||
auto opDividerNonResetting = PeriodicOperationDivider(2, false);
|
||||
REQUIRE(opDividerNonResetting.getCounter() == 1);
|
||||
REQUIRE(opDividerNonResetting.check() == false);
|
||||
REQUIRE(opDividerNonResetting.checkAndIncrement() == false);
|
||||
REQUIRE(opDividerNonResetting.getCounter() == 2);
|
||||
REQUIRE(opDividerNonResetting.check() == true);
|
||||
REQUIRE(opDividerNonResetting.checkAndIncrement() == true);
|
||||
REQUIRE(opDividerNonResetting.getCounter() == 3);
|
||||
REQUIRE(opDividerNonResetting.checkAndIncrement() == true);
|
||||
REQUIRE(opDividerNonResetting.getCounter() == 4);
|
||||
opDividerNonResetting.resetCounter();
|
||||
REQUIRE(opDividerNonResetting.getCounter() == 1);
|
||||
REQUIRE(opDividerNonResetting.check() == false);
|
||||
REQUIRE(opDividerNonResetting.checkAndIncrement() == false);
|
||||
REQUIRE(opDividerNonResetting.getCounter() == 2);
|
||||
}
|
||||
|
@ -1,112 +1,111 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
#include "fsfw/container/SimpleRingBuffer.h"
|
||||
#include "fsfw/container/DynamicFIFO.h"
|
||||
|
||||
#include "fsfw_hal/linux/CommandExecutor.h"
|
||||
#include "fsfw/platform.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <fstream>
|
||||
|
||||
#include "fsfw/container/DynamicFIFO.h"
|
||||
#include "fsfw/container/SimpleRingBuffer.h"
|
||||
#include "fsfw/platform.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
#include "fsfw_hal/linux/CommandExecutor.h"
|
||||
|
||||
#ifdef PLATFORM_UNIX
|
||||
|
||||
static const char TEST_FILE_NAME[] = "/tmp/fsfw-unittest-test.txt";
|
||||
|
||||
TEST_CASE( "Command Executor" , "[cmd-exec]") {
|
||||
// Check blocking mode first
|
||||
CommandExecutor cmdExecutor(1024);
|
||||
std::string cmd = "echo \"test\" >> " + std::string(TEST_FILE_NAME);
|
||||
REQUIRE(cmdExecutor.getCurrentState() == CommandExecutor::States::IDLE);
|
||||
ReturnValue_t result = cmdExecutor.load(cmd, true, true);
|
||||
REQUIRE(cmdExecutor.getCurrentState() == CommandExecutor::States::COMMAND_LOADED);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(cmdExecutor.execute() == HasReturnvaluesIF::RETURN_OK);
|
||||
// Check that file exists with contents
|
||||
std::ifstream file(TEST_FILE_NAME);
|
||||
std::string line;
|
||||
std::getline(file, line);
|
||||
CHECK(line == "test");
|
||||
std::remove(TEST_FILE_NAME);
|
||||
REQUIRE(cmdExecutor.getCurrentState() == CommandExecutor::States::IDLE);
|
||||
TEST_CASE("Command Executor", "[cmd-exec]") {
|
||||
// Check blocking mode first
|
||||
CommandExecutor cmdExecutor(1024);
|
||||
std::string cmd = "echo \"test\" >> " + std::string(TEST_FILE_NAME);
|
||||
REQUIRE(cmdExecutor.getCurrentState() == CommandExecutor::States::IDLE);
|
||||
ReturnValue_t result = cmdExecutor.load(cmd, true, true);
|
||||
REQUIRE(cmdExecutor.getCurrentState() == CommandExecutor::States::COMMAND_LOADED);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(cmdExecutor.execute() == HasReturnvaluesIF::RETURN_OK);
|
||||
// Check that file exists with contents
|
||||
std::ifstream file(TEST_FILE_NAME);
|
||||
std::string line;
|
||||
std::getline(file, line);
|
||||
CHECK(line == "test");
|
||||
std::remove(TEST_FILE_NAME);
|
||||
REQUIRE(cmdExecutor.getCurrentState() == CommandExecutor::States::IDLE);
|
||||
|
||||
// Now check non-blocking mode
|
||||
SimpleRingBuffer outputBuffer(524, true);
|
||||
DynamicFIFO<uint16_t> sizesFifo(12);
|
||||
cmdExecutor.setRingBuffer(&outputBuffer, &sizesFifo);
|
||||
// Now check non-blocking mode
|
||||
SimpleRingBuffer outputBuffer(524, true);
|
||||
DynamicFIFO<uint16_t> sizesFifo(12);
|
||||
cmdExecutor.setRingBuffer(&outputBuffer, &sizesFifo);
|
||||
|
||||
result = cmdExecutor.load("echo \"Hello World\"", false, false);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
cmdExecutor.execute();
|
||||
bool bytesHaveBeenRead = false;
|
||||
size_t limitIdx = 0;
|
||||
while(result != CommandExecutor::EXECUTION_FINISHED) {
|
||||
limitIdx++;
|
||||
result = cmdExecutor.check(bytesHaveBeenRead);
|
||||
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
||||
usleep(500);
|
||||
REQUIRE(limitIdx < 5);
|
||||
}
|
||||
result = cmdExecutor.load("echo \"Hello World\"", false, false);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
cmdExecutor.execute();
|
||||
bool bytesHaveBeenRead = false;
|
||||
size_t limitIdx = 0;
|
||||
while (result != CommandExecutor::EXECUTION_FINISHED) {
|
||||
limitIdx++;
|
||||
result = cmdExecutor.check(bytesHaveBeenRead);
|
||||
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
||||
usleep(500);
|
||||
REQUIRE(limitIdx < 5);
|
||||
}
|
||||
|
||||
limitIdx = 0;
|
||||
CHECK(bytesHaveBeenRead == true);
|
||||
CHECK(result == CommandExecutor::EXECUTION_FINISHED);
|
||||
uint16_t readBytes = 0;
|
||||
sizesFifo.retrieve(&readBytes);
|
||||
REQUIRE(readBytes == 12);
|
||||
REQUIRE(outputBuffer.getAvailableReadData() == 12);
|
||||
uint8_t readBuffer[32] = {};
|
||||
REQUIRE(outputBuffer.readData(readBuffer, 12) == HasReturnvaluesIF::RETURN_OK);
|
||||
std::string readString(reinterpret_cast<char*>(readBuffer));
|
||||
std::string cmpString = "Hello World\n";
|
||||
CHECK(readString == cmpString);
|
||||
outputBuffer.deleteData(12, true);
|
||||
// Test more complex command
|
||||
result = cmdExecutor.load("ping -c 1 localhost", false, false);
|
||||
REQUIRE(cmdExecutor.getCurrentState() == CommandExecutor::States::COMMAND_LOADED);
|
||||
REQUIRE(cmdExecutor.execute() == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING);
|
||||
limitIdx = 0;
|
||||
while(result != CommandExecutor::EXECUTION_FINISHED) {
|
||||
limitIdx++;
|
||||
result = cmdExecutor.check(bytesHaveBeenRead);
|
||||
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
||||
usleep(500);
|
||||
REQUIRE(limitIdx < 20);
|
||||
}
|
||||
limitIdx = 0;
|
||||
CHECK(bytesHaveBeenRead == true);
|
||||
CHECK(result == CommandExecutor::EXECUTION_FINISHED);
|
||||
REQUIRE(cmdExecutor.getCurrentState() == CommandExecutor::States::IDLE);
|
||||
readBytes = 0;
|
||||
sizesFifo.retrieve(&readBytes);
|
||||
// That's about the size of the reply
|
||||
bool beTrue = (readBytes > 200) and (readBytes < 300);
|
||||
REQUIRE(beTrue);
|
||||
uint8_t largerReadBuffer[1024] = {};
|
||||
outputBuffer.readData(largerReadBuffer, readBytes);
|
||||
// You can also check this output in the debugger
|
||||
std::string allTheReply(reinterpret_cast<char*>(largerReadBuffer));
|
||||
// I am just going to assume that this string is the same across ping implementations
|
||||
// of different Linux systems
|
||||
REQUIRE(allTheReply.find("localhost ping statistics") != std::string::npos);
|
||||
limitIdx = 0;
|
||||
CHECK(bytesHaveBeenRead == true);
|
||||
CHECK(result == CommandExecutor::EXECUTION_FINISHED);
|
||||
uint16_t readBytes = 0;
|
||||
sizesFifo.retrieve(&readBytes);
|
||||
REQUIRE(readBytes == 12);
|
||||
REQUIRE(outputBuffer.getAvailableReadData() == 12);
|
||||
uint8_t readBuffer[32] = {};
|
||||
REQUIRE(outputBuffer.readData(readBuffer, 12) == HasReturnvaluesIF::RETURN_OK);
|
||||
std::string readString(reinterpret_cast<char*>(readBuffer));
|
||||
std::string cmpString = "Hello World\n";
|
||||
CHECK(readString == cmpString);
|
||||
outputBuffer.deleteData(12, true);
|
||||
// Test more complex command
|
||||
result = cmdExecutor.load("ping -c 1 localhost", false, false);
|
||||
REQUIRE(cmdExecutor.getCurrentState() == CommandExecutor::States::COMMAND_LOADED);
|
||||
REQUIRE(cmdExecutor.execute() == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(cmdExecutor.getCurrentState() == CommandExecutor::States::PENDING);
|
||||
limitIdx = 0;
|
||||
while (result != CommandExecutor::EXECUTION_FINISHED) {
|
||||
limitIdx++;
|
||||
result = cmdExecutor.check(bytesHaveBeenRead);
|
||||
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
||||
usleep(500);
|
||||
REQUIRE(limitIdx < 20);
|
||||
}
|
||||
limitIdx = 0;
|
||||
CHECK(bytesHaveBeenRead == true);
|
||||
CHECK(result == CommandExecutor::EXECUTION_FINISHED);
|
||||
REQUIRE(cmdExecutor.getCurrentState() == CommandExecutor::States::IDLE);
|
||||
readBytes = 0;
|
||||
sizesFifo.retrieve(&readBytes);
|
||||
// That's about the size of the reply
|
||||
bool beTrue = (readBytes > 200) and (readBytes < 300);
|
||||
REQUIRE(beTrue);
|
||||
uint8_t largerReadBuffer[1024] = {};
|
||||
outputBuffer.readData(largerReadBuffer, readBytes);
|
||||
// You can also check this output in the debugger
|
||||
std::string allTheReply(reinterpret_cast<char*>(largerReadBuffer));
|
||||
// I am just going to assume that this string is the same across ping implementations
|
||||
// of different Linux systems
|
||||
REQUIRE(allTheReply.find("localhost ping statistics") != std::string::npos);
|
||||
|
||||
// Now check failing command
|
||||
result = cmdExecutor.load("false", false, false);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
result = cmdExecutor.execute();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
while(result != CommandExecutor::EXECUTION_FINISHED and result != HasReturnvaluesIF::RETURN_FAILED) {
|
||||
limitIdx++;
|
||||
result = cmdExecutor.check(bytesHaveBeenRead);
|
||||
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
||||
usleep(500);
|
||||
REQUIRE(limitIdx < 20);
|
||||
}
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED);
|
||||
REQUIRE(cmdExecutor.getLastError() == 1);
|
||||
// Now check failing command
|
||||
result = cmdExecutor.load("false", false, false);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
result = cmdExecutor.execute();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
while (result != CommandExecutor::EXECUTION_FINISHED and
|
||||
result != HasReturnvaluesIF::RETURN_FAILED) {
|
||||
limitIdx++;
|
||||
result = cmdExecutor.check(bytesHaveBeenRead);
|
||||
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
||||
usleep(500);
|
||||
REQUIRE(limitIdx < 20);
|
||||
}
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED);
|
||||
REQUIRE(cmdExecutor.getLastError() == 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -4,17 +4,11 @@
|
||||
#include <fsfw/housekeeping/AcceptsHkPacketsIF.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
|
||||
class HkReceiverMock: public SystemObject, public AcceptsHkPacketsIF {
|
||||
public:
|
||||
HkReceiverMock(object_id_t objectId): SystemObject(objectId) {
|
||||
class HkReceiverMock : public SystemObject, public AcceptsHkPacketsIF {
|
||||
public:
|
||||
HkReceiverMock(object_id_t objectId) : SystemObject(objectId) {}
|
||||
|
||||
}
|
||||
|
||||
MessageQueueId_t getHkQueue() const {
|
||||
return MessageQueueIF::NO_QUEUE;
|
||||
}
|
||||
MessageQueueId_t getHkQueue() const { return MessageQueueIF::NO_QUEUE; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* FSFW_UNITTEST_TESTS_MOCKS_HKRECEIVERMOCK_H_ */
|
||||
|
@ -1,123 +1,105 @@
|
||||
#ifndef FSFW_UNITTEST_TESTS_MOCKS_MESSAGEQUEUEMOCKBASE_H_
|
||||
#define FSFW_UNITTEST_TESTS_MOCKS_MESSAGEQUEUEMOCKBASE_H_
|
||||
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
#include <cstring>
|
||||
#include <queue>
|
||||
|
||||
#include "fsfw/ipc/CommandMessage.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/ipc/MessageQueueMessage.h"
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <cstring>
|
||||
class MessageQueueMockBase : public MessageQueueIF {
|
||||
public:
|
||||
MessageQueueId_t myQueueId = tconst::testQueueId;
|
||||
uint8_t messageSentCounter = 0;
|
||||
bool defaultDestSet = false;
|
||||
bool messageSent = false;
|
||||
|
||||
#include <queue>
|
||||
bool wasMessageSent(uint8_t* messageSentCounter = nullptr, bool resetCounter = true) {
|
||||
bool tempMessageSent = messageSent;
|
||||
messageSent = false;
|
||||
if (messageSentCounter != nullptr) {
|
||||
*messageSentCounter = this->messageSentCounter;
|
||||
}
|
||||
if (resetCounter) {
|
||||
this->messageSentCounter = 0;
|
||||
}
|
||||
return tempMessageSent;
|
||||
}
|
||||
|
||||
class MessageQueueMockBase: public MessageQueueIF {
|
||||
public:
|
||||
MessageQueueId_t myQueueId = tconst::testQueueId;
|
||||
uint8_t messageSentCounter = 0;
|
||||
bool defaultDestSet = false;
|
||||
bool messageSent = false;
|
||||
/**
|
||||
* Pop a message, clearing it in the process.
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t popMessage() {
|
||||
CommandMessage message;
|
||||
message.clear();
|
||||
return receiveMessage(&message);
|
||||
}
|
||||
|
||||
virtual ReturnValue_t reply(MessageQueueMessageIF* message) {
|
||||
return sendMessage(myQueueId, message);
|
||||
};
|
||||
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
|
||||
MessageQueueId_t* receivedFrom) {
|
||||
return receiveMessage(message);
|
||||
}
|
||||
|
||||
bool wasMessageSent(uint8_t* messageSentCounter = nullptr,
|
||||
bool resetCounter = true) {
|
||||
bool tempMessageSent = messageSent;
|
||||
messageSent = false;
|
||||
if(messageSentCounter != nullptr) {
|
||||
*messageSentCounter = this->messageSentCounter;
|
||||
}
|
||||
if(resetCounter) {
|
||||
this->messageSentCounter = 0;
|
||||
}
|
||||
return tempMessageSent;
|
||||
}
|
||||
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message) {
|
||||
if (messagesSentQueue.empty()) {
|
||||
return MessageQueueIF::EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop a message, clearing it in the process.
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t popMessage() {
|
||||
CommandMessage message;
|
||||
message.clear();
|
||||
return receiveMessage(&message);
|
||||
}
|
||||
std::memcpy(message->getBuffer(), messagesSentQueue.front().getBuffer(),
|
||||
message->getMessageSize());
|
||||
messagesSentQueue.pop();
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
virtual ReturnValue_t flush(uint32_t* count) { return HasReturnvaluesIF::RETURN_OK; }
|
||||
virtual MessageQueueId_t getLastPartner() const { return myQueueId; }
|
||||
virtual MessageQueueId_t getId() const { return myQueueId; }
|
||||
virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
MessageQueueId_t sentFrom, bool ignoreFault = false) {
|
||||
return sendMessage(sendTo, message);
|
||||
}
|
||||
virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
|
||||
bool ignoreFault = false) {
|
||||
return sendMessage(myQueueId, message);
|
||||
}
|
||||
virtual ReturnValue_t sendToDefault(MessageQueueMessageIF* message) {
|
||||
return sendMessage(myQueueId, message);
|
||||
}
|
||||
virtual ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
bool ignoreFault = false) override {
|
||||
messageSent = true;
|
||||
messageSentCounter++;
|
||||
MessageQueueMessage& messageRef = *(dynamic_cast<MessageQueueMessage*>(message));
|
||||
messagesSentQueue.push(messageRef);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
virtual void setDefaultDestination(MessageQueueId_t defaultDestination) {
|
||||
myQueueId = defaultDestination;
|
||||
defaultDestSet = true;
|
||||
}
|
||||
|
||||
virtual ReturnValue_t reply( MessageQueueMessageIF* message ) {
|
||||
return sendMessage(myQueueId, message);
|
||||
};
|
||||
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
|
||||
MessageQueueId_t *receivedFrom) {
|
||||
return receiveMessage(message);
|
||||
}
|
||||
virtual MessageQueueId_t getDefaultDestination() const { return myQueueId; }
|
||||
virtual bool isDefaultDestinationSet() const { return defaultDestSet; }
|
||||
|
||||
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message) {
|
||||
if(messagesSentQueue.empty()) {
|
||||
return MessageQueueIF::EMPTY;
|
||||
}
|
||||
void clearMessages(bool clearCommandMessages = true) {
|
||||
while (not messagesSentQueue.empty()) {
|
||||
if (clearCommandMessages) {
|
||||
CommandMessage message;
|
||||
std::memcpy(message.getBuffer(), messagesSentQueue.front().getBuffer(),
|
||||
message.getMessageSize());
|
||||
message.clear();
|
||||
}
|
||||
messagesSentQueue.pop();
|
||||
}
|
||||
}
|
||||
|
||||
std::memcpy(message->getBuffer(), messagesSentQueue.front().getBuffer(),
|
||||
message->getMessageSize());
|
||||
messagesSentQueue.pop();
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
virtual ReturnValue_t flush(uint32_t* count) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
virtual MessageQueueId_t getLastPartner() const {
|
||||
return myQueueId;
|
||||
}
|
||||
virtual MessageQueueId_t getId() const {
|
||||
return myQueueId;
|
||||
}
|
||||
virtual ReturnValue_t sendMessageFrom( MessageQueueId_t sendTo,
|
||||
MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
|
||||
bool ignoreFault = false ) {
|
||||
return sendMessage(sendTo, message);
|
||||
}
|
||||
virtual ReturnValue_t sendToDefaultFrom( MessageQueueMessageIF* message,
|
||||
MessageQueueId_t sentFrom, bool ignoreFault = false ) {
|
||||
return sendMessage(myQueueId, message);
|
||||
}
|
||||
virtual ReturnValue_t sendToDefault( MessageQueueMessageIF* message ) {
|
||||
return sendMessage(myQueueId, message);
|
||||
}
|
||||
virtual ReturnValue_t sendMessage( MessageQueueId_t sendTo,
|
||||
MessageQueueMessageIF* message, bool ignoreFault = false ) override {
|
||||
messageSent = true;
|
||||
messageSentCounter++;
|
||||
MessageQueueMessage& messageRef = *(
|
||||
dynamic_cast<MessageQueueMessage*>(message));
|
||||
messagesSentQueue.push(messageRef);
|
||||
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;
|
||||
}
|
||||
|
||||
void clearMessages(bool clearCommandMessages = true) {
|
||||
while(not messagesSentQueue.empty()) {
|
||||
if(clearCommandMessages) {
|
||||
CommandMessage message;
|
||||
std::memcpy(message.getBuffer(),
|
||||
messagesSentQueue.front().getBuffer(),
|
||||
message.getMessageSize());
|
||||
message.clear();
|
||||
}
|
||||
messagesSentQueue.pop();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::queue<MessageQueueMessage> messagesSentQueue;
|
||||
private:
|
||||
std::queue<MessageQueueMessage> messagesSentQueue;
|
||||
};
|
||||
|
||||
|
||||
#endif /* FSFW_UNITTEST_TESTS_MOCKS_MESSAGEQUEUEMOCKBASE_H_ */
|
||||
|
@ -1,43 +1,38 @@
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <fsfw/ipc/MessageQueueIF.h>
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include <array>
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
TEST_CASE("MessageQueue Basic Test","[TestMq]") {
|
||||
MessageQueueIF* testSenderMq =
|
||||
QueueFactory::instance()->createMessageQueue(1);
|
||||
MessageQueueId_t testSenderMqId = testSenderMq->getId();
|
||||
TEST_CASE("MessageQueue Basic Test", "[TestMq]") {
|
||||
MessageQueueIF* testSenderMq = QueueFactory::instance()->createMessageQueue(1);
|
||||
MessageQueueId_t testSenderMqId = testSenderMq->getId();
|
||||
|
||||
MessageQueueIF* testReceiverMq =
|
||||
QueueFactory::instance()->createMessageQueue(1);
|
||||
MessageQueueId_t testReceiverMqId = testReceiverMq->getId();
|
||||
std::array<uint8_t, 20> testData { 0 };
|
||||
testData[0] = 42;
|
||||
MessageQueueMessage testMessage(testData.data(), 1);
|
||||
testSenderMq->setDefaultDestination(testReceiverMqId);
|
||||
|
||||
SECTION("Simple Tests") {
|
||||
auto result = testSenderMq->sendMessage(testReceiverMqId, &testMessage);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
MessageQueueMessage recvMessage;
|
||||
result = testReceiverMq->receiveMessage(&recvMessage);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(recvMessage.getData()[0] == 42);
|
||||
|
||||
result = testSenderMq->sendMessage(testReceiverMqId, &testMessage);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
MessageQueueId_t senderId = 0;
|
||||
result = testReceiverMq->receiveMessage(&recvMessage,&senderId);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(recvMessage.getData()[0] == 42);
|
||||
CHECK(senderId == testSenderMqId);
|
||||
senderId = testReceiverMq->getLastPartner();
|
||||
CHECK(senderId == testSenderMqId);
|
||||
}
|
||||
MessageQueueIF* testReceiverMq = QueueFactory::instance()->createMessageQueue(1);
|
||||
MessageQueueId_t testReceiverMqId = testReceiverMq->getId();
|
||||
std::array<uint8_t, 20> testData{0};
|
||||
testData[0] = 42;
|
||||
MessageQueueMessage testMessage(testData.data(), 1);
|
||||
testSenderMq->setDefaultDestination(testReceiverMqId);
|
||||
|
||||
SECTION("Simple Tests") {
|
||||
auto result = testSenderMq->sendMessage(testReceiverMqId, &testMessage);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
MessageQueueMessage recvMessage;
|
||||
result = testReceiverMq->receiveMessage(&recvMessage);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(recvMessage.getData()[0] == 42);
|
||||
|
||||
result = testSenderMq->sendMessage(testReceiverMqId, &testMessage);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
MessageQueueId_t senderId = 0;
|
||||
result = testReceiverMq->receiveMessage(&recvMessage, &senderId);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(recvMessage.getData()[0] == 42);
|
||||
CHECK(senderId == testSenderMqId);
|
||||
senderId = testReceiverMq->getLastPartner();
|
||||
CHECK(senderId == testSenderMqId);
|
||||
}
|
||||
}
|
||||
|
@ -2,44 +2,44 @@
|
||||
#ifdef LINUX
|
||||
|
||||
/*
|
||||
#include "core/CatchDefinitions.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <fsfw/tasks/SemaphoreFactory.h>
|
||||
#include <fsfw/timemanager/Stopwatch.h>
|
||||
|
||||
#include "catch.hpp"
|
||||
#include "core/CatchDefinitions.h"
|
||||
|
||||
TEST_CASE("Binary Semaphore Test" , "[BinSemaphore]") {
|
||||
//perform set-up here
|
||||
SemaphoreIF* binSemaph = SemaphoreFactory::instance()->
|
||||
createBinarySemaphore();
|
||||
REQUIRE(binSemaph != nullptr);
|
||||
SECTION("Simple Test") {
|
||||
// set-up is run for each section
|
||||
REQUIRE(binSemaph->getSemaphoreCounter() == 1);
|
||||
REQUIRE(binSemaph->release() ==
|
||||
static_cast<int>(SemaphoreIF::SEMAPHORE_NOT_OWNED));
|
||||
REQUIRE(binSemaph->acquire(SemaphoreIF::POLLING) ==
|
||||
retval::CATCH_OK);
|
||||
{
|
||||
// not precise enough on linux.. should use clock instead..
|
||||
//Stopwatch stopwatch(false);
|
||||
//REQUIRE(binSemaph->acquire(SemaphoreIF::TimeoutType::WAITING, 5) ==
|
||||
// SemaphoreIF::SEMAPHORE_TIMEOUT);
|
||||
//dur_millis_t time = stopwatch.stop();
|
||||
//CHECK(time == 5);
|
||||
}
|
||||
REQUIRE(binSemaph->getSemaphoreCounter() == 0);
|
||||
REQUIRE(binSemaph->release() == retval::CATCH_OK);
|
||||
}
|
||||
SemaphoreFactory::instance()->deleteSemaphore(binSemaph);
|
||||
// perform tear-down here
|
||||
//perform set-up here
|
||||
SemaphoreIF* binSemaph = SemaphoreFactory::instance()->
|
||||
createBinarySemaphore();
|
||||
REQUIRE(binSemaph != nullptr);
|
||||
SECTION("Simple Test") {
|
||||
// set-up is run for each section
|
||||
REQUIRE(binSemaph->getSemaphoreCounter() == 1);
|
||||
REQUIRE(binSemaph->release() ==
|
||||
static_cast<int>(SemaphoreIF::SEMAPHORE_NOT_OWNED));
|
||||
REQUIRE(binSemaph->acquire(SemaphoreIF::POLLING) ==
|
||||
retval::CATCH_OK);
|
||||
{
|
||||
// not precise enough on linux.. should use clock instead..
|
||||
//Stopwatch stopwatch(false);
|
||||
//REQUIRE(binSemaph->acquire(SemaphoreIF::TimeoutType::WAITING, 5) ==
|
||||
// SemaphoreIF::SEMAPHORE_TIMEOUT);
|
||||
//dur_millis_t time = stopwatch.stop();
|
||||
//CHECK(time == 5);
|
||||
}
|
||||
REQUIRE(binSemaph->getSemaphoreCounter() == 0);
|
||||
REQUIRE(binSemaph->release() == retval::CATCH_OK);
|
||||
}
|
||||
SemaphoreFactory::instance()->deleteSemaphore(binSemaph);
|
||||
// perform tear-down here
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Counting Semaphore Test" , "[CountingSemaph]") {
|
||||
SECTION("Simple Test") {
|
||||
SECTION("Simple Test") {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
#include "printChar.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
void printChar(const char* character, bool errStream) {
|
||||
if(errStream) {
|
||||
std::putc(*character, stderr);
|
||||
return;
|
||||
}
|
||||
std::putc(*character, stdout);
|
||||
if (errStream) {
|
||||
std::putc(*character, stderr);
|
||||
return;
|
||||
}
|
||||
std::putc(*character, stdout);
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
#ifndef FSFW_UNITTEST_CORE_PRINTCHAR_H_
|
||||
#define FSFW_UNITTEST_CORE_PRINTCHAR_H_
|
||||
|
||||
|
||||
extern "C" void printChar(const char*, bool errStream);
|
||||
|
||||
|
||||
#endif /* FSFW_UNITTEST_CORE_PRINTCHAR_H_ */
|
||||
|
@ -1,147 +1,134 @@
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <fsfw/serialize/SerialBufferAdapter.h>
|
||||
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
static bool test_value_bool = true;
|
||||
static uint16_t tv_uint16 {283};
|
||||
static uint16_t tv_uint16{283};
|
||||
static std::array<uint8_t, 512> testArray;
|
||||
|
||||
TEST_CASE("Serial Buffer Adapter", "[single-file]") {
|
||||
size_t serialized_size = 0;
|
||||
test_value_bool = true;
|
||||
uint8_t * arrayPtr = testArray.data();
|
||||
std::array<uint8_t, 5> test_serial_buffer {5, 4, 3, 2, 1};
|
||||
SerialBufferAdapter<uint8_t> tv_serial_buffer_adapter =
|
||||
SerialBufferAdapter<uint8_t>(test_serial_buffer.data(),
|
||||
test_serial_buffer.size(), false);
|
||||
tv_uint16 = 16;
|
||||
size_t serialized_size = 0;
|
||||
test_value_bool = true;
|
||||
uint8_t* arrayPtr = testArray.data();
|
||||
std::array<uint8_t, 5> test_serial_buffer{5, 4, 3, 2, 1};
|
||||
SerialBufferAdapter<uint8_t> tv_serial_buffer_adapter =
|
||||
SerialBufferAdapter<uint8_t>(test_serial_buffer.data(), test_serial_buffer.size(), false);
|
||||
tv_uint16 = 16;
|
||||
|
||||
SECTION("Serialize without size field") {
|
||||
SerializeAdapter::serialize(&test_value_bool, &arrayPtr,
|
||||
&serialized_size, testArray.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv_serial_buffer_adapter, &arrayPtr,
|
||||
&serialized_size, testArray.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv_uint16, &arrayPtr, &serialized_size,
|
||||
testArray.size(), SerializeIF::Endianness::MACHINE);
|
||||
SECTION("Serialize without size field") {
|
||||
SerializeAdapter::serialize(&test_value_bool, &arrayPtr, &serialized_size, testArray.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv_serial_buffer_adapter, &arrayPtr, &serialized_size,
|
||||
testArray.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv_uint16, &arrayPtr, &serialized_size, testArray.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
|
||||
REQUIRE(serialized_size == 8);
|
||||
REQUIRE(testArray[0] == true);
|
||||
REQUIRE(testArray[1] == 5);
|
||||
REQUIRE(testArray[2] == 4);
|
||||
REQUIRE(testArray[3] == 3);
|
||||
REQUIRE(testArray[4] == 2);
|
||||
REQUIRE(testArray[5] == 1);
|
||||
memcpy(&tv_uint16, testArray.data() + 6, sizeof(tv_uint16));
|
||||
REQUIRE(tv_uint16 == 16);
|
||||
}
|
||||
REQUIRE(serialized_size == 8);
|
||||
REQUIRE(testArray[0] == true);
|
||||
REQUIRE(testArray[1] == 5);
|
||||
REQUIRE(testArray[2] == 4);
|
||||
REQUIRE(testArray[3] == 3);
|
||||
REQUIRE(testArray[4] == 2);
|
||||
REQUIRE(testArray[5] == 1);
|
||||
memcpy(&tv_uint16, testArray.data() + 6, sizeof(tv_uint16));
|
||||
REQUIRE(tv_uint16 == 16);
|
||||
}
|
||||
|
||||
SECTION("Serialize with size field") {
|
||||
SerialBufferAdapter<uint8_t> tv_serial_buffer_adapter_loc =
|
||||
SerialBufferAdapter<uint8_t>(test_serial_buffer.data(),
|
||||
test_serial_buffer.size(), true);
|
||||
serialized_size = 0;
|
||||
arrayPtr = testArray.data();
|
||||
SerializeAdapter::serialize(&test_value_bool, &arrayPtr,&serialized_size,
|
||||
testArray.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv_serial_buffer_adapter_loc, &arrayPtr,
|
||||
&serialized_size, testArray.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv_uint16, &arrayPtr, &serialized_size,
|
||||
testArray.size(), SerializeIF::Endianness::MACHINE);
|
||||
SECTION("Serialize with size field") {
|
||||
SerialBufferAdapter<uint8_t> tv_serial_buffer_adapter_loc =
|
||||
SerialBufferAdapter<uint8_t>(test_serial_buffer.data(), test_serial_buffer.size(), true);
|
||||
serialized_size = 0;
|
||||
arrayPtr = testArray.data();
|
||||
SerializeAdapter::serialize(&test_value_bool, &arrayPtr, &serialized_size, testArray.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv_serial_buffer_adapter_loc, &arrayPtr, &serialized_size,
|
||||
testArray.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv_uint16, &arrayPtr, &serialized_size, testArray.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
|
||||
REQUIRE(serialized_size == 9);
|
||||
REQUIRE(testArray[0] == true);
|
||||
REQUIRE(testArray[1] == 5);
|
||||
REQUIRE(testArray[2] == 5);
|
||||
REQUIRE(testArray[3] == 4);
|
||||
REQUIRE(testArray[4] == 3);
|
||||
REQUIRE(testArray[5] == 2);
|
||||
REQUIRE(testArray[6] == 1);
|
||||
memcpy(&tv_uint16, testArray.data() + 7, sizeof(tv_uint16));
|
||||
REQUIRE(tv_uint16 == 16);
|
||||
}
|
||||
REQUIRE(serialized_size == 9);
|
||||
REQUIRE(testArray[0] == true);
|
||||
REQUIRE(testArray[1] == 5);
|
||||
REQUIRE(testArray[2] == 5);
|
||||
REQUIRE(testArray[3] == 4);
|
||||
REQUIRE(testArray[4] == 3);
|
||||
REQUIRE(testArray[5] == 2);
|
||||
REQUIRE(testArray[6] == 1);
|
||||
memcpy(&tv_uint16, testArray.data() + 7, sizeof(tv_uint16));
|
||||
REQUIRE(tv_uint16 == 16);
|
||||
}
|
||||
|
||||
SECTION("Test set buffer function") {
|
||||
SerialBufferAdapter<uint8_t> tv_serial_buffer_adapter_loc =
|
||||
SerialBufferAdapter<uint8_t>((uint8_t*)nullptr,
|
||||
0, true);
|
||||
tv_serial_buffer_adapter_loc.setBuffer(test_serial_buffer.data(),
|
||||
test_serial_buffer.size());
|
||||
serialized_size = 0;
|
||||
arrayPtr = testArray.data();
|
||||
SerializeAdapter::serialize(&test_value_bool, &arrayPtr,&serialized_size,
|
||||
testArray.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv_serial_buffer_adapter_loc, &arrayPtr,
|
||||
&serialized_size, testArray.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv_uint16, &arrayPtr, &serialized_size,
|
||||
testArray.size(), SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(serialized_size == 9);
|
||||
REQUIRE(testArray[0] == true);
|
||||
REQUIRE(testArray[1] == 5);
|
||||
REQUIRE(testArray[2] == 5);
|
||||
REQUIRE(testArray[3] == 4);
|
||||
REQUIRE(testArray[4] == 3);
|
||||
REQUIRE(testArray[5] == 2);
|
||||
REQUIRE(testArray[6] == 1);
|
||||
memcpy(&tv_uint16, testArray.data() + 7, sizeof(tv_uint16));
|
||||
REQUIRE(tv_uint16 == 16);
|
||||
}
|
||||
SECTION("Test set buffer function") {
|
||||
SerialBufferAdapter<uint8_t> tv_serial_buffer_adapter_loc =
|
||||
SerialBufferAdapter<uint8_t>((uint8_t*)nullptr, 0, true);
|
||||
tv_serial_buffer_adapter_loc.setBuffer(test_serial_buffer.data(), test_serial_buffer.size());
|
||||
serialized_size = 0;
|
||||
arrayPtr = testArray.data();
|
||||
SerializeAdapter::serialize(&test_value_bool, &arrayPtr, &serialized_size, testArray.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv_serial_buffer_adapter_loc, &arrayPtr, &serialized_size,
|
||||
testArray.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tv_uint16, &arrayPtr, &serialized_size, testArray.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(serialized_size == 9);
|
||||
REQUIRE(testArray[0] == true);
|
||||
REQUIRE(testArray[1] == 5);
|
||||
REQUIRE(testArray[2] == 5);
|
||||
REQUIRE(testArray[3] == 4);
|
||||
REQUIRE(testArray[4] == 3);
|
||||
REQUIRE(testArray[5] == 2);
|
||||
REQUIRE(testArray[6] == 1);
|
||||
memcpy(&tv_uint16, testArray.data() + 7, sizeof(tv_uint16));
|
||||
REQUIRE(tv_uint16 == 16);
|
||||
}
|
||||
|
||||
SECTION("Deserialization with size field") {
|
||||
size_t buffer_size = 4;
|
||||
memcpy(testArray.data(), &buffer_size, sizeof(uint16_t));
|
||||
testArray[2] = 1;
|
||||
testArray[3] = 1;
|
||||
testArray[4] = 1;
|
||||
testArray[5] = 0;
|
||||
std::array<uint8_t, 4> test_recv_array;
|
||||
arrayPtr = testArray.data();
|
||||
// copy testArray[1] to testArray[4] into receive buffer, skip
|
||||
// size field (testArray[0]) for deSerialization.
|
||||
SerialBufferAdapter<uint16_t> tv_serial_buffer_adapter3 =
|
||||
SerialBufferAdapter<uint16_t>(test_recv_array.data(), 4, true);
|
||||
// Deserialization
|
||||
size_t size = 6;
|
||||
auto result = tv_serial_buffer_adapter3.deSerialize(
|
||||
const_cast<const uint8_t**>(&arrayPtr), &size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(test_recv_array[0] == 1);
|
||||
CHECK(test_recv_array[1] == 1);
|
||||
CHECK(test_recv_array[2] == 1);
|
||||
CHECK(test_recv_array[3] == 0);
|
||||
}
|
||||
SECTION("Deserialization with size field") {
|
||||
size_t buffer_size = 4;
|
||||
memcpy(testArray.data(), &buffer_size, sizeof(uint16_t));
|
||||
testArray[2] = 1;
|
||||
testArray[3] = 1;
|
||||
testArray[4] = 1;
|
||||
testArray[5] = 0;
|
||||
std::array<uint8_t, 4> test_recv_array;
|
||||
arrayPtr = testArray.data();
|
||||
// copy testArray[1] to testArray[4] into receive buffer, skip
|
||||
// size field (testArray[0]) for deSerialization.
|
||||
SerialBufferAdapter<uint16_t> tv_serial_buffer_adapter3 =
|
||||
SerialBufferAdapter<uint16_t>(test_recv_array.data(), 4, true);
|
||||
// Deserialization
|
||||
size_t size = 6;
|
||||
auto result = tv_serial_buffer_adapter3.deSerialize(const_cast<const uint8_t**>(&arrayPtr),
|
||||
&size, SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(test_recv_array[0] == 1);
|
||||
CHECK(test_recv_array[1] == 1);
|
||||
CHECK(test_recv_array[2] == 1);
|
||||
CHECK(test_recv_array[3] == 0);
|
||||
}
|
||||
|
||||
SECTION("Deserialization without size field") {
|
||||
size_t buffer_size = 4;
|
||||
memcpy(testArray.data(), &buffer_size, sizeof(uint16_t));
|
||||
testArray[2] = 1;
|
||||
testArray[3] = 1;
|
||||
testArray[4] = 1;
|
||||
testArray[5] = 0;
|
||||
std::array<uint8_t, 4> test_recv_array;
|
||||
arrayPtr = testArray.data() + 2;
|
||||
// copy testArray[1] to testArray[4] into receive buffer, skip
|
||||
// size field (testArray[0])
|
||||
SerialBufferAdapter<uint16_t> tv_serial_buffer_adapter3 =
|
||||
SerialBufferAdapter<uint16_t>(test_recv_array.data(), 4, false);
|
||||
// Deserialization
|
||||
size_t size = 4;
|
||||
tv_serial_buffer_adapter3.deSerialize(
|
||||
const_cast<const uint8_t**>(&arrayPtr), &size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
CHECK(test_recv_array[0] == 1);
|
||||
CHECK(test_recv_array[1] == 1);
|
||||
CHECK(test_recv_array[2] == 1);
|
||||
CHECK(test_recv_array[3] == 0);
|
||||
}
|
||||
SECTION("Deserialization without size field") {
|
||||
size_t buffer_size = 4;
|
||||
memcpy(testArray.data(), &buffer_size, sizeof(uint16_t));
|
||||
testArray[2] = 1;
|
||||
testArray[3] = 1;
|
||||
testArray[4] = 1;
|
||||
testArray[5] = 0;
|
||||
std::array<uint8_t, 4> test_recv_array;
|
||||
arrayPtr = testArray.data() + 2;
|
||||
// copy testArray[1] to testArray[4] into receive buffer, skip
|
||||
// size field (testArray[0])
|
||||
SerialBufferAdapter<uint16_t> tv_serial_buffer_adapter3 =
|
||||
SerialBufferAdapter<uint16_t>(test_recv_array.data(), 4, false);
|
||||
// Deserialization
|
||||
size_t size = 4;
|
||||
tv_serial_buffer_adapter3.deSerialize(const_cast<const uint8_t**>(&arrayPtr), &size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
CHECK(test_recv_array[0] == 1);
|
||||
CHECK(test_recv_array[1] == 1);
|
||||
CHECK(test_recv_array[2] == 1);
|
||||
CHECK(test_recv_array[3] == 0);
|
||||
}
|
||||
}
|
||||
|
@ -1,76 +1,73 @@
|
||||
#include "TestSerialLinkedPacket.h"
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <fsfw/globalfunctions/arrayprinter.h>
|
||||
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include <array>
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
TEST_CASE("Serial Linked Packet", "[SerLinkPacket]") {
|
||||
// perform set-up here
|
||||
uint32_t header = 42;
|
||||
std::array<uint8_t, 3> testArray{1, 2, 3};
|
||||
uint32_t tail = 96;
|
||||
size_t packetMaxSize = 256;
|
||||
uint8_t packet[packetMaxSize] = {};
|
||||
size_t packetLen = 0;
|
||||
|
||||
TEST_CASE("Serial Linked Packet" , "[SerLinkPacket]") {
|
||||
// perform set-up here
|
||||
uint32_t header = 42;
|
||||
std::array<uint8_t, 3> testArray {1,2,3};
|
||||
uint32_t tail = 96;
|
||||
size_t packetMaxSize = 256;
|
||||
uint8_t packet [packetMaxSize] = {};
|
||||
size_t packetLen = 0;
|
||||
SECTION("Test Deserialization with Serial Buffer Adapter.") {
|
||||
// This is a serialization of a packet, made "manually".
|
||||
// We generate a packet which store data big-endian by swapping some
|
||||
// values. (like coming from ground).
|
||||
header = EndianConverter::convertBigEndian(header);
|
||||
std::memcpy(packet, &header, sizeof(header));
|
||||
packetLen += sizeof(header);
|
||||
|
||||
SECTION("Test Deserialization with Serial Buffer Adapter.") {
|
||||
// This is a serialization of a packet, made "manually".
|
||||
// We generate a packet which store data big-endian by swapping some
|
||||
// values. (like coming from ground).
|
||||
header = EndianConverter::convertBigEndian(header);
|
||||
std::memcpy(packet, &header, sizeof(header));
|
||||
packetLen += sizeof(header);
|
||||
std::copy(testArray.data(), testArray.data() + testArray.size(), packet + packetLen);
|
||||
packetLen += testArray.size();
|
||||
|
||||
std::copy(testArray.data(), testArray.data() + testArray.size(),
|
||||
packet + packetLen);
|
||||
packetLen += testArray.size();
|
||||
tail = EndianConverter::convertBigEndian(tail);
|
||||
std::memcpy(packet + packetLen, &tail, sizeof(tail));
|
||||
packetLen += sizeof(tail);
|
||||
|
||||
tail = EndianConverter::convertBigEndian(tail);
|
||||
std::memcpy(packet + packetLen, &tail, sizeof(tail));
|
||||
packetLen += sizeof(tail);
|
||||
// arrayprinter::print(packet, packetLen, OutputType::DEC);
|
||||
|
||||
//arrayprinter::print(packet, packetLen, OutputType::DEC);
|
||||
// This is the buffer which will be filled when testClass.deSerialize
|
||||
// is called.
|
||||
std::array<uint8_t, 3> bufferAdaptee = {};
|
||||
TestPacket testClass(packet, packetLen, bufferAdaptee.data(), bufferAdaptee.size());
|
||||
const uint8_t* readOnlyPointer = packet;
|
||||
// Deserialize big endian packet by setting bigEndian to true.
|
||||
ReturnValue_t result =
|
||||
testClass.deSerialize(&readOnlyPointer, &packetLen, SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(testClass.getHeader() == 42);
|
||||
// Equivalent check.
|
||||
// CHECK(testClass.getBuffer()[0] == 1);
|
||||
CHECK(bufferAdaptee[0] == 1);
|
||||
CHECK(bufferAdaptee[1] == 2);
|
||||
CHECK(bufferAdaptee[2] == 3);
|
||||
CHECK(testClass.getTail() == 96);
|
||||
}
|
||||
|
||||
// This is the buffer which will be filled when testClass.deSerialize
|
||||
// is called.
|
||||
std::array<uint8_t, 3> bufferAdaptee = {};
|
||||
TestPacket testClass(packet, packetLen, bufferAdaptee.data(),
|
||||
bufferAdaptee.size());
|
||||
const uint8_t* readOnlyPointer = packet;
|
||||
// Deserialize big endian packet by setting bigEndian to true.
|
||||
ReturnValue_t result = testClass.deSerialize(&readOnlyPointer,
|
||||
&packetLen, SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(testClass.getHeader() == 42);
|
||||
// Equivalent check.
|
||||
// CHECK(testClass.getBuffer()[0] == 1);
|
||||
CHECK(bufferAdaptee[0] == 1);
|
||||
CHECK(bufferAdaptee[1] == 2);
|
||||
CHECK(bufferAdaptee[2] == 3);
|
||||
CHECK(testClass.getTail() == 96);
|
||||
}
|
||||
SECTION("Test Serialization") {
|
||||
// Same process as performed in setup, this time using the class
|
||||
// instead of doing it manually.
|
||||
TestPacket testClass(header, tail, testArray.data(), testArray.size());
|
||||
size_t serializedSize = 0;
|
||||
uint8_t* packetPointer = packet;
|
||||
// serialize for ground: bigEndian = true.
|
||||
ReturnValue_t result = testClass.serialize(&packetPointer, &serializedSize, packetMaxSize,
|
||||
SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
// Result should be big endian now.
|
||||
CHECK(packet[3] == 42);
|
||||
CHECK(packet[4] == 1);
|
||||
CHECK(packet[5] == 2);
|
||||
CHECK(packet[6] == 3);
|
||||
CHECK(packet[10] == 96);
|
||||
}
|
||||
|
||||
SECTION("Test Serialization") {
|
||||
// Same process as performed in setup, this time using the class
|
||||
// instead of doing it manually.
|
||||
TestPacket testClass(header, tail, testArray.data(), testArray.size());
|
||||
size_t serializedSize = 0;
|
||||
uint8_t* packetPointer = packet;
|
||||
// serialize for ground: bigEndian = true.
|
||||
ReturnValue_t result = testClass.serialize(&packetPointer,
|
||||
&serializedSize, packetMaxSize, SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
// Result should be big endian now.
|
||||
CHECK(packet[3] == 42);
|
||||
CHECK(packet[4] == 1);
|
||||
CHECK(packet[5] == 2);
|
||||
CHECK(packet[6] == 3);
|
||||
CHECK(packet[10] == 96);
|
||||
}
|
||||
|
||||
// perform tear-down here
|
||||
// perform tear-down here
|
||||
}
|
||||
|
@ -5,57 +5,46 @@
|
||||
#include <fsfw/parameters/HasParametersIF.h>
|
||||
#include <fsfw/serialize/SerialBufferAdapter.h>
|
||||
#include <fsfw/serialize/SerialLinkedListAdapter.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class TestPacket: public SerialLinkedListAdapter<SerializeIF> {
|
||||
public:
|
||||
/**
|
||||
* For Deserialization
|
||||
*/
|
||||
TestPacket(const uint8_t *somePacket, size_t size, uint8_t * storePointer,
|
||||
size_t storeSize):
|
||||
buffer(storePointer, storeSize)
|
||||
{
|
||||
setLinks();
|
||||
}
|
||||
class TestPacket : public SerialLinkedListAdapter<SerializeIF> {
|
||||
public:
|
||||
/**
|
||||
* For Deserialization
|
||||
*/
|
||||
TestPacket(const uint8_t* somePacket, size_t size, uint8_t* storePointer, size_t storeSize)
|
||||
: buffer(storePointer, storeSize) {
|
||||
setLinks();
|
||||
}
|
||||
|
||||
/**
|
||||
* For Serialization
|
||||
*/
|
||||
TestPacket(uint32_t header, uint32_t tail,
|
||||
const uint8_t* parameters, size_t paramSize):
|
||||
header(header), buffer(parameters, paramSize),
|
||||
tail(tail) {
|
||||
setLinks();
|
||||
}
|
||||
/**
|
||||
* For Serialization
|
||||
*/
|
||||
TestPacket(uint32_t header, uint32_t tail, const uint8_t* parameters, size_t paramSize)
|
||||
: header(header), buffer(parameters, paramSize), tail(tail) {
|
||||
setLinks();
|
||||
}
|
||||
|
||||
uint32_t getHeader() const {
|
||||
return header.entry;
|
||||
}
|
||||
uint32_t getHeader() const { return header.entry; }
|
||||
|
||||
const uint8_t * getBuffer() {
|
||||
return buffer.entry.getConstBuffer();
|
||||
}
|
||||
const uint8_t* getBuffer() { return buffer.entry.getConstBuffer(); }
|
||||
|
||||
size_t getBufferLength() {
|
||||
return buffer.getSerializedSize();
|
||||
}
|
||||
size_t getBufferLength() { return buffer.getSerializedSize(); }
|
||||
|
||||
uint16_t getTail() const { return tail.entry; }
|
||||
|
||||
uint16_t getTail() const {
|
||||
return tail.entry;
|
||||
}
|
||||
private:
|
||||
void setLinks() {
|
||||
setStart(&header);
|
||||
header.setNext(&buffer);
|
||||
buffer.setNext(&tail);
|
||||
tail.setEnd();
|
||||
}
|
||||
private:
|
||||
void setLinks() {
|
||||
setStart(&header);
|
||||
header.setNext(&buffer);
|
||||
buffer.setNext(&tail);
|
||||
tail.setEnd();
|
||||
}
|
||||
|
||||
SerializeElement<uint32_t> header = 0;
|
||||
SerializeElement<SerialBufferAdapter<uint8_t>> buffer;
|
||||
SerializeElement<uint32_t> tail = 0;
|
||||
SerializeElement<uint32_t> header = 0;
|
||||
SerializeElement<SerialBufferAdapter<uint8_t>> buffer;
|
||||
SerializeElement<uint32_t> tail = 0;
|
||||
};
|
||||
|
||||
#endif /* UNITTEST_TESTFW_NEWTESTS_TESTTEMPLATE_H_ */
|
||||
|
@ -1,216 +1,202 @@
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
#include <fsfw/serialize/SerialBufferAdapter.h>
|
||||
#include <fsfw/serialize/SerializeAdapter.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/catch_approx.hpp>
|
||||
#include <fsfw/serialize/SerialBufferAdapter.h>
|
||||
|
||||
#include <array>
|
||||
#include <catch2/catch_approx.hpp>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
static bool testBool = true;
|
||||
static uint8_t tvUint8 {5};
|
||||
static uint16_t tvUint16 {283};
|
||||
static uint32_t tvUint32 {929221};
|
||||
static uint64_t tvUint64 {2929329429};
|
||||
static uint8_t tvUint8{5};
|
||||
static uint16_t tvUint16{283};
|
||||
static uint32_t tvUint32{929221};
|
||||
static uint64_t tvUint64{2929329429};
|
||||
|
||||
static int8_t tvInt8 {-16};
|
||||
static int16_t tvInt16 {-829};
|
||||
static int32_t tvInt32 {-2312};
|
||||
static int8_t tvInt8{-16};
|
||||
static int16_t tvInt16{-829};
|
||||
static int32_t tvInt32{-2312};
|
||||
|
||||
static float tvFloat {8.2149214};
|
||||
static float tvFloat{8.2149214};
|
||||
static float tvSfloat = {-922.2321321};
|
||||
static double tvDouble {9.2132142141e8};
|
||||
static double tvSdouble {-2.2421e19};
|
||||
static double tvDouble{9.2132142141e8};
|
||||
static double tvSdouble{-2.2421e19};
|
||||
|
||||
static std::array<uint8_t, 512> TEST_ARRAY;
|
||||
|
||||
TEST_CASE( "Serialization size tests", "[SerSizeTest]") {
|
||||
//REQUIRE(unitTestClass.test_autoserialization() == 0);
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&testBool) ==
|
||||
sizeof(testBool));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvUint8) ==
|
||||
sizeof(tvUint8));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvUint16) ==
|
||||
sizeof(tvUint16));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvUint32 ) ==
|
||||
sizeof(tvUint32));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvUint64) ==
|
||||
sizeof(tvUint64));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvInt8) ==
|
||||
sizeof(tvInt8));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvInt16) ==
|
||||
sizeof(tvInt16));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvInt32) ==
|
||||
sizeof(tvInt32));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvFloat) ==
|
||||
sizeof(tvFloat));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvSfloat) ==
|
||||
sizeof(tvSfloat ));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvDouble) ==
|
||||
sizeof(tvDouble));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvSdouble) ==
|
||||
sizeof(tvSdouble));
|
||||
TEST_CASE("Serialization size tests", "[SerSizeTest]") {
|
||||
// REQUIRE(unitTestClass.test_autoserialization() == 0);
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&testBool) == sizeof(testBool));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvUint8) == sizeof(tvUint8));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvUint16) == sizeof(tvUint16));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvUint32) == sizeof(tvUint32));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvUint64) == sizeof(tvUint64));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvInt8) == sizeof(tvInt8));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvInt16) == sizeof(tvInt16));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvInt32) == sizeof(tvInt32));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvFloat) == sizeof(tvFloat));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvSfloat) == sizeof(tvSfloat));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvDouble) == sizeof(tvDouble));
|
||||
REQUIRE(SerializeAdapter::getSerializedSize(&tvSdouble) == sizeof(tvSdouble));
|
||||
}
|
||||
|
||||
TEST_CASE("Auto Serialize Adapter", "[SerAdapter]") {
|
||||
size_t serializedSize = 0;
|
||||
uint8_t * pArray = TEST_ARRAY.data();
|
||||
size_t serializedSize = 0;
|
||||
uint8_t* pArray = TEST_ARRAY.data();
|
||||
|
||||
SECTION("SerDe") {
|
||||
size_t deserSize = 0;
|
||||
SerializeAdapter::serialize(&testBool, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 1);
|
||||
REQUIRE(TEST_ARRAY[0] == true);
|
||||
bool readBack = false;
|
||||
SerializeAdapter::deSerialize(&readBack, TEST_ARRAY.data(), &deserSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 1);
|
||||
REQUIRE(readBack == true);
|
||||
SerializeAdapter::serialize(&tvUint8, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 1);
|
||||
REQUIRE(TEST_ARRAY[0] == 5);
|
||||
uint8_t readBackUint8 = 0;
|
||||
uint8_t* const testPtr = TEST_ARRAY.data();
|
||||
uint8_t* const shouldStayConst = testPtr;
|
||||
SerializeAdapter::deSerialize(&readBackUint8, testPtr, &deserSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(testPtr == shouldStayConst);
|
||||
REQUIRE(deserSize == 1);
|
||||
REQUIRE(readBackUint8 == 5);
|
||||
SerializeAdapter::serialize(&tvUint16, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 2);
|
||||
deserSize = 0;
|
||||
uint16_t readBackUint16 = 0;
|
||||
SerializeAdapter::deSerialize(&readBackUint16, TEST_ARRAY.data(), &deserSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 2);
|
||||
REQUIRE(readBackUint16 == 283);
|
||||
SECTION("SerDe") {
|
||||
size_t deserSize = 0;
|
||||
SerializeAdapter::serialize(&testBool, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 1);
|
||||
REQUIRE(TEST_ARRAY[0] == true);
|
||||
bool readBack = false;
|
||||
SerializeAdapter::deSerialize(&readBack, TEST_ARRAY.data(), &deserSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 1);
|
||||
REQUIRE(readBack == true);
|
||||
SerializeAdapter::serialize(&tvUint8, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 1);
|
||||
REQUIRE(TEST_ARRAY[0] == 5);
|
||||
uint8_t readBackUint8 = 0;
|
||||
uint8_t* const testPtr = TEST_ARRAY.data();
|
||||
uint8_t* const shouldStayConst = testPtr;
|
||||
SerializeAdapter::deSerialize(&readBackUint8, testPtr, &deserSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(testPtr == shouldStayConst);
|
||||
REQUIRE(deserSize == 1);
|
||||
REQUIRE(readBackUint8 == 5);
|
||||
SerializeAdapter::serialize(&tvUint16, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 2);
|
||||
deserSize = 0;
|
||||
uint16_t readBackUint16 = 0;
|
||||
SerializeAdapter::deSerialize(&readBackUint16, TEST_ARRAY.data(), &deserSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 2);
|
||||
REQUIRE(readBackUint16 == 283);
|
||||
|
||||
SerializeAdapter::serialize(&tvUint32, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 4);
|
||||
uint32_t readBackUint32 = 0;
|
||||
deserSize = 0;
|
||||
SerializeAdapter::deSerialize(&readBackUint32, TEST_ARRAY.data(), &deserSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 4);
|
||||
REQUIRE(readBackUint32 == 929221);
|
||||
SerializeAdapter::serialize(&tvUint32, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 4);
|
||||
uint32_t readBackUint32 = 0;
|
||||
deserSize = 0;
|
||||
SerializeAdapter::deSerialize(&readBackUint32, TEST_ARRAY.data(), &deserSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 4);
|
||||
REQUIRE(readBackUint32 == 929221);
|
||||
|
||||
SerializeAdapter::serialize(&tvInt16, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 2);
|
||||
int16_t readBackInt16 = 0;
|
||||
SerializeAdapter::deSerialize(&readBackInt16, TEST_ARRAY.data(), &deserSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(readBackInt16 == -829);
|
||||
REQUIRE(deserSize == 2);
|
||||
SerializeAdapter::serialize(&tvInt16, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 2);
|
||||
int16_t readBackInt16 = 0;
|
||||
SerializeAdapter::deSerialize(&readBackInt16, TEST_ARRAY.data(), &deserSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(readBackInt16 == -829);
|
||||
REQUIRE(deserSize == 2);
|
||||
|
||||
SerializeAdapter::serialize(&tvFloat, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
float readBackFloat = 0.0;
|
||||
SerializeAdapter::deSerialize(&readBackFloat, TEST_ARRAY.data(), &deserSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(readBackFloat == Catch::Approx(8.214921));
|
||||
SerializeAdapter::serialize(&tvFloat, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
float readBackFloat = 0.0;
|
||||
SerializeAdapter::deSerialize(&readBackFloat, TEST_ARRAY.data(), &deserSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(readBackFloat == Catch::Approx(8.214921));
|
||||
|
||||
SerializeAdapter::serialize(&tvSdouble, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
double readBackSignedDouble = 0.0;
|
||||
SerializeAdapter::deSerialize(&readBackSignedDouble, TEST_ARRAY.data(), &deserSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(readBackSignedDouble == Catch::Approx(-2.2421e19));
|
||||
SerializeAdapter::serialize(&tvSdouble, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
double readBackSignedDouble = 0.0;
|
||||
SerializeAdapter::deSerialize(&readBackSignedDouble, TEST_ARRAY.data(), &deserSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(readBackSignedDouble == Catch::Approx(-2.2421e19));
|
||||
|
||||
uint8_t testBuf[4] = {1, 2, 3, 4};
|
||||
SerialBufferAdapter<uint8_t> bufferAdapter(testBuf, sizeof(testBuf));
|
||||
SerializeAdapter::serialize(&bufferAdapter, TEST_ARRAY.data(), &deserSize,
|
||||
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 4);
|
||||
for(uint8_t idx = 0; idx < 4; idx++) {
|
||||
REQUIRE(TEST_ARRAY[idx] == idx + 1);
|
||||
}
|
||||
deserSize = 0;
|
||||
testBuf[0] = 0;
|
||||
testBuf[1] = 12;
|
||||
SerializeAdapter::deSerialize(&bufferAdapter, TEST_ARRAY.data(), &deserSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 4);
|
||||
for(uint8_t idx = 0; idx < 4; idx++) {
|
||||
REQUIRE(testBuf[idx] == idx + 1);
|
||||
}
|
||||
uint8_t testBuf[4] = {1, 2, 3, 4};
|
||||
SerialBufferAdapter<uint8_t> bufferAdapter(testBuf, sizeof(testBuf));
|
||||
SerializeAdapter::serialize(&bufferAdapter, TEST_ARRAY.data(), &deserSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 4);
|
||||
for (uint8_t idx = 0; idx < 4; idx++) {
|
||||
REQUIRE(TEST_ARRAY[idx] == idx + 1);
|
||||
}
|
||||
deserSize = 0;
|
||||
testBuf[0] = 0;
|
||||
testBuf[1] = 12;
|
||||
SerializeAdapter::deSerialize(&bufferAdapter, TEST_ARRAY.data(), &deserSize,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(deserSize == 4);
|
||||
for (uint8_t idx = 0; idx < 4; idx++) {
|
||||
REQUIRE(testBuf[idx] == idx + 1);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Serialize incrementing") {
|
||||
SerializeAdapter::serialize(&testBool, &pArray, &serializedSize,
|
||||
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvUint8, &pArray, &serializedSize,
|
||||
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvUint16, &pArray, &serializedSize,
|
||||
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvUint32, &pArray, &serializedSize,
|
||||
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvInt8, &pArray, &serializedSize,
|
||||
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvInt16, &pArray, &serializedSize,
|
||||
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvInt32, &pArray, &serializedSize,
|
||||
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvUint64, &pArray, &serializedSize,
|
||||
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvFloat, &pArray, &serializedSize,
|
||||
TEST_ARRAY.size(), SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvDouble, &pArray, &serializedSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvSfloat, &pArray, &serializedSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvSdouble, &pArray, &serializedSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE (serializedSize == 47);
|
||||
}
|
||||
SECTION("Serialize incrementing") {
|
||||
SerializeAdapter::serialize(&testBool, &pArray, &serializedSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvUint8, &pArray, &serializedSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvUint16, &pArray, &serializedSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvUint32, &pArray, &serializedSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvInt8, &pArray, &serializedSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvInt16, &pArray, &serializedSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvInt32, &pArray, &serializedSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvUint64, &pArray, &serializedSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvFloat, &pArray, &serializedSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvDouble, &pArray, &serializedSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvSfloat, &pArray, &serializedSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::serialize(&tvSdouble, &pArray, &serializedSize, TEST_ARRAY.size(),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(serializedSize == 47);
|
||||
}
|
||||
|
||||
SECTION("Deserialize decrementing") {
|
||||
pArray = TEST_ARRAY.data();
|
||||
size_t remaining_size = serializedSize;
|
||||
SerializeAdapter::deSerialize(&testBool, const_cast<const uint8_t**>(&pArray),
|
||||
&remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvUint8, const_cast<const uint8_t**>(&pArray),
|
||||
&remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvUint16, const_cast<const uint8_t**>(&pArray),
|
||||
&remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvUint32, const_cast<const uint8_t**>(&pArray),
|
||||
&remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvInt8, const_cast<const uint8_t**>(&pArray),
|
||||
&remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvInt16, const_cast<const uint8_t**>(&pArray),
|
||||
&remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvInt32, const_cast<const uint8_t**>(&pArray),
|
||||
&remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvUint64,
|
||||
const_cast<const uint8_t**>(&pArray), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvFloat,
|
||||
const_cast<const uint8_t**>(&pArray), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvDouble,
|
||||
const_cast<const uint8_t**>(&pArray), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvSfloat,
|
||||
const_cast<const uint8_t**>(&pArray), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvSdouble,
|
||||
const_cast<const uint8_t**>(&pArray), &remaining_size, SerializeIF::Endianness::MACHINE);
|
||||
SECTION("Deserialize decrementing") {
|
||||
pArray = TEST_ARRAY.data();
|
||||
size_t remaining_size = serializedSize;
|
||||
SerializeAdapter::deSerialize(&testBool, const_cast<const uint8_t**>(&pArray), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvUint8, const_cast<const uint8_t**>(&pArray), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvUint16, const_cast<const uint8_t**>(&pArray), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvUint32, const_cast<const uint8_t**>(&pArray), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvInt8, const_cast<const uint8_t**>(&pArray), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvInt16, const_cast<const uint8_t**>(&pArray), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvInt32, const_cast<const uint8_t**>(&pArray), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvUint64, const_cast<const uint8_t**>(&pArray), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvFloat, const_cast<const uint8_t**>(&pArray), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvDouble, const_cast<const uint8_t**>(&pArray), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvSfloat, const_cast<const uint8_t**>(&pArray), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&tvSdouble, const_cast<const uint8_t**>(&pArray), &remaining_size,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
|
||||
REQUIRE(testBool == true);
|
||||
REQUIRE(tvUint8 == 5);
|
||||
REQUIRE(tvUint16 == 283);
|
||||
REQUIRE(tvUint32 == 929221);
|
||||
REQUIRE(tvUint64 == 2929329429);
|
||||
REQUIRE(tvInt8 == -16);
|
||||
REQUIRE(tvInt16 == -829);
|
||||
REQUIRE(tvInt32 == -2312);
|
||||
REQUIRE(testBool == true);
|
||||
REQUIRE(tvUint8 == 5);
|
||||
REQUIRE(tvUint16 == 283);
|
||||
REQUIRE(tvUint32 == 929221);
|
||||
REQUIRE(tvUint64 == 2929329429);
|
||||
REQUIRE(tvInt8 == -16);
|
||||
REQUIRE(tvInt16 == -829);
|
||||
REQUIRE(tvInt32 == -2312);
|
||||
|
||||
REQUIRE(tvFloat == Catch::Approx(8.214921));
|
||||
REQUIRE(tvDouble == Catch::Approx(9.2132142141e8));
|
||||
REQUIRE(tvSfloat == Catch::Approx(-922.2321321));
|
||||
REQUIRE(tvSdouble == Catch::Approx(-2.2421e19));
|
||||
}
|
||||
REQUIRE(tvFloat == Catch::Approx(8.214921));
|
||||
REQUIRE(tvDouble == Catch::Approx(9.2132142141e8));
|
||||
REQUIRE(tvSfloat == Catch::Approx(-922.2321321));
|
||||
REQUIRE(tvSdouble == Catch::Approx(-2.2421e19));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,164 +1,159 @@
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <fsfw/storagemanager/LocalPool.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <cstring>
|
||||
|
||||
TEST_CASE( "New Accessor" , "[NewAccessor]") {
|
||||
LocalPool::LocalPoolConfig poolCfg = {{1, 10}};
|
||||
LocalPool SimplePool = LocalPool(0, poolCfg);
|
||||
std::array<uint8_t, 20> testDataArray;
|
||||
std::array<uint8_t, 20> receptionArray;
|
||||
store_address_t testStoreId;
|
||||
ReturnValue_t result = retval::CATCH_FAILED;
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
for(size_t i = 0; i < testDataArray.size(); i++) {
|
||||
testDataArray[i] = i;
|
||||
}
|
||||
size_t size = 10;
|
||||
TEST_CASE("New Accessor", "[NewAccessor]") {
|
||||
LocalPool::LocalPoolConfig poolCfg = {{1, 10}};
|
||||
LocalPool SimplePool = LocalPool(0, poolCfg);
|
||||
std::array<uint8_t, 20> testDataArray;
|
||||
std::array<uint8_t, 20> receptionArray;
|
||||
store_address_t testStoreId;
|
||||
ReturnValue_t result = retval::CATCH_FAILED;
|
||||
|
||||
SECTION ("Simple tests getter functions") {
|
||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
auto resultPair = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultPair.first == retval::CATCH_OK);
|
||||
resultPair.second.getDataCopy(receptionArray.data(), 20);
|
||||
CHECK(resultPair.second.getId() == testStoreId);
|
||||
CHECK(resultPair.second.size() == 10);
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i );
|
||||
}
|
||||
for (size_t i = 0; i < testDataArray.size(); i++) {
|
||||
testDataArray[i] = i;
|
||||
}
|
||||
size_t size = 10;
|
||||
|
||||
std::copy(resultPair.second.data(), resultPair.second.data() +
|
||||
resultPair.second.size(), receptionArray.data());
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i );
|
||||
}
|
||||
SECTION("Simple tests getter functions") {
|
||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
auto resultPair = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultPair.first == retval::CATCH_OK);
|
||||
resultPair.second.getDataCopy(receptionArray.data(), 20);
|
||||
CHECK(resultPair.second.getId() == testStoreId);
|
||||
CHECK(resultPair.second.size() == 10);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i);
|
||||
}
|
||||
|
||||
{
|
||||
auto resultPairLoc = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultPairLoc.first == retval::CATCH_OK);
|
||||
// data should be deleted when accessor goes out of scope.
|
||||
}
|
||||
resultPair = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultPair.first == (int) StorageManagerIF::DATA_DOES_NOT_EXIST);
|
||||
std::copy(resultPair.second.data(), resultPair.second.data() + resultPair.second.size(),
|
||||
receptionArray.data());
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i);
|
||||
}
|
||||
|
||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
{
|
||||
ConstStorageAccessor constAccessor(testStoreId);
|
||||
result = SimplePool.getData(testStoreId, constAccessor);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
constAccessor.getDataCopy(receptionArray.data(), 20);
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i );
|
||||
}
|
||||
// likewise, data should be deleted when accessor gets out of scope.
|
||||
}
|
||||
resultPair = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultPair.first == (int) StorageManagerIF::DATA_DOES_NOT_EXIST);
|
||||
{
|
||||
auto resultPairLoc = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultPairLoc.first == retval::CATCH_OK);
|
||||
// data should be deleted when accessor goes out of scope.
|
||||
}
|
||||
resultPair = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultPair.first == (int)StorageManagerIF::DATA_DOES_NOT_EXIST);
|
||||
|
||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
{
|
||||
resultPair = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultPair.first == retval::CATCH_OK);
|
||||
resultPair.second.release();
|
||||
// now data should not be deleted anymore
|
||||
}
|
||||
resultPair = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultPair.first == retval::CATCH_OK);
|
||||
resultPair.second.getDataCopy(receptionArray.data(), 20);
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i );
|
||||
}
|
||||
}
|
||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
{
|
||||
ConstStorageAccessor constAccessor(testStoreId);
|
||||
result = SimplePool.getData(testStoreId, constAccessor);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
constAccessor.getDataCopy(receptionArray.data(), 20);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i);
|
||||
}
|
||||
// likewise, data should be deleted when accessor gets out of scope.
|
||||
}
|
||||
resultPair = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultPair.first == (int)StorageManagerIF::DATA_DOES_NOT_EXIST);
|
||||
|
||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
{
|
||||
resultPair = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultPair.first == retval::CATCH_OK);
|
||||
resultPair.second.release();
|
||||
// now data should not be deleted anymore
|
||||
}
|
||||
resultPair = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultPair.first == retval::CATCH_OK);
|
||||
resultPair.second.getDataCopy(receptionArray.data(), 20);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Simple tests modify functions") {
|
||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
{
|
||||
StorageAccessor accessor(testStoreId);
|
||||
result = SimplePool.modifyData(testStoreId, accessor);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(accessor.getId() == testStoreId);
|
||||
CHECK(accessor.size() == 10);
|
||||
accessor.getDataCopy(receptionArray.data(), 20);
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i );
|
||||
}
|
||||
std::copy(accessor.data(), accessor.data() +
|
||||
accessor.size(), receptionArray.data());
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i );
|
||||
}
|
||||
// data should be deleted when accessor goes out of scope
|
||||
}
|
||||
auto resultPair = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultPair.first == (int) StorageManagerIF::DATA_DOES_NOT_EXIST);
|
||||
SECTION("Simple tests modify functions") {
|
||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
{
|
||||
StorageAccessor accessor(testStoreId);
|
||||
result = SimplePool.modifyData(testStoreId, accessor);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(accessor.getId() == testStoreId);
|
||||
CHECK(accessor.size() == 10);
|
||||
accessor.getDataCopy(receptionArray.data(), 20);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i);
|
||||
}
|
||||
std::copy(accessor.data(), accessor.data() + accessor.size(), receptionArray.data());
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i);
|
||||
}
|
||||
// data should be deleted when accessor goes out of scope
|
||||
}
|
||||
auto resultPair = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultPair.first == (int)StorageManagerIF::DATA_DOES_NOT_EXIST);
|
||||
|
||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
{
|
||||
auto resultPairLoc = SimplePool.modifyData(testStoreId);
|
||||
REQUIRE(resultPairLoc.first == retval::CATCH_OK);
|
||||
CHECK(resultPairLoc.second.getId() == testStoreId);
|
||||
CHECK(resultPairLoc.second.size() == 10);
|
||||
resultPairLoc.second.getDataCopy(receptionArray.data(), 20);
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i );
|
||||
}
|
||||
std::copy(resultPairLoc.second.data(), resultPairLoc.second.data() +
|
||||
resultPairLoc.second.size(), receptionArray.data());
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i );
|
||||
}
|
||||
resultPairLoc.second.release();
|
||||
// data should not be deleted when accessor goes out of scope
|
||||
}
|
||||
resultPair = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultPair.first == retval::CATCH_OK);
|
||||
}
|
||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
{
|
||||
auto resultPairLoc = SimplePool.modifyData(testStoreId);
|
||||
REQUIRE(resultPairLoc.first == retval::CATCH_OK);
|
||||
CHECK(resultPairLoc.second.getId() == testStoreId);
|
||||
CHECK(resultPairLoc.second.size() == 10);
|
||||
resultPairLoc.second.getDataCopy(receptionArray.data(), 20);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i);
|
||||
}
|
||||
std::copy(resultPairLoc.second.data(),
|
||||
resultPairLoc.second.data() + resultPairLoc.second.size(), receptionArray.data());
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i);
|
||||
}
|
||||
resultPairLoc.second.release();
|
||||
// data should not be deleted when accessor goes out of scope
|
||||
}
|
||||
resultPair = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultPair.first == retval::CATCH_OK);
|
||||
}
|
||||
|
||||
SECTION("Write tests") {
|
||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
{
|
||||
auto resultPair = SimplePool.modifyData(testStoreId);
|
||||
REQUIRE(resultPair.first == retval::CATCH_OK);
|
||||
testDataArray[9] = 42;
|
||||
resultPair.second.write(testDataArray.data(), 10, 0);
|
||||
// now data should not be deleted
|
||||
resultPair.second.release();
|
||||
}
|
||||
auto resultConstPair = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultConstPair.first == retval::CATCH_OK);
|
||||
|
||||
SECTION("Write tests") {
|
||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
{
|
||||
auto resultPair = SimplePool.modifyData(testStoreId);
|
||||
REQUIRE(resultPair.first == retval::CATCH_OK);
|
||||
testDataArray[9] = 42;
|
||||
resultPair.second.write(testDataArray.data(), 10, 0);
|
||||
// now data should not be deleted
|
||||
resultPair.second.release();
|
||||
}
|
||||
auto resultConstPair = SimplePool.getData(testStoreId);
|
||||
REQUIRE(resultConstPair.first == retval::CATCH_OK);
|
||||
resultConstPair.second.getDataCopy(receptionArray.data(), 10);
|
||||
for (size_t i = 0; i < size - 1; i++) {
|
||||
CHECK(receptionArray[i] == i);
|
||||
}
|
||||
CHECK(receptionArray[9] == 42);
|
||||
|
||||
resultConstPair.second.getDataCopy(receptionArray.data(), 10);
|
||||
for(size_t i = 0; i < size-1; i++) {
|
||||
CHECK(receptionArray[i] == i );
|
||||
}
|
||||
CHECK(receptionArray[9] == 42 );
|
||||
auto resultPair = SimplePool.modifyData(testStoreId);
|
||||
REQUIRE(resultPair.first == retval::CATCH_OK);
|
||||
result = resultPair.second.write(testDataArray.data(), 20, 0);
|
||||
REQUIRE(result == retval::CATCH_FAILED);
|
||||
result = resultPair.second.write(testDataArray.data(), 10, 5);
|
||||
REQUIRE(result == retval::CATCH_FAILED);
|
||||
|
||||
auto resultPair = SimplePool.modifyData(testStoreId);
|
||||
REQUIRE(resultPair.first == retval::CATCH_OK);
|
||||
result = resultPair.second.write(testDataArray.data(), 20, 0);
|
||||
REQUIRE(result == retval::CATCH_FAILED);
|
||||
result = resultPair.second.write(testDataArray.data(), 10, 5);
|
||||
REQUIRE(result == retval::CATCH_FAILED);
|
||||
|
||||
std::memset(testDataArray.data(), 42, 5);
|
||||
result = resultPair.second.write(testDataArray.data(), 5, 5);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
resultConstPair = SimplePool.getData(testStoreId);
|
||||
resultPair.second.getDataCopy(receptionArray.data(), 20);
|
||||
for(size_t i = 5; i < 10; i++) {
|
||||
CHECK(receptionArray[i] == 42 );
|
||||
}
|
||||
|
||||
}
|
||||
std::memset(testDataArray.data(), 42, 5);
|
||||
result = resultPair.second.write(testDataArray.data(), 5, 5);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
resultConstPair = SimplePool.getData(testStoreId);
|
||||
resultPair.second.getDataCopy(receptionArray.data(), 20);
|
||||
for (size_t i = 5; i < 10; i++) {
|
||||
CHECK(receptionArray[i] == 42);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,292 +1,289 @@
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
#include <fsfw/storagemanager/LocalPool.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
TEST_CASE( "Local Pool Simple Tests [1 Pool]" , "[TestPool]") {
|
||||
LocalPool::LocalPoolConfig config = {{1, 10}};
|
||||
LocalPool simplePool(0, config);
|
||||
std::array<uint8_t, 20> testDataArray;
|
||||
std::array<uint8_t, 20> receptionArray;
|
||||
store_address_t testStoreId;
|
||||
ReturnValue_t result = retval::CATCH_FAILED;
|
||||
uint8_t *pointer = nullptr;
|
||||
const uint8_t * constPointer = nullptr;
|
||||
TEST_CASE("Local Pool Simple Tests [1 Pool]", "[TestPool]") {
|
||||
LocalPool::LocalPoolConfig config = {{1, 10}};
|
||||
LocalPool simplePool(0, config);
|
||||
std::array<uint8_t, 20> testDataArray;
|
||||
std::array<uint8_t, 20> receptionArray;
|
||||
store_address_t testStoreId;
|
||||
ReturnValue_t result = retval::CATCH_FAILED;
|
||||
uint8_t* pointer = nullptr;
|
||||
const uint8_t* constPointer = nullptr;
|
||||
|
||||
for(size_t i = 0; i < testDataArray.size(); i++) {
|
||||
testDataArray[i] = i;
|
||||
}
|
||||
size_t size = 10;
|
||||
for (size_t i = 0; i < testDataArray.size(); i++) {
|
||||
testDataArray[i] = i;
|
||||
}
|
||||
size_t size = 10;
|
||||
|
||||
SECTION ( "Basic tests") {
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = simplePool.getData(testStoreId, &constPointer, &size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
memcpy(receptionArray.data(), constPointer, size);
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i );
|
||||
}
|
||||
memset(receptionArray.data(), 0, size);
|
||||
result = simplePool.modifyData(testStoreId, &pointer, &size);
|
||||
memcpy(receptionArray.data(), pointer, size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i );
|
||||
}
|
||||
result = simplePool.deleteData(testStoreId);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), 15);
|
||||
CHECK (result == (int) StorageManagerIF::DATA_TOO_LARGE);
|
||||
}
|
||||
SECTION("Basic tests") {
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = simplePool.getData(testStoreId, &constPointer, &size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
memcpy(receptionArray.data(), constPointer, size);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i);
|
||||
}
|
||||
memset(receptionArray.data(), 0, size);
|
||||
result = simplePool.modifyData(testStoreId, &pointer, &size);
|
||||
memcpy(receptionArray.data(), pointer, size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i);
|
||||
}
|
||||
result = simplePool.deleteData(testStoreId);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), 15);
|
||||
CHECK(result == (int)StorageManagerIF::DATA_TOO_LARGE);
|
||||
}
|
||||
|
||||
SECTION ( "Reservation Tests ") {
|
||||
pointer = nullptr;
|
||||
result = simplePool.getFreeElement(&testStoreId, size, &pointer);
|
||||
REQUIRE (result == retval::CATCH_OK);
|
||||
memcpy(pointer, testDataArray.data(), size);
|
||||
constPointer = nullptr;
|
||||
result = simplePool.getData(testStoreId, &constPointer, &size);
|
||||
SECTION("Reservation Tests ") {
|
||||
pointer = nullptr;
|
||||
result = simplePool.getFreeElement(&testStoreId, size, &pointer);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
memcpy(pointer, testDataArray.data(), size);
|
||||
constPointer = nullptr;
|
||||
result = simplePool.getData(testStoreId, &constPointer, &size);
|
||||
|
||||
REQUIRE (result == retval::CATCH_OK);
|
||||
memcpy(receptionArray.data(), constPointer, size);
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i );
|
||||
}
|
||||
}
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
memcpy(receptionArray.data(), constPointer, size);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION ( "Add, delete, add, add when full") {
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = simplePool.getData(testStoreId, &constPointer, &size);
|
||||
REQUIRE( result == retval::CATCH_OK);
|
||||
memcpy(receptionArray.data(), constPointer, size);
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i );
|
||||
}
|
||||
SECTION("Add, delete, add, add when full") {
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = simplePool.getData(testStoreId, &constPointer, &size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
memcpy(receptionArray.data(), constPointer, size);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i);
|
||||
}
|
||||
|
||||
result = simplePool.deleteData(testStoreId);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = simplePool.deleteData(testStoreId);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = simplePool.getData(testStoreId, &constPointer, &size);
|
||||
REQUIRE( result == retval::CATCH_OK);
|
||||
memcpy(receptionArray.data(), constPointer, size);
|
||||
for(size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i );
|
||||
}
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = simplePool.getData(testStoreId, &constPointer, &size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
memcpy(receptionArray.data(), constPointer, size);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
CHECK(receptionArray[i] == i);
|
||||
}
|
||||
|
||||
store_address_t newAddress;
|
||||
result = simplePool.addData(&newAddress, testDataArray.data(), size);
|
||||
REQUIRE(result == (int) StorageManagerIF::DATA_STORAGE_FULL);
|
||||
store_address_t newAddress;
|
||||
result = simplePool.addData(&newAddress, testDataArray.data(), size);
|
||||
REQUIRE(result == (int)StorageManagerIF::DATA_STORAGE_FULL);
|
||||
|
||||
// Packet Index to high intentionally
|
||||
newAddress.packetIndex = 2;
|
||||
pointer = testDataArray.data();
|
||||
result = simplePool.modifyData(newAddress, &pointer, &size);
|
||||
REQUIRE(result == (int) StorageManagerIF::ILLEGAL_STORAGE_ID);
|
||||
// Packet Index to high intentionally
|
||||
newAddress.packetIndex = 2;
|
||||
pointer = testDataArray.data();
|
||||
result = simplePool.modifyData(newAddress, &pointer, &size);
|
||||
REQUIRE(result == (int)StorageManagerIF::ILLEGAL_STORAGE_ID);
|
||||
|
||||
result = simplePool.deleteData(newAddress);
|
||||
REQUIRE(result == (int) StorageManagerIF::ILLEGAL_STORAGE_ID);
|
||||
result = simplePool.deleteData(newAddress);
|
||||
REQUIRE(result == (int)StorageManagerIF::ILLEGAL_STORAGE_ID);
|
||||
|
||||
newAddress.packetIndex = 0;
|
||||
newAddress.poolIndex = 2;
|
||||
result = simplePool.deleteData(newAddress);
|
||||
REQUIRE(result == (int) StorageManagerIF::ILLEGAL_STORAGE_ID);
|
||||
}
|
||||
newAddress.packetIndex = 0;
|
||||
newAddress.poolIndex = 2;
|
||||
result = simplePool.deleteData(newAddress);
|
||||
REQUIRE(result == (int)StorageManagerIF::ILLEGAL_STORAGE_ID);
|
||||
}
|
||||
|
||||
SECTION ( "Initialize and clear store, delete with pointer") {
|
||||
result = simplePool.initialize();
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
simplePool.clearStore();
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = simplePool.modifyData(testStoreId, &pointer, &size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
store_address_t newId;
|
||||
result = simplePool.deleteData(pointer, size, &testStoreId);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
REQUIRE(testStoreId.raw != (uint32_t) StorageManagerIF::INVALID_ADDRESS);
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
}
|
||||
SECTION("Initialize and clear store, delete with pointer") {
|
||||
result = simplePool.initialize();
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
simplePool.clearStore();
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
result = simplePool.modifyData(testStoreId, &pointer, &size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
store_address_t newId;
|
||||
result = simplePool.deleteData(pointer, size, &testStoreId);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
REQUIRE(testStoreId.raw != (uint32_t)StorageManagerIF::INVALID_ADDRESS);
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
}
|
||||
}
|
||||
|
||||
int runIdx = 0;
|
||||
|
||||
TEST_CASE( "Local Pool Extended Tests [3 Pools]" , "[TestPool2]") {
|
||||
LocalPool::LocalPoolConfig* config;
|
||||
if(runIdx == 0) {
|
||||
config = new LocalPool::LocalPoolConfig{{10, 5}, {5, 10}, {2, 20}};
|
||||
}
|
||||
else {
|
||||
// shufle the order, they should be sort implictely so that the
|
||||
// order is ascending for the page sizes.
|
||||
config = new LocalPool::LocalPoolConfig{{5, 10}, {2, 20}, {10, 5}};
|
||||
size_t lastSize = 0;
|
||||
for(const auto& pair: *config) {
|
||||
CHECK(pair.second > lastSize);
|
||||
lastSize = pair.second;
|
||||
}
|
||||
}
|
||||
runIdx++;
|
||||
TEST_CASE("Local Pool Extended Tests [3 Pools]", "[TestPool2]") {
|
||||
LocalPool::LocalPoolConfig* config;
|
||||
if (runIdx == 0) {
|
||||
config = new LocalPool::LocalPoolConfig{{10, 5}, {5, 10}, {2, 20}};
|
||||
} else {
|
||||
// shufle the order, they should be sort implictely so that the
|
||||
// order is ascending for the page sizes.
|
||||
config = new LocalPool::LocalPoolConfig{{5, 10}, {2, 20}, {10, 5}};
|
||||
size_t lastSize = 0;
|
||||
for (const auto& pair : *config) {
|
||||
CHECK(pair.second > lastSize);
|
||||
lastSize = pair.second;
|
||||
}
|
||||
}
|
||||
runIdx++;
|
||||
|
||||
LocalPool simplePool(0, *config);
|
||||
std::array<uint8_t, 20> testDataArray;
|
||||
std::array<uint8_t, 20> receptionArray;
|
||||
store_address_t testStoreId;
|
||||
ReturnValue_t result = retval::CATCH_FAILED;
|
||||
for(size_t i = 0; i < testDataArray.size(); i++) {
|
||||
testDataArray[i] = i;
|
||||
}
|
||||
size_t size = 0;
|
||||
LocalPool simplePool(0, *config);
|
||||
std::array<uint8_t, 20> testDataArray;
|
||||
std::array<uint8_t, 20> receptionArray;
|
||||
store_address_t testStoreId;
|
||||
ReturnValue_t result = retval::CATCH_FAILED;
|
||||
for (size_t i = 0; i < testDataArray.size(); i++) {
|
||||
testDataArray[i] = i;
|
||||
}
|
||||
size_t size = 0;
|
||||
|
||||
SECTION ("Basic tests") {
|
||||
size = 8;
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
// Should be on second page of the pool now for 8 bytes
|
||||
CHECK(testStoreId.poolIndex == 1);
|
||||
CHECK(testStoreId.packetIndex == 0);
|
||||
SECTION("Basic tests") {
|
||||
size = 8;
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
// Should be on second page of the pool now for 8 bytes
|
||||
CHECK(testStoreId.poolIndex == 1);
|
||||
CHECK(testStoreId.packetIndex == 0);
|
||||
|
||||
size = 15;
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
// Should be on third page of the pool now for 15 bytes
|
||||
CHECK(testStoreId.poolIndex == 2);
|
||||
CHECK(testStoreId.packetIndex == 0);
|
||||
size = 15;
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
// Should be on third page of the pool now for 15 bytes
|
||||
CHECK(testStoreId.poolIndex == 2);
|
||||
CHECK(testStoreId.packetIndex == 0);
|
||||
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
// Should be on third page of the pool now for 15 bytes
|
||||
CHECK(testStoreId.poolIndex == 2);
|
||||
CHECK(testStoreId.packetIndex == 1);
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
// Should be on third page of the pool now for 15 bytes
|
||||
CHECK(testStoreId.poolIndex == 2);
|
||||
CHECK(testStoreId.packetIndex == 1);
|
||||
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
// Should be on third page of the pool now for 15 bytes
|
||||
REQUIRE(result == (int) LocalPool::DATA_STORAGE_FULL);
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
// Should be on third page of the pool now for 15 bytes
|
||||
REQUIRE(result == (int)LocalPool::DATA_STORAGE_FULL);
|
||||
|
||||
size = 8;
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
// Should still work
|
||||
CHECK(testStoreId.poolIndex == 1);
|
||||
CHECK(testStoreId.packetIndex == 1);
|
||||
size = 8;
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
// Should still work
|
||||
CHECK(testStoreId.poolIndex == 1);
|
||||
CHECK(testStoreId.packetIndex == 1);
|
||||
|
||||
// fill the rest of the pool
|
||||
for(uint8_t idx = 2; idx < 5; idx++) {
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(testStoreId.poolIndex == 1);
|
||||
CHECK(testStoreId.packetIndex == idx);
|
||||
}
|
||||
}
|
||||
// fill the rest of the pool
|
||||
for (uint8_t idx = 2; idx < 5; idx++) {
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(testStoreId.poolIndex == 1);
|
||||
CHECK(testStoreId.packetIndex == idx);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION ("Fill Count and Clearing") {
|
||||
//SECTION("Basic tests");
|
||||
uint8_t bytesWritten = 0;
|
||||
simplePool.getFillCount(receptionArray.data(), &bytesWritten);
|
||||
// fill count should be all zeros now.
|
||||
CHECK(bytesWritten == 4);
|
||||
CHECK(receptionArray[0] == 0);
|
||||
CHECK(receptionArray[1] == 0);
|
||||
CHECK(receptionArray[2] == 0);
|
||||
CHECK(receptionArray[3] == 0);
|
||||
SECTION("Fill Count and Clearing") {
|
||||
// SECTION("Basic tests");
|
||||
uint8_t bytesWritten = 0;
|
||||
simplePool.getFillCount(receptionArray.data(), &bytesWritten);
|
||||
// fill count should be all zeros now.
|
||||
CHECK(bytesWritten == 4);
|
||||
CHECK(receptionArray[0] == 0);
|
||||
CHECK(receptionArray[1] == 0);
|
||||
CHECK(receptionArray[2] == 0);
|
||||
CHECK(receptionArray[3] == 0);
|
||||
|
||||
// now fill the store completely.
|
||||
size = 5;
|
||||
for(uint8_t idx = 0; idx < 10; idx++) {
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(testStoreId.poolIndex == 0);
|
||||
CHECK(testStoreId.packetIndex == idx);
|
||||
}
|
||||
size = 10;
|
||||
for(uint8_t idx = 0; idx < 5; idx++) {
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(testStoreId.poolIndex == 1);
|
||||
CHECK(testStoreId.packetIndex == idx);
|
||||
}
|
||||
size = 20;
|
||||
for(uint8_t idx = 0; idx < 2; idx++) {
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(testStoreId.poolIndex == 2);
|
||||
CHECK(testStoreId.packetIndex == idx);
|
||||
}
|
||||
bytesWritten = 0;
|
||||
simplePool.getFillCount(receptionArray.data(), &bytesWritten);
|
||||
// fill count should be all 100 now.
|
||||
CHECK(bytesWritten == 4);
|
||||
CHECK(receptionArray[0] == 100);
|
||||
CHECK(receptionArray[1] == 100);
|
||||
CHECK(receptionArray[2] == 100);
|
||||
CHECK(receptionArray[3] == 100);
|
||||
// now fill the store completely.
|
||||
size = 5;
|
||||
for (uint8_t idx = 0; idx < 10; idx++) {
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(testStoreId.poolIndex == 0);
|
||||
CHECK(testStoreId.packetIndex == idx);
|
||||
}
|
||||
size = 10;
|
||||
for (uint8_t idx = 0; idx < 5; idx++) {
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(testStoreId.poolIndex == 1);
|
||||
CHECK(testStoreId.packetIndex == idx);
|
||||
}
|
||||
size = 20;
|
||||
for (uint8_t idx = 0; idx < 2; idx++) {
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(testStoreId.poolIndex == 2);
|
||||
CHECK(testStoreId.packetIndex == idx);
|
||||
}
|
||||
bytesWritten = 0;
|
||||
simplePool.getFillCount(receptionArray.data(), &bytesWritten);
|
||||
// fill count should be all 100 now.
|
||||
CHECK(bytesWritten == 4);
|
||||
CHECK(receptionArray[0] == 100);
|
||||
CHECK(receptionArray[1] == 100);
|
||||
CHECK(receptionArray[2] == 100);
|
||||
CHECK(receptionArray[3] == 100);
|
||||
|
||||
// now clear the store
|
||||
simplePool.clearStore();
|
||||
bytesWritten = 0;
|
||||
simplePool.getFillCount(receptionArray.data(), &bytesWritten);
|
||||
CHECK(bytesWritten == 4);
|
||||
CHECK(receptionArray[0] == 0);
|
||||
CHECK(receptionArray[1] == 0);
|
||||
CHECK(receptionArray[2] == 0);
|
||||
CHECK(receptionArray[3] == 0);
|
||||
// now clear the store
|
||||
simplePool.clearStore();
|
||||
bytesWritten = 0;
|
||||
simplePool.getFillCount(receptionArray.data(), &bytesWritten);
|
||||
CHECK(bytesWritten == 4);
|
||||
CHECK(receptionArray[0] == 0);
|
||||
CHECK(receptionArray[1] == 0);
|
||||
CHECK(receptionArray[2] == 0);
|
||||
CHECK(receptionArray[3] == 0);
|
||||
|
||||
// now fill one page
|
||||
size = 5;
|
||||
for(uint8_t idx = 0; idx < 10; idx++) {
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(testStoreId.poolIndex == 0);
|
||||
CHECK(testStoreId.packetIndex == idx);
|
||||
}
|
||||
bytesWritten = 0;
|
||||
simplePool.getFillCount(receptionArray.data(), &bytesWritten);
|
||||
// First page full, median fill count is 33 %
|
||||
CHECK(bytesWritten == 4);
|
||||
CHECK(receptionArray[0] == 100);
|
||||
CHECK(receptionArray[1] == 0);
|
||||
CHECK(receptionArray[2] == 0);
|
||||
CHECK(receptionArray[3] == 33);
|
||||
// now fill one page
|
||||
size = 5;
|
||||
for (uint8_t idx = 0; idx < 10; idx++) {
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(testStoreId.poolIndex == 0);
|
||||
CHECK(testStoreId.packetIndex == idx);
|
||||
}
|
||||
bytesWritten = 0;
|
||||
simplePool.getFillCount(receptionArray.data(), &bytesWritten);
|
||||
// First page full, median fill count is 33 %
|
||||
CHECK(bytesWritten == 4);
|
||||
CHECK(receptionArray[0] == 100);
|
||||
CHECK(receptionArray[1] == 0);
|
||||
CHECK(receptionArray[2] == 0);
|
||||
CHECK(receptionArray[3] == 33);
|
||||
|
||||
// now fill second page
|
||||
size = 10;
|
||||
for(uint8_t idx = 0; idx < 5; idx++) {
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(testStoreId.poolIndex == 1);
|
||||
CHECK(testStoreId.packetIndex == idx);
|
||||
}
|
||||
bytesWritten = 0;
|
||||
simplePool.getFillCount(receptionArray.data(), &bytesWritten);
|
||||
// First and second page full, median fill count is 66 %
|
||||
CHECK(bytesWritten == 4);
|
||||
CHECK(receptionArray[0] == 100);
|
||||
CHECK(receptionArray[1] == 100);
|
||||
CHECK(receptionArray[2] == 0);
|
||||
CHECK(receptionArray[3] == 66);
|
||||
// now fill second page
|
||||
size = 10;
|
||||
for (uint8_t idx = 0; idx < 5; idx++) {
|
||||
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||
REQUIRE(result == retval::CATCH_OK);
|
||||
CHECK(testStoreId.poolIndex == 1);
|
||||
CHECK(testStoreId.packetIndex == idx);
|
||||
}
|
||||
bytesWritten = 0;
|
||||
simplePool.getFillCount(receptionArray.data(), &bytesWritten);
|
||||
// First and second page full, median fill count is 66 %
|
||||
CHECK(bytesWritten == 4);
|
||||
CHECK(receptionArray[0] == 100);
|
||||
CHECK(receptionArray[1] == 100);
|
||||
CHECK(receptionArray[2] == 0);
|
||||
CHECK(receptionArray[3] == 66);
|
||||
|
||||
// now clear first page
|
||||
simplePool.clearSubPool(0);
|
||||
bytesWritten = 0;
|
||||
simplePool.getFillCount(receptionArray.data(), &bytesWritten);
|
||||
// Second page full, median fill count is 33 %
|
||||
CHECK(bytesWritten == 4);
|
||||
CHECK(receptionArray[0] == 0);
|
||||
CHECK(receptionArray[1] == 100);
|
||||
CHECK(receptionArray[2] == 0);
|
||||
CHECK(receptionArray[3] == 33);
|
||||
}
|
||||
// now clear first page
|
||||
simplePool.clearSubPool(0);
|
||||
bytesWritten = 0;
|
||||
simplePool.getFillCount(receptionArray.data(), &bytesWritten);
|
||||
// Second page full, median fill count is 33 %
|
||||
CHECK(bytesWritten == 4);
|
||||
CHECK(receptionArray[0] == 0);
|
||||
CHECK(receptionArray[1] == 100);
|
||||
CHECK(receptionArray[2] == 0);
|
||||
CHECK(receptionArray[3] == 33);
|
||||
}
|
||||
|
||||
delete(config);
|
||||
delete (config);
|
||||
}
|
||||
|
@ -1,5 +1 @@
|
||||
#include "logicalAddresses.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -6,10 +6,8 @@
|
||||
#include <cstdint>
|
||||
|
||||
namespace addresses {
|
||||
/* Logical addresses have uint32_t datatype */
|
||||
enum logicalAddresses: address_t {
|
||||
};
|
||||
}
|
||||
|
||||
/* Logical addresses have uint32_t datatype */
|
||||
enum logicalAddresses : address_t {};
|
||||
} // namespace addresses
|
||||
|
||||
#endif /* CONFIG_DEVICES_LOGICALADDRESSES_H_ */
|
||||
|
@ -1,4 +1 @@
|
||||
#include "powerSwitcherList.h"
|
||||
|
||||
|
||||
|
||||
|
@ -2,11 +2,9 @@
|
||||
#define CONFIG_DEVICES_POWERSWITCHERLIST_H_
|
||||
|
||||
namespace switches {
|
||||
/* Switches are uint8_t datatype and go from 0 to 255 */
|
||||
enum switcherList {
|
||||
};
|
||||
|
||||
}
|
||||
/* Switches are uint8_t datatype and go from 0 to 255 */
|
||||
enum switcherList {};
|
||||
|
||||
} // namespace switches
|
||||
|
||||
#endif /* CONFIG_DEVICES_POWERSWITCHERLIST_H_ */
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_
|
||||
#define CONFIG_EVENTS_SUBSYSTEMIDRANGES_H_
|
||||
|
||||
#include "fsfw/events/fwSubsystemIdRanges.h"
|
||||
#include <cstdint>
|
||||
|
||||
#include "fsfw/events/fwSubsystemIdRanges.h"
|
||||
|
||||
/**
|
||||
* @brief Custom subsystem IDs can be added here
|
||||
@ -11,9 +11,9 @@
|
||||
* Subsystem IDs are used to create unique events.
|
||||
*/
|
||||
namespace SUBSYSTEM_ID {
|
||||
enum: uint8_t {
|
||||
SUBSYSTEM_ID_START = FW_SUBSYSTEM_ID_RANGE,
|
||||
SUBSYSTEM_ID_END // [EXPORT] : [END]
|
||||
enum : uint8_t {
|
||||
SUBSYSTEM_ID_START = FW_SUBSYSTEM_ID_RANGE,
|
||||
SUBSYSTEM_ID_END // [EXPORT] : [END]
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,8 @@
|
||||
#include <fsfw/ipc/CommandMessage.h>
|
||||
|
||||
void messagetypes::clearMissionMessage(CommandMessage* message) {
|
||||
switch(message->getMessageType()) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (message->getMessageType()) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -11,12 +11,12 @@ class CommandMessage;
|
||||
* <fsfw/ipc/FwMessageTypes.h>
|
||||
* @param message Generic Command Message
|
||||
*/
|
||||
namespace messagetypes{
|
||||
namespace messagetypes {
|
||||
enum MESSAGE_TYPE {
|
||||
MISSION_MESSAGE_TYPE_START = FW_MESSAGES_COUNT,
|
||||
MISSION_MESSAGE_TYPE_START = FW_MESSAGES_COUNT,
|
||||
};
|
||||
|
||||
void clearMissionMessage(CommandMessage* message);
|
||||
}
|
||||
} // namespace messagetypes
|
||||
|
||||
#endif /* CONFIG_IPC_MISSIONMESSAGETYPES_H_ */
|
||||
|
@ -1,28 +1,29 @@
|
||||
#ifndef HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
|
||||
#define HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
|
||||
|
||||
#include "fsfw/objectmanager/frameworkObjects.h"
|
||||
#include <cstdint>
|
||||
|
||||
#include "fsfw/objectmanager/frameworkObjects.h"
|
||||
|
||||
// The objects will be instantiated in the ID order
|
||||
namespace objects {
|
||||
enum sourceObjects: uint32_t {
|
||||
/* All addresses between start and end are reserved for the FSFW */
|
||||
FSFW_CONFIG_RESERVED_START = PUS_SERVICE_1_VERIFICATION,
|
||||
FSFW_CONFIG_RESERVED_END = TM_STORE,
|
||||
enum sourceObjects : uint32_t {
|
||||
/* All addresses between start and end are reserved for the FSFW */
|
||||
FSFW_CONFIG_RESERVED_START = PUS_SERVICE_1_VERIFICATION,
|
||||
FSFW_CONFIG_RESERVED_END = TM_STORE,
|
||||
|
||||
UDP_BRIDGE = 15,
|
||||
UDP_POLLING_TASK = 16,
|
||||
UDP_BRIDGE = 15,
|
||||
UDP_POLLING_TASK = 16,
|
||||
|
||||
TEST_ECHO_COM_IF = 20,
|
||||
TEST_DEVICE = 21,
|
||||
TEST_ECHO_COM_IF = 20,
|
||||
TEST_DEVICE = 21,
|
||||
|
||||
HK_RECEIVER_MOCK = 22,
|
||||
TEST_LOCAL_POOL_OWNER_BASE = 25,
|
||||
HK_RECEIVER_MOCK = 22,
|
||||
TEST_LOCAL_POOL_OWNER_BASE = 25,
|
||||
|
||||
SHARED_SET_ID = 26
|
||||
SHARED_SET_ID = 26
|
||||
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* BSP_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ */
|
||||
|
@ -1,39 +1,30 @@
|
||||
#include "PollingSequenceFactory.h"
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
||||
|
||||
#include "tests/TestsConfig.h"
|
||||
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
||||
ReturnValue_t pst::pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence) {
|
||||
/* Length of a communication cycle */
|
||||
uint32_t length = thisSequence->getPeriodMs();
|
||||
|
||||
ReturnValue_t pst::pollingSequenceInitDefault(
|
||||
FixedTimeslotTaskIF *thisSequence) {
|
||||
/* Length of a communication cycle */
|
||||
uint32_t length = thisSequence->getPeriodMs();
|
||||
/* Add polling sequence table here */
|
||||
thisSequence->addSlot(objects::TEST_DEVICE, 0, DeviceHandlerIF::PERFORM_OPERATION);
|
||||
thisSequence->addSlot(objects::TEST_DEVICE, 0.3, DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::TEST_DEVICE, 0.45 * length, DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::TEST_DEVICE, 0.6 * length, DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::TEST_DEVICE, 0.8 * length, DeviceHandlerIF::GET_READ);
|
||||
|
||||
/* Add polling sequence table here */
|
||||
thisSequence->addSlot(objects::TEST_DEVICE, 0,
|
||||
DeviceHandlerIF::PERFORM_OPERATION);
|
||||
thisSequence->addSlot(objects::TEST_DEVICE, 0.3,
|
||||
DeviceHandlerIF::SEND_WRITE);
|
||||
thisSequence->addSlot(objects::TEST_DEVICE, 0.45 * length,
|
||||
DeviceHandlerIF::GET_WRITE);
|
||||
thisSequence->addSlot(objects::TEST_DEVICE, 0.6 * length,
|
||||
DeviceHandlerIF::SEND_READ);
|
||||
thisSequence->addSlot(objects::TEST_DEVICE, 0.8 * length,
|
||||
DeviceHandlerIF::GET_READ);
|
||||
|
||||
if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
else {
|
||||
if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
} else {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED
|
||||
sif::error << "pst::pollingSequenceInitDefault: Sequence invalid!"
|
||||
<< std::endl;
|
||||
sif::error << "pst::pollingSequenceInitDefault: Sequence invalid!" << std::endl;
|
||||
#else
|
||||
sif::printError("pst::pollingSequenceInitDefault: Sequence invalid!");
|
||||
sif::printError("pst::pollingSequenceInitDefault: Sequence invalid!");
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,8 @@ class FixedTimeslotTaskIF;
|
||||
* The task is created using the FixedTimeslotTaskIF,
|
||||
* which utilises the underlying Operating System Abstraction Layer (OSAL)
|
||||
*
|
||||
* @param thisSequence FixedTimeslotTaskIF * object is passed inside the Factory class when creating the PST
|
||||
* @param thisSequence FixedTimeslotTaskIF * object is passed inside the Factory class when creating
|
||||
* the PST
|
||||
* @return
|
||||
*/
|
||||
namespace pst {
|
||||
@ -26,7 +27,6 @@ namespace pst {
|
||||
/* Default PST */
|
||||
ReturnValue_t pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence);
|
||||
|
||||
|
||||
}
|
||||
} // namespace pst
|
||||
|
||||
#endif /* POLLINGSEQUENCEINIT_H_ */
|
||||
|
@ -8,9 +8,8 @@
|
||||
*/
|
||||
namespace CLASS_ID {
|
||||
enum {
|
||||
MISSION_CLASS_ID_START = FW_CLASS_ID_COUNT,
|
||||
MISSION_CLASS_ID_START = FW_CLASS_ID_COUNT,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif /* CONFIG_RETURNVALUES_CLASSIDS_H_ */
|
||||
|
@ -11,8 +11,7 @@
|
||||
* Chose APID(s) for mission and define it here.
|
||||
*/
|
||||
namespace apid {
|
||||
static const uint16_t DEFAULT_APID = 0x00;
|
||||
static const uint16_t DEFAULT_APID = 0x00;
|
||||
}
|
||||
|
||||
|
||||
#endif /* CONFIG_TMTC_APID_H_ */
|
||||
|
@ -4,21 +4,21 @@
|
||||
#include <cstdint>
|
||||
|
||||
namespace pus {
|
||||
enum Ids: uint8_t {
|
||||
PUS_SERVICE_1 = 1,
|
||||
PUS_SERVICE_2 = 2,
|
||||
PUS_SERVICE_3 = 3,
|
||||
PUS_SERVICE_5 = 5,
|
||||
PUS_SERVICE_6 = 6,
|
||||
PUS_SERVICE_8 = 8,
|
||||
PUS_SERVICE_9 = 9,
|
||||
PUS_SERVICE_11 = 11,
|
||||
PUS_SERVICE_17 = 17,
|
||||
PUS_SERVICE_19 = 19,
|
||||
PUS_SERVICE_20 = 20,
|
||||
PUS_SERVICE_23 = 23,
|
||||
PUS_SERVICE_200 = 200,
|
||||
PUS_SERVICE_201 = 201,
|
||||
enum Ids : uint8_t {
|
||||
PUS_SERVICE_1 = 1,
|
||||
PUS_SERVICE_2 = 2,
|
||||
PUS_SERVICE_3 = 3,
|
||||
PUS_SERVICE_5 = 5,
|
||||
PUS_SERVICE_6 = 6,
|
||||
PUS_SERVICE_8 = 8,
|
||||
PUS_SERVICE_9 = 9,
|
||||
PUS_SERVICE_11 = 11,
|
||||
PUS_SERVICE_17 = 17,
|
||||
PUS_SERVICE_19 = 19,
|
||||
PUS_SERVICE_20 = 20,
|
||||
PUS_SERVICE_23 = 23,
|
||||
PUS_SERVICE_200 = 200,
|
||||
PUS_SERVICE_201 = 201,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
/**
|
||||
* @brief Template test file
|
||||
* @details
|
||||
@ -18,13 +19,13 @@
|
||||
* - https://github.com/catchorg/Catch2/blob/master/docs/assertions.md
|
||||
* - https://github.com/catchorg/Catch2/blob/master/docs/test-cases-and-sections.md
|
||||
*/
|
||||
TEST_CASE("Dummy Test" , "[DummyTest]") {
|
||||
uint8_t testVariable = 1;
|
||||
//perform set-up here
|
||||
CHECK(testVariable == 1);
|
||||
SECTION("TestSection") {
|
||||
// set-up is run for each section
|
||||
REQUIRE(testVariable == 1);
|
||||
}
|
||||
// perform tear-down here
|
||||
TEST_CASE("Dummy Test", "[DummyTest]") {
|
||||
uint8_t testVariable = 1;
|
||||
// perform set-up here
|
||||
CHECK(testVariable == 1);
|
||||
SECTION("TestSection") {
|
||||
// set-up is run for each section
|
||||
REQUIRE(testVariable == 1);
|
||||
}
|
||||
// perform tear-down here
|
||||
}
|
||||
|
@ -1,27 +1,28 @@
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
#include <fsfw/timemanager/Countdown.h>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
TEST_CASE( "Countdown Tests", "[TestCountdown]") {
|
||||
INFO("Countdown Tests");
|
||||
Countdown count(20);
|
||||
REQUIRE(count.timeout == 20);
|
||||
REQUIRE(count.setTimeout(100) == static_cast<uint16_t>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(count.timeout == 100);
|
||||
REQUIRE(count.setTimeout(150) == static_cast<uint16_t>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(count.isBusy());
|
||||
REQUIRE(not count.hasTimedOut());
|
||||
uint32_t number = count.getRemainingMillis();
|
||||
REQUIRE(number > 0);
|
||||
bool blocked = false;
|
||||
while(not count.hasTimedOut()){
|
||||
blocked = true;
|
||||
};
|
||||
REQUIRE(blocked);
|
||||
number = count.getRemainingMillis();
|
||||
REQUIRE(number==0);
|
||||
count.resetTimer();
|
||||
REQUIRE(not count.hasTimedOut());
|
||||
REQUIRE(count.isBusy());
|
||||
TEST_CASE("Countdown Tests", "[TestCountdown]") {
|
||||
INFO("Countdown Tests");
|
||||
Countdown count(20);
|
||||
REQUIRE(count.timeout == 20);
|
||||
REQUIRE(count.setTimeout(100) == static_cast<uint16_t>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(count.timeout == 100);
|
||||
REQUIRE(count.setTimeout(150) == static_cast<uint16_t>(HasReturnvaluesIF::RETURN_OK));
|
||||
REQUIRE(count.isBusy());
|
||||
REQUIRE(not count.hasTimedOut());
|
||||
uint32_t number = count.getRemainingMillis();
|
||||
REQUIRE(number > 0);
|
||||
bool blocked = false;
|
||||
while (not count.hasTimedOut()) {
|
||||
blocked = true;
|
||||
};
|
||||
REQUIRE(blocked);
|
||||
number = count.getRemainingMillis();
|
||||
REQUIRE(number == 0);
|
||||
count.resetTimer();
|
||||
REQUIRE(not count.hasTimedOut());
|
||||
REQUIRE(count.isBusy());
|
||||
}
|
||||
|
@ -1,3 +1 @@
|
||||
|
||||
|
||||
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
#include "fsfw/tmtcpacket/SpacePacket.h"
|
||||
|
||||
TEST_CASE( "CCSDS Test" , "[ccsds]") {
|
||||
REQUIRE(spacepacket::getTcSpacePacketIdFromApid(0x22) == 0x1822);
|
||||
REQUIRE(spacepacket::getTmSpacePacketIdFromApid(0x22) == 0x0822);
|
||||
TEST_CASE("CCSDS Test", "[ccsds]") {
|
||||
REQUIRE(spacepacket::getTcSpacePacketIdFromApid(0x22) == 0x1822);
|
||||
REQUIRE(spacepacket::getTmSpacePacketIdFromApid(0x22) == 0x0822);
|
||||
|
||||
REQUIRE(spacepacket::getTcSpacePacketIdFromApid(0x7ff) == 0x1fff);
|
||||
REQUIRE(spacepacket::getTmSpacePacketIdFromApid(0x7ff) == 0xfff);
|
||||
REQUIRE(spacepacket::getTcSpacePacketIdFromApid(0x7ff) == 0x1fff);
|
||||
REQUIRE(spacepacket::getTmSpacePacketIdFromApid(0x7ff) == 0xfff);
|
||||
}
|
||||
|
Reference in New Issue
Block a user