#include #include #include #include #include #include #include #include #include #include #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); }