fixed unittests
This commit is contained in:
parent
b619c1f06f
commit
401db7def6
@ -21,7 +21,7 @@ dp::structure_id_t HousekeepingMessage::getHkDataReply(const CommandMessage *mes
|
|||||||
if (storeIdToSet != nullptr) {
|
if (storeIdToSet != nullptr) {
|
||||||
*storeIdToSet = message->getParameter3();
|
*storeIdToSet = message->getParameter3();
|
||||||
}
|
}
|
||||||
return getSid(message);
|
return getStructureId(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setToggleReportingCommand(CommandMessage *message, dp::structure_id_t sid,
|
void HousekeepingMessage::setToggleReportingCommand(CommandMessage *message, dp::structure_id_t sid,
|
||||||
@ -48,15 +48,14 @@ void HousekeepingMessage::setOneShotReportCommand(CommandMessage *command, dp::s
|
|||||||
setSid(command, sid);
|
setSid(command, sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setCollectionIntervalModificationCommand(CommandMessage *command,
|
void HousekeepingMessage::setCollectionIntervalModificationCommand(
|
||||||
dp::structure_id_t sid,
|
CommandMessage *command, dp::structure_id_t sid, dur_millis_t collectionIntervalMs) {
|
||||||
float collectionInterval) {
|
|
||||||
command->setCommand(MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL);
|
command->setCommand(MODIFY_PARAMETER_REPORT_COLLECTION_INTERVAL);
|
||||||
|
|
||||||
/* Raw storage of the float in the message. Do not use setParameter3, does
|
/* Raw storage of the float in the message. Do not use setParameter3, does
|
||||||
implicit conversion to integer type! */
|
implicit conversion to integer type! */
|
||||||
std::memcpy(command->getData() + 2 * sizeof(uint32_t), &collectionInterval,
|
std::memcpy(command->getData() + 2 * sizeof(uint32_t), &collectionIntervalMs,
|
||||||
sizeof(collectionInterval));
|
sizeof(collectionIntervalMs));
|
||||||
|
|
||||||
setSid(command, sid);
|
setSid(command, sid);
|
||||||
}
|
}
|
||||||
@ -66,7 +65,7 @@ dp::structure_id_t HousekeepingMessage::getCollectionIntervalModificationCommand
|
|||||||
std::memcpy(&newCollectionIntervalMs, command->getData() + 2 * sizeof(uint32_t),
|
std::memcpy(&newCollectionIntervalMs, command->getData() + 2 * sizeof(uint32_t),
|
||||||
sizeof(newCollectionIntervalMs));
|
sizeof(newCollectionIntervalMs));
|
||||||
|
|
||||||
return getSid(command);
|
return getStructureId(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HousekeepingMessage::setHkRequestSuccessReply(CommandMessage *reply, dp::structure_id_t sid) {
|
void HousekeepingMessage::setHkRequestSuccessReply(CommandMessage *reply, dp::structure_id_t sid) {
|
||||||
@ -86,10 +85,10 @@ dp::structure_id_t HousekeepingMessage::getHkRequestFailureReply(const CommandMe
|
|||||||
if (error != nullptr) {
|
if (error != nullptr) {
|
||||||
*error = reply->getParameter3();
|
*error = reply->getParameter3();
|
||||||
}
|
}
|
||||||
return getSid(reply);
|
return getStructureId(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
dp::structure_id_t HousekeepingMessage::getSid(const CommandMessage *message) {
|
dp::structure_id_t HousekeepingMessage::getStructureId(const CommandMessage *message) {
|
||||||
dp::structure_id_t sid;
|
dp::structure_id_t sid;
|
||||||
std::memcpy(&sid.raw, message->getData(), sizeof(sid.raw));
|
std::memcpy(&sid.raw, message->getData(), sizeof(sid.raw));
|
||||||
return sid;
|
return sid;
|
||||||
@ -126,7 +125,7 @@ void HousekeepingMessage::clear(CommandMessage *message) {
|
|||||||
|
|
||||||
dp::structure_id_t HousekeepingMessage::getUpdateNotificationSetCommand(
|
dp::structure_id_t HousekeepingMessage::getUpdateNotificationSetCommand(
|
||||||
const CommandMessage *command) {
|
const CommandMessage *command) {
|
||||||
return getSid(command);
|
return getStructureId(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
dp::g_id_t HousekeepingMessage::getUpdateNotificationVariableCommand(
|
dp::g_id_t HousekeepingMessage::getUpdateNotificationVariableCommand(
|
||||||
@ -139,7 +138,7 @@ dp::structure_id_t HousekeepingMessage::getUpdateSnapshotSetCommand(const Comman
|
|||||||
if (storeId != nullptr) {
|
if (storeId != nullptr) {
|
||||||
*storeId = command->getParameter3();
|
*storeId = command->getParameter3();
|
||||||
}
|
}
|
||||||
return getSid(command);
|
return getStructureId(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
dp::g_id_t HousekeepingMessage::getUpdateSnapshotVariableCommand(const CommandMessage *command,
|
dp::g_id_t HousekeepingMessage::getUpdateSnapshotVariableCommand(const CommandMessage *command,
|
||||||
|
@ -54,7 +54,7 @@ class HousekeepingMessage {
|
|||||||
|
|
||||||
// static constexpr Command_t UPDATE_HK_REPORT = MAKE_COMMAND_ID(134);
|
// static constexpr Command_t UPDATE_HK_REPORT = MAKE_COMMAND_ID(134);
|
||||||
|
|
||||||
static dp::sid_t getSid(const CommandMessage* message);
|
static dp::sid_t getStructureId(const CommandMessage* message);
|
||||||
static dp::g_id_t getGpid(const CommandMessage* message);
|
static dp::g_id_t getGpid(const CommandMessage* message);
|
||||||
|
|
||||||
/* Housekeeping Interface Messages */
|
/* Housekeeping Interface Messages */
|
||||||
@ -64,7 +64,7 @@ class HousekeepingMessage {
|
|||||||
static void setStructureReportingCommand(CommandMessage* command, dp::sid_t sid);
|
static void setStructureReportingCommand(CommandMessage* command, dp::sid_t sid);
|
||||||
static void setOneShotReportCommand(CommandMessage* command, dp::sid_t sid);
|
static void setOneShotReportCommand(CommandMessage* command, dp::sid_t sid);
|
||||||
static void setCollectionIntervalModificationCommand(CommandMessage* command, dp::sid_t sid,
|
static void setCollectionIntervalModificationCommand(CommandMessage* command, dp::sid_t sid,
|
||||||
float collectionInterval);
|
dur_millis_t collectionIntervalMs);
|
||||||
|
|
||||||
static void setHkReportReply(CommandMessage* reply, dp::sid_t sid, store_address_t storeId);
|
static void setHkReportReply(CommandMessage* reply, dp::sid_t sid, store_address_t storeId);
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ ReturnValue_t PeriodicHelper::performHkOperation() {
|
|||||||
|
|
||||||
ReturnValue_t PeriodicHelper::handleHousekeepingMessage(CommandMessage* message) {
|
ReturnValue_t PeriodicHelper::handleHousekeepingMessage(CommandMessage* message) {
|
||||||
Command_t command = message->getCommand();
|
Command_t command = message->getCommand();
|
||||||
dp::sid_t sid = HousekeepingMessage::getSid(message);
|
dp::sid_t sid = HousekeepingMessage::getStructureId(message);
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
switch (command) {
|
switch (command) {
|
||||||
// Houskeeping interface handling.
|
// Houskeeping interface handling.
|
||||||
@ -112,7 +112,7 @@ ReturnValue_t PeriodicHelper::handleHousekeepingMessage(CommandMessage* message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case (HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT): {
|
case (HousekeepingMessage::GENERATE_ONE_PARAMETER_REPORT): {
|
||||||
return generateHousekeepingPacket(HousekeepingMessage::getSid(message));
|
return generateHousekeepingPacket(HousekeepingMessage::getStructureId(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -138,13 +138,13 @@ GeneratesPeriodicHkIF* PeriodicHelper::getOwner() const { return owner; }
|
|||||||
ReturnValue_t PeriodicHelper::generateHousekeepingPacket(const dp::sid_t sid,
|
ReturnValue_t PeriodicHelper::generateHousekeepingPacket(const dp::sid_t sid,
|
||||||
MessageQueueId_t destination) {
|
MessageQueueId_t destination) {
|
||||||
store_address_t storeId;
|
store_address_t storeId;
|
||||||
auto optSetSpec = getSetSpecification(sid);
|
const auto optSetSpec = getSetSpecification(sid);
|
||||||
if (!optSetSpec.has_value()) {
|
if (!optSetSpec.has_value()) {
|
||||||
return DATASET_NOT_FOUND;
|
return DATASET_NOT_FOUND;
|
||||||
}
|
}
|
||||||
auto& setSpec = optSetSpec.value().get();
|
const auto& setSpec = optSetSpec.value().get();
|
||||||
uint8_t* dataPtr = nullptr;
|
uint8_t* dataPtr = nullptr;
|
||||||
const size_t maxSize = setSpec.size + dp::structure_id_t::SIZE;
|
const size_t maxSize = setSpec.serializedSize + dp::structure_id_t::SIZE;
|
||||||
ReturnValue_t result = ipcStore->getFreeElement(&storeId, maxSize, &dataPtr);
|
ReturnValue_t result = ipcStore->getFreeElement(&storeId, maxSize, &dataPtr);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
@ -189,12 +189,12 @@ ReturnValue_t PeriodicHelper::generateHousekeepingPacket(const dp::sid_t sid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PeriodicHelper::performPeriodicHkGeneration(SetSpecification& setSpec, timeval& now) {
|
void PeriodicHelper::performPeriodicHkGeneration(SetSpecification& setSpec, timeval& now) {
|
||||||
dp::sid_t sid = setSpec.dataId.sid;
|
const dp::sid_t sid = setSpec.dataId.sid;
|
||||||
|
|
||||||
timeval diff = now - setSpec.lastGenerated;
|
auto [tv_sec, tv_usec] = now - setSpec.lastGenerated;
|
||||||
dur_millis_t diffMillis = diff.tv_sec * 1000 + diff.tv_usec / 1000;
|
if (const dur_millis_t diffMillis = tv_sec * 1000 + tv_usec / 1000;
|
||||||
if (diffMillis > setSpec.collectionFrequency) {
|
diffMillis >= setSpec.collectionFrequency) {
|
||||||
ReturnValue_t result = generateHousekeepingPacket(sid);
|
const ReturnValue_t result = generateHousekeepingPacket(sid);
|
||||||
setSpec.lastGenerated = now;
|
setSpec.lastGenerated = now;
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
// Configuration error
|
// Configuration error
|
||||||
@ -210,8 +210,8 @@ void PeriodicHelper::performPeriodicHkGeneration(SetSpecification& setSpec, time
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PeriodicHelper::togglePeriodicGeneration(dp::sid_t sid, bool enable) {
|
ReturnValue_t PeriodicHelper::togglePeriodicGeneration(const dp::sid_t sid, const bool enable) {
|
||||||
auto optSetSpec = getSetSpecification(sid);
|
const auto optSetSpec = getSetSpecification(sid);
|
||||||
if (!optSetSpec.has_value()) {
|
if (!optSetSpec.has_value()) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_WARNING, "togglePeriodicGeneration",
|
printWarningOrError(sif::OutputTypes::OUT_WARNING, "togglePeriodicGeneration",
|
||||||
DATASET_NOT_FOUND);
|
DATASET_NOT_FOUND);
|
||||||
@ -259,7 +259,7 @@ ReturnValue_t PeriodicHelper::generateSetStructurePacket(dp::structure_id_t sid)
|
|||||||
|
|
||||||
uint8_t* storePtr = nullptr;
|
uint8_t* storePtr = nullptr;
|
||||||
store_address_t storeId;
|
store_address_t storeId;
|
||||||
ReturnValue_t result = ipcStore->getFreeElement(&storeId, setSpec.size, &storePtr);
|
ReturnValue_t result = ipcStore->getFreeElement(&storeId, setSpec.serializedSize, &storePtr);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
printWarningOrError(sif::OutputTypes::OUT_ERROR, "generateSetStructurePacket",
|
printWarningOrError(sif::OutputTypes::OUT_ERROR, "generateSetStructurePacket",
|
||||||
returnvalue::FAILED, "Could not get free element from IPC store.");
|
returnvalue::FAILED, "Could not get free element from IPC store.");
|
||||||
|
@ -149,10 +149,10 @@ class PeriodicHelper : public PeriodicHelperIF {
|
|||||||
ReturnValue_t setCollectionInterval(dp::sid_t structureId,
|
ReturnValue_t setCollectionInterval(dp::sid_t structureId,
|
||||||
dur_millis_t newCollectionIntervalMs) override;
|
dur_millis_t newCollectionIntervalMs) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
std::optional<std::reference_wrapper<SetSpecification>> getSetSpecification(
|
std::optional<std::reference_wrapper<SetSpecification>> getSetSpecification(
|
||||||
dp::sid_t structureId);
|
dp::sid_t structureId);
|
||||||
|
|
||||||
|
protected:
|
||||||
std::optional<dur_millis_t> getCollectionFrequency(dp::sid_t structureId);
|
std::optional<dur_millis_t> getCollectionFrequency(dp::sid_t structureId);
|
||||||
|
|
||||||
/** The class which actually owns the manager (and its datapool). */
|
/** The class which actually owns the manager (and its datapool). */
|
||||||
|
@ -48,25 +48,32 @@ struct SetSpecification {
|
|||||||
friend class PeriodicHelper;
|
friend class PeriodicHelper;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SetSpecification(dp::sid_t structureId, size_t size, dur_millis_t collectionFrequency,
|
SetSpecification(const dp::structure_id_t structureId, const size_t serializedSize,
|
||||||
MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE)
|
const dur_millis_t collectionFrequency,
|
||||||
|
const MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE)
|
||||||
: dataId(DataId::forSetId(structureId)),
|
: dataId(DataId::forSetId(structureId)),
|
||||||
collectionFrequency(collectionFrequency),
|
destinationQueue(destinationQueue),
|
||||||
size(size),
|
serializedSize(serializedSize),
|
||||||
destinationQueue(destinationQueue) {};
|
collectionFrequency(collectionFrequency) {};
|
||||||
// Object ID of receiver
|
// Object ID of receiver
|
||||||
object_id_t objectId = objects::NO_OBJECT;
|
object_id_t objectId = objects::NO_OBJECT;
|
||||||
|
|
||||||
DataType dataType = DataType::DATA_SET;
|
DataType dataType = DataType::DATA_SET;
|
||||||
DataId dataId;
|
DataId dataId;
|
||||||
|
|
||||||
dur_millis_t collectionFrequency = 0;
|
|
||||||
size_t size = 0;
|
|
||||||
ReportingType reportingType = ReportingType::PERIODIC;
|
ReportingType reportingType = ReportingType::PERIODIC;
|
||||||
|
|
||||||
|
[[nodiscard]] size_t getSerializedSize() const { return serializedSize; }
|
||||||
|
|
||||||
|
[[nodiscard]] dur_millis_t getCollectionFrequency() const { return collectionFrequency; }
|
||||||
|
|
||||||
|
[[nodiscard]] bool collectionEnabled() const { return periodicCollectionEnabled; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE;
|
MessageQueueId_t destinationQueue = MessageQueueIF::NO_QUEUE;
|
||||||
bool periodicCollectionEnabled = false;
|
bool periodicCollectionEnabled = false;
|
||||||
|
size_t serializedSize = 0;
|
||||||
|
dur_millis_t collectionFrequency = 0;
|
||||||
timeval lastGenerated{};
|
timeval lastGenerated{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ add_subdirectory(osal)
|
|||||||
add_subdirectory(pus)
|
add_subdirectory(pus)
|
||||||
add_subdirectory(subsystem)
|
add_subdirectory(subsystem)
|
||||||
add_subdirectory(serialize)
|
add_subdirectory(serialize)
|
||||||
add_subdirectory(datapoollocal)
|
add_subdirectory(datapool)
|
||||||
add_subdirectory(storagemanager)
|
add_subdirectory(storagemanager)
|
||||||
add_subdirectory(globalfunctions)
|
add_subdirectory(globalfunctions)
|
||||||
add_subdirectory(timemanager)
|
add_subdirectory(timemanager)
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
target_sources(
|
target_sources(
|
||||||
${FSFW_TEST_TGT} PRIVATE testLocalPoolVariable.cpp testLocalPoolVector.cpp
|
${FSFW_TEST_TGT} PRIVATE testLocalPoolVariable.cpp testLocalPoolVector.cpp
|
||||||
testDataSet.cpp testLocalPoolManager.cpp)
|
testDataSet.cpp testPeriodicHkHelper.cpp)
|
159
unittests/datapool/testPeriodicHkHelper.cpp
Normal file
159
unittests/datapool/testPeriodicHkHelper.cpp
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
#include <fsfw/datapool/PoolReadGuard.h>
|
||||||
|
#include <fsfw/globalfunctions/timevalOperations.h>
|
||||||
|
#include <fsfw/ipc/CommandMessageCleaner.h>
|
||||||
|
#include <fsfw/objectmanager/ObjectManager.h>
|
||||||
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
|
#include <fsfw/timemanager/CCSDSTime.h>
|
||||||
|
|
||||||
|
#include <catch2/catch_approx.hpp>
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <catch2/matchers/catch_matchers_floating_point.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "CatchDefinitions.h"
|
||||||
|
#include "mock/HkReceiverMock.h"
|
||||||
|
#include "mock/TestPoolOwner.h"
|
||||||
|
|
||||||
|
using namespace lpool;
|
||||||
|
|
||||||
|
TEST_CASE("Pool Owner and Periodic HK", "[datapool]") {
|
||||||
|
constexpr MessageQueueId_t DEFAULT_DEST_ID = 1;
|
||||||
|
constexpr MessageQueueId_t HK_DEST = DEFAULT_DEST_ID;
|
||||||
|
auto hkReceiver = HkReceiverMock(HK_DEST);
|
||||||
|
auto queue = MessageQueueMock(3, HK_DEST);
|
||||||
|
CommandMessage msg;
|
||||||
|
TestPoolOwner poolOwner(queue, HK_DEST, objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||||
|
|
||||||
|
REQUIRE(poolOwner.initialize() == returnvalue::OK);
|
||||||
|
|
||||||
|
MessageQueueMock& poolOwnerMock = poolOwner.getMockQueueHandle();
|
||||||
|
CommandMessage messageSent;
|
||||||
|
|
||||||
|
// TODO: Fix
|
||||||
|
SECTION("Basic Test") {
|
||||||
|
{
|
||||||
|
// For code coverage, should not crash
|
||||||
|
hk::PeriodicHelper manager(nullptr, nullptr);
|
||||||
|
}
|
||||||
|
auto owner = poolOwner.hkHelper.getOwner();
|
||||||
|
REQUIRE(owner != nullptr);
|
||||||
|
CHECK(owner->getObjectId() == objects::TEST_LOCAL_POOL_OWNER_BASE);
|
||||||
|
|
||||||
|
// Clear message to avoid memory leak, our mock won't do it for us (yet)
|
||||||
|
CommandMessageCleaner::clearCommandMessage(&messageSent);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Periodic HK And Messaging") {
|
||||||
|
// 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.enablePeriodicHk(testSid0, 50) == returnvalue::OK);
|
||||||
|
REQUIRE(poolOwner.hkHelper.performHkOperation() == returnvalue::OK);
|
||||||
|
// Now HK packet should be sent as message immediately.
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessages() == 1);
|
||||||
|
CHECK(poolOwnerMock.getNextSentMessageToDefaultDest(msg) == returnvalue::OK);
|
||||||
|
CHECK(msg.getCommand() == HousekeepingMessage::HK_REPORT);
|
||||||
|
auto structureId = HousekeepingMessage::getStructureId(&msg);
|
||||||
|
CHECK(structureId == testSid0);
|
||||||
|
|
||||||
|
CHECK(poolOwnerMock.clearLastSentMessage() == returnvalue::OK);
|
||||||
|
REQUIRE(poolOwner.hkHelper.performHkOperation() == returnvalue::OK);
|
||||||
|
// No packet should be generated now.
|
||||||
|
REQUIRE(!poolOwnerMock.wasMessageSent());
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessages() == 0);
|
||||||
|
|
||||||
|
TaskFactory::delayTask(50);
|
||||||
|
|
||||||
|
// Should be generated again now.
|
||||||
|
REQUIRE(poolOwner.hkHelper.performHkOperation() == returnvalue::OK);
|
||||||
|
// No packet should be generated now.
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessages() == 1);
|
||||||
|
CHECK(poolOwnerMock.getNextSentMessageToDefaultDest(msg) == returnvalue::OK);
|
||||||
|
CHECK(msg.getCommand() == HousekeepingMessage::HK_REPORT);
|
||||||
|
structureId = HousekeepingMessage::getStructureId(&msg);
|
||||||
|
CHECK(structureId == testSid0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Manual generation with API") {
|
||||||
|
// We can always generate a packet ourselves.
|
||||||
|
CHECK(poolOwner.hkHelper.generateHousekeepingPacket(lpool::testSid0) == returnvalue::OK);
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessages() == 1);
|
||||||
|
|
||||||
|
CHECK(poolOwnerMock.getNextSentMessageToDefaultDest(msg) == returnvalue::OK);
|
||||||
|
auto structureId = HousekeepingMessage::getStructureId(&msg);
|
||||||
|
CHECK(structureId == testSid0);
|
||||||
|
CHECK(poolOwnerMock.clearLastSentMessage() == returnvalue::OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Generation with Message") {
|
||||||
|
HousekeepingMessage::setOneShotReportCommand(&msg, lpool::testSid0);
|
||||||
|
CHECK(poolOwner.hkHelper.handleHousekeepingMessage(&msg) == returnvalue::OK);
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
REQUIRE(poolOwnerMock.numberOfSentMessages() == 1);
|
||||||
|
CHECK(poolOwnerMock.getNextSentMessageToDefaultDest(msg) == returnvalue::OK);
|
||||||
|
auto structureId = HousekeepingMessage::getStructureId(&msg);
|
||||||
|
CHECK(structureId == testSid0);
|
||||||
|
poolOwnerMock.clearMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Toggle generation with message") {
|
||||||
|
HousekeepingMessage::setToggleReportingCommand(&msg, lpool::testSid0, false);
|
||||||
|
CHECK(poolOwner.hkHelper.handleHousekeepingMessage(&msg) == returnvalue::OK);
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
CHECK(poolOwnerMock.numberOfSentMessages() == 1);
|
||||||
|
CHECK(poolOwnerMock.getNextSentMessageToDefaultDest(msg) == returnvalue::OK);
|
||||||
|
CHECK(msg.getCommand() == HousekeepingMessage::HK_REQUEST_SUCCESS);
|
||||||
|
auto structureId = HousekeepingMessage::getStructureId(&msg);
|
||||||
|
CHECK(structureId == testSid0);
|
||||||
|
CHECK(poolOwnerMock.clearLastSentMessage() == returnvalue::OK);
|
||||||
|
auto optSetSpec = poolOwner.hkHelper.getSetSpecification(testSid0);
|
||||||
|
REQUIRE(optSetSpec.has_value());
|
||||||
|
REQUIRE(!optSetSpec.value().get().collectionEnabled());
|
||||||
|
|
||||||
|
HousekeepingMessage::setToggleReportingCommand(&msg, lpool::testSid0, true);
|
||||||
|
CHECK(poolOwner.hkHelper.handleHousekeepingMessage(&msg) == returnvalue::OK);
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
CHECK(poolOwnerMock.getNextSentMessageToDefaultDest(msg) == returnvalue::OK);
|
||||||
|
CHECK(msg.getCommand() == HousekeepingMessage::HK_REQUEST_SUCCESS);
|
||||||
|
structureId = HousekeepingMessage::getStructureId(&msg);
|
||||||
|
CHECK(structureId == testSid0);
|
||||||
|
CHECK(poolOwnerMock.clearLastSentMessage() == returnvalue::OK);
|
||||||
|
REQUIRE(optSetSpec.has_value());
|
||||||
|
REQUIRE(optSetSpec.value().get().collectionEnabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Modify collection interval with message") {
|
||||||
|
HousekeepingMessage::setCollectionIntervalModificationCommand(&msg, lpool::testSid0, 400);
|
||||||
|
CHECK(poolOwner.hkHelper.handleHousekeepingMessage(&msg) == returnvalue::OK);
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
REQUIRE(poolOwnerMock.numberOfSentMessages() == 1);
|
||||||
|
CHECK(poolOwnerMock.getNextSentMessageToDefaultDest(msg) == returnvalue::OK);
|
||||||
|
CHECK(msg.getCommand() == HousekeepingMessage::HK_REQUEST_SUCCESS);
|
||||||
|
auto structureId = HousekeepingMessage::getStructureId(&msg);
|
||||||
|
CHECK(structureId == testSid0);
|
||||||
|
auto optSetSpec = poolOwner.hkHelper.getSetSpecification(testSid0);
|
||||||
|
REQUIRE(optSetSpec.has_value());
|
||||||
|
CHECK(optSetSpec.value().get().getCollectionFrequency() == 400);
|
||||||
|
|
||||||
|
CHECK(poolOwnerMock.clearLastSentMessage() == returnvalue::OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Structure reporting command") {
|
||||||
|
HousekeepingMessage::setStructureReportingCommand(&msg, lpool::testSid0);
|
||||||
|
REQUIRE(poolOwner.hkHelper.performHkOperation() == returnvalue::OK);
|
||||||
|
CHECK(poolOwner.hkHelper.handleHousekeepingMessage(&msg) == returnvalue::OK);
|
||||||
|
// Now HK packet should be sent as message.
|
||||||
|
REQUIRE(poolOwnerMock.wasMessageSent());
|
||||||
|
REQUIRE(poolOwnerMock.numberOfSentMessages() == 1);
|
||||||
|
poolOwnerMock.clearMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
// we need to reset the subscription list because the pool owner
|
||||||
|
// is a global object.
|
||||||
|
CHECK(poolOwner.reset() == returnvalue::OK);
|
||||||
|
poolOwnerMock.clearMessages(true);
|
||||||
|
}
|
@ -1,140 +0,0 @@
|
|||||||
#include <fsfw/datapool/PoolReadGuard.h>
|
|
||||||
#include <fsfw/globalfunctions/timevalOperations.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 <catch2/matchers/catch_matchers_floating_point.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "CatchDefinitions.h"
|
|
||||||
#include "mock/HkReceiverMock.h"
|
|
||||||
#include "mock/TestPoolOwner.h"
|
|
||||||
|
|
||||||
using namespace lpool;
|
|
||||||
|
|
||||||
TEST_CASE("Pool Owner and Periodic HK", "[datapool]") {
|
|
||||||
constexpr MessageQueueId_t DEFAULT_DEST_ID = 1;
|
|
||||||
constexpr MessageQueueId_t HK_DEST = DEFAULT_DEST_ID;
|
|
||||||
auto hkReceiver = HkReceiverMock(HK_DEST);
|
|
||||||
auto queue = MessageQueueMock(3, HK_DEST);
|
|
||||||
TestPoolOwner poolOwner(queue, HK_DEST, objects::TEST_LOCAL_POOL_OWNER_BASE);
|
|
||||||
|
|
||||||
REQUIRE(poolOwner.initialize() == returnvalue::OK);
|
|
||||||
|
|
||||||
MessageQueueMock& poolOwnerMock = poolOwner.getMockQueueHandle();
|
|
||||||
CommandMessage messageSent;
|
|
||||||
|
|
||||||
// TODO: Fix
|
|
||||||
SECTION("Basic Test") {
|
|
||||||
{
|
|
||||||
// For code coverage, should not crash
|
|
||||||
hk::PeriodicHelper manager(nullptr, nullptr);
|
|
||||||
}
|
|
||||||
auto owner = poolOwner.hkHelper.getOwner();
|
|
||||||
REQUIRE(owner != nullptr);
|
|
||||||
CHECK(owner->getObjectId() == objects::TEST_LOCAL_POOL_OWNER_BASE);
|
|
||||||
|
|
||||||
// Clear message to avoid memory leak, our mock won't do it for us (yet)
|
|
||||||
CommandMessageCleaner::clearCommandMessage(&messageSent);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("Periodic HK And Messaging") {
|
|
||||||
// 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.enablePeriodicHk(lpool::testSid0, 30) == returnvalue::OK);
|
|
||||||
REQUIRE(poolOwner.hkHelper.performHkOperation() == returnvalue::OK);
|
|
||||||
// Now HK packet should be sent as message immediately.
|
|
||||||
REQUIRE(poolOwnerMock.wasMessageSent());
|
|
||||||
CHECK(poolOwnerMock.numberOfSentMessages() == 1);
|
|
||||||
CHECK(poolOwnerMock.clearLastSentMessage() == returnvalue::OK);
|
|
||||||
|
|
||||||
CHECK(poolOwner.hkHelper.generateHousekeepingPacket(lpool::testSid0) == returnvalue::OK);
|
|
||||||
REQUIRE(poolOwnerMock.wasMessageSent());
|
|
||||||
CHECK(poolOwnerMock.numberOfSentMessages() == 1);
|
|
||||||
CHECK(poolOwnerMock.clearLastSentMessage() == returnvalue::OK);
|
|
||||||
|
|
||||||
// CHECK(setHandle->getReportingEnabled() == true);
|
|
||||||
CommandMessage hkCmd;
|
|
||||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid0, false);
|
|
||||||
CHECK(poolOwner.hkHelper.handleHousekeepingMessage(&hkCmd) == returnvalue::OK);
|
|
||||||
// CHECK(setHandle->getReportingEnabled() == false);
|
|
||||||
REQUIRE(poolOwnerMock.wasMessageSent());
|
|
||||||
CHECK(poolOwnerMock.numberOfSentMessages() == 1);
|
|
||||||
CHECK(poolOwnerMock.clearLastSentMessage() == returnvalue::OK);
|
|
||||||
|
|
||||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid0, true);
|
|
||||||
CHECK(poolOwner.hkHelper.handleHousekeepingMessage(&hkCmd) == returnvalue::OK);
|
|
||||||
// CHECK(setHandle->getReportingEnabled() == true);
|
|
||||||
REQUIRE(poolOwnerMock.wasMessageSent());
|
|
||||||
CHECK(poolOwnerMock.clearLastSentMessage() == returnvalue::OK);
|
|
||||||
|
|
||||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid0, false);
|
|
||||||
CHECK(poolOwner.hkHelper.handleHousekeepingMessage(&hkCmd) == returnvalue::OK);
|
|
||||||
// CHECK(setHandle->getReportingEnabled() == false);
|
|
||||||
REQUIRE(poolOwnerMock.wasMessageSent());
|
|
||||||
CHECK(poolOwnerMock.clearLastSentMessage() == returnvalue::OK);
|
|
||||||
|
|
||||||
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid0, 0.4);
|
|
||||||
CHECK(poolOwner.hkHelper.handleHousekeepingMessage(&hkCmd) == returnvalue::OK);
|
|
||||||
// CHECK_THAT(poolOwner.dataset.getCollectionInterval(), Catch::Matchers::WithinAbs(0.4, 0.01));
|
|
||||||
REQUIRE(poolOwnerMock.wasMessageSent());
|
|
||||||
REQUIRE(poolOwnerMock.numberOfSentMessages() == 1);
|
|
||||||
CHECK(poolOwnerMock.clearLastSentMessage() == returnvalue::OK);
|
|
||||||
|
|
||||||
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid0);
|
|
||||||
REQUIRE(poolOwner.hkHelper.performHkOperation() == returnvalue::OK);
|
|
||||||
CHECK(poolOwner.hkHelper.handleHousekeepingMessage(&hkCmd) == returnvalue::OK);
|
|
||||||
// Now HK packet should be sent as message.
|
|
||||||
REQUIRE(poolOwnerMock.wasMessageSent());
|
|
||||||
REQUIRE(poolOwnerMock.numberOfSentMessages() == 1);
|
|
||||||
poolOwnerMock.clearMessages();
|
|
||||||
|
|
||||||
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid0);
|
|
||||||
CHECK(poolOwner.hkHelper.handleHousekeepingMessage(&hkCmd) == returnvalue::OK);
|
|
||||||
REQUIRE(poolOwnerMock.wasMessageSent());
|
|
||||||
REQUIRE(poolOwnerMock.numberOfSentMessages() == 1);
|
|
||||||
poolOwnerMock.clearMessages();
|
|
||||||
|
|
||||||
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid0);
|
|
||||||
CHECK(poolOwner.hkHelper.handleHousekeepingMessage(&hkCmd) == returnvalue::OK);
|
|
||||||
REQUIRE(poolOwnerMock.wasMessageSent());
|
|
||||||
REQUIRE(poolOwnerMock.numberOfSentMessages() == 1);
|
|
||||||
poolOwnerMock.clearMessages();
|
|
||||||
|
|
||||||
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid0, 0.4);
|
|
||||||
CHECK(poolOwner.hkHelper.handleHousekeepingMessage(&hkCmd) == returnvalue::OK);
|
|
||||||
REQUIRE(poolOwnerMock.wasMessageSent());
|
|
||||||
REQUIRE(poolOwnerMock.numberOfSentMessages() == 1);
|
|
||||||
poolOwnerMock.clearMessages();
|
|
||||||
|
|
||||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid0, true);
|
|
||||||
CHECK(poolOwner.hkHelper.handleHousekeepingMessage(&hkCmd) == returnvalue::OK);
|
|
||||||
REQUIRE(poolOwnerMock.wasMessageSent());
|
|
||||||
REQUIRE(poolOwnerMock.numberOfSentMessages() == 1);
|
|
||||||
poolOwnerMock.clearMessages();
|
|
||||||
|
|
||||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid0, false);
|
|
||||||
CHECK(poolOwner.hkHelper.handleHousekeepingMessage(&hkCmd) == returnvalue::OK);
|
|
||||||
REQUIRE(poolOwnerMock.wasMessageSent());
|
|
||||||
REQUIRE(poolOwnerMock.numberOfSentMessages() == 1);
|
|
||||||
poolOwnerMock.clearMessages();
|
|
||||||
|
|
||||||
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid0);
|
|
||||||
CHECK(poolOwner.hkHelper.handleHousekeepingMessage(&hkCmd) == returnvalue::OK);
|
|
||||||
REQUIRE(poolOwnerMock.wasMessageSent());
|
|
||||||
REQUIRE(poolOwnerMock.numberOfSentMessages() == 1);
|
|
||||||
poolOwnerMock.clearMessages();
|
|
||||||
|
|
||||||
// poolOwner.hkHelper.printPoolEntry(lpool::uint8VarId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// we need to reset the subscription list because the pool owner
|
|
||||||
// is a global object.
|
|
||||||
CHECK(poolOwner.reset() == returnvalue::OK);
|
|
||||||
poolOwnerMock.clearMessages(true);
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user