cleaning up message queue mock and subscription API
This commit is contained in:
parent
5fd5d488ff
commit
6d0fa36f8a
@ -79,8 +79,7 @@ class HasLocalDataPoolIF {
|
|||||||
* @param clearMessage If this is set to true, the pool manager will take care of
|
* @param clearMessage If this is set to true, the pool manager will take care of
|
||||||
* clearing the store automatically
|
* clearing the store automatically
|
||||||
*/
|
*/
|
||||||
virtual void handleChangedDataset(sid_t sid,
|
virtual void handleChangedDataset(sid_t sid, store_address_t storeId = store_address_t::invalid(),
|
||||||
store_address_t storeId = store_address_t::invalid(),
|
|
||||||
bool* clearMessage = nullptr) {
|
bool* clearMessage = nullptr) {
|
||||||
if (clearMessage != nullptr) {
|
if (clearMessage != nullptr) {
|
||||||
*clearMessage = true;
|
*clearMessage = true;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
#include "fsfw/datapoollocal/LocalDataPoolManager.h"
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "fsfw/datapoollocal.h"
|
#include "fsfw/datapoollocal.h"
|
||||||
@ -15,6 +14,7 @@
|
|||||||
#include "internal/HasLocalDpIFManagerAttorney.h"
|
#include "internal/HasLocalDpIFManagerAttorney.h"
|
||||||
#include "internal/LocalPoolDataSetAttorney.h"
|
#include "internal/LocalPoolDataSetAttorney.h"
|
||||||
|
|
||||||
|
// TODO: Get rid of this. This should be a constructor argument, not something hardcoded in any way
|
||||||
object_id_t LocalDataPoolManager::defaultHkDestination = objects::PUS_SERVICE_3_HOUSEKEEPING;
|
object_id_t LocalDataPoolManager::defaultHkDestination = objects::PUS_SERVICE_3_HOUSEKEEPING;
|
||||||
|
|
||||||
LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse,
|
LocalDataPoolManager::LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse,
|
||||||
@ -57,7 +57,7 @@ ReturnValue_t LocalDataPoolManager::initialize(MessageQueueIF* queueToUse) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (defaultHkDestination != objects::NO_OBJECT) {
|
if (defaultHkDestination != objects::NO_OBJECT) {
|
||||||
AcceptsHkPacketsIF* hkPacketReceiver =
|
auto* hkPacketReceiver =
|
||||||
ObjectManager::instance()->get<AcceptsHkPacketsIF>(defaultHkDestination);
|
ObjectManager::instance()->get<AcceptsHkPacketsIF>(defaultHkDestination);
|
||||||
if (hkPacketReceiver != nullptr) {
|
if (hkPacketReceiver != nullptr) {
|
||||||
hkDestinationId = hkPacketReceiver->getHkQueue();
|
hkDestinationId = hkPacketReceiver->getHkQueue();
|
||||||
@ -335,29 +335,32 @@ void LocalDataPoolManager::resetHkUpdateResetHelper() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid, bool enableReporting,
|
ReturnValue_t LocalDataPoolManager::subscribeForRegularPeriodicPacket(
|
||||||
float collectionInterval,
|
subdp::RegularHkPeriodicParams params) {
|
||||||
bool isDiagnostics,
|
return subscribeForPeriodicPacket(params);
|
||||||
object_id_t packetDestination) {
|
}
|
||||||
AcceptsHkPacketsIF* hkReceiverObject =
|
|
||||||
ObjectManager::instance()->get<AcceptsHkPacketsIF>(packetDestination);
|
|
||||||
if (hkReceiverObject == nullptr) {
|
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "subscribeForPeriodicPacket",
|
|
||||||
QUEUE_OR_DESTINATION_INVALID);
|
|
||||||
return QUEUE_OR_DESTINATION_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
ReturnValue_t LocalDataPoolManager::subscribeForDiagPeriodicPacket(
|
||||||
|
subdp::DiagnosticsHkPeriodicParams params) {
|
||||||
|
return subscribeForPeriodicPacket(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(subdp::ParamsBase& params) {
|
||||||
struct HkReceiver hkReceiver;
|
struct HkReceiver hkReceiver;
|
||||||
hkReceiver.dataId.sid = sid;
|
hkReceiver.dataId.sid = params.sid;
|
||||||
hkReceiver.reportingType = ReportingType::PERIODIC;
|
hkReceiver.reportingType = ReportingType::PERIODIC;
|
||||||
hkReceiver.dataType = DataType::DATA_SET;
|
hkReceiver.dataType = DataType::DATA_SET;
|
||||||
hkReceiver.destinationQueue = hkReceiverObject->getHkQueue();
|
if (params.receiver == MessageQueueIF::NO_QUEUE) {
|
||||||
|
hkReceiver.destinationQueue = hkDestinationId;
|
||||||
|
} else {
|
||||||
|
hkReceiver.destinationQueue = params.receiver;
|
||||||
|
}
|
||||||
|
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, params.sid);
|
||||||
if (dataSet != nullptr) {
|
if (dataSet != nullptr) {
|
||||||
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, enableReporting);
|
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, params.enableReporting);
|
||||||
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, isDiagnostics);
|
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, params.isDiagnostics());
|
||||||
LocalPoolDataSetAttorney::initializePeriodicHelper(*dataSet, collectionInterval,
|
LocalPoolDataSetAttorney::initializePeriodicHelper(*dataSet, params.collectionInterval,
|
||||||
owner->getPeriodicOperationFrequency());
|
owner->getPeriodicOperationFrequency());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,27 +368,30 @@ ReturnValue_t LocalDataPoolManager::subscribeForPeriodicPacket(sid_t sid, bool e
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalDataPoolManager::subscribeForUpdatePacket(sid_t sid, bool isDiagnostics,
|
ReturnValue_t LocalDataPoolManager::subscribeForRegularUpdatePacket(
|
||||||
bool reportingEnabled,
|
subdp::RegularHkUpdateParams params) {
|
||||||
object_id_t packetDestination) {
|
return subscribeForUpdatePacket(params);
|
||||||
AcceptsHkPacketsIF* hkReceiverObject =
|
}
|
||||||
ObjectManager::instance()->get<AcceptsHkPacketsIF>(packetDestination);
|
ReturnValue_t LocalDataPoolManager::subscribeForDiagUpdatePacket(
|
||||||
if (hkReceiverObject == nullptr) {
|
subdp::DiagnosticsHkUpdateParams params) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "subscribeForPeriodicPacket",
|
return subscribeForUpdatePacket(params);
|
||||||
QUEUE_OR_DESTINATION_INVALID);
|
}
|
||||||
return QUEUE_OR_DESTINATION_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
ReturnValue_t LocalDataPoolManager::subscribeForUpdatePacket(subdp::ParamsBase& params) {
|
||||||
struct HkReceiver hkReceiver;
|
struct HkReceiver hkReceiver;
|
||||||
hkReceiver.dataId.sid = sid;
|
hkReceiver.dataId.sid = params.sid;
|
||||||
hkReceiver.reportingType = ReportingType::UPDATE_HK;
|
hkReceiver.reportingType = ReportingType::UPDATE_HK;
|
||||||
hkReceiver.dataType = DataType::DATA_SET;
|
hkReceiver.dataType = DataType::DATA_SET;
|
||||||
hkReceiver.destinationQueue = hkReceiverObject->getHkQueue();
|
if (params.receiver == MessageQueueIF::NO_QUEUE) {
|
||||||
|
hkReceiver.destinationQueue = hkDestinationId;
|
||||||
|
} else {
|
||||||
|
hkReceiver.destinationQueue = params.receiver;
|
||||||
|
}
|
||||||
|
|
||||||
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, sid);
|
LocalPoolDataSetBase* dataSet = HasLocalDpIFManagerAttorney::getDataSetHandle(owner, params.sid);
|
||||||
if (dataSet != nullptr) {
|
if (dataSet != nullptr) {
|
||||||
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, true);
|
LocalPoolDataSetAttorney::setReportingEnabled(*dataSet, true);
|
||||||
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, isDiagnostics);
|
LocalPoolDataSetAttorney::setDiagnostic(*dataSet, params.isDiagnostics());
|
||||||
}
|
}
|
||||||
|
|
||||||
hkReceivers.push_back(hkReceiver);
|
hkReceivers.push_back(hkReceiver);
|
||||||
@ -639,6 +645,7 @@ ReturnValue_t LocalDataPoolManager::generateHousekeepingPacket(sid_t sid,
|
|||||||
/* Error, all destinations invalid */
|
/* Error, all destinations invalid */
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateHousekeepingPacket",
|
printWarningOrError(sif::OutputTypes::OUT_WARNING, "generateHousekeepingPacket",
|
||||||
QUEUE_OR_DESTINATION_INVALID);
|
QUEUE_OR_DESTINATION_INVALID);
|
||||||
|
return QUEUE_OR_DESTINATION_INVALID;
|
||||||
}
|
}
|
||||||
destination = hkDestinationId;
|
destination = hkDestinationId;
|
||||||
}
|
}
|
||||||
@ -879,3 +886,7 @@ void LocalDataPoolManager::printWarningOrError(sif::OutputTypes outputType,
|
|||||||
}
|
}
|
||||||
|
|
||||||
LocalDataPoolManager* LocalDataPoolManager::getPoolManagerHandle() { return this; }
|
LocalDataPoolManager* LocalDataPoolManager::getPoolManagerHandle() { return this; }
|
||||||
|
|
||||||
|
void LocalDataPoolManager::setHkDestinationId(MessageQueueId_t hkDestId) {
|
||||||
|
hkDestinationId = hkDestId;
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "ProvidesDataPoolSubscriptionIF.h"
|
#include "ProvidesDataPoolSubscriptionIF.h"
|
||||||
#include "fsfw/datapool/DataSetIF.h"
|
#include "fsfw/datapool/DataSetIF.h"
|
||||||
#include "fsfw/datapool/PoolEntry.h"
|
#include "fsfw/datapool/PoolEntry.h"
|
||||||
|
#include "fsfw/housekeeping/AcceptsHkPacketsIF.h"
|
||||||
#include "fsfw/housekeeping/HousekeepingMessage.h"
|
#include "fsfw/housekeeping/HousekeepingMessage.h"
|
||||||
#include "fsfw/housekeeping/HousekeepingPacketDownlink.h"
|
#include "fsfw/housekeeping/HousekeepingPacketDownlink.h"
|
||||||
#include "fsfw/housekeeping/PeriodicHousekeepingHelper.h"
|
#include "fsfw/housekeeping/PeriodicHousekeepingHelper.h"
|
||||||
@ -80,7 +81,9 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
|||||||
*/
|
*/
|
||||||
LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse,
|
LocalDataPoolManager(HasLocalDataPoolIF* owner, MessageQueueIF* queueToUse,
|
||||||
bool appendValidityBuffer = true);
|
bool appendValidityBuffer = true);
|
||||||
virtual ~LocalDataPoolManager();
|
~LocalDataPoolManager() override;
|
||||||
|
|
||||||
|
void setHkDestinationId(MessageQueueId_t hkDestId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assigns the queue to use. Make sure to call this in the #initialize
|
* Assigns the queue to use. Make sure to call this in the #initialize
|
||||||
@ -112,31 +115,6 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
|||||||
*/
|
*/
|
||||||
virtual ReturnValue_t performHkOperation();
|
virtual ReturnValue_t performHkOperation();
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Subscribe for the generation of periodic packets.
|
|
||||||
* @details
|
|
||||||
* This subscription mechanism will generally be used by the data creator
|
|
||||||
* to generate housekeeping packets which are downlinked directly.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ReturnValue_t subscribeForPeriodicPacket(
|
|
||||||
sid_t sid, bool enableReporting, float collectionInterval, bool isDiagnostics,
|
|
||||||
object_id_t packetDestination = defaultHkDestination) override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Subscribe for the generation of packets if the dataset
|
|
||||||
* is marked as changed.
|
|
||||||
* @details
|
|
||||||
* This subscription mechanism will generally be used by the data creator.
|
|
||||||
* @param sid
|
|
||||||
* @param isDiagnostics
|
|
||||||
* @param packetDestination
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
ReturnValue_t subscribeForUpdatePacket(
|
|
||||||
sid_t sid, bool reportingEnabled, bool isDiagnostics,
|
|
||||||
object_id_t packetDestination = defaultHkDestination) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Subscribe for a notification message which will be sent
|
* @brief Subscribe for a notification message which will be sent
|
||||||
* if a dataset has changed.
|
* if a dataset has changed.
|
||||||
@ -151,7 +129,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
|||||||
* Otherwise, only an notification message is sent.
|
* Otherwise, only an notification message is sent.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ReturnValue_t subscribeForSetUpdateMessage(const uint32_t setId, object_id_t destinationObject,
|
ReturnValue_t subscribeForSetUpdateMessage(uint32_t setId, object_id_t destinationObject,
|
||||||
MessageQueueId_t targetQueueId,
|
MessageQueueId_t targetQueueId,
|
||||||
bool generateSnapshot) override;
|
bool generateSnapshot) override;
|
||||||
|
|
||||||
@ -169,7 +147,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
|||||||
* Otherwise, only an notification message is sent.
|
* Otherwise, only an notification message is sent.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ReturnValue_t subscribeForVariableUpdateMessage(const lp_id_t localPoolId,
|
ReturnValue_t subscribeForVariableUpdateMessage(lp_id_t localPoolId,
|
||||||
object_id_t destinationObject,
|
object_id_t destinationObject,
|
||||||
MessageQueueId_t targetQueueId,
|
MessageQueueId_t targetQueueId,
|
||||||
bool generateSnapshot) override;
|
bool generateSnapshot) override;
|
||||||
@ -252,7 +230,7 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
|||||||
*/
|
*/
|
||||||
void clearReceiversList();
|
void clearReceiversList();
|
||||||
|
|
||||||
object_id_t getCreatorObjectId() const;
|
[[nodiscard]] object_id_t getCreatorObjectId() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the pointer to the mutex. Can be used to lock the data pool
|
* Get the pointer to the mutex. Can be used to lock the data pool
|
||||||
@ -262,7 +240,14 @@ class LocalDataPoolManager : public ProvidesDataPoolSubscriptionIF, public Acces
|
|||||||
*/
|
*/
|
||||||
MutexIF* getMutexHandle();
|
MutexIF* getMutexHandle();
|
||||||
|
|
||||||
virtual LocalDataPoolManager* getPoolManagerHandle() override;
|
LocalDataPoolManager* getPoolManagerHandle() override;
|
||||||
|
ReturnValue_t subscribeForRegularPeriodicPacket(subdp::RegularHkPeriodicParams params) override;
|
||||||
|
ReturnValue_t subscribeForDiagPeriodicPacket(subdp::DiagnosticsHkPeriodicParams params) override;
|
||||||
|
ReturnValue_t subscribeForPeriodicPacket(subdp::ParamsBase& params);
|
||||||
|
|
||||||
|
ReturnValue_t subscribeForRegularUpdatePacket(subdp::RegularHkUpdateParams params) override;
|
||||||
|
ReturnValue_t subscribeForDiagUpdatePacket(subdp::DiagnosticsHkUpdateParams params) override;
|
||||||
|
ReturnValue_t subscribeForUpdatePacket(subdp::ParamsBase& params);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Core data structure for the actual pool data */
|
/** Core data structure for the actual pool data */
|
||||||
|
@ -1,14 +1,56 @@
|
|||||||
#ifndef FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_
|
#ifndef FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_
|
||||||
#define FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_
|
#define FSFW_DATAPOOLLOCAL_PROVIDESDATAPOOLSUBSCRIPTION_H_
|
||||||
|
|
||||||
#include "../ipc/messageQueueDefinitions.h"
|
#include "fsfw/housekeeping/AcceptsHkPacketsIF.h"
|
||||||
#include "../returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/ipc/MessageQueueIF.h"
|
||||||
|
#include "fsfw/ipc/messageQueueDefinitions.h"
|
||||||
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
#include "localPoolDefinitions.h"
|
#include "localPoolDefinitions.h"
|
||||||
|
|
||||||
|
namespace subdp {
|
||||||
|
|
||||||
|
struct ParamsBase {
|
||||||
|
ParamsBase(sid_t sid, bool enableReporting, float collectionInterval, bool diagnostics)
|
||||||
|
: sid(sid),
|
||||||
|
enableReporting(enableReporting),
|
||||||
|
collectionInterval(collectionInterval),
|
||||||
|
diagnostics(diagnostics) {}
|
||||||
|
|
||||||
|
[[nodiscard]] bool isDiagnostics() const { return diagnostics; }
|
||||||
|
|
||||||
|
sid_t sid;
|
||||||
|
bool enableReporting;
|
||||||
|
float collectionInterval;
|
||||||
|
MessageQueueId_t receiver = MessageQueueIF::NO_QUEUE;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool diagnostics;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RegularHkPeriodicParams : public ParamsBase {
|
||||||
|
RegularHkPeriodicParams(sid_t sid, bool enableReporting, float collectionInterval)
|
||||||
|
: ParamsBase(sid, enableReporting, collectionInterval, false) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DiagnosticsHkPeriodicParams : public ParamsBase {
|
||||||
|
DiagnosticsHkPeriodicParams(sid_t sid, bool enableReporting, float collectionInterval)
|
||||||
|
: ParamsBase(sid, enableReporting, collectionInterval, true) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RegularHkUpdateParams : public ParamsBase {
|
||||||
|
RegularHkUpdateParams(sid_t sid, bool enableReporting)
|
||||||
|
: ParamsBase(sid, enableReporting, 0.0, false) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DiagnosticsHkUpdateParams : public ParamsBase {
|
||||||
|
DiagnosticsHkUpdateParams(sid_t sid, bool enableReporting)
|
||||||
|
: ParamsBase(sid, enableReporting, 0.0, true) {}
|
||||||
|
};
|
||||||
|
} // namespace subdp
|
||||||
|
|
||||||
class ProvidesDataPoolSubscriptionIF {
|
class ProvidesDataPoolSubscriptionIF {
|
||||||
public:
|
public:
|
||||||
virtual ~ProvidesDataPoolSubscriptionIF(){};
|
virtual ~ProvidesDataPoolSubscriptionIF() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Subscribe for the generation of periodic packets.
|
* @brief Subscribe for the generation of periodic packets.
|
||||||
* @details
|
* @details
|
||||||
@ -16,9 +58,11 @@ class ProvidesDataPoolSubscriptionIF {
|
|||||||
* to generate housekeeping packets which are downlinked directly.
|
* to generate housekeeping packets which are downlinked directly.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t subscribeForPeriodicPacket(sid_t sid, bool enableReporting,
|
virtual ReturnValue_t subscribeForRegularPeriodicPacket(
|
||||||
float collectionInterval, bool isDiagnostics,
|
subdp::RegularHkPeriodicParams params) = 0;
|
||||||
object_id_t packetDestination) = 0;
|
virtual ReturnValue_t subscribeForDiagPeriodicPacket(
|
||||||
|
subdp::DiagnosticsHkPeriodicParams params) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Subscribe for the generation of packets if the dataset
|
* @brief Subscribe for the generation of packets if the dataset
|
||||||
* is marked as changed.
|
* is marked as changed.
|
||||||
@ -29,9 +73,9 @@ class ProvidesDataPoolSubscriptionIF {
|
|||||||
* @param packetDestination
|
* @param packetDestination
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t subscribeForUpdatePacket(sid_t sid, bool reportingEnabled,
|
virtual ReturnValue_t subscribeForRegularUpdatePacket(subdp::RegularHkUpdateParams params) = 0;
|
||||||
bool isDiagnostics,
|
virtual ReturnValue_t subscribeForDiagUpdatePacket(subdp::DiagnosticsHkUpdateParams params) = 0;
|
||||||
object_id_t packetDestination) = 0;
|
|
||||||
/**
|
/**
|
||||||
* @brief Subscribe for a notification message which will be sent
|
* @brief Subscribe for a notification message which will be sent
|
||||||
* if a dataset has changed.
|
* if a dataset has changed.
|
||||||
@ -46,8 +90,7 @@ class ProvidesDataPoolSubscriptionIF {
|
|||||||
* Otherwise, only an notification message is sent.
|
* Otherwise, only an notification message is sent.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t subscribeForSetUpdateMessage(const uint32_t setId,
|
virtual ReturnValue_t subscribeForSetUpdateMessage(uint32_t setId, object_id_t destinationObject,
|
||||||
object_id_t destinationObject,
|
|
||||||
MessageQueueId_t targetQueueId,
|
MessageQueueId_t targetQueueId,
|
||||||
bool generateSnapshot) = 0;
|
bool generateSnapshot) = 0;
|
||||||
/**
|
/**
|
||||||
@ -64,7 +107,7 @@ class ProvidesDataPoolSubscriptionIF {
|
|||||||
* only an notification message is sent.
|
* only an notification message is sent.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t subscribeForVariableUpdateMessage(const lp_id_t localPoolId,
|
virtual ReturnValue_t subscribeForVariableUpdateMessage(lp_id_t localPoolId,
|
||||||
object_id_t destinationObject,
|
object_id_t destinationObject,
|
||||||
MessageQueueId_t targetQueueId,
|
MessageQueueId_t targetQueueId,
|
||||||
bool generateSnapshot) = 0;
|
bool generateSnapshot) = 0;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
#ifndef FRAMEWORK_HOUSEKEEPING_ACCEPTSHKPACKETSIF_H_
|
#ifndef FRAMEWORK_HOUSEKEEPING_ACCEPTSHKPACKETSIF_H_
|
||||||
#define FRAMEWORK_HOUSEKEEPING_ACCEPTSHKPACKETSIF_H_
|
#define FRAMEWORK_HOUSEKEEPING_ACCEPTSHKPACKETSIF_H_
|
||||||
|
|
||||||
#include "../ipc/MessageQueueMessageIF.h"
|
#include "fsfw/ipc/MessageQueueMessageIF.h"
|
||||||
|
|
||||||
class AcceptsHkPacketsIF {
|
class AcceptsHkPacketsIF {
|
||||||
public:
|
public:
|
||||||
virtual ~AcceptsHkPacketsIF(){};
|
virtual ~AcceptsHkPacketsIF() = default;
|
||||||
virtual MessageQueueId_t getHkQueue() const = 0;
|
[[nodiscard]] virtual MessageQueueId_t getHkQueue() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_HOUSEKEEPING_ACCEPTSHKPACKETSIF_H_ */
|
#endif /* FRAMEWORK_HOUSEKEEPING_ACCEPTSHKPACKETSIF_H_ */
|
||||||
|
@ -129,8 +129,9 @@ ReturnValue_t InternalErrorReporter::initializeLocalDataPool(localpool::DataPool
|
|||||||
localDataPoolMap.emplace(errorPoolIds::TM_HITS, new PoolEntry<uint32_t>());
|
localDataPoolMap.emplace(errorPoolIds::TM_HITS, new PoolEntry<uint32_t>());
|
||||||
localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS, new PoolEntry<uint32_t>());
|
localDataPoolMap.emplace(errorPoolIds::QUEUE_HITS, new PoolEntry<uint32_t>());
|
||||||
localDataPoolMap.emplace(errorPoolIds::STORE_HITS, new PoolEntry<uint32_t>());
|
localDataPoolMap.emplace(errorPoolIds::STORE_HITS, new PoolEntry<uint32_t>());
|
||||||
poolManager.subscribeForPeriodicPacket(internalErrorSid, false, getPeriodicOperationFrequency(),
|
poolManager.subscribeForDiagPeriodicPacket(subdp::DiagnosticsHkPeriodicParams(
|
||||||
true);
|
internalErrorSid, false,
|
||||||
|
static_cast<float>(getPeriodicOperationFrequency()) / static_cast<float>(1000.0)));
|
||||||
internalErrorDataset.setValidity(true, true);
|
internalErrorDataset.setValidity(true, true);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,18 @@ class MessageQueueBase : public MessageQueueIF {
|
|||||||
[[nodiscard]] MessageQueueId_t getDefaultDestination() const override;
|
[[nodiscard]] MessageQueueId_t getDefaultDestination() const override;
|
||||||
[[nodiscard]] bool isDefaultDestinationSet() const override;
|
[[nodiscard]] bool isDefaultDestinationSet() const override;
|
||||||
ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||||
bool ignoreFault) override;
|
bool ignoreFault) override;
|
||||||
ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override;
|
ReturnValue_t sendToDefault(MessageQueueMessageIF* message) override;
|
||||||
ReturnValue_t reply(MessageQueueMessageIF* message) override;
|
ReturnValue_t reply(MessageQueueMessageIF* message) override;
|
||||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
|
ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
|
||||||
MessageQueueId_t* receivedFrom) override;
|
MessageQueueId_t* receivedFrom) override;
|
||||||
ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
|
ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
|
||||||
bool ignoreFault = false) override;
|
bool ignoreFault = false) override;
|
||||||
|
|
||||||
// OSAL specific, forward the abstract function
|
// OSAL specific, forward the abstract function
|
||||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override = 0;
|
ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override = 0;
|
||||||
ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||||
MessageQueueId_t sentFrom, bool ignoreFault = false) override = 0;
|
MessageQueueId_t sentFrom, bool ignoreFault = false) override = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MessageQueueId_t id = MessageQueueIF::NO_QUEUE;
|
MessageQueueId_t id = MessageQueueIF::NO_QUEUE;
|
||||||
|
@ -10,10 +10,10 @@ MessageQueueMessage::MessageQueueMessage() : messageSize(getMinimumMessageSize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueMessage::MessageQueueMessage(uint8_t* data, size_t size)
|
MessageQueueMessage::MessageQueueMessage(uint8_t* data, size_t size)
|
||||||
: messageSize(this->HEADER_SIZE + size) {
|
: messageSize(MessageQueueMessage::HEADER_SIZE + size) {
|
||||||
if (size <= this->MAX_DATA_SIZE) {
|
if (size <= MessageQueueMessage::MAX_DATA_SIZE) {
|
||||||
memcpy(this->getData(), data, size);
|
std::memcpy(internalBuffer + MessageQueueMessage::HEADER_SIZE, data, size);
|
||||||
this->messageSize = this->HEADER_SIZE + size;
|
this->messageSize = MessageQueueMessage::HEADER_SIZE + size;
|
||||||
} else {
|
} else {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "MessageQueueMessage: Passed size larger than maximum"
|
sif::warning << "MessageQueueMessage: Passed size larger than maximum"
|
||||||
@ -21,21 +21,23 @@ MessageQueueMessage::MessageQueueMessage(uint8_t* data, size_t size)
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
memset(this->internalBuffer, 0, sizeof(this->internalBuffer));
|
memset(this->internalBuffer, 0, sizeof(this->internalBuffer));
|
||||||
this->messageSize = this->HEADER_SIZE;
|
this->messageSize = MessageQueueMessage::HEADER_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageQueueMessage::~MessageQueueMessage() {}
|
MessageQueueMessage::~MessageQueueMessage() = default;
|
||||||
|
|
||||||
const uint8_t* MessageQueueMessage::getBuffer() const { return this->internalBuffer; }
|
const uint8_t* MessageQueueMessage::getBuffer() const { return this->internalBuffer; }
|
||||||
|
|
||||||
uint8_t* MessageQueueMessage::getBuffer() { return this->internalBuffer; }
|
uint8_t* MessageQueueMessage::getBuffer() { return this->internalBuffer; }
|
||||||
|
|
||||||
const uint8_t* MessageQueueMessage::getData() const {
|
const uint8_t* MessageQueueMessage::getData() const {
|
||||||
return this->internalBuffer + this->HEADER_SIZE;
|
return this->internalBuffer + MessageQueueMessage::HEADER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* MessageQueueMessage::getData() { return this->internalBuffer + this->HEADER_SIZE; }
|
uint8_t* MessageQueueMessage::getData() {
|
||||||
|
return this->internalBuffer + MessageQueueMessage::HEADER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
MessageQueueId_t MessageQueueMessage::getSender() const {
|
MessageQueueId_t MessageQueueMessage::getSender() const {
|
||||||
MessageQueueId_t temp_id;
|
MessageQueueId_t temp_id;
|
||||||
@ -58,14 +60,22 @@ void MessageQueueMessage::print(bool printWholeMessage) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageQueueMessage::clear() { memset(this->getBuffer(), 0, this->MAX_MESSAGE_SIZE); }
|
void MessageQueueMessage::clear() {
|
||||||
|
memset(this->getBuffer(), 0, MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
size_t MessageQueueMessage::getMessageSize() const { return this->messageSize; }
|
size_t MessageQueueMessage::getMessageSize() const { return this->messageSize; }
|
||||||
|
|
||||||
void MessageQueueMessage::setMessageSize(size_t messageSize) { this->messageSize = messageSize; }
|
void MessageQueueMessage::setMessageSize(size_t messageSize_) { this->messageSize = messageSize_; }
|
||||||
|
|
||||||
size_t MessageQueueMessage::getMinimumMessageSize() const { return this->MIN_MESSAGE_SIZE; }
|
size_t MessageQueueMessage::getMinimumMessageSize() const {
|
||||||
|
return MessageQueueMessage::MIN_MESSAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
size_t MessageQueueMessage::getMaximumMessageSize() const { return this->MAX_MESSAGE_SIZE; }
|
size_t MessageQueueMessage::getMaximumMessageSize() const {
|
||||||
|
return MessageQueueMessage::MAX_MESSAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
size_t MessageQueueMessage::getMaximumDataSize() const { return this->MAX_DATA_SIZE; }
|
size_t MessageQueueMessage::getMaximumDataSize() const {
|
||||||
|
return MessageQueueMessage::MAX_DATA_SIZE;
|
||||||
|
}
|
||||||
|
@ -25,6 +25,30 @@
|
|||||||
*/
|
*/
|
||||||
class MessageQueueMessage : public MessageQueueMessageIF {
|
class MessageQueueMessage : public MessageQueueMessageIF {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief This constant defines the maximum size of the data content,
|
||||||
|
* excluding the header.
|
||||||
|
* @details
|
||||||
|
* It may be changed if necessary, but in general should be kept
|
||||||
|
* as small as possible.
|
||||||
|
*/
|
||||||
|
static const size_t MAX_DATA_SIZE = 24;
|
||||||
|
/**
|
||||||
|
* @brief This constant defines the maximum total size in bytes
|
||||||
|
* of a sent message.
|
||||||
|
* @details
|
||||||
|
* It is the sum of the maximum data and the header size. Be aware that
|
||||||
|
* this constant is used to define the buffer sizes for every message
|
||||||
|
* queue in the system. So, a change here may have significant impact on
|
||||||
|
* the required resources.
|
||||||
|
*/
|
||||||
|
static constexpr size_t MAX_MESSAGE_SIZE = MAX_DATA_SIZE + HEADER_SIZE;
|
||||||
|
/**
|
||||||
|
* @brief Defines the minimum size of a message where only the
|
||||||
|
* header is included
|
||||||
|
*/
|
||||||
|
static constexpr size_t MIN_MESSAGE_SIZE = HEADER_SIZE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The class is initialized empty with this constructor.
|
* @brief The class is initialized empty with this constructor.
|
||||||
* @details
|
* @details
|
||||||
@ -50,59 +74,12 @@ class MessageQueueMessage : public MessageQueueMessageIF {
|
|||||||
* @brief As no memory is allocated in this class,
|
* @brief As no memory is allocated in this class,
|
||||||
* the destructor is empty.
|
* the destructor is empty.
|
||||||
*/
|
*/
|
||||||
virtual ~MessageQueueMessage();
|
~MessageQueueMessage() override;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The size information of each message is stored in
|
|
||||||
* this attribute.
|
|
||||||
* @details
|
|
||||||
* It is public to simplify usage and to allow for passing the size
|
|
||||||
* address as a pointer. Care must be taken when inheriting from this class,
|
|
||||||
* as every child class is responsible for managing the size information by
|
|
||||||
* itself. When using the class to receive a message, the size information
|
|
||||||
* is updated automatically.
|
|
||||||
*
|
|
||||||
* Please note that the minimum size is limited by the size of the header
|
|
||||||
* while the maximum size is limited by the maximum allowed message size.
|
|
||||||
*/
|
|
||||||
size_t messageSize;
|
|
||||||
/**
|
|
||||||
* @brief This constant defines the maximum size of the data content,
|
|
||||||
* excluding the header.
|
|
||||||
* @details
|
|
||||||
* It may be changed if necessary, but in general should be kept
|
|
||||||
* as small as possible.
|
|
||||||
*/
|
|
||||||
static const size_t MAX_DATA_SIZE = 24;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief This constant defines the maximum total size in bytes
|
|
||||||
* of a sent message.
|
|
||||||
* @details
|
|
||||||
* It is the sum of the maximum data and the header size. Be aware that
|
|
||||||
* this constant is used to define the buffer sizes for every message
|
|
||||||
* queue in the system. So, a change here may have significant impact on
|
|
||||||
* the required resources.
|
|
||||||
*/
|
|
||||||
static constexpr size_t MAX_MESSAGE_SIZE = MAX_DATA_SIZE + HEADER_SIZE;
|
|
||||||
/**
|
|
||||||
* @brief Defines the minimum size of a message where only the
|
|
||||||
* header is included
|
|
||||||
*/
|
|
||||||
static constexpr size_t MIN_MESSAGE_SIZE = HEADER_SIZE;
|
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* @brief This is the internal buffer that contains the
|
|
||||||
* actual message data.
|
|
||||||
*/
|
|
||||||
uint8_t internalBuffer[MAX_MESSAGE_SIZE];
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
/**
|
||||||
* @brief This method is used to get the complete data of the message.
|
* @brief This method is used to get the complete data of the message.
|
||||||
*/
|
*/
|
||||||
const uint8_t* getBuffer() const override;
|
[[nodiscard]] const uint8_t* getBuffer() const override;
|
||||||
/**
|
/**
|
||||||
* @brief This method is used to get the complete data of the message.
|
* @brief This method is used to get the complete data of the message.
|
||||||
*/
|
*/
|
||||||
@ -112,7 +89,7 @@ class MessageQueueMessage : public MessageQueueMessageIF {
|
|||||||
* @details
|
* @details
|
||||||
* It shall be used by child classes to add data at the right position.
|
* It shall be used by child classes to add data at the right position.
|
||||||
*/
|
*/
|
||||||
const uint8_t* getData() const override;
|
[[nodiscard]] const uint8_t* getData() const override;
|
||||||
/**
|
/**
|
||||||
* @brief This method is used to fetch the data content of the message.
|
* @brief This method is used to fetch the data content of the message.
|
||||||
* @details
|
* @details
|
||||||
@ -123,7 +100,7 @@ class MessageQueueMessage : public MessageQueueMessageIF {
|
|||||||
* @brief This method is used to extract the sender's message
|
* @brief This method is used to extract the sender's message
|
||||||
* queue id information from a received message.
|
* queue id information from a received message.
|
||||||
*/
|
*/
|
||||||
MessageQueueId_t getSender() const override;
|
[[nodiscard]] MessageQueueId_t getSender() const override;
|
||||||
/**
|
/**
|
||||||
* @brief With this method, the whole content
|
* @brief With this method, the whole content
|
||||||
* and the message size is set to zero.
|
* and the message size is set to zero.
|
||||||
@ -138,16 +115,40 @@ class MessageQueueMessage : public MessageQueueMessageIF {
|
|||||||
*/
|
*/
|
||||||
void setSender(MessageQueueId_t setId) override;
|
void setSender(MessageQueueId_t setId) override;
|
||||||
|
|
||||||
virtual size_t getMessageSize() const override;
|
[[nodiscard]] size_t getMessageSize() const override;
|
||||||
virtual void setMessageSize(size_t messageSize) override;
|
void setMessageSize(size_t messageSize) override;
|
||||||
virtual size_t getMinimumMessageSize() const override;
|
[[nodiscard]] size_t getMinimumMessageSize() const override;
|
||||||
virtual size_t getMaximumMessageSize() const override;
|
[[nodiscard]] size_t getMaximumMessageSize() const override;
|
||||||
virtual size_t getMaximumDataSize() const override;
|
[[nodiscard]] size_t getMaximumDataSize() const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is a debug method that prints the content.
|
* @brief This is a debug method that prints the content.
|
||||||
*/
|
*/
|
||||||
void print(bool printWholeMessage);
|
void print(bool printWholeMessage);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: This really should not be public. If it should be possible to pass size address as a
|
||||||
|
* pointer, add a getter function returning a const reference to the size
|
||||||
|
* @brief The size information of each message is stored in
|
||||||
|
* this attribute.
|
||||||
|
* @details
|
||||||
|
* It is public to simplify usage and to allow for passing the size
|
||||||
|
* address as a pointer. Care must be taken when inheriting from this class,
|
||||||
|
* as every child class is responsible for managing the size information by
|
||||||
|
* itself. When using the class to receive a message, the size information
|
||||||
|
* is updated automatically.
|
||||||
|
*
|
||||||
|
* Please note that the minimum size is limited by the size of the header
|
||||||
|
* while the maximum size is limited by the maximum allowed message size.
|
||||||
|
*/
|
||||||
|
size_t messageSize;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* @brief This is the internal buffer that contains the
|
||||||
|
* actual message data.
|
||||||
|
*/
|
||||||
|
uint8_t internalBuffer[MAX_MESSAGE_SIZE] = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FSFW_IPC_MESSAGEQUEUEMESSAGE_H_ */
|
#endif /* FSFW_IPC_MESSAGEQUEUEMESSAGE_H_ */
|
||||||
|
@ -14,7 +14,7 @@ class MessageQueueMessageIF {
|
|||||||
*/
|
*/
|
||||||
static const size_t HEADER_SIZE = sizeof(MessageQueueId_t);
|
static const size_t HEADER_SIZE = sizeof(MessageQueueId_t);
|
||||||
|
|
||||||
virtual ~MessageQueueMessageIF(){};
|
virtual ~MessageQueueMessageIF() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief With this method, the whole content and the message
|
* @brief With this method, the whole content and the message
|
||||||
@ -29,7 +29,7 @@ class MessageQueueMessageIF {
|
|||||||
* @brief Get read-only pointer to the complete data of the message.
|
* @brief Get read-only pointer to the complete data of the message.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual const uint8_t* getBuffer() const = 0;
|
[[nodiscard]] virtual const uint8_t* getBuffer() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This method is used to get the complete data of the message.
|
* @brief This method is used to get the complete data of the message.
|
||||||
@ -48,14 +48,14 @@ class MessageQueueMessageIF {
|
|||||||
* @brief This method is used to extract the sender's message queue id
|
* @brief This method is used to extract the sender's message queue id
|
||||||
* information from a received message.
|
* information from a received message.
|
||||||
*/
|
*/
|
||||||
virtual MessageQueueId_t getSender() const = 0;
|
[[nodiscard]] virtual MessageQueueId_t getSender() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This method is used to fetch the data content of the message.
|
* @brief This method is used to fetch the data content of the message.
|
||||||
* @details
|
* @details
|
||||||
* It shall be used by child classes to add data at the right position.
|
* It shall be used by child classes to add data at the right position.
|
||||||
*/
|
*/
|
||||||
virtual const uint8_t* getData() const = 0;
|
[[nodiscard]] virtual const uint8_t* getData() const = 0;
|
||||||
/**
|
/**
|
||||||
* @brief This method is used to fetch the data content of the message.
|
* @brief This method is used to fetch the data content of the message.
|
||||||
* @details
|
* @details
|
||||||
@ -67,12 +67,28 @@ class MessageQueueMessageIF {
|
|||||||
* Get constant message size of current message implementation.
|
* Get constant message size of current message implementation.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual size_t getMessageSize() const = 0;
|
[[nodiscard]] virtual size_t getMessageSize() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current message size of a given message
|
||||||
|
* @param messageSize
|
||||||
|
*/
|
||||||
virtual void setMessageSize(size_t messageSize) = 0;
|
virtual void setMessageSize(size_t messageSize) = 0;
|
||||||
virtual size_t getMinimumMessageSize() const = 0;
|
/**
|
||||||
virtual size_t getMaximumMessageSize() const = 0;
|
* Returns the smallest possible message size, including any headers
|
||||||
virtual size_t getMaximumDataSize() const = 0;
|
* @return
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual size_t getMinimumMessageSize() const = 0;
|
||||||
|
/**
|
||||||
|
* Returns the largest possible message size, including any headers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual size_t getMaximumMessageSize() const = 0;
|
||||||
|
/**
|
||||||
|
* Returns the largest possible data size without any headers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual size_t getMaximumDataSize() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_ */
|
#endif /* FRAMEWORK_IPC_MESSAGEQUEUEMESSAGEIF_H_ */
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
#include <linux/sysinfo.h>
|
#include <linux/sysinfo.h>
|
||||||
#include <sys/sysinfo.h>
|
#include <sys/sysinfo.h>
|
||||||
#include <ctime>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include "fsfw/ipc/MutexGuard.h"
|
#include "fsfw/ipc/MutexGuard.h"
|
||||||
|
@ -64,7 +64,7 @@ class SerializeIF {
|
|||||||
/**
|
/**
|
||||||
* Forwards to regular @serialize call with big (network) endianness
|
* Forwards to regular @serialize call with big (network) endianness
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t serializeBe(uint8_t** buffer, size_t* size, size_t maxSize) {
|
virtual ReturnValue_t serializeBe(uint8_t **buffer, size_t *size, size_t maxSize) {
|
||||||
return serialize(buffer, size, maxSize, SerializeIF::Endianness::NETWORK);
|
return serialize(buffer, size, maxSize, SerializeIF::Endianness::NETWORK);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -105,7 +105,7 @@ class SerializeIF {
|
|||||||
/**
|
/**
|
||||||
* Forwards to regular @deSerialize call with big (network) endianness
|
* Forwards to regular @deSerialize call with big (network) endianness
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t deSerializeBe(const uint8_t** buffer, size_t* size) {
|
virtual ReturnValue_t deSerializeBe(const uint8_t **buffer, size_t *size) {
|
||||||
return deSerialize(buffer, size, SerializeIF::Endianness::NETWORK);
|
return deSerialize(buffer, size, SerializeIF::Endianness::NETWORK);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
|
||||||
#include "Clock.h"
|
#include "Clock.h"
|
||||||
#include "clockDefinitions.h"
|
#include "clockDefinitions.h"
|
||||||
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
|
|
||||||
bool operator<(const timeval &lhs, const timeval &rhs);
|
bool operator<(const timeval &lhs, const timeval &rhs);
|
||||||
bool operator<=(const timeval &lhs, const timeval &rhs);
|
bool operator<=(const timeval &lhs, const timeval &rhs);
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "fsfw/ipc/MessageQueueMessage.h"
|
|
||||||
#include "Clock.h"
|
#include "Clock.h"
|
||||||
|
#include "fsfw/ipc/MessageQueueMessage.h"
|
||||||
|
|
||||||
class TimeMessage : public MessageQueueMessage {
|
class TimeMessage : public MessageQueueMessage {
|
||||||
protected:
|
protected:
|
||||||
|
@ -101,7 +101,7 @@ ReturnValue_t PusTcCreator::setRawUserData(const uint8_t *data, size_t len) {
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PusTcCreator::setSerializableUserData(SerializeIF& serializable) {
|
ReturnValue_t PusTcCreator::setSerializableUserData(SerializeIF &serializable) {
|
||||||
// TODO: Check length field?
|
// TODO: Check length field?
|
||||||
pusParams.dataWrapper.setSerializable(serializable);
|
pusParams.dataWrapper.setSerializable(serializable);
|
||||||
updateSpLengthField();
|
updateSpLengthField();
|
||||||
|
@ -47,7 +47,7 @@ class PusTcCreator : public PusTcIF, public SerializeIF, public CustomUserDataIF
|
|||||||
[[nodiscard]] uint8_t getSubService() const override;
|
[[nodiscard]] uint8_t getSubService() const override;
|
||||||
[[nodiscard]] uint16_t getSourceId() const override;
|
[[nodiscard]] uint16_t getSourceId() const override;
|
||||||
ReturnValue_t setRawUserData(const uint8_t *data, size_t len) override;
|
ReturnValue_t setRawUserData(const uint8_t *data, size_t len) override;
|
||||||
ReturnValue_t setSerializableUserData(SerializeIF& serializable) override;
|
ReturnValue_t setSerializableUserData(SerializeIF &serializable) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
ReturnValue_t serialize(uint8_t **buffer, size_t *size, size_t maxSize,
|
||||||
|
@ -2,16 +2,17 @@
|
|||||||
|
|
||||||
#include "fsfw/ipc/MessageQueueSenderIF.h"
|
#include "fsfw/ipc/MessageQueueSenderIF.h"
|
||||||
|
|
||||||
TmSendHelper::TmSendHelper(MessageQueueIF* queue, InternalErrorReporterIF *reporter, MessageQueueId_t tmtcMsgDest)
|
TmSendHelper::TmSendHelper(MessageQueueIF *queue, InternalErrorReporterIF *reporter,
|
||||||
|
MessageQueueId_t tmtcMsgDest)
|
||||||
: tmtcMsgDest(tmtcMsgDest), queue(queue), errReporter(reporter) {}
|
: tmtcMsgDest(tmtcMsgDest), queue(queue), errReporter(reporter) {}
|
||||||
|
|
||||||
TmSendHelper::TmSendHelper(MessageQueueIF *queue, InternalErrorReporterIF *reporter)
|
TmSendHelper::TmSendHelper(MessageQueueIF *queue, InternalErrorReporterIF *reporter)
|
||||||
: queue(queue), errReporter(reporter) {}
|
: queue(queue), errReporter(reporter) {}
|
||||||
|
|
||||||
TmSendHelper::TmSendHelper(InternalErrorReporterIF *reporter) : errReporter(reporter) {}
|
TmSendHelper::TmSendHelper(InternalErrorReporterIF *reporter) : errReporter(reporter) {}
|
||||||
|
|
||||||
ReturnValue_t TmSendHelper::sendPacket(const store_address_t &storeId) {
|
ReturnValue_t TmSendHelper::sendPacket(const store_address_t &storeId) {
|
||||||
if(queue == nullptr) {
|
if (queue == nullptr) {
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
TmTcMessage message(storeId);
|
TmTcMessage message(storeId);
|
||||||
|
@ -9,11 +9,11 @@
|
|||||||
|
|
||||||
class TmSendHelper {
|
class TmSendHelper {
|
||||||
public:
|
public:
|
||||||
TmSendHelper(MessageQueueIF* queue, InternalErrorReporterIF* reporter, MessageQueueId_t tmtcMsgDest);
|
TmSendHelper(MessageQueueIF* queue, InternalErrorReporterIF* reporter,
|
||||||
|
MessageQueueId_t tmtcMsgDest);
|
||||||
TmSendHelper(MessageQueueIF* queue, InternalErrorReporterIF* reporter);
|
TmSendHelper(MessageQueueIF* queue, InternalErrorReporterIF* reporter);
|
||||||
explicit TmSendHelper(InternalErrorReporterIF* reporter);
|
explicit TmSendHelper(InternalErrorReporterIF* reporter);
|
||||||
|
|
||||||
|
|
||||||
void setMsgQueue(MessageQueueIF* queue);
|
void setMsgQueue(MessageQueueIF* queue);
|
||||||
void setMsgDestination(MessageQueueId_t msgDest);
|
void setMsgDestination(MessageQueueId_t msgDest);
|
||||||
void setInternalErrorReporter(InternalErrorReporterIF* reporter);
|
void setInternalErrorReporter(InternalErrorReporterIF* reporter);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "TmTcMessage.h"
|
#include "TmTcMessage.h"
|
||||||
|
|
||||||
TmStoreHelper::TmStoreHelper(uint16_t defaultApid): tmStore(nullptr) {
|
TmStoreHelper::TmStoreHelper(uint16_t defaultApid) : tmStore(nullptr) {
|
||||||
creator.setApid(defaultApid);
|
creator.setApid(defaultApid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,7 +17,6 @@ TmStoreHelper::TmStoreHelper(uint16_t defaultApid, StorageManagerIF& tmStore,
|
|||||||
creator.setTimeStamper(timeStamper);
|
creator.setTimeStamper(timeStamper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ReturnValue_t TmStoreHelper::preparePacket(uint8_t service, uint8_t subservice, uint16_t counter) {
|
ReturnValue_t TmStoreHelper::preparePacket(uint8_t service, uint8_t subservice, uint16_t counter) {
|
||||||
PusTmParams& params = creator.getParams();
|
PusTmParams& params = creator.getParams();
|
||||||
params.secHeader.service = service;
|
params.secHeader.service = service;
|
||||||
@ -33,8 +32,8 @@ void TmStoreHelper::setTmStore(StorageManagerIF& store) { tmStore = &store; }
|
|||||||
const store_address_t& TmStoreHelper::getCurrentAddr() const { return currentAddr; }
|
const store_address_t& TmStoreHelper::getCurrentAddr() const { return currentAddr; }
|
||||||
|
|
||||||
ReturnValue_t TmStoreHelper::deletePacket() {
|
ReturnValue_t TmStoreHelper::deletePacket() {
|
||||||
ReturnValue_t result = tmStore->deleteData(currentAddr);
|
ReturnValue_t result = tmStore->deleteData(currentAddr);
|
||||||
if(result == HasReturnvaluesIF::RETURN_OK) {
|
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||||
currentAddr = store_address_t::invalid();
|
currentAddr = store_address_t::invalid();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -30,7 +30,6 @@ class TmStoreHelper {
|
|||||||
ReturnValue_t setSourceDataRaw(const uint8_t* data, size_t len);
|
ReturnValue_t setSourceDataRaw(const uint8_t* data, size_t len);
|
||||||
ReturnValue_t setSourceDataSerializable(SerializeIF& serializable);
|
ReturnValue_t setSourceDataSerializable(SerializeIF& serializable);
|
||||||
|
|
||||||
|
|
||||||
ReturnValue_t addPacketToStore();
|
ReturnValue_t addPacketToStore();
|
||||||
ReturnValue_t deletePacket();
|
ReturnValue_t deletePacket();
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
||||||
#include <fsfw/tmtcservices/PusServiceBase.h>
|
#include <fsfw/tmtcservices/PusServiceBase.h>
|
||||||
|
|
||||||
#include "datapoollocal/LocalPoolOwnerBase.h"
|
|
||||||
#include "mocks/HkReceiverMock.h"
|
#include "mocks/HkReceiverMock.h"
|
||||||
#include "tests/TestsConfig.h"
|
#include "tests/TestsConfig.h"
|
||||||
|
|
||||||
@ -34,8 +33,6 @@ void Factory::produceFrameworkObjects(void* args) {
|
|||||||
new EventManager(objects::EVENT_MANAGER);
|
new EventManager(objects::EVENT_MANAGER);
|
||||||
new HealthTable(objects::HEALTH_TABLE);
|
new HealthTable(objects::HEALTH_TABLE);
|
||||||
new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER);
|
new InternalErrorReporter(objects::INTERNAL_ERROR_REPORTER);
|
||||||
|
|
||||||
new LocalPoolOwnerBase(objects::TEST_LOCAL_POOL_OWNER_BASE);
|
|
||||||
new HkReceiverMock(objects::HK_RECEIVER_MOCK);
|
new HkReceiverMock(objects::HK_RECEIVER_MOCK);
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -54,6 +51,9 @@ void Factory::produceFrameworkObjects(void* args) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Our tests, and the code base in general should really not depend on some arbitrary function
|
||||||
|
// like this. Instead, this should be more like a general struct containing all important
|
||||||
|
// object IDs which are then explicitely passed in the object constructor
|
||||||
void Factory::setStaticFrameworkObjectIds() {
|
void Factory::setStaticFrameworkObjectIds() {
|
||||||
PusServiceBase::packetSource = objects::NO_OBJECT;
|
PusServiceBase::packetSource = objects::NO_OBJECT;
|
||||||
PusServiceBase::packetDestination = objects::NO_OBJECT;
|
PusServiceBase::packetDestination = objects::NO_OBJECT;
|
||||||
@ -66,7 +66,8 @@ void Factory::setStaticFrameworkObjectIds() {
|
|||||||
DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
|
DeviceHandlerBase::powerSwitcherId = objects::NO_OBJECT;
|
||||||
DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT;
|
DeviceHandlerBase::rawDataReceiverId = objects::NO_OBJECT;
|
||||||
|
|
||||||
LocalDataPoolManager::defaultHkDestination = objects::HK_RECEIVER_MOCK;
|
// TODO: Incredibly ugly, get rid of it
|
||||||
|
LocalDataPoolManager::defaultHkDestination = objects::NO_OBJECT;
|
||||||
|
|
||||||
DeviceHandlerFailureIsolation::powerConfirmationId = objects::NO_OBJECT;
|
DeviceHandlerFailureIsolation::powerConfirmationId = objects::NO_OBJECT;
|
||||||
}
|
}
|
||||||
|
@ -57,8 +57,7 @@ TEST_CASE("Action Helper", "[ActionHelper]") {
|
|||||||
step += 1;
|
step += 1;
|
||||||
CHECK(testMqMock.wasMessageSent());
|
CHECK(testMqMock.wasMessageSent());
|
||||||
CommandMessage testMessage;
|
CommandMessage testMessage;
|
||||||
REQUIRE(testMqMock.receiveMessage(&testMessage) ==
|
REQUIRE(testMqMock.getNextSentMessage(testMessage) == HasReturnvaluesIF::RETURN_OK);
|
||||||
static_cast<uint32_t>(HasReturnvaluesIF::RETURN_OK));
|
|
||||||
REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::STEP_FAILED));
|
REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::STEP_FAILED));
|
||||||
REQUIRE(testMessage.getParameter() == static_cast<uint32_t>(testActionId));
|
REQUIRE(testMessage.getParameter() == static_cast<uint32_t>(testActionId));
|
||||||
uint32_t parameter2 = ((uint32_t)step << 16) | (uint32_t)status;
|
uint32_t parameter2 = ((uint32_t)step << 16) | (uint32_t)status;
|
||||||
@ -72,8 +71,7 @@ TEST_CASE("Action Helper", "[ActionHelper]") {
|
|||||||
actionHelper.finish(false, testMqMock.getId(), testActionId, status);
|
actionHelper.finish(false, testMqMock.getId(), testActionId, status);
|
||||||
CHECK(testMqMock.wasMessageSent());
|
CHECK(testMqMock.wasMessageSent());
|
||||||
CommandMessage testMessage;
|
CommandMessage testMessage;
|
||||||
REQUIRE(testMqMock.receiveMessage(&testMessage) ==
|
REQUIRE(testMqMock.getNextSentMessage(testMessage) == HasReturnvaluesIF::RETURN_OK);
|
||||||
static_cast<uint32_t>(HasReturnvaluesIF::RETURN_OK));
|
|
||||||
REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::COMPLETION_FAILED));
|
REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::COMPLETION_FAILED));
|
||||||
REQUIRE(ActionMessage::getActionId(&testMessage) == testActionId);
|
REQUIRE(ActionMessage::getActionId(&testMessage) == testActionId);
|
||||||
REQUIRE(ActionMessage::getReturnCode(&testMessage) == static_cast<uint32_t>(status));
|
REQUIRE(ActionMessage::getReturnCode(&testMessage) == static_cast<uint32_t>(status));
|
||||||
@ -89,8 +87,7 @@ TEST_CASE("Action Helper", "[ActionHelper]") {
|
|||||||
REQUIRE(ipcStore->getData(toLongParamAddress).first ==
|
REQUIRE(ipcStore->getData(toLongParamAddress).first ==
|
||||||
static_cast<uint32_t>(StorageManagerIF::DATA_DOES_NOT_EXIST));
|
static_cast<uint32_t>(StorageManagerIF::DATA_DOES_NOT_EXIST));
|
||||||
CommandMessage testMessage;
|
CommandMessage testMessage;
|
||||||
REQUIRE(testMqMock.receiveMessage(&testMessage) ==
|
REQUIRE(testMqMock.getNextSentMessage(testMessage) == HasReturnvaluesIF::RETURN_OK);
|
||||||
static_cast<uint32_t>(HasReturnvaluesIF::RETURN_OK));
|
|
||||||
REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::STEP_FAILED));
|
REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::STEP_FAILED));
|
||||||
REQUIRE(ActionMessage::getReturnCode(&testMessage) == 0xAFFE);
|
REQUIRE(ActionMessage::getReturnCode(&testMessage) == 0xAFFE);
|
||||||
REQUIRE(ActionMessage::getStep(&testMessage) == 0);
|
REQUIRE(ActionMessage::getStep(&testMessage) == 0);
|
||||||
@ -102,8 +99,7 @@ TEST_CASE("Action Helper", "[ActionHelper]") {
|
|||||||
CHECK(not testDhMock.executeActionCalled);
|
CHECK(not testDhMock.executeActionCalled);
|
||||||
REQUIRE(actionHelper.handleActionMessage(&actionMessage) == retval::CATCH_OK);
|
REQUIRE(actionHelper.handleActionMessage(&actionMessage) == retval::CATCH_OK);
|
||||||
CommandMessage testMessage;
|
CommandMessage testMessage;
|
||||||
REQUIRE(testMqMock.receiveMessage(&testMessage) ==
|
REQUIRE(testMqMock.getNextSentMessage(testMessage) == HasReturnvaluesIF::RETURN_OK);
|
||||||
static_cast<uint32_t>(HasReturnvaluesIF::RETURN_OK));
|
|
||||||
REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::STEP_FAILED));
|
REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::STEP_FAILED));
|
||||||
REQUIRE(ActionMessage::getReturnCode(&testMessage) ==
|
REQUIRE(ActionMessage::getReturnCode(&testMessage) ==
|
||||||
static_cast<uint32_t>(StorageManagerIF::ILLEGAL_STORAGE_ID));
|
static_cast<uint32_t>(StorageManagerIF::ILLEGAL_STORAGE_ID));
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
target_sources(${FSFW_TEST_TGT} PRIVATE
|
target_sources(${FSFW_TEST_TGT} PRIVATE
|
||||||
LocalPoolVariableTest.cpp
|
testLocalPoolVariable.cpp
|
||||||
LocalPoolVectorTest.cpp
|
testLocalPoolVector.cpp
|
||||||
DataSetTest.cpp
|
testDataSet.cpp
|
||||||
LocalPoolManagerTest.cpp
|
testLocalPoolManager.cpp
|
||||||
LocalPoolOwnerBase.cpp
|
LocalPoolOwnerBase.cpp
|
||||||
)
|
)
|
||||||
|
@ -1,413 +0,0 @@
|
|||||||
#include <fsfw/datapool/PoolReadGuard.h>
|
|
||||||
#include <fsfw/datapoollocal/HasLocalDataPoolIF.h>
|
|
||||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
|
||||||
#include <fsfw/globalfunctions/timevalOperations.h>
|
|
||||||
#include <fsfw/housekeeping/HousekeepingSnapshot.h>
|
|
||||||
#include <fsfw/ipc/CommandMessageCleaner.h>
|
|
||||||
#include <fsfw/objectmanager/ObjectManager.h>
|
|
||||||
#include <fsfw/timemanager/CCSDSTime.h>
|
|
||||||
|
|
||||||
#include <catch2/catch_approx.hpp>
|
|
||||||
#include <catch2/catch_test_macros.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "CatchDefinitions.h"
|
|
||||||
#include "LocalPoolOwnerBase.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);
|
|
||||||
|
|
||||||
MessageQueueMockBase* poolOwnerMock = poolOwner->getMockQueueHandle();
|
|
||||||
REQUIRE(poolOwnerMock != nullptr);
|
|
||||||
|
|
||||||
// MessageQueueIF* hkCommander = QueueFactory::instance()->createMessageQueue();
|
|
||||||
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);
|
|
||||||
|
|
||||||
/* 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(poolOwnerMock->wasMessageSent() == true);
|
|
||||||
|
|
||||||
REQUIRE(poolOwnerMock->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);
|
|
||||||
|
|
||||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
REQUIRE(poolOwnerMock->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(poolOwnerMock->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(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
|
||||||
CHECK(messageSent.getCommand() ==
|
|
||||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
|
||||||
|
|
||||||
REQUIRE(poolOwnerMock->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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
timeval now;
|
|
||||||
Clock::getClock_timeval(&now);
|
|
||||||
|
|
||||||
/* Trigger generation of snapshot */
|
|
||||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
|
||||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
REQUIRE(poolOwnerMock->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 */
|
|
||||||
timeval timeFromHK;
|
|
||||||
auto result = CCSDSTime::convertFromCDS(&timeFromHK, &cdsShort);
|
|
||||||
CHECK(result == HasReturnvaluesIF::RETURN_OK);
|
|
||||||
timeval difference = timeFromHK - now;
|
|
||||||
CHECK(timevalOperations::toDouble(difference) < 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
poolVar->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);
|
|
||||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
|
||||||
|
|
||||||
/* Check update snapshot was sent. */
|
|
||||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
|
|
||||||
/* Should have been reset. */
|
|
||||||
CHECK(poolVar->hasChanged() == false);
|
|
||||||
REQUIRE(poolOwnerMock->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);
|
|
||||||
|
|
||||||
/* Now we check that both times are equal */
|
|
||||||
timeval timeFromHK;
|
|
||||||
auto result = CCSDSTime::convertFromCDS(&timeFromHK, &cdsShort);
|
|
||||||
CHECK(result == HasReturnvaluesIF::RETURN_OK);
|
|
||||||
timeval difference = timeFromHK - now;
|
|
||||||
CHECK(timevalOperations::toDouble(difference) < 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
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(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
/* Should have been reset. */
|
|
||||||
CHECK(poolVar->hasChanged() == false);
|
|
||||||
REQUIRE(poolOwnerMock->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(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 2);
|
|
||||||
poolOwnerMock->clearMessages(true);
|
|
||||||
|
|
||||||
poolOwner->dataset.setChanged(true);
|
|
||||||
poolVar->setChanged(true);
|
|
||||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
|
||||||
/* Now three messages should be sent. */
|
|
||||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 3);
|
|
||||||
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
|
||||||
CHECK(messageSent.getCommand() ==
|
|
||||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE));
|
|
||||||
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
|
||||||
CHECK(messageSent.getCommand() ==
|
|
||||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
|
||||||
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
|
||||||
CHECK(messageSent.getCommand() == static_cast<int>(HousekeepingMessage::HK_REPORT));
|
|
||||||
CommandMessageCleaner::clearCommandMessage(&messageSent);
|
|
||||||
REQUIRE(poolOwnerMock->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(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
CHECK(poolOwnerMock->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(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
CHECK(poolOwnerMock->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(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
|
||||||
|
|
||||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, false);
|
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
|
||||||
CHECK(setHandle->getReportingEnabled() == true);
|
|
||||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
|
||||||
|
|
||||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, false);
|
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
|
||||||
CHECK(setHandle->getReportingEnabled() == false);
|
|
||||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(poolOwnerMock->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(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
CHECK(poolOwnerMock->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(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
|
||||||
|
|
||||||
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false);
|
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
|
||||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
CHECK(poolOwnerMock->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(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
CHECK(poolOwnerMock->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(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
|
||||||
|
|
||||||
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false);
|
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
|
||||||
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
|
||||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
|
||||||
|
|
||||||
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, true);
|
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
|
||||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
|
||||||
|
|
||||||
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4,
|
|
||||||
true);
|
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
|
||||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
|
||||||
|
|
||||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, true);
|
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
|
||||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
|
||||||
|
|
||||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, true);
|
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
|
||||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
|
||||||
|
|
||||||
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false);
|
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
|
||||||
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
|
||||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
|
||||||
|
|
||||||
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, true);
|
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
|
||||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
|
||||||
CHECK(messagesSent == 1);
|
|
||||||
CHECK(poolOwnerMock->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,
|
|
||||||
store_address_t::invalid());
|
|
||||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
|
||||||
CHECK(poolOwner->changedDataSetCallbackWasCalled(sidToCheck, storeId) == true);
|
|
||||||
CHECK(sidToCheck == lpool::testSid);
|
|
||||||
|
|
||||||
HousekeepingMessage::setUpdateSnapshotVariableCommand(&hkCmd, lpool::uint8VarGpid,
|
|
||||||
store_address_t::invalid());
|
|
||||||
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);
|
|
||||||
poolOwnerMock->clearMessages(true);
|
|
||||||
}
|
|
@ -13,11 +13,10 @@
|
|||||||
#include "tests/TestsConfig.h"
|
#include "tests/TestsConfig.h"
|
||||||
|
|
||||||
TEST_CASE("DataSetTest", "[DataSetTest]") {
|
TEST_CASE("DataSetTest", "[DataSetTest]") {
|
||||||
LocalPoolOwnerBase* poolOwner =
|
auto queue = MessageQueueMockBase();
|
||||||
ObjectManager::instance()->get<LocalPoolOwnerBase>(objects::TEST_LOCAL_POOL_OWNER_BASE);
|
LocalPoolOwnerBase poolOwner(queue, objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||||
REQUIRE(poolOwner != nullptr);
|
REQUIRE(poolOwner.initializeHkManager() == retval::CATCH_OK);
|
||||||
REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK);
|
REQUIRE(poolOwner.initializeHkManagerAfterTaskCreation() == retval::CATCH_OK);
|
||||||
REQUIRE(poolOwner->initializeHkManagerAfterTaskCreation() == retval::CATCH_OK);
|
|
||||||
LocalPoolStaticTestDataSet localSet;
|
LocalPoolStaticTestDataSet localSet;
|
||||||
|
|
||||||
SECTION("BasicTest") {
|
SECTION("BasicTest") {
|
||||||
@ -30,9 +29,9 @@ TEST_CASE("DataSetTest", "[DataSetTest]") {
|
|||||||
size_t maxSize = localSet.getLocalPoolIdsSerializedSize(true);
|
size_t maxSize = localSet.getLocalPoolIdsSerializedSize(true);
|
||||||
uint8_t localPoolIdBuff[maxSize];
|
uint8_t localPoolIdBuff[maxSize];
|
||||||
/* Skip size field */
|
/* Skip size field */
|
||||||
lp_id_t* lpIds = reinterpret_cast<lp_id_t*>(localPoolIdBuff + 1);
|
auto* lpIds = reinterpret_cast<lp_id_t*>(localPoolIdBuff + 1);
|
||||||
size_t serSize = 0;
|
size_t serSize = 0;
|
||||||
uint8_t* localPoolIdBuffPtr = reinterpret_cast<uint8_t*>(localPoolIdBuff);
|
auto* localPoolIdBuffPtr = reinterpret_cast<uint8_t*>(localPoolIdBuff);
|
||||||
|
|
||||||
/* Test local pool ID serialization */
|
/* Test local pool ID serialization */
|
||||||
CHECK(localSet.serializeLocalPoolIds(&localPoolIdBuffPtr, &serSize, maxSize,
|
CHECK(localSet.serializeLocalPoolIds(&localPoolIdBuffPtr, &serSize, maxSize,
|
||||||
@ -200,7 +199,7 @@ TEST_CASE("DataSetTest", "[DataSetTest]") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Common fault test cases */
|
/* Common fault test cases */
|
||||||
LocalPoolObjectBase* variableHandle = poolOwner->getPoolObjectHandle(lpool::uint32VarId);
|
LocalPoolObjectBase* variableHandle = poolOwner.getPoolObjectHandle(lpool::uint32VarId);
|
||||||
CHECK(variableHandle != nullptr);
|
CHECK(variableHandle != nullptr);
|
||||||
CHECK(localSet.registerVariable(variableHandle) == static_cast<int>(DataSetIF::DATA_SET_FULL));
|
CHECK(localSet.registerVariable(variableHandle) == static_cast<int>(DataSetIF::DATA_SET_FULL));
|
||||||
variableHandle = nullptr;
|
variableHandle = nullptr;
|
||||||
@ -209,7 +208,7 @@ TEST_CASE("DataSetTest", "[DataSetTest]") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SECTION("MorePoolVariables") {
|
SECTION("MorePoolVariables") {
|
||||||
LocalDataSet set(poolOwner, 2, 10);
|
LocalDataSet set(&poolOwner, 2, 10);
|
||||||
|
|
||||||
/* Register same variables again to get more than 8 registered variables */
|
/* Register same variables again to get more than 8 registered variables */
|
||||||
for (uint8_t idx = 0; idx < 8; idx++) {
|
for (uint8_t idx = 0; idx < 8; idx++) {
|
||||||
@ -234,7 +233,7 @@ TEST_CASE("DataSetTest", "[DataSetTest]") {
|
|||||||
uint8_t* buffPtr = buffer;
|
uint8_t* buffPtr = buffer;
|
||||||
CHECK(set.serialize(&buffPtr, &serSize, maxSize, SerializeIF::Endianness::MACHINE) ==
|
CHECK(set.serialize(&buffPtr, &serSize, maxSize, SerializeIF::Endianness::MACHINE) ==
|
||||||
retval::CATCH_OK);
|
retval::CATCH_OK);
|
||||||
std::array<uint8_t, 2> validityBuffer;
|
std::array<uint8_t, 2> validityBuffer{};
|
||||||
std::memcpy(validityBuffer.data(), buffer + 9 + sizeof(uint16_t) * 3, 2);
|
std::memcpy(validityBuffer.data(), buffer + 9 + sizeof(uint16_t) * 3, 2);
|
||||||
/* The first 9 variables should be valid */
|
/* The first 9 variables should be valid */
|
||||||
CHECK(validityBuffer[0] == 0xff);
|
CHECK(validityBuffer[0] == 0xff);
|
||||||
@ -258,7 +257,7 @@ TEST_CASE("DataSetTest", "[DataSetTest]") {
|
|||||||
|
|
||||||
SECTION("SharedDataSet") {
|
SECTION("SharedDataSet") {
|
||||||
object_id_t sharedSetId = objects::SHARED_SET_ID;
|
object_id_t sharedSetId = objects::SHARED_SET_ID;
|
||||||
SharedLocalDataSet sharedSet(sharedSetId, poolOwner, lpool::testSetId, 5);
|
SharedLocalDataSet sharedSet(sharedSetId, &poolOwner, lpool::testSetId, 5);
|
||||||
localSet.localPoolVarUint8.setReadWriteMode(pool_rwm_t::VAR_WRITE);
|
localSet.localPoolVarUint8.setReadWriteMode(pool_rwm_t::VAR_WRITE);
|
||||||
localSet.localPoolUint16Vec.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.localPoolVarUint8) == retval::CATCH_OK);
|
||||||
@ -279,8 +278,4 @@ TEST_CASE("DataSetTest", "[DataSetTest]") {
|
|||||||
|
|
||||||
sharedSet.setReadCommitProtectionBehaviour(true);
|
sharedSet.setReadCommitProtectionBehaviour(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we need to reset the subscription list because the pool owner
|
|
||||||
is a global object. */
|
|
||||||
CHECK(poolOwner->reset() == retval::CATCH_OK);
|
|
||||||
}
|
}
|
430
unittests/datapoollocal/testLocalPoolManager.cpp
Normal file
430
unittests/datapoollocal/testLocalPoolManager.cpp
Normal file
@ -0,0 +1,430 @@
|
|||||||
|
#include <fsfw/datapool/PoolReadGuard.h>
|
||||||
|
#include <fsfw/datapoollocal/HasLocalDataPoolIF.h>
|
||||||
|
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
||||||
|
#include <fsfw/globalfunctions/timevalOperations.h>
|
||||||
|
#include <fsfw/housekeeping/HousekeepingSnapshot.h>
|
||||||
|
#include <fsfw/ipc/CommandMessageCleaner.h>
|
||||||
|
#include <fsfw/objectmanager/ObjectManager.h>
|
||||||
|
#include <fsfw/timemanager/CCSDSTime.h>
|
||||||
|
|
||||||
|
#include <catch2/catch_approx.hpp>
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "CatchDefinitions.h"
|
||||||
|
#include "LocalPoolOwnerBase.h"
|
||||||
|
#include "mocks/HkReceiverMock.h"
|
||||||
|
|
||||||
|
TEST_CASE("Local Pool Manager Tests", "[LocManTest]") {
|
||||||
|
const MessageQueueId_t defaultDestId = 1;
|
||||||
|
const MessageQueueId_t hkDest = defaultDestId;
|
||||||
|
const MessageQueueId_t subscriberId = 2;
|
||||||
|
auto hkReceiver = HkReceiverMock(hkDest);
|
||||||
|
auto queue = MessageQueueMockBase();
|
||||||
|
LocalPoolOwnerBase poolOwner(queue, objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||||
|
REQUIRE(poolOwner.initializeHkManager() == retval::CATCH_OK);
|
||||||
|
REQUIRE(poolOwner.initializeHkManagerAfterTaskCreation() == retval::CATCH_OK);
|
||||||
|
|
||||||
|
MessageQueueMockBase& poolOwnerMock = poolOwner.getMockQueueHandle();
|
||||||
|
|
||||||
|
// TODO: This is ugly. This should be an arbitrary ctor argument. Fix this in the pool
|
||||||
|
// manager
|
||||||
|
poolOwnerMock.setDefaultDestination(defaultDestId);
|
||||||
|
poolOwner.setHkDestId(hkDest);
|
||||||
|
|
||||||
|
auto* hkMan = poolOwner.getHkManagerHandle();
|
||||||
|
|
||||||
|
CommandMessage messageSent;
|
||||||
|
|
||||||
|
SECTION("Basic Test") {
|
||||||
|
{
|
||||||
|
/* 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(subscriberId) == 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(poolOwnerMock.wasMessageSent());
|
||||||
|
|
||||||
|
REQUIRE(poolOwnerMock.getNextSentMessage(subscriberId, messageSent) == retval::CATCH_OK);
|
||||||
|
CHECK(messageSent.getCommand() ==
|
||||||
|
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||||
|
|
||||||
|
/* Should have been reset. */
|
||||||
|
CHECK(poolOwner.dataset.hasChanged() == false);
|
||||||
|
poolOwnerMock.clearMessages(true);
|
||||||
|
/* Set changed again, result should be the same. */
|
||||||
|
poolOwner.dataset.setChanged(true);
|
||||||
|
REQUIRE(poolOwner.poolManager.performHkOperation() == retval::CATCH_OK);
|
||||||
|
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent() == true);
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
REQUIRE(poolOwnerMock.getNextSentMessage(subscriberId, messageSent) == retval::CATCH_OK);
|
||||||
|
CHECK(messageSent.getCommand() ==
|
||||||
|
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||||
|
|
||||||
|
poolOwnerMock.clearMessages(true);
|
||||||
|
/* Now subscribe for set update HK as well. */
|
||||||
|
REQUIRE(poolOwner.subscribeWrapperSetUpdateHk(false, &hkReceiver) == retval::CATCH_OK);
|
||||||
|
poolOwner.dataset.setChanged(true);
|
||||||
|
REQUIRE(poolOwner.poolManager.performHkOperation() == retval::CATCH_OK);
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent() == true);
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessage() == 2);
|
||||||
|
// first message sent should be the update notification
|
||||||
|
REQUIRE(poolOwnerMock.getNextSentMessage(subscriberId, messageSent) == retval::CATCH_OK);
|
||||||
|
CHECK(messageSent.getCommand() ==
|
||||||
|
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||||
|
REQUIRE(poolOwnerMock.getNextSentMessage(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Subscribe for snapshot generation on update. */
|
||||||
|
REQUIRE(poolOwner.subscribeWrapperSetUpdateSnapshot(subscriberId) == retval::CATCH_OK);
|
||||||
|
poolOwner.dataset.setChanged(true);
|
||||||
|
|
||||||
|
/* Store current time, we are going to check the (approximate) time equality later */
|
||||||
|
timeval now{};
|
||||||
|
Clock::getClock_timeval(&now);
|
||||||
|
|
||||||
|
/* Trigger generation of snapshot */
|
||||||
|
REQUIRE(poolOwner.poolManager.performHkOperation() == retval::CATCH_OK);
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
REQUIRE(poolOwnerMock.getNextSentMessage(subscriberId, 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 */
|
||||||
|
timeval timeFromHK{};
|
||||||
|
auto result = CCSDSTime::convertFromCDS(&timeFromHK, &cdsShort);
|
||||||
|
CHECK(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
timeval difference = timeFromHK - now;
|
||||||
|
CHECK(timevalOperations::toDouble(difference) < 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("VariableSnapshotTest") {
|
||||||
|
/* Acquire subscription interface */
|
||||||
|
ProvidesDataPoolSubscriptionIF* subscriptionIF = poolOwner.getSubscriptionInterface();
|
||||||
|
REQUIRE(subscriptionIF != nullptr);
|
||||||
|
|
||||||
|
/* Subscribe for variable snapshot */
|
||||||
|
REQUIRE(poolOwner.subscribeWrapperVariableSnapshot(subscriberId, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
poolVar->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);
|
||||||
|
REQUIRE(poolOwner.poolManager.performHkOperation() == retval::CATCH_OK);
|
||||||
|
|
||||||
|
/* Check update snapshot was sent. */
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
|
||||||
|
/* Should have been reset. */
|
||||||
|
CHECK(poolVar->hasChanged() == false);
|
||||||
|
REQUIRE(poolOwnerMock.getNextSentMessage(subscriberId, 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);
|
||||||
|
|
||||||
|
/* Now we check that both times are equal */
|
||||||
|
timeval timeFromHK{};
|
||||||
|
auto result = CCSDSTime::convertFromCDS(&timeFromHK, &cdsShort);
|
||||||
|
CHECK(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
timeval difference = timeFromHK - now;
|
||||||
|
CHECK(timevalOperations::toDouble(difference) < 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("VariableNotificationTest") {
|
||||||
|
/* Acquire subscription interface */
|
||||||
|
ProvidesDataPoolSubscriptionIF* subscriptionIF = poolOwner.getSubscriptionInterface();
|
||||||
|
REQUIRE(subscriptionIF != nullptr);
|
||||||
|
|
||||||
|
/* Subscribe for variable update */
|
||||||
|
REQUIRE(poolOwner.subscribeWrapperVariableUpdate(subscriberId, lpool::uint8VarId) ==
|
||||||
|
retval::CATCH_OK);
|
||||||
|
auto* 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(poolOwnerMock.wasMessageSent());
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
/* Should have been reset. */
|
||||||
|
CHECK(poolVar->hasChanged() == false);
|
||||||
|
REQUIRE(poolOwnerMock.getNextSentMessage(subscriberId, 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,
|
||||||
|
subscriberId, false) == retval::CATCH_OK);
|
||||||
|
REQUIRE(poolOwner.subscribeWrapperSetUpdateHk(false, &hkReceiver) == retval::CATCH_OK);
|
||||||
|
|
||||||
|
poolOwner.dataset.setChanged(true);
|
||||||
|
poolOwnerMock.clearMessages();
|
||||||
|
REQUIRE(poolOwner.poolManager.performHkOperation() == retval::CATCH_OK);
|
||||||
|
/* Now two messages should be sent. */
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessage() == 2);
|
||||||
|
poolOwnerMock.clearMessages(true);
|
||||||
|
|
||||||
|
poolOwner.dataset.setChanged(true);
|
||||||
|
poolOwnerMock.clearMessages(true);
|
||||||
|
poolVar->setChanged(true);
|
||||||
|
REQUIRE(poolOwner.poolManager.performHkOperation() == retval::CATCH_OK);
|
||||||
|
/* Now three messages should be sent. */
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessage() == 3);
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessage(subscriberId) == 2);
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessage(hkDest) == 1);
|
||||||
|
REQUIRE(poolOwnerMock.getNextSentMessage(subscriberId, messageSent) == retval::CATCH_OK);
|
||||||
|
CHECK(messageSent.getCommand() ==
|
||||||
|
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE));
|
||||||
|
REQUIRE(poolOwnerMock.clearLastSentMessage(subscriberId) == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
REQUIRE(poolOwnerMock.getNextSentMessage(subscriberId, messageSent) ==
|
||||||
|
HasReturnvaluesIF::RETURN_OK);
|
||||||
|
CHECK(messageSent.getCommand() ==
|
||||||
|
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||||
|
REQUIRE(poolOwnerMock.clearLastSentMessage(subscriberId) == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
REQUIRE(poolOwnerMock.getNextSentMessage(messageSent) == retval::CATCH_OK);
|
||||||
|
CHECK(messageSent.getCommand() == static_cast<int>(HousekeepingMessage::HK_REPORT));
|
||||||
|
REQUIRE(poolOwnerMock.clearLastSentMessage() == HasReturnvaluesIF::RETURN_OK);
|
||||||
|
REQUIRE(poolOwnerMock.getNextSentMessage(subscriberId, messageSent) == MessageQueueIF::EMPTY);
|
||||||
|
REQUIRE(poolOwnerMock.getNextSentMessage(messageSent) == 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(poolOwnerMock.wasMessageSent());
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
CHECK(poolOwnerMock.clearLastSentMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
|
LocalPoolDataSetBase* setHandle = poolOwner.getDataSetHandle(lpool::testSid);
|
||||||
|
REQUIRE(setHandle != nullptr);
|
||||||
|
CHECK(poolOwner.poolManager.generateHousekeepingPacket(lpool::testSid, setHandle, false) ==
|
||||||
|
retval::CATCH_OK);
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
CHECK(poolOwnerMock.clearLastSentMessage() == 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(poolOwnerMock.wasMessageSent());
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
CHECK(poolOwnerMock.clearLastSentMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
|
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, false);
|
||||||
|
CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
|
CHECK(setHandle->getReportingEnabled() == true);
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
CHECK(poolOwnerMock.clearLastSentMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
|
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, false);
|
||||||
|
CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
|
CHECK(setHandle->getReportingEnabled() == false);
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
CHECK(poolOwnerMock.clearLastSentMessage() == 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(poolOwnerMock.wasMessageSent());
|
||||||
|
REQUIRE(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
CHECK(poolOwnerMock.clearLastSentMessage() == 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(poolOwnerMock.wasMessageSent());
|
||||||
|
REQUIRE(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
poolOwnerMock.clearMessages();
|
||||||
|
|
||||||
|
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false);
|
||||||
|
CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
REQUIRE(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
poolOwnerMock.clearMessages();
|
||||||
|
|
||||||
|
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(poolOwnerMock.wasMessageSent());
|
||||||
|
REQUIRE(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
CHECK(poolOwnerMock.clearLastSentMessage() == 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(poolOwnerMock.wasMessageSent());
|
||||||
|
REQUIRE(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
CHECK(poolOwnerMock.clearLastSentMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
|
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, false);
|
||||||
|
CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) ==
|
||||||
|
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
REQUIRE(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
CHECK(poolOwnerMock.clearLastSentMessage() == retval::CATCH_OK);
|
||||||
|
|
||||||
|
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, true);
|
||||||
|
CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
REQUIRE(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
poolOwnerMock.clearMessages();
|
||||||
|
|
||||||
|
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4,
|
||||||
|
true);
|
||||||
|
CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
REQUIRE(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
poolOwnerMock.clearMessages();
|
||||||
|
|
||||||
|
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, true);
|
||||||
|
CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
REQUIRE(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
poolOwnerMock.clearMessages();
|
||||||
|
|
||||||
|
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, true);
|
||||||
|
CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
REQUIRE(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
poolOwnerMock.clearMessages();
|
||||||
|
|
||||||
|
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false);
|
||||||
|
CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) ==
|
||||||
|
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
REQUIRE(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
poolOwnerMock.clearMessages();
|
||||||
|
|
||||||
|
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, true);
|
||||||
|
CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
REQUIRE(poolOwnerMock.numberOfSentMessage() == 1);
|
||||||
|
poolOwnerMock.clearMessages();
|
||||||
|
|
||||||
|
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,
|
||||||
|
store_address_t::invalid());
|
||||||
|
CHECK(poolOwner.poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||||
|
CHECK(poolOwner.changedDataSetCallbackWasCalled(sidToCheck, storeId) == true);
|
||||||
|
CHECK(sidToCheck == lpool::testSid);
|
||||||
|
|
||||||
|
HousekeepingMessage::setUpdateSnapshotVariableCommand(&hkCmd, lpool::uint8VarGpid,
|
||||||
|
store_address_t::invalid());
|
||||||
|
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);
|
||||||
|
poolOwnerMock.clearMessages(true);
|
||||||
|
}
|
@ -4,11 +4,11 @@
|
|||||||
#include <catch2/catch_test_macros.hpp>
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
#include "CatchDefinitions.h"
|
#include "CatchDefinitions.h"
|
||||||
#include "LocalPoolOwnerBase.h"
|
#include "mocks/LocalPoolOwnerBase.h"
|
||||||
#include "tests/TestsConfig.h"
|
#include "tests/TestsConfig.h"
|
||||||
|
|
||||||
TEST_CASE("LocalPoolVector", "[LocPoolVecTest]") {
|
TEST_CASE("LocalPoolVector", "[LocPoolVecTest]") {
|
||||||
LocalPoolOwnerBase* poolOwner =
|
auto* poolOwner =
|
||||||
ObjectManager::instance()->get<LocalPoolOwnerBase>(objects::TEST_LOCAL_POOL_OWNER_BASE);
|
ObjectManager::instance()->get<LocalPoolOwnerBase>(objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||||
REQUIRE(poolOwner != nullptr);
|
REQUIRE(poolOwner != nullptr);
|
||||||
REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK);
|
REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK);
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "fsfw/timemanager/TimeStamperIF.h"
|
|
||||||
#include "fsfw/timemanager/TimeReaderIF.h"
|
#include "fsfw/timemanager/TimeReaderIF.h"
|
||||||
|
#include "fsfw/timemanager/TimeStamperIF.h"
|
||||||
|
|
||||||
class CdsShortTimestamperMock : public TimeStamperIF, public TimeReaderIF {
|
class CdsShortTimestamperMock : public TimeStamperIF, public TimeReaderIF {
|
||||||
public:
|
public:
|
||||||
@ -75,7 +75,7 @@ class CdsShortTimestamperMock : public TimeStamperIF, public TimeReaderIF {
|
|||||||
serFailRetval = HasReturnvaluesIF::RETURN_FAILED;
|
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);
|
return deSerialize(&buffer, &maxSize, SerializeIF::Endianness::NETWORK);
|
||||||
}
|
}
|
||||||
size_t getTimestampLen() override { return getSerializedSize(); }
|
size_t getTimestampLen() override { return getSerializedSize(); }
|
||||||
|
@ -2,13 +2,15 @@
|
|||||||
#define FSFW_UNITTEST_TESTS_MOCKS_HKRECEIVERMOCK_H_
|
#define FSFW_UNITTEST_TESTS_MOCKS_HKRECEIVERMOCK_H_
|
||||||
|
|
||||||
#include <fsfw/housekeeping/AcceptsHkPacketsIF.h>
|
#include <fsfw/housekeeping/AcceptsHkPacketsIF.h>
|
||||||
#include <fsfw/objectmanager/SystemObject.h>
|
|
||||||
|
|
||||||
class HkReceiverMock : public SystemObject, public AcceptsHkPacketsIF {
|
class HkReceiverMock : public AcceptsHkPacketsIF {
|
||||||
public:
|
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_ */
|
#endif /* FSFW_UNITTEST_TESTS_MOCKS_HKRECEIVERMOCK_H_ */
|
||||||
|
@ -2,12 +2,6 @@
|
|||||||
|
|
||||||
InternalErrorReporterMock::InternalErrorReporterMock() = default;
|
InternalErrorReporterMock::InternalErrorReporterMock() = default;
|
||||||
|
|
||||||
void InternalErrorReporterMock::queueMessageNotSent() {
|
void InternalErrorReporterMock::queueMessageNotSent() { queueMsgNotSentCallCnt++; }
|
||||||
queueMsgNotSentCallCnt++;
|
void InternalErrorReporterMock::lostTm() { lostTmCallCnt++; }
|
||||||
}
|
void InternalErrorReporterMock::storeFull() { storeFullCallCnt++; }
|
||||||
void InternalErrorReporterMock::lostTm() {
|
|
||||||
lostTmCallCnt++;
|
|
||||||
}
|
|
||||||
void InternalErrorReporterMock::storeFull() {
|
|
||||||
storeFullCallCnt++;
|
|
||||||
}
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
#include "fsfw/internalerror/InternalErrorReporterIF.h"
|
||||||
|
|
||||||
class InternalErrorReporterMock: public InternalErrorReporterIF {
|
class InternalErrorReporterMock : public InternalErrorReporterIF {
|
||||||
public:
|
public:
|
||||||
unsigned int queueMsgNotSentCallCnt = 0;
|
unsigned int queueMsgNotSentCallCnt = 0;
|
||||||
unsigned int lostTmCallCnt = 0;
|
unsigned int lostTmCallCnt = 0;
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
#include "LocalPoolOwnerBase.h"
|
#include "LocalPoolOwnerBase.h"
|
||||||
|
|
||||||
LocalPoolOwnerBase::LocalPoolOwnerBase(object_id_t objectId)
|
LocalPoolOwnerBase::LocalPoolOwnerBase(MessageQueueIF &queue, object_id_t objectId)
|
||||||
: SystemObject(objectId), poolManager(this, messageQueue), dataset(this, lpool::testSetId) {
|
: SystemObject(objectId),
|
||||||
messageQueue = new MessageQueueMockBase();
|
queue(queue),
|
||||||
}
|
poolManager(this, &queue),
|
||||||
|
dataset(this, lpool::testSetId) {}
|
||||||
|
|
||||||
LocalPoolOwnerBase::~LocalPoolOwnerBase() {
|
LocalPoolOwnerBase::~LocalPoolOwnerBase() = default;
|
||||||
QueueFactory::instance()->deleteMessageQueue(messageQueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPoolOwnerBase::initializeHkManager() {
|
ReturnValue_t LocalPoolOwnerBase::initializeHkManager() {
|
||||||
if (not initialized) {
|
if (not initialized) {
|
||||||
initialized = true;
|
initialized = true;
|
||||||
return poolManager.initialize(messageQueue);
|
return poolManager.initialize(&queue);
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
@ -125,3 +124,5 @@ void LocalPoolOwnerBase::handleChangedPoolVariable(gp_id_t globPoolId, store_add
|
|||||||
this->changedPoolVariableGpid = globPoolId;
|
this->changedPoolVariableGpid = globPoolId;
|
||||||
this->storeIdForChangedVariable = storeId;
|
this->storeIdForChangedVariable = storeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LocalPoolOwnerBase::setHkDestId(MessageQueueId_t id) { poolManager.setHkDestinationId(id); }
|
@ -64,26 +64,29 @@ class LocalPoolTestDataSet : public LocalDataSet {
|
|||||||
|
|
||||||
class LocalPoolOwnerBase : public SystemObject, public HasLocalDataPoolIF {
|
class LocalPoolOwnerBase : public SystemObject, public HasLocalDataPoolIF {
|
||||||
public:
|
public:
|
||||||
LocalPoolOwnerBase(object_id_t objectId = objects::TEST_LOCAL_POOL_OWNER_BASE);
|
explicit LocalPoolOwnerBase(MessageQueueIF& queue,
|
||||||
|
object_id_t objectId = objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||||
|
|
||||||
~LocalPoolOwnerBase();
|
~LocalPoolOwnerBase() override;
|
||||||
|
|
||||||
object_id_t getObjectId() const override { return SystemObject::getObjectId(); }
|
[[nodiscard]] object_id_t getObjectId() const override { return SystemObject::getObjectId(); }
|
||||||
|
|
||||||
ReturnValue_t initializeHkManager();
|
ReturnValue_t initializeHkManager();
|
||||||
|
|
||||||
|
void setHkDestId(MessageQueueId_t id);
|
||||||
|
|
||||||
ReturnValue_t initializeHkManagerAfterTaskCreation();
|
ReturnValue_t initializeHkManagerAfterTaskCreation();
|
||||||
|
|
||||||
/** Command queue for housekeeping messages. */
|
/** Command queue for housekeeping messages. */
|
||||||
MessageQueueId_t getCommandQueue() const override { return messageQueue->getId(); }
|
[[nodiscard]] MessageQueueId_t getCommandQueue() const override { return queue.getId(); }
|
||||||
|
|
||||||
// This is called by initializeAfterTaskCreation of the HK manager.
|
// This is called by initializeAfterTaskCreation of the HK manager.
|
||||||
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
LocalDataPoolManager& poolManager) override;
|
LocalDataPoolManager& poolManager) override;
|
||||||
|
|
||||||
LocalDataPoolManager* getHkManagerHandle() override { return &poolManager; }
|
LocalDataPoolManager* getHkManagerHandle() override { return &poolManager; }
|
||||||
|
|
||||||
dur_millis_t getPeriodicOperationFrequency() const override { return 200; }
|
[[nodiscard]] dur_millis_t getPeriodicOperationFrequency() const override { return 200; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is used by the pool manager to get a valid dataset
|
* This function is used by the pool manager to get a valid dataset
|
||||||
@ -91,41 +94,54 @@ class LocalPoolOwnerBase : public SystemObject, public HasLocalDataPoolIF {
|
|||||||
* @param sid Corresponding structure ID
|
* @param sid Corresponding structure ID
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override { return &dataset; }
|
LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override { return &dataset; }
|
||||||
|
|
||||||
virtual LocalPoolObjectBase* getPoolObjectHandle(lp_id_t localPoolId) override;
|
LocalPoolObjectBase* getPoolObjectHandle(lp_id_t localPoolId) override;
|
||||||
|
|
||||||
MessageQueueMockBase* getMockQueueHandle() const {
|
[[nodiscard]] MessageQueueMockBase& getMockQueueHandle() const {
|
||||||
return dynamic_cast<MessageQueueMockBase*>(messageQueue);
|
return dynamic_cast<MessageQueueMockBase&>(queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t subscribePeriodicHk(bool enableReporting) {
|
ReturnValue_t subscribePeriodicHk(bool enableReporting) {
|
||||||
return poolManager.subscribeForPeriodicPacket(lpool::testSid, enableReporting, 0.2, false);
|
return poolManager.subscribeForRegularPeriodicPacket(
|
||||||
|
subdp::RegularHkPeriodicParams(lpool::testSid, enableReporting, 0.2));
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t subscribeWrapperSetUpdate() {
|
ReturnValue_t subscribeWrapperSetUpdate(MessageQueueId_t receiverId) {
|
||||||
return poolManager.subscribeForSetUpdateMessage(lpool::testSetId, objects::NO_OBJECT,
|
return poolManager.subscribeForSetUpdateMessage(lpool::testSetId, objects::NO_OBJECT,
|
||||||
objects::HK_RECEIVER_MOCK, false);
|
receiverId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t subscribeWrapperSetUpdateSnapshot() {
|
ReturnValue_t subscribeWrapperSetUpdateSnapshot(MessageQueueId_t receiverId) {
|
||||||
return poolManager.subscribeForSetUpdateMessage(lpool::testSetId, objects::NO_OBJECT,
|
return poolManager.subscribeForSetUpdateMessage(lpool::testSetId, objects::NO_OBJECT,
|
||||||
objects::HK_RECEIVER_MOCK, true);
|
receiverId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t subscribeWrapperSetUpdateHk(bool diagnostics = false) {
|
ReturnValue_t subscribeWrapperSetUpdateHk(bool diagnostics = false,
|
||||||
return poolManager.subscribeForUpdatePacket(lpool::testSid, diagnostics, false,
|
AcceptsHkPacketsIF* receiver = nullptr) {
|
||||||
objects::HK_RECEIVER_MOCK);
|
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(lp_id_t localPoolId) {
|
ReturnValue_t subscribeWrapperVariableUpdate(MessageQueueId_t receiverId, lp_id_t localPoolId) {
|
||||||
return poolManager.subscribeForVariableUpdateMessage(localPoolId, MessageQueueIF::NO_QUEUE,
|
return poolManager.subscribeForVariableUpdateMessage(localPoolId, MessageQueueIF::NO_QUEUE,
|
||||||
objects::HK_RECEIVER_MOCK, false);
|
receiverId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t subscribeWrapperVariableSnapshot(lp_id_t localPoolId) {
|
ReturnValue_t subscribeWrapperVariableSnapshot(MessageQueueId_t receiverId, lp_id_t localPoolId) {
|
||||||
return poolManager.subscribeForVariableUpdateMessage(localPoolId, MessageQueueIF::NO_QUEUE,
|
return poolManager.subscribeForVariableUpdateMessage(localPoolId, MessageQueueIF::NO_QUEUE,
|
||||||
objects::HK_RECEIVER_MOCK, true);
|
receiverId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t reset();
|
ReturnValue_t reset();
|
||||||
@ -155,7 +171,7 @@ class LocalPoolOwnerBase : public SystemObject, public HasLocalDataPoolIF {
|
|||||||
lp_vec_t<uint16_t, 3> testUint16Vec = lp_vec_t<uint16_t, 3>(this, lpool::uint16Vec3Id);
|
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<int64_t, 2> testInt64Vec = lp_vec_t<int64_t, 2>(this, lpool::int64Vec2Id);
|
||||||
|
|
||||||
MessageQueueIF* messageQueue = nullptr;
|
MessageQueueIF& queue;
|
||||||
|
|
||||||
bool initialized = false;
|
bool initialized = false;
|
||||||
bool initializedAfterTaskCreation = false;
|
bool initializedAfterTaskCreation = false;
|
@ -1,5 +1,7 @@
|
|||||||
#include "MessageQueueMockBase.h"
|
#include "MessageQueueMockBase.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
MessageQueueMockBase::MessageQueueMockBase()
|
MessageQueueMockBase::MessageQueueMockBase()
|
||||||
: MessageQueueBase(MessageQueueIF::NO_QUEUE, MessageQueueIF::NO_QUEUE, nullptr) {}
|
: MessageQueueBase(MessageQueueIF::NO_QUEUE, MessageQueueIF::NO_QUEUE, nullptr) {}
|
||||||
@ -7,32 +9,47 @@ MessageQueueMockBase::MessageQueueMockBase()
|
|||||||
MessageQueueMockBase::MessageQueueMockBase(MessageQueueId_t queueId)
|
MessageQueueMockBase::MessageQueueMockBase(MessageQueueId_t queueId)
|
||||||
: MessageQueueBase(queueId, MessageQueueIF::NO_QUEUE, nullptr) {}
|
: MessageQueueBase(queueId, MessageQueueIF::NO_QUEUE, nullptr) {}
|
||||||
|
|
||||||
bool MessageQueueMockBase::wasMessageSent(uint8_t* messageSentCounter_, bool resetCounter) {
|
bool MessageQueueMockBase::wasMessageSent() const {
|
||||||
bool tempMessageSent = messageSent;
|
return std::any_of(
|
||||||
messageSent = false;
|
sendMap.begin(), sendMap.end(),
|
||||||
if (messageSentCounter_ != nullptr) {
|
[](const std::pair<MessageQueueId_t, SendInfo>& pair) { return pair.second.callCount > 0; });
|
||||||
*messageSentCounter_ = this->messageSentCounter;
|
|
||||||
}
|
|
||||||
if (resetCounter) {
|
|
||||||
this->messageSentCounter = 0;
|
|
||||||
}
|
|
||||||
return tempMessageSent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t MessageQueueMockBase::popMessage() {
|
size_t MessageQueueMockBase::numberOfSentMessage() const {
|
||||||
CommandMessage message;
|
size_t callCount = 0;
|
||||||
message.clear();
|
for (auto& destInfo : sendMap) {
|
||||||
return receiveMessage(&message);
|
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) {
|
ReturnValue_t MessageQueueMockBase::receiveMessage(MessageQueueMessageIF* message) {
|
||||||
if (messagesSentQueue.empty()) {
|
if (receivedMsgs.empty()) {
|
||||||
return MessageQueueIF::EMPTY;
|
return MessageQueueIF::EMPTY;
|
||||||
}
|
}
|
||||||
this->last = message->getSender();
|
std::memcpy(message->getBuffer(), receivedMsgs.front().getBuffer(), message->getMessageSize());
|
||||||
std::memcpy(message->getBuffer(), messagesSentQueue.front().getBuffer(),
|
receivedMsgs.pop_front();
|
||||||
message->getMessageSize());
|
|
||||||
messagesSentQueue.pop();
|
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,12 +60,18 @@ ReturnValue_t MessageQueueMockBase::flush(uint32_t* count) {
|
|||||||
ReturnValue_t MessageQueueMockBase::sendMessageFrom(MessageQueueId_t sendTo,
|
ReturnValue_t MessageQueueMockBase::sendMessageFrom(MessageQueueId_t sendTo,
|
||||||
MessageQueueMessageIF* message,
|
MessageQueueMessageIF* message,
|
||||||
MessageQueueId_t sentFrom, bool ignoreFault) {
|
MessageQueueId_t sentFrom, bool ignoreFault) {
|
||||||
|
if (message == nullptr) {
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
auto iter = sendMap.find(sendTo);
|
auto iter = sendMap.find(sendTo);
|
||||||
|
MessageQueueMessage messageCopy;
|
||||||
if (iter == sendMap.end()) {
|
if (iter == sendMap.end()) {
|
||||||
sendMap.emplace(sendTo, SendInfo(message, 1));
|
createMsgCopy(messageCopy, *message);
|
||||||
|
sendMap.emplace(sendTo, SendInfo(messageCopy, 1));
|
||||||
} else {
|
} else {
|
||||||
iter->second.callCount += 1;
|
iter->second.callCount += 1;
|
||||||
iter->second.msgs.push(message);
|
createMsgCopy(messageCopy, *message);
|
||||||
|
iter->second.msgs.push_back(messageCopy);
|
||||||
}
|
}
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
@ -58,19 +81,87 @@ ReturnValue_t MessageQueueMockBase::reply(MessageQueueMessageIF* message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MessageQueueMockBase::clearMessages(bool clearCommandMessages) {
|
void MessageQueueMockBase::clearMessages(bool clearCommandMessages) {
|
||||||
for (const auto& destInfo: sendMap) {
|
if (not clearCommandMessages) {
|
||||||
if (clearCommandMessages) {
|
sendMap.clear();
|
||||||
CommandMessage message;
|
return;
|
||||||
std::memcpy(message.getBuffer(), destInfo.second.msgs.front()->getBuffer(),
|
|
||||||
message.getMessageSize());
|
|
||||||
}
|
}
|
||||||
while (not messagesSentQueue.empty()) {
|
for (auto& destInfo : sendMap) {
|
||||||
if (clearCommandMessages) {
|
for (auto& msg : destInfo.second.msgs) {
|
||||||
CommandMessage message;
|
CommandMessage message;
|
||||||
std::memcpy(message.getBuffer(), messagesSentQueue.front().getBuffer(),
|
std::memcpy(message.getBuffer(), destInfo.second.msgs.front().getBuffer(),
|
||||||
message.getMessageSize());
|
message.getMessageSize());
|
||||||
message.clear();
|
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_
|
#define FSFW_UNITTEST_TESTS_MOCKS_MESSAGEQUEUEMOCKBASE_H_
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <queue>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
#include "CatchDefinitions.h"
|
#include "CatchDefinitions.h"
|
||||||
#include "fsfw/ipc/CommandMessage.h"
|
#include "fsfw/ipc/CommandMessage.h"
|
||||||
@ -12,39 +12,52 @@
|
|||||||
#include "fsfw/ipc/MessageQueueMessage.h"
|
#include "fsfw/ipc/MessageQueueMessage.h"
|
||||||
|
|
||||||
struct SendInfo {
|
struct SendInfo {
|
||||||
explicit SendInfo(MessageQueueMessageIF* initMsg, unsigned int initCallCnt = 1): callCount(initCallCnt) {
|
explicit SendInfo(MessageQueueMessage& initMsg, unsigned int initCallCnt = 1)
|
||||||
msgs.push(initMsg);
|
: callCount(initCallCnt) {
|
||||||
|
msgs.push_back(initMsg);
|
||||||
}
|
}
|
||||||
unsigned int callCount = 0;
|
unsigned int callCount = 0;
|
||||||
std::queue<MessageQueueMessageIF*> msgs;
|
std::deque<MessageQueueMessage> msgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MessageQueueMockBase : public MessageQueueBase {
|
class MessageQueueMockBase : public MessageQueueBase {
|
||||||
public:
|
public:
|
||||||
MessageQueueMockBase();
|
MessageQueueMockBase();
|
||||||
|
|
||||||
|
void addReceivedMessage(MessageQueueMessageIF& msg);
|
||||||
explicit MessageQueueMockBase(MessageQueueId_t queueId);
|
explicit MessageQueueMockBase(MessageQueueId_t queueId);
|
||||||
|
|
||||||
std::map<MessageQueueId_t, SendInfo> sendMap;
|
//! Get next message which was sent to the default destination
|
||||||
|
ReturnValue_t getNextSentMessage(MessageQueueMessageIF& message);
|
||||||
bool wasMessageSent(uint8_t* messageSentCounter_ = nullptr, bool resetCounter = true);
|
//! 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.
|
* Pop a message, clearing it in the process.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ReturnValue_t popMessage();
|
ReturnValue_t clearLastReceivedMessage(bool clearCmdMsg = true);
|
||||||
|
|
||||||
ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override;
|
|
||||||
|
|
||||||
ReturnValue_t flush(uint32_t* count) override;
|
ReturnValue_t flush(uint32_t* count) override;
|
||||||
ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||||
MessageQueueId_t sentFrom,
|
MessageQueueId_t sentFrom, bool ignoreFault = false) override;
|
||||||
bool ignoreFault = false) override;
|
|
||||||
ReturnValue_t reply(MessageQueueMessageIF* message) 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:
|
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_ */
|
#endif /* FSFW_UNITTEST_TESTS_MOCKS_MESSAGEQUEUEMOCKBASE_H_ */
|
||||||
|
@ -65,7 +65,8 @@ TEST_CASE("Serialize IF Serialize", "[serialize-if-ser]") {
|
|||||||
HasReturnvaluesIF::RETURN_OK);
|
HasReturnvaluesIF::RETURN_OK);
|
||||||
}
|
}
|
||||||
SECTION("Network 1") {
|
SECTION("Network 1") {
|
||||||
REQUIRE(simpleSer.SerializeIF::serializeBe(buf.data(), buf.size()) == HasReturnvaluesIF::RETURN_OK);
|
REQUIRE(simpleSer.SerializeIF::serializeBe(buf.data(), buf.size()) ==
|
||||||
|
HasReturnvaluesIF::RETURN_OK);
|
||||||
}
|
}
|
||||||
CHECK(buf[0] == 1);
|
CHECK(buf[0] == 1);
|
||||||
CHECK(buf[1] == 2);
|
CHECK(buf[1] == 2);
|
||||||
@ -154,7 +155,8 @@ TEST_CASE("SerializeIF Deserialize", "[serialize-if-de]") {
|
|||||||
HasReturnvaluesIF::RETURN_OK);
|
HasReturnvaluesIF::RETURN_OK);
|
||||||
}
|
}
|
||||||
SECTION("Network 1") {
|
SECTION("Network 1") {
|
||||||
REQUIRE(simpleSer.SerializeIF::deSerializeBe(buf.data(), buf.size()) == HasReturnvaluesIF::RETURN_OK);
|
REQUIRE(simpleSer.SerializeIF::deSerializeBe(buf.data(), buf.size()) ==
|
||||||
|
HasReturnvaluesIF::RETURN_OK);
|
||||||
}
|
}
|
||||||
CHECK(simpleSer.getU8() == 5);
|
CHECK(simpleSer.getU8() == 5);
|
||||||
CHECK(simpleSer.getU16() == 1);
|
CHECK(simpleSer.getU16() == 1);
|
||||||
|
@ -31,4 +31,4 @@ enum sourceObjects : uint32_t {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* BSP_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ */
|
#endif /* HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_ */
|
||||||
|
@ -9,7 +9,5 @@ TEST_CASE("TM Send Helper", "[tm-send-helper]") {
|
|||||||
auto msgQueue = MessageQueueMockBase();
|
auto msgQueue = MessageQueueMockBase();
|
||||||
TmSendHelper sendHelper(&msgQueue, &errReporter);
|
TmSendHelper sendHelper(&msgQueue, &errReporter);
|
||||||
|
|
||||||
SECTION("State") {
|
SECTION("State") {}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user