Merge remote-tracking branch 'upstream/development' into mueller/refactor-power-switch-if-etc
This commit is contained in:
@ -21,8 +21,10 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
||||
REQUIRE(poolOwner->initializeHkManager() == retval::CATCH_OK);
|
||||
REQUIRE(poolOwner->initializeHkManagerAfterTaskCreation() == retval::CATCH_OK);
|
||||
|
||||
MessageQueueMockBase* mqMock = poolOwner->getMockQueueHandle();
|
||||
REQUIRE(mqMock != nullptr);
|
||||
MessageQueueMockBase* poolOwnerMock = poolOwner->getMockQueueHandle();
|
||||
REQUIRE(poolOwnerMock != nullptr);
|
||||
|
||||
// MessageQueueIF* hkCommander = QueueFactory::instance()->createMessageQueue();
|
||||
CommandMessage messageSent;
|
||||
uint8_t messagesSent = 0;
|
||||
|
||||
@ -41,9 +43,9 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
||||
poolOwner->dataset.setChanged(true);
|
||||
/* Now the update message should be generated. */
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent() == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent() == true);
|
||||
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() ==
|
||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||
|
||||
@ -53,9 +55,9 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
||||
poolOwner->dataset.setChanged(true);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() ==
|
||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||
|
||||
@ -63,15 +65,15 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
||||
REQUIRE(poolOwner->subscribeWrapperSetUpdateHk() == retval::CATCH_OK);
|
||||
poolOwner->dataset.setChanged(true);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
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(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() ==
|
||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
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);
|
||||
@ -99,9 +101,9 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
||||
|
||||
/* Trigger generation of snapshot */
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
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 */
|
||||
@ -162,12 +164,12 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
|
||||
/* Check update snapshot was sent. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
|
||||
/* Should have been reset. */
|
||||
CHECK(poolVar->hasChanged() == false);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
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 */
|
||||
@ -209,11 +211,11 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
|
||||
/* Check update notification was sent. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
/* Should have been reset. */
|
||||
CHECK(poolVar->hasChanged() == false);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
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 */
|
||||
@ -225,26 +227,26 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
||||
poolOwner->dataset.setChanged(true);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
/* Now two messages should be sent. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 2);
|
||||
mqMock->clearMessages(true);
|
||||
poolOwnerMock->clearMessages(true);
|
||||
|
||||
poolOwner->dataset.setChanged(true);
|
||||
poolVar->setChanged(true);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
/* Now three messages should be sent. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 3);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() ==
|
||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_VARIABLE));
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() ==
|
||||
static_cast<int>(HousekeepingMessage::UPDATE_NOTIFICATION_SET));
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == retval::CATCH_OK);
|
||||
CHECK(messageSent.getCommand() == static_cast<int>(HousekeepingMessage::HK_REPORT));
|
||||
CommandMessageCleaner::clearCommandMessage(&messageSent);
|
||||
REQUIRE(mqMock->receiveMessage(&messageSent) == static_cast<int>(MessageQueueIF::EMPTY));
|
||||
REQUIRE(poolOwnerMock->receiveMessage(&messageSent) == static_cast<int>(MessageQueueIF::EMPTY));
|
||||
}
|
||||
|
||||
SECTION("PeriodicHKAndMessaging") {
|
||||
@ -255,38 +257,38 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
||||
REQUIRE(poolOwner->subscribePeriodicHk(true) == retval::CATCH_OK);
|
||||
REQUIRE(poolOwner->poolManager.performHkOperation() == retval::CATCH_OK);
|
||||
/* Now HK packet should be sent as message immediately. */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
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(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
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(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
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(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
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(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4,
|
||||
false);
|
||||
@ -294,23 +296,23 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
||||
/* For non-diagnostics and a specified minimum frequency of 0.2 seconds, the
|
||||
resulting collection interval should be 1.0 second */
|
||||
CHECK(poolOwner->dataset.getCollectionInterval() == 1.0);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
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(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, false);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setUpdateNotificationSetCommand(&hkCmd, lpool::testSid);
|
||||
sid_t sidToCheck;
|
||||
@ -326,62 +328,62 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) ==
|
||||
static_cast<int>(LocalDataPoolManager::WRONG_HK_PACKET_TYPE));
|
||||
/* We still expect a failure message being sent */
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
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(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
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(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setStructureReportingCommand(&hkCmd, lpool::testSid, true);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setCollectionIntervalModificationCommand(&hkCmd, lpool::testSid, 0.4,
|
||||
true);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, true, true);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setToggleReportingCommand(&hkCmd, lpool::testSid, false, true);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
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(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setOneShotReportCommand(&hkCmd, lpool::testSid, true);
|
||||
CHECK(poolOwner->poolManager.handleHousekeepingMessage(&hkCmd) == retval::CATCH_OK);
|
||||
REQUIRE(mqMock->wasMessageSent(&messagesSent) == true);
|
||||
REQUIRE(poolOwnerMock->wasMessageSent(&messagesSent) == true);
|
||||
CHECK(messagesSent == 1);
|
||||
CHECK(mqMock->popMessage() == retval::CATCH_OK);
|
||||
CHECK(poolOwnerMock->popMessage() == retval::CATCH_OK);
|
||||
|
||||
HousekeepingMessage::setUpdateNotificationVariableCommand(&hkCmd, lpool::uint8VarGpid);
|
||||
gp_id_t gpidToCheck;
|
||||
@ -407,5 +409,5 @@ TEST_CASE("LocalPoolManagerTest", "[LocManTest]") {
|
||||
/* we need to reset the subscription list because the pool owner
|
||||
is a global object. */
|
||||
CHECK(poolOwner->reset() == retval::CATCH_OK);
|
||||
mqMock->clearMessages(true);
|
||||
poolOwnerMock->clearMessages(true);
|
||||
}
|
||||
|
@ -3,4 +3,5 @@ target_sources(${FSFW_TEST_TGT} PRIVATE
|
||||
testOpDivider.cpp
|
||||
testBitutil.cpp
|
||||
testCRC.cpp
|
||||
testTimevalOperations.cpp
|
||||
)
|
||||
|
@ -0,0 +1,124 @@
|
||||
#include <fsfw/globalfunctions/timevalOperations.h>
|
||||
|
||||
#include <catch2/catch_approx.hpp>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
TEST_CASE("TimevalTest", "[timevalOperations]") {
|
||||
SECTION("Comparison") {
|
||||
timeval t1;
|
||||
t1.tv_sec = 1648227422;
|
||||
t1.tv_usec = 123456;
|
||||
timeval t2;
|
||||
t2.tv_sec = 1648227422;
|
||||
t2.tv_usec = 123456;
|
||||
REQUIRE(t1 == t2);
|
||||
REQUIRE(t2 == t1);
|
||||
REQUIRE_FALSE(t1 != t2);
|
||||
REQUIRE_FALSE(t2 != t1);
|
||||
REQUIRE(t1 <= t2);
|
||||
REQUIRE(t2 <= t1);
|
||||
REQUIRE(t1 >= t2);
|
||||
REQUIRE(t2 >= t1);
|
||||
REQUIRE_FALSE(t1 < t2);
|
||||
REQUIRE_FALSE(t2 < t1);
|
||||
REQUIRE_FALSE(t1 > t2);
|
||||
REQUIRE_FALSE(t2 > t1);
|
||||
|
||||
timeval t3;
|
||||
t3.tv_sec = 1648227422;
|
||||
t3.tv_usec = 123457;
|
||||
REQUIRE_FALSE(t1 == t3);
|
||||
REQUIRE(t1 != t3);
|
||||
REQUIRE(t1 <= t3);
|
||||
REQUIRE_FALSE(t3 <= t1);
|
||||
REQUIRE_FALSE(t1 >= t3);
|
||||
REQUIRE(t3 >= t1);
|
||||
REQUIRE(t1 < t3);
|
||||
REQUIRE_FALSE(t3 < t1);
|
||||
REQUIRE_FALSE(t1 > t3);
|
||||
REQUIRE(t3 > t1);
|
||||
|
||||
timeval t4;
|
||||
t4.tv_sec = 1648227423;
|
||||
t4.tv_usec = 123456;
|
||||
REQUIRE_FALSE(t1 == t4);
|
||||
REQUIRE(t1 != t4);
|
||||
REQUIRE(t1 <= t4);
|
||||
REQUIRE_FALSE(t4 <= t1);
|
||||
REQUIRE_FALSE(t1 >= t4);
|
||||
REQUIRE(t4 >= t1);
|
||||
REQUIRE(t1 < t4);
|
||||
REQUIRE_FALSE(t4 < t1);
|
||||
REQUIRE_FALSE(t1 > t4);
|
||||
REQUIRE(t4 > t1);
|
||||
}
|
||||
SECTION("Operators") {
|
||||
timeval t1;
|
||||
t1.tv_sec = 1648227422;
|
||||
t1.tv_usec = 123456;
|
||||
timeval t2;
|
||||
t2.tv_sec = 1648227422;
|
||||
t2.tv_usec = 123456;
|
||||
timeval t3 = t1 - t2;
|
||||
REQUIRE(t3.tv_sec == 0);
|
||||
REQUIRE(t3.tv_usec == 0);
|
||||
timeval t4 = t1 - t3;
|
||||
REQUIRE(t4.tv_sec == 1648227422);
|
||||
REQUIRE(t4.tv_usec == 123456);
|
||||
timeval t5 = t3 - t1;
|
||||
REQUIRE(t5.tv_sec == -1648227422);
|
||||
REQUIRE(t5.tv_usec == -123456);
|
||||
|
||||
timeval t6;
|
||||
t6.tv_sec = 1648227400;
|
||||
t6.tv_usec = 999999;
|
||||
|
||||
timeval t7 = t6 + t1;
|
||||
REQUIRE(t7.tv_sec == (1648227422ull + 1648227400ull + 1ull));
|
||||
REQUIRE(t7.tv_usec == 123455);
|
||||
|
||||
timeval t8 = t1 - t6;
|
||||
REQUIRE(t8.tv_sec == 1648227422 - 1648227400 - 1);
|
||||
REQUIRE(t8.tv_usec == 123457);
|
||||
|
||||
double scalar = 2;
|
||||
timeval t9 = t1 * scalar;
|
||||
REQUIRE(t9.tv_sec == 3296454844);
|
||||
REQUIRE(t9.tv_usec == 246912);
|
||||
timeval t10 = scalar * t1;
|
||||
REQUIRE(t10.tv_sec == 3296454844);
|
||||
REQUIRE(t10.tv_usec == 246912);
|
||||
timeval t11 = t6 * scalar;
|
||||
REQUIRE(t11.tv_sec == (3296454800 + 1));
|
||||
REQUIRE(t11.tv_usec == 999998);
|
||||
|
||||
timeval t12 = t1 / scalar;
|
||||
REQUIRE(t12.tv_sec == 824113711);
|
||||
REQUIRE(t12.tv_usec == 61728);
|
||||
|
||||
timeval t13 = t6 / scalar;
|
||||
REQUIRE(t13.tv_sec == 824113700);
|
||||
// Rounding issue
|
||||
REQUIRE(t13.tv_usec == 499999);
|
||||
|
||||
double scalar2 = t9 / t1;
|
||||
REQUIRE(scalar2 == Catch::Approx(2.0));
|
||||
double scalar3 = t1 / t6;
|
||||
REQUIRE(scalar3 == Catch::Approx(1.000000013));
|
||||
double scalar4 = t3 / t1;
|
||||
REQUIRE(scalar4 == Catch::Approx(0));
|
||||
double scalar5 = t12 / t1;
|
||||
REQUIRE(scalar5 == Catch::Approx(0.5));
|
||||
}
|
||||
|
||||
SECTION("timevalOperations::toTimeval") {
|
||||
double seconds = 1648227422.123456;
|
||||
timeval t1 = timevalOperations::toTimeval(seconds);
|
||||
REQUIRE(t1.tv_sec == 1648227422);
|
||||
// Allow 1 usec rounding tolerance
|
||||
REQUIRE(t1.tv_usec >= 123455);
|
||||
REQUIRE(t1.tv_usec <= 123457);
|
||||
}
|
||||
}
|
@ -4,16 +4,18 @@
|
||||
#include <cstring>
|
||||
#include <queue>
|
||||
|
||||
#include "fsfw/ipc/MessageQueueBase.h"
|
||||
#include "fsfw/ipc/CommandMessage.h"
|
||||
#include "fsfw/ipc/MessageQueueIF.h"
|
||||
#include "fsfw/ipc/MessageQueueMessage.h"
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
class MessageQueueMockBase : public MessageQueueIF {
|
||||
class MessageQueueMockBase : public MessageQueueBase {
|
||||
public:
|
||||
MessageQueueId_t myQueueId = tconst::testQueueId;
|
||||
MessageQueueMockBase()
|
||||
: MessageQueueBase(MessageQueueIF::NO_QUEUE, MessageQueueIF::NO_QUEUE, nullptr) {}
|
||||
|
||||
uint8_t messageSentCounter = 0;
|
||||
bool defaultDestSet = false;
|
||||
bool messageSent = false;
|
||||
|
||||
bool wasMessageSent(uint8_t* messageSentCounter = nullptr, bool resetCounter = true) {
|
||||
@ -38,53 +40,30 @@ class MessageQueueMockBase : public MessageQueueIF {
|
||||
return receiveMessage(&message);
|
||||
}
|
||||
|
||||
virtual ReturnValue_t reply(MessageQueueMessageIF* message) {
|
||||
return sendMessage(myQueueId, message);
|
||||
};
|
||||
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message,
|
||||
MessageQueueId_t* receivedFrom) {
|
||||
return receiveMessage(message);
|
||||
}
|
||||
|
||||
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message) {
|
||||
virtual ReturnValue_t receiveMessage(MessageQueueMessageIF* message) override {
|
||||
if (messagesSentQueue.empty()) {
|
||||
return MessageQueueIF::EMPTY;
|
||||
}
|
||||
|
||||
this->last = message->getSender();
|
||||
std::memcpy(message->getBuffer(), messagesSentQueue.front().getBuffer(),
|
||||
message->getMessageSize());
|
||||
messagesSentQueue.pop();
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
virtual ReturnValue_t flush(uint32_t* count) { return HasReturnvaluesIF::RETURN_OK; }
|
||||
virtual MessageQueueId_t getLastPartner() const { return myQueueId; }
|
||||
virtual MessageQueueId_t getId() const { return myQueueId; }
|
||||
virtual ReturnValue_t sendMessageFrom(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
MessageQueueId_t sentFrom, bool ignoreFault = false) {
|
||||
return sendMessage(sendTo, message);
|
||||
}
|
||||
virtual ReturnValue_t sendToDefaultFrom(MessageQueueMessageIF* message, MessageQueueId_t sentFrom,
|
||||
bool ignoreFault = false) {
|
||||
return sendMessage(myQueueId, message);
|
||||
}
|
||||
virtual ReturnValue_t sendToDefault(MessageQueueMessageIF* message) {
|
||||
return sendMessage(myQueueId, message);
|
||||
}
|
||||
virtual ReturnValue_t sendMessage(MessageQueueId_t sendTo, MessageQueueMessageIF* message,
|
||||
bool ignoreFault = false) override {
|
||||
MessageQueueId_t sentFrom,
|
||||
bool ignoreFault = false) override {
|
||||
messageSent = true;
|
||||
messageSentCounter++;
|
||||
MessageQueueMessage& messageRef = *(dynamic_cast<MessageQueueMessage*>(message));
|
||||
messagesSentQueue.push(messageRef);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
virtual void setDefaultDestination(MessageQueueId_t defaultDestination) {
|
||||
myQueueId = defaultDestination;
|
||||
defaultDestSet = true;
|
||||
}
|
||||
|
||||
virtual MessageQueueId_t getDefaultDestination() const { return myQueueId; }
|
||||
virtual bool isDefaultDestinationSet() const { return defaultDestSet; }
|
||||
virtual ReturnValue_t reply(MessageQueueMessageIF* message) override {
|
||||
return sendMessageFrom(MessageQueueIF::NO_QUEUE, message, this->getId(), false);
|
||||
}
|
||||
|
||||
void clearMessages(bool clearCommandMessages = true) {
|
||||
while (not messagesSentQueue.empty()) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
target_sources(${FSFW_TEST_TGT} PRIVATE
|
||||
TestMessageQueue.cpp
|
||||
TestSemaphore.cpp
|
||||
TestClock.cpp
|
||||
)
|
||||
|
86
tests/src/fsfw_tests/unit/osal/TestClock.cpp
Normal file
86
tests/src/fsfw_tests/unit/osal/TestClock.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
#include <fsfw/globalfunctions/timevalOperations.h>
|
||||
#include <fsfw/timemanager/Clock.h>
|
||||
|
||||
#include <array>
|
||||
#include <catch2/catch_approx.hpp>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw_tests/unit/CatchDefinitions.h"
|
||||
|
||||
TEST_CASE("OSAL::Clock Test", "[OSAL::Clock Test]") {
|
||||
SECTION("Test getClock") {
|
||||
timeval time;
|
||||
ReturnValue_t result = Clock::getClock_timeval(&time);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
Clock::TimeOfDay_t timeOfDay;
|
||||
result = Clock::getDateAndTime(&timeOfDay);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
timeval timeOfDayAsTimeval;
|
||||
result = Clock::convertTimeOfDayToTimeval(&timeOfDay, &timeOfDayAsTimeval);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
// We require timeOfDayAsTimeval to be larger than time as it
|
||||
// was request a few ns later
|
||||
double difference = timevalOperations::toDouble(timeOfDayAsTimeval - time);
|
||||
CHECK(difference >= 0.0);
|
||||
CHECK(difference <= 0.005);
|
||||
|
||||
// Conversion in the other direction
|
||||
Clock::TimeOfDay_t timevalAsTimeOfDay;
|
||||
result = Clock::convertTimevalToTimeOfDay(&time, &timevalAsTimeOfDay);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
CHECK(timevalAsTimeOfDay.year <= timeOfDay.year);
|
||||
// TODO We should write TimeOfDay operators!
|
||||
}
|
||||
SECTION("Leap seconds") {
|
||||
uint16_t leapSeconds = 0;
|
||||
ReturnValue_t result = Clock::getLeapSeconds(&leapSeconds);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED);
|
||||
REQUIRE(leapSeconds == 0);
|
||||
result = Clock::setLeapSeconds(18);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
result = Clock::getLeapSeconds(&leapSeconds);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(leapSeconds == 18);
|
||||
}
|
||||
SECTION("usec Test") {
|
||||
timeval timeAsTimeval;
|
||||
ReturnValue_t result = Clock::getClock_timeval(&timeAsTimeval);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
uint64_t timeAsUsec = 0;
|
||||
result = Clock::getClock_usecs(&timeAsUsec);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
double timeAsUsecDouble = static_cast<double>(timeAsUsec) / 1000000.0;
|
||||
timeval timeAsUsecTimeval = timevalOperations::toTimeval(timeAsUsecDouble);
|
||||
double difference = timevalOperations::toDouble(timeAsUsecTimeval - timeAsTimeval);
|
||||
// We accept 5 ms difference
|
||||
CHECK(difference >= 0.0);
|
||||
CHECK(difference <= 0.005);
|
||||
uint64_t timevalAsUint64 = static_cast<uint64_t>(timeAsTimeval.tv_sec) * 1000000ull +
|
||||
static_cast<uint64_t>(timeAsTimeval.tv_usec);
|
||||
CHECK((timeAsUsec - timevalAsUint64) >= 0);
|
||||
CHECK((timeAsUsec - timevalAsUint64) <= (5 * 1000));
|
||||
}
|
||||
SECTION("Test j2000") {
|
||||
double j2000;
|
||||
timeval time;
|
||||
time.tv_sec = 1648208539;
|
||||
time.tv_usec = 0;
|
||||
ReturnValue_t result = Clock::convertTimevalToJD2000(time, &j2000);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
double correctJ2000 = 2459663.98772 - 2451545.0;
|
||||
CHECK(j2000 == Catch::Approx(correctJ2000).margin(1.2 * 1e-8));
|
||||
}
|
||||
SECTION("Convert to TT") {
|
||||
timeval utcTime;
|
||||
utcTime.tv_sec = 1648208539;
|
||||
utcTime.tv_usec = 999000;
|
||||
timeval tt;
|
||||
ReturnValue_t result = Clock::setLeapSeconds(27);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
result = Clock::convertUTCToTT(utcTime, &tt);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
CHECK(tt.tv_usec == 183000);
|
||||
// The plus 1 is a own forced overflow of usecs
|
||||
CHECK(tt.tv_sec == (1648208539 + 27 + 10 + 32 + 1));
|
||||
}
|
||||
}
|
@ -81,7 +81,8 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") {
|
||||
std::string timeAscii = "2022-12-31T23:59:59.123Z";
|
||||
Clock::TimeOfDay_t timeTo;
|
||||
const uint8_t* timeChar = reinterpret_cast<const uint8_t*>(timeAscii.c_str());
|
||||
CCSDSTime::convertFromASCII(&timeTo, timeChar, timeAscii.length());
|
||||
auto result = CCSDSTime::convertFromASCII(&timeTo, timeChar, timeAscii.length());
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(timeTo.year == 2022);
|
||||
REQUIRE(timeTo.month == 12);
|
||||
REQUIRE(timeTo.day == 31);
|
||||
@ -89,6 +90,19 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") {
|
||||
REQUIRE(timeTo.minute == 59);
|
||||
REQUIRE(timeTo.second == 59);
|
||||
REQUIRE(timeTo.usecond == Catch::Approx(123000));
|
||||
|
||||
std::string timeAscii2 = "2022-365T23:59:59.123Z";
|
||||
const uint8_t* timeChar2 = reinterpret_cast<const uint8_t*>(timeAscii2.c_str());
|
||||
Clock::TimeOfDay_t timeTo2;
|
||||
result = CCSDSTime::convertFromCcsds(&timeTo2, timeChar2, timeAscii2.length());
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(timeTo2.year == 2022);
|
||||
REQUIRE(timeTo2.month == 12);
|
||||
REQUIRE(timeTo2.day == 31);
|
||||
REQUIRE(timeTo2.hour == 23);
|
||||
REQUIRE(timeTo2.minute == 59);
|
||||
REQUIRE(timeTo2.second == 59);
|
||||
REQUIRE(timeTo2.usecond == Catch::Approx(123000));
|
||||
}
|
||||
|
||||
SECTION("CDS Conversions") {
|
||||
@ -119,6 +133,7 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") {
|
||||
CHECK(cdsTime.msDay_h == 0xE0);
|
||||
CHECK(cdsTime.msDay_l == 0xC5);
|
||||
CHECK(cdsTime.msDay_ll == 0xC3);
|
||||
CHECK(cdsTime.pField == CCSDSTime::P_FIELD_CDS_SHORT);
|
||||
|
||||
// Conversion back to timeval
|
||||
timeval timeReturnAsTimeval;
|
||||
@ -128,5 +143,56 @@ TEST_CASE("CCSDSTime Tests", "[TestCCSDSTime]") {
|
||||
timeval difference = timeAsTimeval - timeReturnAsTimeval;
|
||||
CHECK(difference.tv_usec == 456);
|
||||
CHECK(difference.tv_sec == 0);
|
||||
|
||||
Clock::TimeOfDay_t timeReturnAsTimeOfDay;
|
||||
result = CCSDSTime::convertFromCDS(&timeReturnAsTimeOfDay, &cdsTime);
|
||||
CHECK(result == HasReturnvaluesIF::RETURN_OK);
|
||||
CHECK(timeReturnAsTimeOfDay.year == 2020);
|
||||
CHECK(timeReturnAsTimeOfDay.month == 2);
|
||||
CHECK(timeReturnAsTimeOfDay.day == 29);
|
||||
CHECK(timeReturnAsTimeOfDay.hour == 13);
|
||||
CHECK(timeReturnAsTimeOfDay.minute == 24);
|
||||
CHECK(timeReturnAsTimeOfDay.second == 45);
|
||||
// micro seconds precision is lost
|
||||
CHECK(timeReturnAsTimeOfDay.usecond == 123000);
|
||||
|
||||
Clock::TimeOfDay_t timeReturnAsTodFromBuffer;
|
||||
const uint8_t* buffer = reinterpret_cast<const uint8_t*>(&cdsTime);
|
||||
result = CCSDSTime::convertFromCDS(&timeReturnAsTodFromBuffer, buffer, sizeof(cdsTime));
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
CHECK(timeReturnAsTodFromBuffer.year == time.year);
|
||||
CHECK(timeReturnAsTodFromBuffer.month == time.month);
|
||||
CHECK(timeReturnAsTodFromBuffer.day == time.day);
|
||||
CHECK(timeReturnAsTodFromBuffer.hour == time.hour);
|
||||
CHECK(timeReturnAsTodFromBuffer.minute == time.minute);
|
||||
CHECK(timeReturnAsTodFromBuffer.second == time.second);
|
||||
CHECK(timeReturnAsTodFromBuffer.usecond == 123000);
|
||||
|
||||
Clock::TimeOfDay_t todFromCCSDS;
|
||||
result = CCSDSTime::convertFromCcsds(&todFromCCSDS, buffer, sizeof(cdsTime));
|
||||
CHECK(result == HasReturnvaluesIF::RETURN_OK);
|
||||
CHECK(todFromCCSDS.year == time.year);
|
||||
CHECK(todFromCCSDS.month == time.month);
|
||||
CHECK(todFromCCSDS.day == time.day);
|
||||
CHECK(todFromCCSDS.hour == time.hour);
|
||||
CHECK(todFromCCSDS.minute == time.minute);
|
||||
CHECK(todFromCCSDS.second == time.second);
|
||||
CHECK(todFromCCSDS.usecond == 123000);
|
||||
}
|
||||
SECTION("CCSDS Failures") {
|
||||
Clock::TimeOfDay_t time;
|
||||
time.year = 2020;
|
||||
time.month = 12;
|
||||
time.day = 32;
|
||||
time.hour = 13;
|
||||
time.minute = 24;
|
||||
time.second = 45;
|
||||
time.usecond = 123456;
|
||||
CCSDSTime::Ccs_mseconds to;
|
||||
auto result = CCSDSTime::convertToCcsds(&to, &time);
|
||||
REQUIRE(result == CCSDSTime::INVALID_TIME_FORMAT);
|
||||
CCSDSTime::Ccs_seconds to2;
|
||||
result = CCSDSTime::convertToCcsds(&to2, &time);
|
||||
REQUIRE(result == CCSDSTime::INVALID_TIME_FORMAT);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user