cleaning up message queue mock and subscription API
This commit is contained in:
@ -3,8 +3,8 @@
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "fsfw/timemanager/TimeStamperIF.h"
|
||||
#include "fsfw/timemanager/TimeReaderIF.h"
|
||||
#include "fsfw/timemanager/TimeStamperIF.h"
|
||||
|
||||
class CdsShortTimestamperMock : public TimeStamperIF, public TimeReaderIF {
|
||||
public:
|
||||
@ -75,7 +75,7 @@ class CdsShortTimestamperMock : public TimeStamperIF, public TimeReaderIF {
|
||||
serFailRetval = HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
ReturnValue_t readTimeStamp(const uint8_t* buffer, size_t maxSize) override {
|
||||
ReturnValue_t readTimeStamp(const uint8_t *buffer, size_t maxSize) override {
|
||||
return deSerialize(&buffer, &maxSize, SerializeIF::Endianness::NETWORK);
|
||||
}
|
||||
size_t getTimestampLen() override { return getSerializedSize(); }
|
||||
|
@ -2,13 +2,15 @@
|
||||
#define FSFW_UNITTEST_TESTS_MOCKS_HKRECEIVERMOCK_H_
|
||||
|
||||
#include <fsfw/housekeeping/AcceptsHkPacketsIF.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
|
||||
class HkReceiverMock : public SystemObject, public AcceptsHkPacketsIF {
|
||||
class HkReceiverMock : public AcceptsHkPacketsIF {
|
||||
public:
|
||||
HkReceiverMock(object_id_t objectId) : SystemObject(objectId) {}
|
||||
explicit HkReceiverMock(MessageQueueId_t queueId) : queueId(queueId) {}
|
||||
|
||||
MessageQueueId_t getHkQueue() const { return MessageQueueIF::NO_QUEUE; }
|
||||
[[nodiscard]] MessageQueueId_t getHkQueue() const override { return queueId; }
|
||||
|
||||
private:
|
||||
MessageQueueId_t queueId;
|
||||
};
|
||||
|
||||
#endif /* FSFW_UNITTEST_TESTS_MOCKS_HKRECEIVERMOCK_H_ */
|
||||
|
@ -2,12 +2,6 @@
|
||||
|
||||
InternalErrorReporterMock::InternalErrorReporterMock() = default;
|
||||
|
||||
void InternalErrorReporterMock::queueMessageNotSent() {
|
||||
queueMsgNotSentCallCnt++;
|
||||
}
|
||||
void InternalErrorReporterMock::lostTm() {
|
||||
lostTmCallCnt++;
|
||||
}
|
||||
void InternalErrorReporterMock::storeFull() {
|
||||
storeFullCallCnt++;
|
||||
}
|
||||
void InternalErrorReporterMock::queueMessageNotSent() { queueMsgNotSentCallCnt++; }
|
||||
void InternalErrorReporterMock::lostTm() { lostTmCallCnt++; }
|
||||
void InternalErrorReporterMock::storeFull() { storeFullCallCnt++; }
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
||||
|
||||
class InternalErrorReporterMock: public InternalErrorReporterIF {
|
||||
class InternalErrorReporterMock : public InternalErrorReporterIF {
|
||||
public:
|
||||
unsigned int queueMsgNotSentCallCnt = 0;
|
||||
unsigned int lostTmCallCnt = 0;
|
||||
|
128
unittests/mocks/LocalPoolOwnerBase.cpp
Normal file
128
unittests/mocks/LocalPoolOwnerBase.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
#include "LocalPoolOwnerBase.h"
|
||||
|
||||
LocalPoolOwnerBase::LocalPoolOwnerBase(MessageQueueIF &queue, object_id_t objectId)
|
||||
: SystemObject(objectId),
|
||||
queue(queue),
|
||||
poolManager(this, &queue),
|
||||
dataset(this, lpool::testSetId) {}
|
||||
|
||||
LocalPoolOwnerBase::~LocalPoolOwnerBase() = default;
|
||||
|
||||
ReturnValue_t LocalPoolOwnerBase::initializeHkManager() {
|
||||
if (not initialized) {
|
||||
initialized = true;
|
||||
return poolManager.initialize(&queue);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t LocalPoolOwnerBase::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
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}));
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
{
|
||||
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);
|
||||
}
|
||||
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 = store_address_t::invalid();
|
||||
return condition;
|
||||
}
|
||||
|
||||
void LocalPoolOwnerBase::handleChangedDataset(sid_t sid, store_address_t 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 = store_address_t::invalid();
|
||||
return condition;
|
||||
}
|
||||
|
||||
ReturnValue_t LocalPoolOwnerBase::initializeHkManagerAfterTaskCreation() {
|
||||
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;
|
||||
}
|
||||
|
||||
void LocalPoolOwnerBase::setHkDestId(MessageQueueId_t id) { poolManager.setHkDestinationId(id); }
|
180
unittests/mocks/LocalPoolOwnerBase.h
Normal file
180
unittests/mocks/LocalPoolOwnerBase.h
Normal file
@ -0,0 +1,180 @@
|
||||
#ifndef FSFW_UNITTEST_TESTS_DATAPOOLLOCAL_LOCALPOOLOWNERBASE_H_
|
||||
#define FSFW_UNITTEST_TESTS_DATAPOOLLOCAL_LOCALPOOLOWNERBASE_H_
|
||||
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw/datapoollocal/HasLocalDataPoolIF.h>
|
||||
#include <fsfw/datapoollocal/LocalDataSet.h>
|
||||
#include <fsfw/datapoollocal/LocalPoolVariable.h>
|
||||
#include <fsfw/datapoollocal/LocalPoolVector.h>
|
||||
#include <fsfw/datapoollocal/StaticLocalDataSet.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;
|
||||
static constexpr lp_id_t floatVarId = 1;
|
||||
static constexpr lp_id_t uint32VarId = 2;
|
||||
static constexpr lp_id_t uint16Vec3Id = 3;
|
||||
static constexpr lp_id_t int64Vec2Id = 4;
|
||||
|
||||
static constexpr uint32_t testSetId = 0;
|
||||
static constexpr uint8_t dataSetMaxVariables = 10;
|
||||
|
||||
static const sid_t testSid = sid_t(objects::TEST_LOCAL_POOL_OWNER_BASE, testSetId);
|
||||
|
||||
static const gp_id_t uint8VarGpid = gp_id_t(objects::TEST_LOCAL_POOL_OWNER_BASE, uint8VarId);
|
||||
static const gp_id_t floatVarGpid = gp_id_t(objects::TEST_LOCAL_POOL_OWNER_BASE, floatVarId);
|
||||
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) {}
|
||||
|
||||
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:
|
||||
};
|
||||
|
||||
class LocalPoolTestDataSet : public LocalDataSet {
|
||||
public:
|
||||
LocalPoolTestDataSet() : LocalDataSet(lpool::testSid, 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);
|
||||
|
||||
void setDiagnostic(bool isDiagnostic) { LocalPoolDataSetBase::setDiagnostic(isDiagnostic); }
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class LocalPoolOwnerBase : public SystemObject, public HasLocalDataPoolIF {
|
||||
public:
|
||||
explicit LocalPoolOwnerBase(MessageQueueIF& queue,
|
||||
object_id_t objectId = objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||
|
||||
~LocalPoolOwnerBase() override;
|
||||
|
||||
[[nodiscard]] object_id_t getObjectId() const override { return SystemObject::getObjectId(); }
|
||||
|
||||
ReturnValue_t initializeHkManager();
|
||||
|
||||
void setHkDestId(MessageQueueId_t id);
|
||||
|
||||
ReturnValue_t initializeHkManagerAfterTaskCreation();
|
||||
|
||||
/** Command queue for housekeeping messages. */
|
||||
[[nodiscard]] MessageQueueId_t getCommandQueue() const override { return queue.getId(); }
|
||||
|
||||
// This is called by initializeAfterTaskCreation of the HK manager.
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
|
||||
LocalDataPoolManager* getHkManagerHandle() override { return &poolManager; }
|
||||
|
||||
[[nodiscard]] 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
|
||||
*/
|
||||
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override { return &dataset; }
|
||||
|
||||
LocalPoolObjectBase* getPoolObjectHandle(lp_id_t localPoolId) override;
|
||||
|
||||
[[nodiscard]] MessageQueueMockBase& getMockQueueHandle() const {
|
||||
return dynamic_cast<MessageQueueMockBase&>(queue);
|
||||
}
|
||||
|
||||
ReturnValue_t subscribePeriodicHk(bool enableReporting) {
|
||||
return poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(lpool::testSid, enableReporting, 0.2));
|
||||
}
|
||||
|
||||
ReturnValue_t subscribeWrapperSetUpdate(MessageQueueId_t receiverId) {
|
||||
return poolManager.subscribeForSetUpdateMessage(lpool::testSetId, objects::NO_OBJECT,
|
||||
receiverId, false);
|
||||
}
|
||||
|
||||
ReturnValue_t subscribeWrapperSetUpdateSnapshot(MessageQueueId_t receiverId) {
|
||||
return poolManager.subscribeForSetUpdateMessage(lpool::testSetId, objects::NO_OBJECT,
|
||||
receiverId, true);
|
||||
}
|
||||
|
||||
ReturnValue_t subscribeWrapperSetUpdateHk(bool diagnostics = false,
|
||||
AcceptsHkPacketsIF* receiver = nullptr) {
|
||||
if (diagnostics) {
|
||||
auto params = subdp::DiagnosticsHkUpdateParams(lpool::testSid, true);
|
||||
if (receiver != nullptr) {
|
||||
params.receiver = receiver->getHkQueue();
|
||||
}
|
||||
return poolManager.subscribeForDiagUpdatePacket(params);
|
||||
} else {
|
||||
auto params = subdp::RegularHkUpdateParams(lpool::testSid, true);
|
||||
if (receiver != nullptr) {
|
||||
params.receiver = receiver->getHkQueue();
|
||||
}
|
||||
return poolManager.subscribeForRegularUpdatePacket(params);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t subscribeWrapperVariableUpdate(MessageQueueId_t receiverId, lp_id_t localPoolId) {
|
||||
return poolManager.subscribeForVariableUpdateMessage(localPoolId, MessageQueueIF::NO_QUEUE,
|
||||
receiverId, false);
|
||||
}
|
||||
|
||||
ReturnValue_t subscribeWrapperVariableSnapshot(MessageQueueId_t receiverId, lp_id_t localPoolId) {
|
||||
return poolManager.subscribeForVariableUpdateMessage(localPoolId, MessageQueueIF::NO_QUEUE,
|
||||
receiverId, true);
|
||||
}
|
||||
|
||||
ReturnValue_t reset();
|
||||
|
||||
void resetSubscriptionList() { poolManager.clearReceiversList(); }
|
||||
|
||||
bool changedDataSetCallbackWasCalled(sid_t& sid, store_address_t& storeId);
|
||||
bool changedVariableCallbackWasCalled(gp_id_t& gpid, store_address_t& storeId);
|
||||
|
||||
LocalDataPoolManager poolManager;
|
||||
LocalPoolTestDataSet dataset;
|
||||
|
||||
private:
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
MessageQueueIF& queue;
|
||||
|
||||
bool initialized = false;
|
||||
bool initializedAfterTaskCreation = false;
|
||||
};
|
||||
|
||||
#endif /* FSFW_UNITTEST_TESTS_DATAPOOLLOCAL_LOCALPOOLOWNERBASE_H_ */
|
@ -1,5 +1,7 @@
|
||||
#include "MessageQueueMockBase.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
MessageQueueMockBase::MessageQueueMockBase()
|
||||
: MessageQueueBase(MessageQueueIF::NO_QUEUE, MessageQueueIF::NO_QUEUE, nullptr) {}
|
||||
@ -7,32 +9,47 @@ MessageQueueMockBase::MessageQueueMockBase()
|
||||
MessageQueueMockBase::MessageQueueMockBase(MessageQueueId_t queueId)
|
||||
: MessageQueueBase(queueId, MessageQueueIF::NO_QUEUE, nullptr) {}
|
||||
|
||||
bool MessageQueueMockBase::wasMessageSent(uint8_t* messageSentCounter_, bool resetCounter) {
|
||||
bool tempMessageSent = messageSent;
|
||||
messageSent = false;
|
||||
if (messageSentCounter_ != nullptr) {
|
||||
*messageSentCounter_ = this->messageSentCounter;
|
||||
}
|
||||
if (resetCounter) {
|
||||
this->messageSentCounter = 0;
|
||||
}
|
||||
return tempMessageSent;
|
||||
bool MessageQueueMockBase::wasMessageSent() const {
|
||||
return std::any_of(
|
||||
sendMap.begin(), sendMap.end(),
|
||||
[](const std::pair<MessageQueueId_t, SendInfo>& pair) { return pair.second.callCount > 0; });
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueueMockBase::popMessage() {
|
||||
CommandMessage message;
|
||||
message.clear();
|
||||
return receiveMessage(&message);
|
||||
size_t MessageQueueMockBase::numberOfSentMessage() const {
|
||||
size_t callCount = 0;
|
||||
for (auto& destInfo : sendMap) {
|
||||
callCount += destInfo.second.callCount;
|
||||
}
|
||||
return callCount;
|
||||
}
|
||||
|
||||
size_t MessageQueueMockBase::numberOfSentMessage(MessageQueueId_t id) const {
|
||||
auto iter = sendMap.find(id);
|
||||
if (iter == sendMap.end()) {
|
||||
return 0;
|
||||
}
|
||||
return iter->second.callCount;
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueueMockBase::clearLastReceivedMessage(bool clearCmdMsg) {
|
||||
if (receivedMsgs.empty()) {
|
||||
return MessageQueueIF::EMPTY;
|
||||
}
|
||||
if (clearCmdMsg) {
|
||||
CommandMessage message;
|
||||
std::memcpy(message.getBuffer(), receivedMsgs.front().getBuffer(), message.getMessageSize());
|
||||
message.clearCommandMessage();
|
||||
}
|
||||
receivedMsgs.pop_front();
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueueMockBase::receiveMessage(MessageQueueMessageIF* message) {
|
||||
if (messagesSentQueue.empty()) {
|
||||
if (receivedMsgs.empty()) {
|
||||
return MessageQueueIF::EMPTY;
|
||||
}
|
||||
this->last = message->getSender();
|
||||
std::memcpy(message->getBuffer(), messagesSentQueue.front().getBuffer(),
|
||||
message->getMessageSize());
|
||||
messagesSentQueue.pop();
|
||||
std::memcpy(message->getBuffer(), receivedMsgs.front().getBuffer(), message->getMessageSize());
|
||||
receivedMsgs.pop_front();
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
@ -43,12 +60,18 @@ ReturnValue_t MessageQueueMockBase::flush(uint32_t* count) {
|
||||
ReturnValue_t MessageQueueMockBase::sendMessageFrom(MessageQueueId_t sendTo,
|
||||
MessageQueueMessageIF* message,
|
||||
MessageQueueId_t sentFrom, bool ignoreFault) {
|
||||
if (message == nullptr) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
auto iter = sendMap.find(sendTo);
|
||||
MessageQueueMessage messageCopy;
|
||||
if (iter == sendMap.end()) {
|
||||
sendMap.emplace(sendTo, SendInfo(message, 1));
|
||||
createMsgCopy(messageCopy, *message);
|
||||
sendMap.emplace(sendTo, SendInfo(messageCopy, 1));
|
||||
} else {
|
||||
iter->second.callCount += 1;
|
||||
iter->second.msgs.push(message);
|
||||
createMsgCopy(messageCopy, *message);
|
||||
iter->second.msgs.push_back(messageCopy);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
@ -58,19 +81,87 @@ ReturnValue_t MessageQueueMockBase::reply(MessageQueueMessageIF* message) {
|
||||
}
|
||||
|
||||
void MessageQueueMockBase::clearMessages(bool clearCommandMessages) {
|
||||
for (const auto& destInfo: sendMap) {
|
||||
if (clearCommandMessages) {
|
||||
CommandMessage message;
|
||||
std::memcpy(message.getBuffer(), destInfo.second.msgs.front()->getBuffer(),
|
||||
message.getMessageSize());
|
||||
if (not clearCommandMessages) {
|
||||
sendMap.clear();
|
||||
return;
|
||||
}
|
||||
while (not messagesSentQueue.empty()) {
|
||||
if (clearCommandMessages) {
|
||||
for (auto& destInfo : sendMap) {
|
||||
for (auto& msg : destInfo.second.msgs) {
|
||||
CommandMessage message;
|
||||
std::memcpy(message.getBuffer(), messagesSentQueue.front().getBuffer(),
|
||||
std::memcpy(message.getBuffer(), destInfo.second.msgs.front().getBuffer(),
|
||||
message.getMessageSize());
|
||||
message.clear();
|
||||
destInfo.second.msgs.pop_front();
|
||||
destInfo.second.callCount--;
|
||||
}
|
||||
}
|
||||
sendMap.clear();
|
||||
}
|
||||
|
||||
void MessageQueueMockBase::addReceivedMessage(MessageQueueMessageIF& msg) {
|
||||
MessageQueueMessage messageCopy;
|
||||
createMsgCopy(messageCopy, msg);
|
||||
receivedMsgs.push_back(messageCopy);
|
||||
}
|
||||
|
||||
void MessageQueueMockBase::createMsgCopy(MessageQueueMessageIF& into, MessageQueueMessageIF& from) {
|
||||
if (from.getMessageSize() > into.getMaximumDataSize()) {
|
||||
throw std::invalid_argument("Passed message does not fit into message copy");
|
||||
}
|
||||
std::memcpy(into.getBuffer(), from.getBuffer(), from.getMaximumDataSize());
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueueMockBase::getNextSentMessage(MessageQueueId_t id,
|
||||
MessageQueueMessageIF& message) {
|
||||
auto iter = sendMap.find(id);
|
||||
if (iter == sendMap.end() or iter->second.callCount == 0) {
|
||||
return MessageQueueIF::EMPTY;
|
||||
}
|
||||
createMsgCopy(message, iter->second.msgs.front());
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueueMockBase::getNextSentMessage(MessageQueueMessageIF& message) {
|
||||
return getNextSentMessage(MessageQueueBase::getDefaultDestination(), message);
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueueMockBase::clearLastSentMessage(MessageQueueId_t destId,
|
||||
bool clearCmdMsg) {
|
||||
auto iter = sendMap.find(destId);
|
||||
if (iter == sendMap.end()) {
|
||||
return MessageQueueIF::EMPTY;
|
||||
}
|
||||
return clearLastSentMessage(iter, clearCmdMsg);
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueueMockBase::clearLastSentMessage(bool clearCmdMsg) {
|
||||
auto iter = sendMap.find(getDefaultDestination());
|
||||
if (iter == sendMap.end()) {
|
||||
return MessageQueueIF::EMPTY;
|
||||
}
|
||||
ReturnValue_t result = clearLastSentMessage(iter, clearCmdMsg);
|
||||
clearEmptyEntries();
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t MessageQueueMockBase::clearLastSentMessage(
|
||||
std::map<MessageQueueId_t, SendInfo>::iterator& iter, bool clearCmdMsg) {
|
||||
if (clearCmdMsg) {
|
||||
CommandMessage message;
|
||||
std::memcpy(message.getBuffer(), iter->second.msgs.front().getBuffer(),
|
||||
message.getMessageSize());
|
||||
message.clear();
|
||||
}
|
||||
iter->second.msgs.pop_front();
|
||||
iter->second.callCount--;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
void MessageQueueMockBase::clearEmptyEntries() {
|
||||
for (auto it = sendMap.cbegin(); it != sendMap.cend();) {
|
||||
if (it->second.callCount == 0) {
|
||||
sendMap.erase(it++);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
messagesSentQueue.pop();
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
#define FSFW_UNITTEST_TESTS_MOCKS_MESSAGEQUEUEMOCKBASE_H_
|
||||
|
||||
#include <cstring>
|
||||
#include <queue>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
|
||||
#include "CatchDefinitions.h"
|
||||
#include "fsfw/ipc/CommandMessage.h"
|
||||
@ -12,39 +12,52 @@
|
||||
#include "fsfw/ipc/MessageQueueMessage.h"
|
||||
|
||||
struct SendInfo {
|
||||
explicit SendInfo(MessageQueueMessageIF* initMsg, unsigned int initCallCnt = 1): callCount(initCallCnt) {
|
||||
msgs.push(initMsg);
|
||||
explicit SendInfo(MessageQueueMessage& initMsg, unsigned int initCallCnt = 1)
|
||||
: callCount(initCallCnt) {
|
||||
msgs.push_back(initMsg);
|
||||
}
|
||||
unsigned int callCount = 0;
|
||||
std::queue<MessageQueueMessageIF*> msgs;
|
||||
std::deque<MessageQueueMessage> msgs;
|
||||
};
|
||||
|
||||
class MessageQueueMockBase : public MessageQueueBase {
|
||||
public:
|
||||
MessageQueueMockBase();
|
||||
|
||||
void addReceivedMessage(MessageQueueMessageIF& msg);
|
||||
explicit MessageQueueMockBase(MessageQueueId_t queueId);
|
||||
|
||||
std::map<MessageQueueId_t, SendInfo> sendMap;
|
||||
|
||||
bool wasMessageSent(uint8_t* messageSentCounter_ = nullptr, bool resetCounter = true);
|
||||
|
||||
//! Get next message which was sent to the default destination
|
||||
ReturnValue_t getNextSentMessage(MessageQueueMessageIF& message);
|
||||
//! Get message which was sent to a specific ID
|
||||
ReturnValue_t getNextSentMessage(MessageQueueId_t id, MessageQueueMessageIF& message);
|
||||
[[nodiscard]] bool wasMessageSent() const;
|
||||
[[nodiscard]] size_t numberOfSentMessage() const;
|
||||
[[nodiscard]] size_t numberOfSentMessage(MessageQueueId_t id) const;
|
||||
/**
|
||||
* Pop a message, clearing it in the process.
|
||||
* @return
|
||||
*/
|
||||
ReturnValue_t popMessage();
|
||||
|
||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override;
|
||||
ReturnValue_t clearLastReceivedMessage(bool clearCmdMsg = true);
|
||||
|
||||
ReturnValue_t flush(uint32_t* count) override;
|
||||
ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
MessageQueueId_t sentFrom,
|
||||
bool ignoreFault = false) override;
|
||||
MessageQueueId_t sentFrom, bool ignoreFault = false) override;
|
||||
ReturnValue_t reply(MessageQueueMessageIF* message) override;
|
||||
|
||||
void clearMessages(bool clearCommandMessages = true);
|
||||
ReturnValue_t clearLastSentMessage(MessageQueueId_t destId, bool clearCmdMsg = true);
|
||||
ReturnValue_t clearLastSentMessage(bool clearCmdMsg = true);
|
||||
void clearMessages(bool clearCmdMsg = true);
|
||||
|
||||
private:
|
||||
using SendMap = std::map<MessageQueueId_t, SendInfo>;
|
||||
SendMap sendMap;
|
||||
std::deque<MessageQueueMessage> receivedMsgs;
|
||||
|
||||
void clearEmptyEntries();
|
||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override;
|
||||
static ReturnValue_t clearLastSentMessage(SendMap::iterator& iter, bool clearCmdMsg = true);
|
||||
static void createMsgCopy(MessageQueueMessageIF& into, MessageQueueMessageIF& from);
|
||||
};
|
||||
|
||||
#endif /* FSFW_UNITTEST_TESTS_MOCKS_MESSAGEQUEUEMOCKBASE_H_ */
|
||||
|
Reference in New Issue
Block a user