From b350018cad26979c3dd11a4b55e924c5d53bf49a Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 22 Jul 2022 18:22:35 +0200 Subject: [PATCH] completed basic test set --- src/fsfw/timemanager/TimeReaderIF.h | 2 +- src/fsfw/tmtcpacket/pus/tc/PusTcReader.cpp | 2 + src/fsfw/tmtcpacket/pus/tc/PusTcReader.h | 7 +- src/fsfw/tmtcpacket/pus/tm/PusTmReader.cpp | 8 +- src/fsfw/tmtcpacket/pus/tm/PusTmReader.h | 6 +- unittests/mocks/CdsShortTimestamperMock.h | 19 ++++- unittests/tmtcpacket/testPusTcReader.cpp | 5 +- unittests/tmtcpacket/testPusTmCreator.cpp | 1 + unittests/tmtcpacket/testPusTmReader.cpp | 86 ++++++++++++++++++++-- 9 files changed, 117 insertions(+), 19 deletions(-) diff --git a/src/fsfw/timemanager/TimeReaderIF.h b/src/fsfw/timemanager/TimeReaderIF.h index 388f7d71..cfad90ff 100644 --- a/src/fsfw/timemanager/TimeReaderIF.h +++ b/src/fsfw/timemanager/TimeReaderIF.h @@ -8,7 +8,7 @@ class TimeReaderIF { public: virtual ~TimeReaderIF() = default; - virtual ReturnValue_t readTimeStamp(const uint8_t* buffer, uint8_t maxSize) = 0; + virtual ReturnValue_t readTimeStamp(const uint8_t* buffer, size_t maxSize) = 0; // Would be nice to have this, but the clock backend needs to be redesigned // virtual ReturnValue_t readTimestampLen(const uint8_t* buffer, uint8_t maxSize, size_t& // timestampLen) = 0; diff --git a/src/fsfw/tmtcpacket/pus/tc/PusTcReader.cpp b/src/fsfw/tmtcpacket/pus/tc/PusTcReader.cpp index f5dd143a..f50affa7 100644 --- a/src/fsfw/tmtcpacket/pus/tc/PusTcReader.cpp +++ b/src/fsfw/tmtcpacket/pus/tc/PusTcReader.cpp @@ -82,3 +82,5 @@ const uint8_t* PusTcReader::getUserData() const { return pointers.userDataStart; size_t PusTcReader::getUserDataLen() const { return appDataSize; } bool PusTcReader::isNull() const { return spReader.isNull(); } + +PusTcReader::operator bool() const { return not isNull(); } diff --git a/src/fsfw/tmtcpacket/pus/tc/PusTcReader.h b/src/fsfw/tmtcpacket/pus/tc/PusTcReader.h index 3be2e5e6..1b9eea49 100644 --- a/src/fsfw/tmtcpacket/pus/tc/PusTcReader.h +++ b/src/fsfw/tmtcpacket/pus/tc/PusTcReader.h @@ -33,16 +33,13 @@ class PusTcReader : public PusTcIF, * @param setData The position where the packet data lies. */ PusTcReader(const uint8_t* setData, size_t size); + ~PusTcReader() override; + explicit operator bool() const; [[nodiscard]] bool isNull() const; ReturnValue_t parseDataWithCrcCheck(); ReturnValue_t parseDataWithoutCrcCheck(); - /** - * This is the empty default destructor. - */ - ~PusTcReader() override; - /** * This is a debugging helper method that prints the whole packet content * to the screen. diff --git a/src/fsfw/tmtcpacket/pus/tm/PusTmReader.cpp b/src/fsfw/tmtcpacket/pus/tm/PusTmReader.cpp index e700a428..0dfab4ce 100644 --- a/src/fsfw/tmtcpacket/pus/tm/PusTmReader.cpp +++ b/src/fsfw/tmtcpacket/pus/tm/PusTmReader.cpp @@ -71,8 +71,11 @@ ReturnValue_t PusTmReader::parseData(bool crcCheck) { return SerializeIF::STREAM_TOO_SHORT; } currentOffset += timestampLen; - pointers.userDataStart = pointers.spHeaderStart + currentOffset; sourceDataLen = spReader.getFullPacketLen() - currentOffset - sizeof(ecss::PusChecksumT); + pointers.userDataStart = nullptr; + if (sourceDataLen > 0) { + pointers.userDataStart = pointers.spHeaderStart + currentOffset; + } currentOffset += sourceDataLen; pointers.crcStart = pointers.spHeaderStart + currentOffset; if (crcCheck) { @@ -84,3 +87,6 @@ ReturnValue_t PusTmReader::parseData(bool crcCheck) { } return HasReturnvaluesIF::RETURN_OK; } +bool PusTmReader::isNull() const { return spReader.isNull(); } + +PusTmReader::operator bool() const { return not isNull(); } diff --git a/src/fsfw/tmtcpacket/pus/tm/PusTmReader.h b/src/fsfw/tmtcpacket/pus/tm/PusTmReader.h index 1d91eb95..e5a61aec 100644 --- a/src/fsfw/tmtcpacket/pus/tm/PusTmReader.h +++ b/src/fsfw/tmtcpacket/pus/tm/PusTmReader.h @@ -21,6 +21,8 @@ class PusTmReader : public PusTmIF, ReturnValue_t parseDataWithCrcCheck(); const uint8_t* getFullData() override; + explicit operator bool() const; + [[nodiscard]] bool isNull() const; void setTimeReader(TimeReaderIF* timeReader); TimeReaderIF* getTimeReader(); ReturnValue_t setReadOnlyData(const uint8_t* data, size_t size); @@ -30,8 +32,8 @@ class PusTmReader : public PusTmIF, [[nodiscard]] uint8_t getPusVersion() const override; [[nodiscard]] uint8_t getService() const override; [[nodiscard]] uint8_t getSubService() const override; - const uint8_t* getUserData() const override; - size_t getUserDataLen() const override; + [[nodiscard]] const uint8_t* getUserData() const override; + [[nodiscard]] size_t getUserDataLen() const override; uint8_t getScTimeRefStatus() override; uint16_t getMessageTypeCounter() override; uint16_t getDestId() override; diff --git a/unittests/mocks/CdsShortTimestamperMock.h b/unittests/mocks/CdsShortTimestamperMock.h index 779859d0..460c98c5 100644 --- a/unittests/mocks/CdsShortTimestamperMock.h +++ b/unittests/mocks/CdsShortTimestamperMock.h @@ -5,9 +5,11 @@ #include "fsfw/timemanager/TimeStamperIF.h" -class CdsShortTimestamperMock : public TimeStamperIF { +class CdsShortTimestamperMock : public TimeStamperIF, public TimeReaderIF { public: unsigned int serializeCallCount = 0; + unsigned int deserializeCallCount = 0; + ReturnValue_t lastDeserializeResult = HasReturnvaluesIF::RETURN_OK; ReturnValue_t lastSerializeResult = HasReturnvaluesIF::RETURN_OK; unsigned int getSizeCallCount = 0; std::array valueToStamp{}; @@ -38,8 +40,15 @@ class CdsShortTimestamperMock : public TimeStamperIF { } ReturnValue_t deSerialize(const uint8_t **buffer, size_t *size, Endianness streamEndianness) override { - return HasReturnvaluesIF::RETURN_FAILED; + deserializeCallCount += 1; + if (*size < 7) { + lastDeserializeResult = SerializeIF::STREAM_TOO_SHORT; + return lastDeserializeResult; + } + std::copy(*buffer, *buffer + getSerializedSize(), valueToStamp.begin()); + return lastDeserializeResult; } + [[nodiscard]] size_t getTimestampSize() const override { return getSerializedSize(); } ReturnValue_t addTimeStamp(uint8_t *buffer, uint8_t maxSize) override { return 0; } @@ -47,7 +56,13 @@ class CdsShortTimestamperMock : public TimeStamperIF { serializeCallCount = 0; getSizeCallCount = 0; } + ReturnValue_t readTimeStamp(const uint8_t *buffer, size_t maxSize) override { + return deSerialize(&buffer, &maxSize, SerializeIF::Endianness::NETWORK); + } + size_t getTimestampLen() override { return getSerializedSize(); } + timeval &getTime() override { return dummyTime; } private: + timeval dummyTime{}; }; #endif // FSFW_TESTS_CDSSHORTTIMESTAMPERMOCK_H diff --git a/unittests/tmtcpacket/testPusTcReader.cpp b/unittests/tmtcpacket/testPusTcReader.cpp index 82a88542..3245218a 100644 --- a/unittests/tmtcpacket/testPusTcReader.cpp +++ b/unittests/tmtcpacket/testPusTcReader.cpp @@ -14,13 +14,11 @@ TEST_CASE("PUS TC Reader", "[pus-tc-reader]") { uint8_t* dataPtr = buf.data(); size_t serLen = 0; PusTcReader reader; - auto checkReaderFields = [&](PusTcReader& reader) { - - }; SECTION("State") { REQUIRE(creator.serialize(&dataPtr, &serLen, buf.size()) == HasReturnvaluesIF::RETURN_OK); REQUIRE(reader.isNull()); + REQUIRE(not reader); PusTcReader* readerPtr = nullptr; bool callDelete = false; SECTION("Setter") { @@ -35,6 +33,7 @@ TEST_CASE("PUS TC Reader", "[pus-tc-reader]") { REQUIRE(readerPtr->parseDataWithCrcCheck() == HasReturnvaluesIF::RETURN_OK); } REQUIRE(not readerPtr->isNull()); + REQUIRE(*readerPtr); REQUIRE(readerPtr->getPacketType() == ccsds::PacketType::TC); REQUIRE(readerPtr->getApid() == 0x02); REQUIRE(readerPtr->getService() == 17); diff --git a/unittests/tmtcpacket/testPusTmCreator.cpp b/unittests/tmtcpacket/testPusTmCreator.cpp index 2b60515f..035126f0 100644 --- a/unittests/tmtcpacket/testPusTmCreator.cpp +++ b/unittests/tmtcpacket/testPusTmCreator.cpp @@ -70,6 +70,7 @@ TEST_CASE("PUS TM Creator", "[pus-tm-creator]") { REQUIRE(CRC::crc16ccitt(buf.data(), serLen) == 0); REQUIRE(buf[20] == 0x03); REQUIRE(buf[21] == 0x79); + REQUIRE(timeStamper.serializeCallCount == 1); } SECTION("Custom Fields") { diff --git a/unittests/tmtcpacket/testPusTmReader.cpp b/unittests/tmtcpacket/testPusTmReader.cpp index 69dc7088..8540b97c 100644 --- a/unittests/tmtcpacket/testPusTmReader.cpp +++ b/unittests/tmtcpacket/testPusTmReader.cpp @@ -1,18 +1,94 @@ #include #include "fsfw/tmtcpacket/pus/tm/PusTmCreator.h" +#include "fsfw/tmtcpacket/pus/tm/PusTmReader.h" #include "mocks/CdsShortTimestamperMock.h" TEST_CASE("PUS TM Reader", "[pus-tm-reader]") { auto packetId = PacketId(ccsds::PacketType::TC, true, 0xef); auto spParams = SpacePacketParams(packetId, PacketSeqCtrl(ccsds::SequenceFlags::UNSEGMENTED, 22), 0x00); - auto timeStamper = CdsShortTimestamperMock(); - auto pusTmParams = PusTmParams(17, 2, &timeStamper); - timeStamper.valueToStamp = {1, 2, 3, 4, 5, 6, 7}; + auto timeStamperAndReader = CdsShortTimestamperMock(); + auto pusTmParams = PusTmParams(17, 2, &timeStamperAndReader); + timeStamperAndReader.valueToStamp = {1, 2, 3, 4, 5, 6, 7}; PusTmCreator creator(spParams, pusTmParams); + PusTmReader reader(&timeStamperAndReader); + std::array buf{}; + uint8_t* dataPtr = buf.data(); + size_t serLen = 0; - SECTION("State") { - + SECTION("Basic") { + PusTmReader* readerPtr = &reader; + bool deleteReader = false; + dataPtr = buf.data(); + serLen = 0; + REQUIRE(creator.serialize(&dataPtr, &serLen, buf.size()) == HasReturnvaluesIF::RETURN_OK); + REQUIRE(not(*readerPtr)); + REQUIRE(readerPtr->isNull()); + + SECTION("Setter") { + REQUIRE(readerPtr->setReadOnlyData(buf.data(), serLen) == HasReturnvaluesIF::RETURN_OK); + } + SECTION("Full Construction") { + readerPtr = new PusTmReader(&timeStamperAndReader, buf.data(), serLen); + deleteReader = true; + } + SECTION("Time Stamper set manually") { + readerPtr = new PusTmReader(buf.data(), serLen); + readerPtr->setTimeReader(&timeStamperAndReader); + deleteReader = true; + } + REQUIRE(readerPtr); + REQUIRE(not readerPtr->isNull()); + REQUIRE(readerPtr->parseDataWithCrcCheck() == HasReturnvaluesIF::RETURN_OK); + REQUIRE(readerPtr->getService() == 17); + REQUIRE(readerPtr->getSubService() == 2); + REQUIRE(readerPtr->getApid() == 0xef); + REQUIRE(readerPtr->getSequenceFlags() == ccsds::SequenceFlags::UNSEGMENTED); + REQUIRE(readerPtr->getScTimeRefStatus() == 0); + REQUIRE(readerPtr->getDestId() == 0); + REQUIRE(readerPtr->getMessageTypeCounter() == 0); + REQUIRE(readerPtr->getTimeReader() == &timeStamperAndReader); + REQUIRE(readerPtr->getPusVersion() == 2); + REQUIRE(readerPtr->getPacketDataLen() == 15); + REQUIRE(readerPtr->getFullPacketLen() == 22); + REQUIRE(readerPtr->getUserDataLen() == 0); + REQUIRE(readerPtr->getUserData() == nullptr); + REQUIRE(readerPtr->getFullData() == buf.data()); + if (deleteReader) { + delete readerPtr; + } + } + + SECTION("Invalid CRC") { + REQUIRE(creator.serialize(&dataPtr, &serLen, buf.size()) == HasReturnvaluesIF::RETURN_OK); + buf[20] = 0; + REQUIRE(reader.setReadOnlyData(buf.data(), serLen) == HasReturnvaluesIF::RETURN_OK); + REQUIRE(reader.parseDataWithCrcCheck() == PusIF::INVALID_CRC_16); + } + + SECTION("Set Time Reader") { + reader.setTimeReader(nullptr); + REQUIRE(reader.getTimeReader() == nullptr); + } + + SECTION("Invalid CRC ignored") { + REQUIRE(creator.serialize(&dataPtr, &serLen, buf.size()) == HasReturnvaluesIF::RETURN_OK); + buf[20] = 0; + REQUIRE(reader.setReadOnlyData(buf.data(), serLen) == HasReturnvaluesIF::RETURN_OK); + REQUIRE(reader.parseDataWithoutCrcCheck() == HasReturnvaluesIF::RETURN_OK); + } + + SECTION("Read with source data") { + std::array data{1, 2, 3}; + creator.setRawUserData(data.data(), data.size()); + REQUIRE(creator.serialize(&dataPtr, &serLen, buf.size()) == HasReturnvaluesIF::RETURN_OK); + REQUIRE(reader.setReadOnlyData(buf.data(), serLen) == HasReturnvaluesIF::RETURN_OK); + REQUIRE(reader.parseDataWithCrcCheck() == HasReturnvaluesIF::RETURN_OK); + REQUIRE(reader.getUserDataLen() == 3); + const uint8_t* roData = reader.getUserData(); + REQUIRE(roData[0] == 1); + REQUIRE(roData[1] == 2); + REQUIRE(roData[2] == 3); } } \ No newline at end of file