From 244e2d0737902519670f505e9bd42fc110fd1548 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 25 Jul 2023 13:58:22 +0200 Subject: [PATCH] start adding message parser unittests --- src/fsfw/cfdp/VarLenFields.h | 13 +++++ src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp | 4 +- unittests/cfdp/CMakeLists.txt | 5 +- .../cfdp/handler/testReservedMsgParser.cpp | 27 +++++++++- unittests/cfdp/testReservedMsgCreator.cpp | 49 +++++++++++++++++++ 5 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 unittests/cfdp/testReservedMsgCreator.cpp diff --git a/src/fsfw/cfdp/VarLenFields.h b/src/fsfw/cfdp/VarLenFields.h index cdfcc775..db094db6 100644 --- a/src/fsfw/cfdp/VarLenFields.h +++ b/src/fsfw/cfdp/VarLenFields.h @@ -74,6 +74,19 @@ struct EntityId : public VarLenField { template explicit EntityId(UnsignedByteField byteField) : VarLenField(byteField) {} EntityId(cfdp::WidthInBytes width, size_t entityId) : VarLenField(width, entityId) {} + + ReturnValue_t serializeAsLv(uint8_t **buffer, size_t *size, size_t maxSize) { + if (buffer == nullptr or size == nullptr) { + return returnvalue::FAILED; + } + if (*size + 1 + getWidth() > maxSize) { + return SerializeIF::BUFFER_TOO_SHORT; + } + **buffer = getWidth(); + *buffer += 1; + *size += 1; + return serialize(buffer, size, maxSize, SerializeIF::Endianness::NETWORK); + } }; struct TransactionSeqNum : public VarLenField { diff --git a/src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp b/src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp index 5eaf72c6..d37338ed 100644 --- a/src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp +++ b/src/fsfw/cfdp/tlv/ReservedMessageCreator.cpp @@ -13,7 +13,7 @@ ReturnValue_t cfdp::ReservedMessageCreator::serialize( **buffer = TlvType::MSG_TO_USER; *buffer += 1; *size += 1; - **buffer = getSerializedSize() - 1; + **buffer = getSerializedSize() - 2; *size += 1; *buffer += 1; std::memcpy(*buffer, MSG_HEADER, 4); @@ -23,6 +23,8 @@ ReturnValue_t cfdp::ReservedMessageCreator::serialize( *buffer += 1; *size += 1; std::memcpy(*buffer, msgData, msgSize); + *buffer += msgSize; + *size += msgSize; return returnvalue::OK; } diff --git a/unittests/cfdp/CMakeLists.txt b/unittests/cfdp/CMakeLists.txt index 1867a534..aba30ede 100644 --- a/unittests/cfdp/CMakeLists.txt +++ b/unittests/cfdp/CMakeLists.txt @@ -1,5 +1,6 @@ -target_sources(${FSFW_TEST_TGT} PRIVATE testCfdp.cpp testOtherTlvs.cpp - testTlv.cpp testLvs.cpp) +target_sources( + ${FSFW_TEST_TGT} PRIVATE testCfdp.cpp testOtherTlvs.cpp + testReservedMsgCreator.cpp testTlv.cpp testLvs.cpp) add_subdirectory(handler) add_subdirectory(pdu) diff --git a/unittests/cfdp/handler/testReservedMsgParser.cpp b/unittests/cfdp/handler/testReservedMsgParser.cpp index ea038b6a..035cef5f 100644 --- a/unittests/cfdp/handler/testReservedMsgParser.cpp +++ b/unittests/cfdp/handler/testReservedMsgParser.cpp @@ -1,6 +1,10 @@ #include +#include "fsfw/cfdp/VarLenFields.h" #include "fsfw/cfdp/handler/ReservedMessageParser.h" +#include "fsfw/cfdp/tlv/Lv.h" +#include "fsfw/cfdp/tlv/ReservedMessageCreator.h" +#include "fsfw/cfdp/tlv/StringLv.h" #include "mocks/MessageQueueMock.h" #include "mocks/StorageManagerMock.h" @@ -8,11 +12,30 @@ TEST_CASE("Reserved Message Parser", "[cfdp]") { using namespace cfdp; using namespace returnvalue; + std::string srcFileName = "hello.txt"; + std::string destFileName = "hello2.txt"; MessageQueueId_t destQueueId = 2; MessageQueueMock msgQueue(destQueueId); LocalPool::LocalPoolConfig storeCfg = {{10, 32}, {10, 64}, {10, 128}, {10, 1024}}; StorageManagerMock ipcStore(0, storeCfg); - ReservedMessageParser parser(ipcStore, msgQueue, destQueueId); + std::array buffer{}; + uint8_t msgBuf[32]{}; + EntityId entityId(cfdp::WidthInBytes::ONE_BYTE, 5); + uint8_t* msgBufPtr = msgBuf; + size_t serLen = 0; + cfdp::StringLv srcName(srcFileName); + cfdp::StringLv destName(destFileName); + CHECK(entityId.serializeAsLv(&msgBufPtr, &serLen, sizeof(msgBuf)) == OK); + CHECK(srcName.serialize(&msgBufPtr, &serLen, sizeof(msgBuf), SerializeIF::Endianness::NETWORK) == + OK); + CHECK(destName.serialize(&msgBufPtr, &serLen, sizeof(msgBuf), SerializeIF::Endianness::NETWORK) == + OK); + ReservedMessageCreator creator(static_cast(ProxyOpMessageType::PUT_REQUEST), msgBuf, + serLen); + serLen = 0; + ReturnValue_t result = creator.serializeBe(buffer.data(), serLen, buffer.size()); + CHECK(result == returnvalue::OK); - // parser.parse() + ReservedMessageParser parser(ipcStore, msgQueue, destQueueId); + CHECK(parser.parse(buffer.data(), buffer.max_size()) == OK); } diff --git a/unittests/cfdp/testReservedMsgCreator.cpp b/unittests/cfdp/testReservedMsgCreator.cpp new file mode 100644 index 00000000..1873becf --- /dev/null +++ b/unittests/cfdp/testReservedMsgCreator.cpp @@ -0,0 +1,49 @@ +#include +#include + +#include "fsfw/cfdp/VarLenFields.h" +#include "fsfw/cfdp/tlv/ReservedMessageCreator.h" +#include "fsfw/cfdp/tlv/StringLv.h" + +TEST_CASE("Reserved Message Creator", "[cfdp][tlv]") { + using namespace cfdp; + using namespace returnvalue; + + std::string srcFileName = "hello.txt"; + std::string destFileName = "hello2.txt"; + std::array buffer{}; + uint8_t msgBuf[32]{}; + EntityId entityId(cfdp::WidthInBytes::ONE_BYTE, 5); + uint8_t* msgBufPtr = msgBuf; + size_t serLen = 0; + cfdp::StringLv srcName(srcFileName); + cfdp::StringLv destName(destFileName); + CHECK(entityId.serializeAsLv(&msgBufPtr, &serLen, sizeof(msgBuf)) == OK); + CHECK(srcName.serialize(&msgBufPtr, &serLen, sizeof(msgBuf), SerializeIF::Endianness::NETWORK) == + OK); + CHECK(destName.serialize(&msgBufPtr, &serLen, sizeof(msgBuf), SerializeIF::Endianness::NETWORK) == + OK); + ReservedMessageCreator creator(static_cast(ProxyOpMessageType::PUT_REQUEST), msgBuf, + serLen); + serLen = 0; + ReturnValue_t result = creator.serializeBe(buffer.data(), serLen, buffer.size()); + CHECK(result == returnvalue::OK); + CHECK(buffer[0] == TlvType::MSG_TO_USER); + // 4 bytes "cfdp" header, 1 byte message type, entity ID LV, source name LV and dest name LV + CHECK(buffer[1] == + 5 + 1 + entityId.getSerializedSize() + 1 + srcFileName.size() + 1 + destFileName.size()); + CHECK(buffer[2] == 'c'); + CHECK(buffer[3] == 'f'); + CHECK(buffer[4] == 'd'); + CHECK(buffer[5] == 'p'); + CHECK(buffer[6] == static_cast(ProxyOpMessageType::PUT_REQUEST)); + CHECK(buffer[7] == 1); + CHECK(buffer[8] == entityId.getValue()); + CHECK(buffer[9] == srcFileName.size()); + size_t currentIdx = 10; + CHECK(std::string(reinterpret_cast(buffer.data()) + currentIdx, + srcFileName.size()) == srcFileName); + currentIdx += srcFileName.size() + 1; + CHECK(std::string(reinterpret_cast(buffer.data()) + currentIdx, + destFileName.size()) == destFileName); +}