unittests for TC and CCSDS distributor

This commit is contained in:
2022-08-01 17:16:37 +02:00
parent bf540ebb49
commit 902a4bfa9c
29 changed files with 277 additions and 66 deletions

View File

@ -13,6 +13,7 @@ target_sources(${FSFW_TEST_TGT} PRIVATE
add_subdirectory(testcfg)
add_subdirectory(mocks)
add_subdirectory(tcdistributor)
add_subdirectory(action)
add_subdirectory(power)
add_subdirectory(util)

View File

@ -1,9 +1,10 @@
#include "fsfw/FSFW.h"
#include "CatchDefinitions.h"
#include <fsfw/objectmanager/ObjectManager.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include "fsfw/FSFW.h"
StorageManagerIF* tglob::getIpcStoreHandle() {
if (ObjectManager::instance() != nullptr) {
return ObjectManager::instance()->get<StorageManagerIF>(objects::IPC_STORE);

View File

@ -1,11 +1,12 @@
#ifndef FSFW_UNITTEST_CORE_CATCHDEFINITIONS_H_
#define FSFW_UNITTEST_CORE_CATCHDEFINITIONS_H_
#include "fsfw/FSFW.h"
#include <fsfw/ipc/messageQueueDefinitions.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <fsfw/storagemanager/StorageManagerIF.h>
#include "fsfw/FSFW.h"
namespace tconst {
static constexpr MessageQueueId_t testQueueId = 42;
}

View File

@ -1,6 +1,6 @@
#include "fsfw/FSFW.h"
#include "CatchDefinitions.h"
#include "CatchFactory.h"
#include "fsfw/FSFW.h"
#ifdef GCOV
#include <gcov.h>

View File

@ -0,0 +1,8 @@
#include "AcceptsTcMock.h"
AcceptsTcMock::AcceptsTcMock(const char* name, uint32_t id, MessageQueueId_t queueId)
: name(name), id(id), queueId(queueId) {}
const char* AcceptsTcMock::getName() const { return name; }
uint32_t AcceptsTcMock::getIdentifier() const { return id; }
MessageQueueId_t AcceptsTcMock::getRequestQueue() const { return queueId; }

View File

@ -0,0 +1,20 @@
#ifndef FSFW_TESTS_ACCEPTSTCMOCK_H
#define FSFW_TESTS_ACCEPTSTCMOCK_H
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
class AcceptsTcMock : public AcceptsTelecommandsIF {
public:
AcceptsTcMock(const char* name, uint32_t id, MessageQueueId_t queueId);
[[nodiscard]] const char* getName() const override;
[[nodiscard]] uint32_t getIdentifier() const override;
[[nodiscard]] MessageQueueId_t getRequestQueue() const override;
const char* name;
uint32_t id;
MessageQueueId_t queueId;
private:
};
#endif // FSFW_TESTS_ACCEPTSTCMOCK_H

View File

@ -11,4 +11,6 @@ target_sources(${FSFW_TEST_TGT} PRIVATE
PusServiceBaseMock.cpp
AcceptsTmMock.cpp
PusDistributorMock.cpp
CcsdsCheckerMock.cpp
AcceptsTcMock.cpp
)

View File

@ -0,0 +1,10 @@
#include "CcsdsCheckerMock.h"
CcsdsCheckerMock::CcsdsCheckerMock() = default;
ReturnValue_t CcsdsCheckerMock::checkPacket(const SpacePacketReader& currentPacket,
size_t packetLen) {
checkCallCount++;
checkedPacketLen = packetLen;
return nextResult;
}

View File

@ -0,0 +1,16 @@
#ifndef FSFW_TESTS_CCSDSCHECKERMOCK_H
#define FSFW_TESTS_CCSDSCHECKERMOCK_H
#include "fsfw/tcdistribution/CcsdsPacketCheckIF.h"
class CcsdsCheckerMock : public CcsdsPacketCheckIF {
public:
CcsdsCheckerMock();
unsigned int checkCallCount = 0;
size_t checkedPacketLen = 0;
ReturnValue_t nextResult = HasReturnvaluesIF::RETURN_OK;
ReturnValue_t checkPacket(const SpacePacketReader& currentPacket, size_t packetLen) override;
private:
};
#endif // FSFW_TESTS_CCSDSCHECKERMOCK_H

View File

@ -1,11 +1,11 @@
#ifndef FSFW_TESTS_PUSDISTRIBUTORMOCK_H
#define FSFW_TESTS_PUSDISTRIBUTORMOCK_H
#include <vector>
#include "fsfw/objectmanager/SystemObject.h"
#include "fsfw/tcdistribution/PusDistributorIF.h"
#include <vector>
class PusDistributorMock : public SystemObject, public PusDistributorIF {
public:
PusDistributorMock();

View File

@ -0,0 +1,3 @@
target_sources(${FSFW_TEST_TGT} PRIVATE
testCcsdsDistributor.cpp
)

View File

@ -0,0 +1,113 @@
#include <array>
#include <catch2/catch_test_macros.hpp>
#include "fsfw/storagemanager/LocalPool.h"
#include "fsfw/tcdistribution/CcsdsDistributor.h"
#include "fsfw/tmtcpacket/ccsds/SpacePacketCreator.h"
#include "mocks/AcceptsTcMock.h"
#include "mocks/CcsdsCheckerMock.h"
#include "mocks/MessageQueueMock.h"
TEST_CASE("CCSDS Distributor", "[ccsds-distrib]") {
LocalPool::LocalPoolConfig cfg = {{5, 32}, {2, 64}};
LocalPool pool(objects::NO_OBJECT, cfg);
auto queue = MessageQueueMock(1);
auto checkerMock = CcsdsCheckerMock();
uint16_t unregisteredApid = 0;
uint16_t defaultApid = 4;
MessageQueueId_t defaultQueueId = 5;
auto ccsdsDistrib = CcsdsDistributor(defaultApid, 1, &pool, &queue, &checkerMock);
uint32_t tcAcceptorApid = 1;
MessageQueueId_t tcAcceptorQueueId = 3;
auto tcAcceptorMock = AcceptsTcMock("TC Receiver Dummy", tcAcceptorApid, tcAcceptorQueueId);
auto defReceiverMock = AcceptsTcMock("Default Receiver Dummy", defaultApid, defaultQueueId);
auto packetId = PacketId(ccsds::PacketType::TC, true, 0);
auto psc = PacketSeqCtrl(ccsds::SequenceFlags::FIRST_SEGMENT, 0x34);
auto spParams = SpacePacketParams(packetId, psc, 0x16);
SpacePacketCreator spCreator(spParams);
std::array<uint8_t, 32> buf{};
auto createSpacePacket = [&](uint16_t apid, TmTcMessage& msg) {
store_address_t storeId{};
spCreator.setApid(tcAcceptorApid);
uint8_t* dataPtr;
REQUIRE(pool.getFreeElement(&storeId, spCreator.getSerializedSize(), &dataPtr) == result::OK);
size_t serLen = 0;
REQUIRE(spCreator.SerializeIF::serializeBe(dataPtr, serLen, ccsds::HEADER_LEN) == result::OK);
REQUIRE(spCreator.SerializeIF::serializeBe(buf.data(), serLen, ccsds::HEADER_LEN) ==
result::OK);
msg.setStorageId(storeId);
};
SECTION("State") {
CHECK(ccsdsDistrib.initialize() == result::OK);
CHECK(ccsdsDistrib.getRequestQueue() == 1);
CHECK(ccsdsDistrib.getIdentifier() == 0);
CHECK(ccsdsDistrib.getObjectId() == 1);
REQUIRE(ccsdsDistrib.getName() != nullptr);
CHECK(std::strcmp(ccsdsDistrib.getName(), "CCSDS Distributor") == 0);
}
SECTION("Basic Forwarding") {
CcsdsDistributor::DestInfo info(tcAcceptorMock, false);
REQUIRE(ccsdsDistrib.registerApplication(info) == result::OK);
TmTcMessage message;
createSpacePacket(tcAcceptorApid, message);
store_address_t storeId = message.getStorageId();
queue.addReceivedMessage(message);
REQUIRE(ccsdsDistrib.performOperation(0) == result::OK);
CHECK(checkerMock.checkedPacketLen == 6);
CHECK(checkerMock.checkCallCount == 1);
CHECK(queue.wasMessageSent());
CHECK(queue.numberOfSentMessages() == 1);
// The packet is forwarded, with no need to delete the data
CHECK(pool.hasDataAtId(storeId));
TmTcMessage sentMsg;
CHECK(queue.getNextSentMessage(tcAcceptorQueueId, sentMsg) == result::OK);
CHECK(sentMsg.getStorageId() == storeId);
auto accessor = pool.getData(storeId);
CHECK(accessor.first == result::OK);
CHECK(accessor.second.size() == ccsds::HEADER_LEN);
for (size_t i = 0; i < ccsds::HEADER_LEN; i++) {
CHECK(accessor.second.data()[i] == buf[i]);
}
}
SECTION("Forwarding to Default Destination, but not registered") {
TmTcMessage message;
createSpacePacket(unregisteredApid, message);
store_address_t storeId = message.getStorageId();
message.setStorageId(storeId);
queue.addReceivedMessage(message);
REQUIRE(ccsdsDistrib.performOperation(0) == TcDistributorBase::DESTINATION_NOT_FOUND);
}
SECTION("Forward to Default Handler") {
CcsdsDistributor::DestInfo info(defReceiverMock, false);
ccsdsDistrib.registerApplication(info);
TmTcMessage message;
createSpacePacket(defaultApid, message);
store_address_t storeId = message.getStorageId();
message.setStorageId(storeId);
queue.addReceivedMessage(message);
REQUIRE(ccsdsDistrib.performOperation(0) == result::OK);
CHECK(checkerMock.checkedPacketLen == 6);
CHECK(checkerMock.checkCallCount == 1);
CHECK(queue.wasMessageSent());
CHECK(queue.numberOfSentMessages() == 1);
// The packet is forwarded, with no need to delete the data
CHECK(pool.hasDataAtId(storeId));
TmTcMessage sentMsg;
CHECK(queue.getNextSentMessage(defaultQueueId, sentMsg) == result::OK);
CHECK(sentMsg.getStorageId() == storeId);
auto accessor = pool.getData(storeId);
CHECK(accessor.first == result::OK);
CHECK(accessor.second.size() == ccsds::HEADER_LEN);
for (size_t i = 0; i < ccsds::HEADER_LEN; i++) {
CHECK(accessor.second.data()[i] == buf[i]);
}
}
SECTION("Remove CCSDS header") {}
}

View File

@ -1,10 +1,10 @@
#include "fsfw/FSFW.h"
#include "PollingSequenceFactory.h"
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
#include "fsfw/FSFW.h"
#include "tests/TestsConfig.h"
ReturnValue_t pst::pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence) {

View File

@ -64,7 +64,7 @@ TEST_CASE("CCSDS Reader", "[ccsds-reader]") {
SECTION("Invalid Size") {
for (size_t i = 0; i < 5; i++) {
REQUIRE(reader.setReadOnlyData(buf.data(), i) == SerializeIF::STREAM_TOO_SHORT);
REQUIRE(not reader.isNull());
REQUIRE(reader.isNull());
REQUIRE(reader.getPacketData() == nullptr);
}
}