add CFDP fault handler mock
This commit is contained in:
13
unittests/cfdp/pdu/CMakeLists.txt
Normal file
13
unittests/cfdp/pdu/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
target_sources(
|
||||
${FSFW_TEST_TGT}
|
||||
PRIVATE testAckPdu.cpp
|
||||
testAckPdu.cpp
|
||||
testEofPdu.cpp
|
||||
testNakPdu.cpp
|
||||
testFinishedPdu.cpp
|
||||
testPromptPdu.cpp
|
||||
testKeepAlivePdu.cpp
|
||||
testMetadataPdu.cpp
|
||||
testFileData.cpp
|
||||
testCfdpHeader.cpp
|
||||
testFileDirective.cpp)
|
100
unittests/cfdp/pdu/testAckPdu.cpp
Normal file
100
unittests/cfdp/pdu/testAckPdu.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/pdu/AckPduDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/AckPduSerializer.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
|
||||
TEST_CASE("ACK PDU", "[cfdp][pdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result;
|
||||
std::array<uint8_t, 256> buf = {};
|
||||
uint8_t* bufptr = buf.data();
|
||||
size_t maxsz = buf.size();
|
||||
size_t sz = 0;
|
||||
auto seqNum = TransactionSeqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
auto sourceId = EntityId(WidthInBytes::TWO_BYTES, 1);
|
||||
auto destId = EntityId(WidthInBytes::TWO_BYTES, 2);
|
||||
auto pduConf = PduConfig(sourceId, destId, TransmissionModes::ACKNOWLEDGED, seqNum);
|
||||
AckInfo ackInfo(FileDirectives::EOF_DIRECTIVE, ConditionCode::NO_ERROR,
|
||||
AckTransactionStatus::ACTIVE);
|
||||
auto ackSerializer = AckPduSerializer(ackInfo, pduConf);
|
||||
result = ackSerializer.serialize(&bufptr, &sz, maxsz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
SECTION("Serialize") {
|
||||
REQUIRE(buf[sz - 3] == cfdp::FileDirectives::ACK);
|
||||
REQUIRE((buf[sz - 2] >> 4) == FileDirectives::EOF_DIRECTIVE);
|
||||
REQUIRE((buf[sz - 2] & 0x0f) == 0);
|
||||
REQUIRE(buf[sz - 1] == AckTransactionStatus::ACTIVE);
|
||||
ackInfo.setAckedDirective(FileDirectives::FINISH);
|
||||
ackInfo.setAckedConditionCode(ConditionCode::FILESTORE_REJECTION);
|
||||
ackInfo.setTransactionStatus(AckTransactionStatus::TERMINATED);
|
||||
auto ackSerializer2 = AckPduSerializer(ackInfo, pduConf);
|
||||
bufptr = buf.data();
|
||||
sz = 0;
|
||||
result = ackSerializer2.serialize(&bufptr, &sz, maxsz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(buf[sz - 3] == cfdp::FileDirectives::ACK);
|
||||
REQUIRE((buf[sz - 2] >> 4) == FileDirectives::FINISH);
|
||||
REQUIRE((buf[sz - 2] & 0x0f) == 0b0001);
|
||||
REQUIRE((buf[sz - 1] >> 4) == ConditionCode::FILESTORE_REJECTION);
|
||||
REQUIRE((buf[sz - 1] & 0b11) == AckTransactionStatus::TERMINATED);
|
||||
|
||||
bufptr = buf.data();
|
||||
sz = 0;
|
||||
ackInfo.setAckedDirective(FileDirectives::KEEP_ALIVE);
|
||||
auto ackSerializer3 = AckPduSerializer(ackInfo, pduConf);
|
||||
result = ackSerializer3.serialize(&bufptr, &sz, maxsz, SerializeIF::Endianness::NETWORK);
|
||||
// Invalid file directive
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
ackInfo.setAckedDirective(FileDirectives::FINISH);
|
||||
// buffer too small
|
||||
result = ackSerializer.serialize(&bufptr, &sz, 8, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
|
||||
SECTION("Deserialize") {
|
||||
AckInfo ackInfo2;
|
||||
auto reader = AckPduDeserializer(buf.data(), sz, ackInfo2);
|
||||
result = reader.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(ackInfo2.getAckedDirective() == FileDirectives::EOF_DIRECTIVE);
|
||||
REQUIRE(ackInfo2.getAckedConditionCode() == ConditionCode::NO_ERROR);
|
||||
REQUIRE(ackInfo2.getDirectiveSubtypeCode() == 0);
|
||||
REQUIRE(ackInfo2.getTransactionStatus() == AckTransactionStatus::ACTIVE);
|
||||
|
||||
AckInfo newInfo = AckInfo(FileDirectives::FINISH, ConditionCode::FILESTORE_REJECTION,
|
||||
AckTransactionStatus::TERMINATED);
|
||||
auto ackSerializer2 = AckPduSerializer(newInfo, pduConf);
|
||||
bufptr = buf.data();
|
||||
sz = 0;
|
||||
result = ackSerializer2.serialize(&bufptr, &sz, maxsz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
auto reader2 = AckPduDeserializer(buf.data(), sz, ackInfo2);
|
||||
result = reader2.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(ackInfo2.getAckedDirective() == FileDirectives::FINISH);
|
||||
REQUIRE(ackInfo2.getAckedConditionCode() == ConditionCode::FILESTORE_REJECTION);
|
||||
REQUIRE(ackInfo2.getDirectiveSubtypeCode() == 0b0001);
|
||||
REQUIRE(ackInfo2.getTransactionStatus() == AckTransactionStatus::TERMINATED);
|
||||
|
||||
uint8_t prevVal = buf[sz - 2];
|
||||
buf[sz - 2] = FileDirectives::INVALID_DIRECTIVE << 4;
|
||||
result = reader2.parseData();
|
||||
REQUIRE(result == cfdp::INVALID_ACK_DIRECTIVE_FIELDS);
|
||||
buf[sz - 2] = FileDirectives::FINISH << 4 | 0b1111;
|
||||
result = reader2.parseData();
|
||||
REQUIRE(result == cfdp::INVALID_ACK_DIRECTIVE_FIELDS);
|
||||
buf[sz - 2] = prevVal;
|
||||
buf[sz - 3] = cfdp::FileDirectives::INVALID_DIRECTIVE;
|
||||
result = reader2.parseData();
|
||||
REQUIRE(result == cfdp::INVALID_DIRECTIVE_FIELDS);
|
||||
buf[sz - 3] = cfdp::FileDirectives::ACK;
|
||||
auto maxSizeTooSmall = AckPduDeserializer(buf.data(), sz - 2, ackInfo2);
|
||||
result = maxSizeTooSmall.parseData();
|
||||
REQUIRE(result == SerializeIF::STREAM_TOO_SHORT);
|
||||
}
|
||||
}
|
316
unittests/cfdp/pdu/testCfdpHeader.cpp
Normal file
316
unittests/cfdp/pdu/testCfdpHeader.cpp
Normal file
@ -0,0 +1,316 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/pdu/HeaderCreator.h"
|
||||
#include "fsfw/cfdp/pdu/HeaderReader.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
TEST_CASE("CFDP Header", "[cfdp]") {
|
||||
using namespace cfdp;
|
||||
std::array<uint8_t, 32> serBuf{};
|
||||
ReturnValue_t result;
|
||||
cfdp::TransactionSeqNum seqNum = TransactionSeqNum(cfdp::WidthInBytes::ONE_BYTE, 2);
|
||||
cfdp::EntityId sourceId = EntityId(cfdp::WidthInBytes::ONE_BYTE, 0);
|
||||
cfdp::EntityId destId = EntityId(cfdp::WidthInBytes::ONE_BYTE, 1);
|
||||
PduConfig pduConf =
|
||||
PduConfig(sourceId, destId, cfdp::TransmissionModes::ACKNOWLEDGED, seqNum, false);
|
||||
uint8_t* serTarget = serBuf.data();
|
||||
const uint8_t* deserTarget = serTarget;
|
||||
size_t serSize = 0;
|
||||
auto headerSerializer = HeaderCreator(pduConf, cfdp::PduType::FILE_DIRECTIVE, 0);
|
||||
|
||||
SECTION("Header State") {
|
||||
REQUIRE(seqNum.getSerializedSize() == 1);
|
||||
REQUIRE(headerSerializer.getPduDataFieldLen() == 0);
|
||||
REQUIRE(headerSerializer.getSerializedSize() == 7);
|
||||
REQUIRE(headerSerializer.getWholePduSize() == 7);
|
||||
REQUIRE(headerSerializer.getCrcFlag() == false);
|
||||
REQUIRE(headerSerializer.getDirection() == cfdp::Direction::TOWARDS_RECEIVER);
|
||||
REQUIRE(headerSerializer.getLargeFileFlag() == false);
|
||||
REQUIRE(headerSerializer.getLenEntityIds() == 1);
|
||||
REQUIRE(headerSerializer.getLenSeqNum() == 1);
|
||||
REQUIRE(headerSerializer.getPduType() == cfdp::PduType::FILE_DIRECTIVE);
|
||||
REQUIRE(headerSerializer.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::NOT_PRESENT);
|
||||
REQUIRE(headerSerializer.getSegmentationControl() == false);
|
||||
REQUIRE(headerSerializer.getTransmissionMode() == cfdp::TransmissionModes::ACKNOWLEDGED);
|
||||
cfdp::TransactionSeqNum seqNumLocal;
|
||||
headerSerializer.getTransactionSeqNum(seqNumLocal);
|
||||
REQUIRE(seqNumLocal.getWidth() == cfdp::WidthInBytes::ONE_BYTE);
|
||||
REQUIRE(seqNumLocal.getValue() == 2);
|
||||
cfdp::EntityId sourceDestId;
|
||||
headerSerializer.getSourceId(sourceDestId);
|
||||
REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::ONE_BYTE);
|
||||
REQUIRE(sourceDestId.getValue() == 0);
|
||||
headerSerializer.getDestId(sourceDestId);
|
||||
REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::ONE_BYTE);
|
||||
REQUIRE(sourceDestId.getValue() == 1);
|
||||
}
|
||||
|
||||
SECTION("Deserialization fails") {
|
||||
const uint8_t** dummyPtr = nullptr;
|
||||
REQUIRE(headerSerializer.deSerialize(dummyPtr, &serSize, SerializeIF::Endianness::NETWORK) ==
|
||||
result::FAILED);
|
||||
}
|
||||
|
||||
SECTION("Serialization fails") {
|
||||
REQUIRE(headerSerializer.serialize(nullptr, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK) == result::FAILED);
|
||||
}
|
||||
|
||||
SECTION("Buffer Too Short") {
|
||||
for (uint8_t idx = 0; idx < 7; idx++) {
|
||||
result = headerSerializer.serialize(&serTarget, &serSize, idx, SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == static_cast<int>(SerializeIF::BUFFER_TOO_SHORT));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Set Data Field Len") {
|
||||
// Set PDU data field len
|
||||
headerSerializer.setPduDataFieldLen(0x0ff0);
|
||||
REQUIRE(headerSerializer.getPduDataFieldLen() == 0x0ff0);
|
||||
REQUIRE(headerSerializer.getSerializedSize() == 7);
|
||||
REQUIRE(headerSerializer.getWholePduSize() == 7 + 0x0ff0);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
result = headerSerializer.serialize(&serTarget, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::BIG);
|
||||
REQUIRE(serBuf[1] == 0x0f);
|
||||
REQUIRE(serBuf[2] == 0xf0);
|
||||
}
|
||||
|
||||
SECTION("Serialize with Fields Flipped") {
|
||||
pduConf.crcFlag = true;
|
||||
pduConf.largeFile = true;
|
||||
pduConf.direction = cfdp::Direction::TOWARDS_SENDER;
|
||||
pduConf.mode = cfdp::TransmissionModes::UNACKNOWLEDGED;
|
||||
headerSerializer.setSegmentationControl(
|
||||
cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION);
|
||||
headerSerializer.setPduType(cfdp::PduType::FILE_DATA);
|
||||
headerSerializer.setSegmentMetadataFlag(cfdp::SegmentMetadataFlag::PRESENT);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
|
||||
SECTION("Regular") {
|
||||
// Everything except version bit flipped to one now
|
||||
REQUIRE(headerSerializer.serialize(&serTarget, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::BIG) == result::OK);
|
||||
CHECK(serBuf[0] == 0x3f);
|
||||
CHECK(serBuf[3] == 0x99);
|
||||
REQUIRE(headerSerializer.getCrcFlag() == true);
|
||||
REQUIRE(headerSerializer.getDirection() == cfdp::Direction::TOWARDS_SENDER);
|
||||
REQUIRE(headerSerializer.getLargeFileFlag() == true);
|
||||
REQUIRE(headerSerializer.getLenEntityIds() == 1);
|
||||
REQUIRE(headerSerializer.getLenSeqNum() == 1);
|
||||
REQUIRE(headerSerializer.getPduType() == cfdp::PduType::FILE_DATA);
|
||||
REQUIRE(headerSerializer.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT);
|
||||
REQUIRE(headerSerializer.getTransmissionMode() == cfdp::TransmissionModes::UNACKNOWLEDGED);
|
||||
REQUIRE(headerSerializer.getSegmentationControl() == true);
|
||||
}
|
||||
|
||||
SECTION("Other variable sized fields") {
|
||||
pduConf.seqNum.setValue(cfdp::WidthInBytes::TWO_BYTES, 0x0fff);
|
||||
pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00);
|
||||
pduConf.destId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff);
|
||||
REQUIRE(pduConf.sourceId.getSerializedSize() == 4);
|
||||
REQUIRE(headerSerializer.getSerializedSize() == 14);
|
||||
REQUIRE(headerSerializer.serialize(&serTarget, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::BIG) == result::OK);
|
||||
REQUIRE(headerSerializer.getCrcFlag() == true);
|
||||
REQUIRE(headerSerializer.getDirection() == cfdp::Direction::TOWARDS_SENDER);
|
||||
REQUIRE(headerSerializer.getLargeFileFlag() == true);
|
||||
REQUIRE(headerSerializer.getLenEntityIds() == 4);
|
||||
REQUIRE(headerSerializer.getLenSeqNum() == 2);
|
||||
REQUIRE(headerSerializer.getPduType() == cfdp::PduType::FILE_DATA);
|
||||
REQUIRE(headerSerializer.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT);
|
||||
REQUIRE(headerSerializer.getTransmissionMode() == cfdp::TransmissionModes::UNACKNOWLEDGED);
|
||||
REQUIRE(headerSerializer.getSegmentationControl() == true);
|
||||
// Last three bits are 2 now (length of seq number) and bit 1 to bit 3 is 4 (len entity IDs)
|
||||
REQUIRE(serBuf[3] == 0b11001010);
|
||||
uint32_t entityId = 0;
|
||||
size_t deSerSize = 0;
|
||||
SerializeAdapter::deSerialize(&entityId, serBuf.data() + 4, &deSerSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
CHECK(deSerSize == 4);
|
||||
CHECK(entityId == 0xff00ff00);
|
||||
uint16_t seqNumRaw = 0;
|
||||
SerializeAdapter::deSerialize(&seqNumRaw, serBuf.data() + 8, &deSerSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
CHECK(deSerSize == 2);
|
||||
CHECK(seqNumRaw == 0x0fff);
|
||||
SerializeAdapter::deSerialize(&entityId, serBuf.data() + 10, &deSerSize,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
CHECK(deSerSize == 4);
|
||||
CHECK(entityId == 0x00ff00ff);
|
||||
}
|
||||
|
||||
SECTION("Buffer Too Short") {
|
||||
pduConf.seqNum.setValue(cfdp::WidthInBytes::TWO_BYTES, 0x0fff);
|
||||
pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00);
|
||||
pduConf.destId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff);
|
||||
for (uint8_t idx = 0; idx < 14; idx++) {
|
||||
REQUIRE(
|
||||
headerSerializer.serialize(&serTarget, &serSize, idx, SerializeIF::Endianness::BIG) ==
|
||||
SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Invalid Variable Sized Fields") {
|
||||
result = pduConf.sourceId.setValue(cfdp::WidthInBytes::ONE_BYTE, 0xfff);
|
||||
REQUIRE(result == result::FAILED);
|
||||
result = pduConf.sourceId.setValue(cfdp::WidthInBytes::TWO_BYTES, 0xfffff);
|
||||
REQUIRE(result == result::FAILED);
|
||||
result = pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xfffffffff);
|
||||
REQUIRE(result == result::FAILED);
|
||||
}
|
||||
|
||||
SECTION("Header Serialization") {
|
||||
result = headerSerializer.serialize(&serTarget, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == result::OK);
|
||||
REQUIRE(serSize == 7);
|
||||
// Only version bits are set
|
||||
REQUIRE(serBuf[0] == 0b00100000);
|
||||
// PDU data field length is 0
|
||||
REQUIRE(serBuf[1] == 0);
|
||||
REQUIRE(serBuf[2] == 0);
|
||||
// Entity and Transaction Sequence number are 1 byte large
|
||||
REQUIRE(serBuf[3] == 0b00010001);
|
||||
// Source ID
|
||||
REQUIRE(serBuf[4] == 0);
|
||||
// Transaction Seq Number
|
||||
REQUIRE(serBuf[5] == 2);
|
||||
// Dest ID
|
||||
REQUIRE(serBuf[6] == 1);
|
||||
|
||||
uint8_t oneByteSourceId = 32;
|
||||
serTarget = &oneByteSourceId;
|
||||
size_t deserLen = 1;
|
||||
pduConf.sourceId.deSerialize(cfdp::WidthInBytes::ONE_BYTE,
|
||||
const_cast<const uint8_t**>(&serTarget), &deserLen,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(pduConf.sourceId.getValue() == 32);
|
||||
|
||||
uint16_t twoByteSourceId = 0xf0f0;
|
||||
serTarget = reinterpret_cast<uint8_t*>(&twoByteSourceId);
|
||||
deserLen = 2;
|
||||
pduConf.sourceId.deSerialize(cfdp::WidthInBytes::TWO_BYTES,
|
||||
const_cast<const uint8_t**>(&serTarget), &deserLen,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(pduConf.sourceId.getValue() == 0xf0f0);
|
||||
|
||||
uint32_t fourByteSourceId = 0xf0f0f0f0;
|
||||
serTarget = reinterpret_cast<uint8_t*>(&fourByteSourceId);
|
||||
deserLen = 4;
|
||||
pduConf.sourceId.deSerialize(cfdp::WidthInBytes::FOUR_BYTES,
|
||||
const_cast<const uint8_t**>(&serTarget), &deserLen,
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(pduConf.sourceId.getValue() == 0xf0f0f0f0);
|
||||
|
||||
pduConf.sourceId.setValue(cfdp::WidthInBytes::ONE_BYTE, 1);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 1;
|
||||
result = pduConf.sourceId.serialize(&serTarget, &serSize, 1, SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(result == static_cast<int>(SerializeIF::BUFFER_TOO_SHORT));
|
||||
}
|
||||
|
||||
SECTION("Header Deserialization") {
|
||||
REQUIRE(headerSerializer.serialize(&serTarget, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::BIG) == result::OK);
|
||||
REQUIRE(serBuf[1] == 0);
|
||||
REQUIRE(serBuf[2] == 0);
|
||||
// Entity and Transaction Sequence number are 1 byte large
|
||||
REQUIRE(serBuf[3] == 0b00010001);
|
||||
REQUIRE(serSize == 7);
|
||||
// Deser call not strictly necessary
|
||||
auto headerDeser = HeaderReader(serBuf.data(), serBuf.size());
|
||||
|
||||
ReturnValue_t serResult = headerDeser.parseData();
|
||||
REQUIRE(serResult == result::OK);
|
||||
REQUIRE(headerDeser.getPduDataFieldLen() == 0);
|
||||
REQUIRE(headerDeser.getHeaderSize() == 7);
|
||||
REQUIRE(headerDeser.getWholePduSize() == 7);
|
||||
REQUIRE(headerDeser.getCrcFlag() == false);
|
||||
REQUIRE(headerDeser.getDirection() == cfdp::Direction::TOWARDS_RECEIVER);
|
||||
REQUIRE(headerDeser.getLargeFileFlag() == false);
|
||||
REQUIRE(headerDeser.getLenEntityIds() == 1);
|
||||
REQUIRE(headerDeser.getLenSeqNum() == 1);
|
||||
REQUIRE(headerDeser.getPduType() == cfdp::PduType::FILE_DIRECTIVE);
|
||||
REQUIRE(headerDeser.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::NOT_PRESENT);
|
||||
REQUIRE(headerDeser.getSegmentationControl() == false);
|
||||
REQUIRE(headerDeser.getTransmissionMode() == cfdp::TransmissionModes::ACKNOWLEDGED);
|
||||
|
||||
pduConf.crcFlag = true;
|
||||
pduConf.largeFile = true;
|
||||
pduConf.direction = cfdp::Direction::TOWARDS_SENDER;
|
||||
pduConf.mode = cfdp::TransmissionModes::UNACKNOWLEDGED;
|
||||
headerSerializer.setSegmentationControl(
|
||||
cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION);
|
||||
headerSerializer.setPduType(cfdp::PduType::FILE_DATA);
|
||||
headerSerializer.setSegmentMetadataFlag(cfdp::SegmentMetadataFlag::PRESENT);
|
||||
result = pduConf.seqNum.setValue(cfdp::WidthInBytes::TWO_BYTES, 0x0fff);
|
||||
REQUIRE(result == result::OK);
|
||||
result = pduConf.sourceId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0xff00ff00);
|
||||
REQUIRE(result == result::OK);
|
||||
result = pduConf.destId.setValue(cfdp::WidthInBytes::FOUR_BYTES, 0x00ff00ff);
|
||||
REQUIRE(result == result::OK);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
result = headerSerializer.serialize(&serTarget, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::BIG);
|
||||
headerDeser = HeaderReader(serBuf.data(), serBuf.size());
|
||||
|
||||
result = headerDeser.parseData();
|
||||
REQUIRE(result == result::OK);
|
||||
// Everything except version bit flipped to one now
|
||||
REQUIRE(serBuf[0] == 0x3f);
|
||||
REQUIRE(serBuf[3] == 0b11001010);
|
||||
REQUIRE(headerDeser.getWholePduSize() == 14);
|
||||
|
||||
REQUIRE(headerDeser.getCrcFlag() == true);
|
||||
REQUIRE(headerDeser.getDirection() == cfdp::Direction::TOWARDS_SENDER);
|
||||
REQUIRE(headerDeser.getLargeFileFlag() == true);
|
||||
REQUIRE(headerDeser.getLenEntityIds() == 4);
|
||||
REQUIRE(headerDeser.getLenSeqNum() == 2);
|
||||
REQUIRE(headerDeser.getPduType() == cfdp::PduType::FILE_DATA);
|
||||
REQUIRE(headerDeser.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT);
|
||||
REQUIRE(headerDeser.getSegmentationControl() == true);
|
||||
REQUIRE(headerDeser.getTransmissionMode() == cfdp::TransmissionModes::UNACKNOWLEDGED);
|
||||
|
||||
cfdp::TransactionSeqNum seqNumLocal;
|
||||
headerDeser.getTransactionSeqNum(seqNumLocal);
|
||||
REQUIRE(seqNumLocal.getWidth() == cfdp::WidthInBytes::TWO_BYTES);
|
||||
REQUIRE(seqNumLocal.getValue() == 0x0fff);
|
||||
cfdp::EntityId sourceDestId;
|
||||
headerDeser.getSourceId(sourceDestId);
|
||||
REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::FOUR_BYTES);
|
||||
REQUIRE(sourceDestId.getValue() == 0xff00ff00);
|
||||
headerDeser.getDestId(sourceDestId);
|
||||
REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::FOUR_BYTES);
|
||||
REQUIRE(sourceDestId.getValue() == 0x00ff00ff);
|
||||
|
||||
size_t deSerSize = headerDeser.getWholePduSize();
|
||||
serTarget = serBuf.data();
|
||||
const auto** serTargetConst = const_cast<const uint8_t**>(&serTarget);
|
||||
result = headerDeser.parseData();
|
||||
REQUIRE(result == result::OK);
|
||||
|
||||
CHECK(headerDeser.setData(nullptr, -1) != result::OK);
|
||||
REQUIRE(headerDeser.getHeaderSize() == 14);
|
||||
headerDeser.setData(serBuf.data(), serBuf.size());
|
||||
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
pduConf.sourceId.setValue(cfdp::WidthInBytes::ONE_BYTE, 22);
|
||||
pduConf.destId.setValue(cfdp::WidthInBytes::ONE_BYTE, 48);
|
||||
result = headerSerializer.serialize(&serTarget, &serSize, serBuf.size(),
|
||||
SerializeIF::Endianness::BIG);
|
||||
REQUIRE(result == result::OK);
|
||||
REQUIRE(headerDeser.getWholePduSize() == 8);
|
||||
headerDeser.setData(serBuf.data(), serBuf.size());
|
||||
|
||||
headerDeser.getSourceId(sourceDestId);
|
||||
REQUIRE(sourceDestId.getWidth() == cfdp::WidthInBytes::ONE_BYTE);
|
||||
REQUIRE(sourceDestId.getValue() == 22);
|
||||
}
|
||||
}
|
118
unittests/cfdp/pdu/testEofPdu.cpp
Normal file
118
unittests/cfdp/pdu/testEofPdu.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/pdu/EofPduDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/EofPduSerializer.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
|
||||
TEST_CASE("EOF PDU", "[cfdp][pdu]") {
|
||||
using namespace cfdp;
|
||||
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 128> buf = {};
|
||||
uint8_t* bufPtr = buf.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
EntityIdTlv faultLoc(destId);
|
||||
FileSize fileSize(12);
|
||||
// We can already set the fault location, it will be ignored
|
||||
EofInfo eofInfo(cfdp::ConditionCode::NO_ERROR, 5, fileSize, &faultLoc);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
|
||||
PduConfig pduConf(sourceId, destId, TransmissionModes::ACKNOWLEDGED, seqNum);
|
||||
|
||||
auto eofSerializer = EofPduSerializer(pduConf, eofInfo);
|
||||
SECTION("Serialize") {
|
||||
result = eofSerializer.serialize(&bufPtr, &sz, buf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(((buf[1] << 8) | buf[2]) == 10);
|
||||
uint32_t checksum = 0;
|
||||
result = SerializeAdapter::deSerialize(&checksum, buf.data() + sz - 8, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(checksum == 5);
|
||||
uint32_t fileSizeVal = 0;
|
||||
result = SerializeAdapter::deSerialize(&fileSizeVal, buf.data() + sz - 4, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(fileSizeVal == 12);
|
||||
REQUIRE(buf[sz - 10] == cfdp::FileDirectives::EOF_DIRECTIVE);
|
||||
REQUIRE(buf[sz - 9] == 0x00);
|
||||
REQUIRE(sz == 20);
|
||||
|
||||
eofInfo.setConditionCode(cfdp::ConditionCode::FILESTORE_REJECTION);
|
||||
eofInfo.setFileSize(0x10ffffff10, true);
|
||||
pduConf.largeFile = true;
|
||||
// Should serialize with fault location now
|
||||
auto serializeWithFaultLocation = EofPduSerializer(pduConf, eofInfo);
|
||||
bufPtr = buf.data();
|
||||
sz = 0;
|
||||
result = serializeWithFaultLocation.serialize(&bufPtr, &sz, buf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(sz == 28);
|
||||
REQUIRE(buf[10] == cfdp::FileDirectives::EOF_DIRECTIVE);
|
||||
REQUIRE(buf[11] >> 4 == cfdp::ConditionCode::FILESTORE_REJECTION);
|
||||
uint64_t fileSizeLarge = 0;
|
||||
result = SerializeAdapter::deSerialize(&fileSizeLarge, buf.data() + 16, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(fileSizeLarge == 0x10ffffff10);
|
||||
REQUIRE(buf[sz - 4] == cfdp::TlvTypes::ENTITY_ID);
|
||||
// width of entity ID is 2
|
||||
REQUIRE(buf[sz - 3] == 2);
|
||||
uint16_t entityIdRaw = 0;
|
||||
result = SerializeAdapter::deSerialize(&entityIdRaw, buf.data() + sz - 2, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(entityIdRaw == 2);
|
||||
bufPtr = buf.data();
|
||||
sz = 0;
|
||||
for (size_t idx = 0; idx < 27; idx++) {
|
||||
result =
|
||||
serializeWithFaultLocation.serialize(&bufPtr, &sz, idx, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
bufPtr = buf.data();
|
||||
sz = 0;
|
||||
}
|
||||
eofInfo.setChecksum(16);
|
||||
eofInfo.setFaultLoc(nullptr);
|
||||
}
|
||||
|
||||
SECTION("Deserialize") {
|
||||
result = eofSerializer.serialize(&bufPtr, &sz, buf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
EntityIdTlv tlv(destId);
|
||||
EofInfo emptyInfo(&tlv);
|
||||
auto deserializer = EofPduDeserializer(buf.data(), buf.size(), emptyInfo);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(emptyInfo.getConditionCode() == cfdp::ConditionCode::NO_ERROR);
|
||||
REQUIRE(emptyInfo.getChecksum() == 5);
|
||||
REQUIRE(emptyInfo.getFileSize().getSize() == 12);
|
||||
|
||||
eofInfo.setConditionCode(cfdp::ConditionCode::FILESTORE_REJECTION);
|
||||
eofInfo.setFileSize(0x10ffffff10, true);
|
||||
pduConf.largeFile = true;
|
||||
// Should serialize with fault location now
|
||||
auto serializeWithFaultLocation = EofPduSerializer(pduConf, eofInfo);
|
||||
bufPtr = buf.data();
|
||||
sz = 0;
|
||||
result = serializeWithFaultLocation.serialize(&bufPtr, &sz, buf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
auto deserializer2 = EofPduDeserializer(buf.data(), buf.size(), emptyInfo);
|
||||
result = deserializer2.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(emptyInfo.getConditionCode() == cfdp::ConditionCode::FILESTORE_REJECTION);
|
||||
REQUIRE(emptyInfo.getChecksum() == 5);
|
||||
REQUIRE(emptyInfo.getFileSize().getSize() == 0x10ffffff10);
|
||||
REQUIRE(emptyInfo.getFaultLoc()->getType() == cfdp::TlvTypes::ENTITY_ID);
|
||||
REQUIRE(emptyInfo.getFaultLoc()->getSerializedSize() == 4);
|
||||
uint16_t destId = emptyInfo.getFaultLoc()->getEntityId().getValue();
|
||||
REQUIRE(destId == 2);
|
||||
for (size_t maxSz = 0; maxSz < deserializer2.getWholePduSize() - 1; maxSz++) {
|
||||
auto invalidDeser = EofPduDeserializer(buf.data(), maxSz, emptyInfo);
|
||||
result = invalidDeser.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
}
|
171
unittests/cfdp/pdu/testFileData.cpp
Normal file
171
unittests/cfdp/pdu/testFileData.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/pdu/FileDataCreator.h"
|
||||
#include "fsfw/cfdp/pdu/FileDataReader.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
TEST_CASE("File Data PDU", "[cfdp][pdu]") {
|
||||
using namespace cfdp;
|
||||
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 128> fileBuffer = {};
|
||||
std::array<uint8_t, 256> fileDataBuffer = {};
|
||||
uint8_t* buffer = fileDataBuffer.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(sourceId, destId, TransmissionModes::ACKNOWLEDGED, seqNum);
|
||||
|
||||
for (uint8_t idx = 0; idx < 10; idx++) {
|
||||
fileBuffer[idx] = idx;
|
||||
}
|
||||
FileSize offset(50);
|
||||
FileDataInfo info(offset, fileBuffer.data(), 10);
|
||||
|
||||
SECTION("Serialization") {
|
||||
FileDataCreator serializer(pduConf, info);
|
||||
result =
|
||||
serializer.serialize(&buffer, &sz, fileDataBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(sz == 24);
|
||||
// 10 file bytes plus 4 byte offset
|
||||
REQUIRE(((fileDataBuffer[1] << 8) | fileDataBuffer[2]) == 14);
|
||||
// File Data -> Fourth bit is one
|
||||
REQUIRE(fileDataBuffer[0] == 0b00110000);
|
||||
uint32_t offsetRaw = 0;
|
||||
buffer = fileDataBuffer.data();
|
||||
result = SerializeAdapter::deSerialize(&offsetRaw, buffer + 10, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(offsetRaw == 50);
|
||||
buffer = fileDataBuffer.data() + 14;
|
||||
for (size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(buffer[idx] == idx);
|
||||
}
|
||||
|
||||
REQUIRE(info.hasSegmentMetadata() == false);
|
||||
info.addSegmentMetadataInfo(cfdp::RecordContinuationState::CONTAINS_START_AND_END,
|
||||
fileBuffer.data(), 10);
|
||||
REQUIRE(info.hasSegmentMetadata() == true);
|
||||
REQUIRE(info.getSegmentationControl() ==
|
||||
cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION);
|
||||
info.setSegmentationControl(cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION);
|
||||
serializer.update();
|
||||
REQUIRE(serializer.getSegmentationControl() ==
|
||||
cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION);
|
||||
buffer = fileDataBuffer.data();
|
||||
sz = 0;
|
||||
serializer.setSegmentationControl(cfdp::SegmentationControl::RECORD_BOUNDARIES_PRESERVATION);
|
||||
|
||||
result =
|
||||
serializer.serialize(&buffer, &sz, fileDataBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(((fileDataBuffer[1] << 8) | fileDataBuffer[2]) == 25);
|
||||
// First bit: Seg Ctrl is set
|
||||
// Bits 1 to 3 length of enitity IDs is 2
|
||||
// Bit 4: Segment metadata flag is set
|
||||
// Bit 5 to seven: length of transaction seq num is 2
|
||||
REQUIRE(fileDataBuffer[3] == 0b10101010);
|
||||
REQUIRE((fileDataBuffer[10] >> 6) &
|
||||
0b11 == cfdp::RecordContinuationState::CONTAINS_START_AND_END);
|
||||
// Segment metadata length
|
||||
REQUIRE((fileDataBuffer[10] & 0x3f) == 10);
|
||||
buffer = fileDataBuffer.data() + 11;
|
||||
// Check segment metadata
|
||||
for (size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(buffer[idx] == idx);
|
||||
}
|
||||
// Check filedata
|
||||
buffer = fileDataBuffer.data() + 25;
|
||||
for (size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(buffer[idx] == idx);
|
||||
}
|
||||
|
||||
for (size_t invalidStartSz = 1; invalidStartSz < sz; invalidStartSz++) {
|
||||
buffer = fileDataBuffer.data();
|
||||
sz = 0;
|
||||
result = serializer.serialize(&buffer, &invalidStartSz, sz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
|
||||
info.setSegmentMetadataFlag(true);
|
||||
REQUIRE(info.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::PRESENT);
|
||||
info.setSegmentMetadataFlag(false);
|
||||
REQUIRE(info.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::NOT_PRESENT);
|
||||
info.setRecordContinuationState(cfdp::RecordContinuationState::CONTAINS_END_NO_START);
|
||||
info.setSegmentMetadataLen(10);
|
||||
info.setSegmentMetadata(nullptr);
|
||||
info.setFileData(nullptr, 0);
|
||||
}
|
||||
|
||||
SECTION("Deserialization") {
|
||||
FileDataCreator serializer(pduConf, info);
|
||||
result =
|
||||
serializer.serialize(&buffer, &sz, fileDataBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
FileSize emptyOffset;
|
||||
FileDataInfo emptyInfo(emptyOffset);
|
||||
FileDataReader deserializer(fileDataBuffer.data(), fileDataBuffer.size(), emptyInfo);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserializer.getWholePduSize() == 24);
|
||||
REQUIRE(deserializer.getPduDataFieldLen() == 14);
|
||||
REQUIRE(deserializer.getSegmentationControl() ==
|
||||
cfdp::SegmentationControl::NO_RECORD_BOUNDARIES_PRESERVATION);
|
||||
REQUIRE(deserializer.getSegmentMetadataFlag() == cfdp::SegmentMetadataFlag::NOT_PRESENT);
|
||||
|
||||
REQUIRE(emptyInfo.getOffset().getSize() == 50);
|
||||
REQUIRE(emptyInfo.hasSegmentMetadata() == false);
|
||||
size_t emptyFileSize = 0;
|
||||
const uint8_t* fileData = emptyInfo.getFileData(&emptyFileSize);
|
||||
REQUIRE(emptyFileSize == 10);
|
||||
for (size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(fileData[idx] == idx);
|
||||
}
|
||||
|
||||
deserializer.setEndianness(SerializeIF::Endianness::NETWORK);
|
||||
|
||||
info.addSegmentMetadataInfo(cfdp::RecordContinuationState::CONTAINS_START_AND_END,
|
||||
fileBuffer.data(), 10);
|
||||
serializer.update();
|
||||
buffer = fileDataBuffer.data();
|
||||
sz = 0;
|
||||
result =
|
||||
serializer.serialize(&buffer, &sz, fileDataBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
REQUIRE(emptyInfo.getOffset().getSize() == 50);
|
||||
REQUIRE(emptyInfo.hasSegmentMetadata() == true);
|
||||
REQUIRE(emptyInfo.getRecordContinuationState() ==
|
||||
cfdp::RecordContinuationState::CONTAINS_START_AND_END);
|
||||
emptyFileSize = 0;
|
||||
fileData = emptyInfo.getFileData(&emptyFileSize);
|
||||
REQUIRE(emptyFileSize == 10);
|
||||
for (size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(fileData[idx] == idx);
|
||||
}
|
||||
size_t segmentMetadataLen = 0;
|
||||
fileData = emptyInfo.getSegmentMetadata(&segmentMetadataLen);
|
||||
REQUIRE(segmentMetadataLen == 10);
|
||||
for (size_t idx = 0; idx < 10; idx++) {
|
||||
REQUIRE(fileData[idx] == idx);
|
||||
}
|
||||
for (size_t invalidPduField = 0; invalidPduField < 24; invalidPduField++) {
|
||||
fileDataBuffer[1] = (invalidPduField >> 8) & 0xff;
|
||||
fileDataBuffer[2] = invalidPduField & 0xff;
|
||||
result = deserializer.parseData();
|
||||
// Starting at 15, the file data is parsed. There is not leading file data length
|
||||
// field to the parser can't check whether the remaining length is valid
|
||||
if (invalidPduField < 15) {
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
85
unittests/cfdp/pdu/testFileDirective.cpp
Normal file
85
unittests/cfdp/pdu/testFileDirective.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveCreator.h"
|
||||
#include "fsfw/cfdp/pdu/FileDirectiveReader.h"
|
||||
|
||||
TEST_CASE("CFDP File Directive", "[cfdp]") {
|
||||
using namespace cfdp;
|
||||
std::array<uint8_t, 32> serBuf{};
|
||||
ReturnValue_t result;
|
||||
cfdp::TransactionSeqNum seqNum = TransactionSeqNum(cfdp::WidthInBytes::ONE_BYTE, 2);
|
||||
cfdp::EntityId sourceId = EntityId(cfdp::WidthInBytes::ONE_BYTE, 0);
|
||||
cfdp::EntityId destId = EntityId(cfdp::WidthInBytes::ONE_BYTE, 1);
|
||||
PduConfig pduConf =
|
||||
PduConfig(sourceId, destId, cfdp::TransmissionModes::ACKNOWLEDGED, seqNum, false);
|
||||
uint8_t* serTarget = serBuf.data();
|
||||
const uint8_t* deserTarget = serTarget;
|
||||
size_t serSize = 0;
|
||||
auto fdSer = FileDirectiveCreator(pduConf, FileDirectives::ACK, 4);
|
||||
|
||||
SECTION("Serialization") {
|
||||
REQUIRE(fdSer.getSerializedSize() == 8);
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
result = fdSer.serialize(&serTarget, &serSize, serBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
// Only version bits are set
|
||||
REQUIRE(serBuf[0] == 0b00100000);
|
||||
// PDU data field length is 5 (4 + Directive code octet)
|
||||
REQUIRE(serBuf[1] == 0);
|
||||
REQUIRE(serBuf[2] == 5);
|
||||
// Entity and Transaction Sequence number are 1 byte large
|
||||
REQUIRE(serBuf[3] == 0b00010001);
|
||||
// Source ID
|
||||
REQUIRE(serBuf[4] == 0);
|
||||
// Transaction Seq Number
|
||||
REQUIRE(serBuf[5] == 2);
|
||||
// Dest ID
|
||||
REQUIRE(serBuf[6] == 1);
|
||||
REQUIRE(serBuf[7] == FileDirectives::ACK);
|
||||
}
|
||||
|
||||
SECTION("Serialization fails") {
|
||||
REQUIRE(fdSer.serialize(nullptr, nullptr, 85, SerializeIF::Endianness::NETWORK) ==
|
||||
HasReturnvaluesIF::RETURN_FAILED);
|
||||
}
|
||||
|
||||
SECTION("Buffer Too Short") {
|
||||
for (uint8_t idx = 0; idx < 8; idx++) {
|
||||
serTarget = serBuf.data();
|
||||
serSize = 0;
|
||||
REQUIRE(fdSer.serialize(&serTarget, &serSize, idx, SerializeIF::Endianness::NETWORK) ==
|
||||
SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Deserialize") {
|
||||
CHECK(fdSer.serialize(&serTarget, &serSize, serBuf.size(), SerializeIF::Endianness::NETWORK) ==
|
||||
result::OK);
|
||||
serTarget = serBuf.data();
|
||||
|
||||
REQUIRE(fdSer.deSerialize(&deserTarget, &serSize, SerializeIF::Endianness::NETWORK) ==
|
||||
HasReturnvaluesIF::RETURN_FAILED);
|
||||
deserTarget = serBuf.data();
|
||||
CHECK(serSize == 8);
|
||||
auto fdDeser = FileDirectiveReader(deserTarget, serBuf.size());
|
||||
REQUIRE(fdDeser.isNull());
|
||||
REQUIRE(not fdDeser);
|
||||
REQUIRE(fdDeser.getEndianness() == SerializeIF::Endianness::NETWORK);
|
||||
fdDeser.setEndianness(SerializeIF::Endianness::MACHINE);
|
||||
REQUIRE(fdDeser.getEndianness() == SerializeIF::Endianness::MACHINE);
|
||||
fdDeser.setEndianness(SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(fdDeser.parseData() == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(not fdDeser.isNull());
|
||||
REQUIRE(fdDeser);
|
||||
REQUIRE(fdDeser.getFileDirective() == FileDirectives::ACK);
|
||||
REQUIRE(fdDeser.getPduDataFieldLen() == 5);
|
||||
REQUIRE(fdDeser.getHeaderSize() == 8);
|
||||
REQUIRE(fdDeser.getPduType() == cfdp::PduType::FILE_DIRECTIVE);
|
||||
|
||||
serBuf[7] = 0xff;
|
||||
// Invalid file directive
|
||||
REQUIRE(fdDeser.parseData() == cfdp::INVALID_DIRECTIVE_FIELDS);
|
||||
}
|
||||
}
|
189
unittests/cfdp/pdu/testFinishedPdu.cpp
Normal file
189
unittests/cfdp/pdu/testFinishedPdu.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/pdu/FinishedPduDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/FinishedPduSerializer.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
|
||||
TEST_CASE("Finished PDU", "[cfdp][pdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> fnBuffer = {};
|
||||
uint8_t* buffer = fnBuffer.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(sourceId, destId, TransmissionModes::ACKNOWLEDGED, seqNum);
|
||||
|
||||
cfdp::Lv emptyFsMsg;
|
||||
FinishedInfo info(cfdp::ConditionCode::INACTIVITY_DETECTED,
|
||||
cfdp::FinishedDeliveryCode::DATA_INCOMPLETE,
|
||||
cfdp::FinishedFileStatus::DISCARDED_DELIBERATELY);
|
||||
|
||||
SECTION("Serialize") {
|
||||
FinishPduSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getSerializedSize() == 12);
|
||||
REQUIRE(((fnBuffer[1] << 8) | fnBuffer[2]) == 2);
|
||||
REQUIRE(fnBuffer[10] == cfdp::FileDirectives::FINISH);
|
||||
REQUIRE(((fnBuffer[sz - 1] >> 4) & 0x0f) == cfdp::ConditionCode::INACTIVITY_DETECTED);
|
||||
REQUIRE(((fnBuffer[sz - 1] >> 2) & 0x01) == cfdp::FinishedDeliveryCode::DATA_INCOMPLETE);
|
||||
REQUIRE((fnBuffer[sz - 1] & 0b11) == cfdp::FinishedFileStatus::DISCARDED_DELIBERATELY);
|
||||
REQUIRE(sz == 12);
|
||||
|
||||
// Add a filestore response
|
||||
std::string firstName = "hello.txt";
|
||||
cfdp::Lv firstNameLv(reinterpret_cast<const uint8_t*>(firstName.data()), firstName.size());
|
||||
FilestoreResponseTlv response(cfdp::FilestoreActionCode::DELETE_FILE,
|
||||
cfdp::FSR_APPEND_FILE_1_NOT_EXISTS, firstNameLv, nullptr);
|
||||
FilestoreResponseTlv* responsePtr = &response;
|
||||
REQUIRE(response.getSerializedSize() == 14);
|
||||
size_t len = 1;
|
||||
info.setFilestoreResponsesArray(&responsePtr, &len, &len);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
REQUIRE(serializer.getSerializedSize() == 12 + 14);
|
||||
sz = 0;
|
||||
buffer = fnBuffer.data();
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getSerializedSize() == 12 + 14);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 16);
|
||||
|
||||
// Add two filestore responses and a fault location parameter
|
||||
std::string secondName = "hello2.txt";
|
||||
cfdp::Lv secondNameLv(reinterpret_cast<const uint8_t*>(secondName.data()), secondName.size());
|
||||
FilestoreResponseTlv response2(cfdp::FilestoreActionCode::DENY_FILE, cfdp::FSR_SUCCESS,
|
||||
secondNameLv, nullptr);
|
||||
REQUIRE(response2.getSerializedSize() == 15);
|
||||
len = 2;
|
||||
std::array<FilestoreResponseTlv*, 2> responses{&response, &response2};
|
||||
info.setFilestoreResponsesArray(responses.data(), &len, &len);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
|
||||
EntityIdTlv faultLoc(destId);
|
||||
REQUIRE(faultLoc.getSerializedSize() == 4);
|
||||
info.setFaultLocation(&faultLoc);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
sz = 0;
|
||||
buffer = fnBuffer.data();
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
info.setConditionCode(cfdp::ConditionCode::FILESTORE_REJECTION);
|
||||
REQUIRE(serializer.getSerializedSize() == 12 + 14 + 15 + 4);
|
||||
REQUIRE(sz == 12 + 14 + 15 + 4);
|
||||
info.setFileStatus(cfdp::FinishedFileStatus::DISCARDED_FILESTORE_REJECTION);
|
||||
REQUIRE(info.getFileStatus() == cfdp::FinishedFileStatus::DISCARDED_FILESTORE_REJECTION);
|
||||
info.setDeliveryCode(cfdp::FinishedDeliveryCode::DATA_INCOMPLETE);
|
||||
REQUIRE(info.getDeliveryCode() == cfdp::FinishedDeliveryCode::DATA_INCOMPLETE);
|
||||
for (size_t maxSz = 0; maxSz < 45; maxSz++) {
|
||||
sz = 0;
|
||||
buffer = fnBuffer.data();
|
||||
result = serializer.serialize(&buffer, &sz, maxSz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Deserialize") {
|
||||
FinishedInfo emptyInfo;
|
||||
FinishPduSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
FinishPduDeserializer deserializer(fnBuffer.data(), fnBuffer.size(), emptyInfo);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(emptyInfo.getFileStatus() == cfdp::FinishedFileStatus::DISCARDED_DELIBERATELY);
|
||||
REQUIRE(emptyInfo.getConditionCode() == cfdp::ConditionCode::INACTIVITY_DETECTED);
|
||||
REQUIRE(emptyInfo.getDeliveryCode() == cfdp::FinishedDeliveryCode::DATA_INCOMPLETE);
|
||||
|
||||
// Add a filestore response
|
||||
sz = 0;
|
||||
buffer = fnBuffer.data();
|
||||
std::string firstName = "hello.txt";
|
||||
cfdp::Lv firstNameLv(reinterpret_cast<const uint8_t*>(firstName.data()), firstName.size());
|
||||
FilestoreResponseTlv response(cfdp::FilestoreActionCode::DELETE_FILE, cfdp::FSR_NOT_PERFORMED,
|
||||
firstNameLv, nullptr);
|
||||
FilestoreResponseTlv* responsePtr = &response;
|
||||
size_t len = 1;
|
||||
info.setFilestoreResponsesArray(&responsePtr, &len, &len);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 16);
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
FilestoreResponseTlv emptyResponse(firstNameLv, nullptr);
|
||||
responsePtr = &emptyResponse;
|
||||
emptyInfo.setFilestoreResponsesArray(&responsePtr, nullptr, &len);
|
||||
FinishPduDeserializer deserializer2(fnBuffer.data(), fnBuffer.size(), emptyInfo);
|
||||
result = deserializer2.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(emptyInfo.getFsResponsesLen() == 1);
|
||||
FilestoreResponseTlv** responseArray = nullptr;
|
||||
emptyInfo.getFilestoreResonses(&responseArray, nullptr, nullptr);
|
||||
REQUIRE(responseArray[0]->getActionCode() == cfdp::FilestoreActionCode::DELETE_FILE);
|
||||
REQUIRE(responseArray[0]->getStatusCode() == cfdp::FSR_NOT_PERFORMED);
|
||||
auto& fileNameRef = responseArray[0]->getFirstFileName();
|
||||
size_t stringSize = 0;
|
||||
const char* string = reinterpret_cast<const char*>(fileNameRef.getValue(&stringSize));
|
||||
std::string firstFileName(string, stringSize);
|
||||
REQUIRE(firstFileName == "hello.txt");
|
||||
|
||||
// Add two filestore responses and a fault location parameter
|
||||
std::string secondName = "hello2.txt";
|
||||
cfdp::Lv secondNameLv(reinterpret_cast<const uint8_t*>(secondName.data()), secondName.size());
|
||||
FilestoreResponseTlv response2(cfdp::FilestoreActionCode::DENY_FILE, cfdp::FSR_SUCCESS,
|
||||
secondNameLv, nullptr);
|
||||
REQUIRE(response2.getSerializedSize() == 15);
|
||||
len = 2;
|
||||
std::array<FilestoreResponseTlv*, 2> responses{&response, &response2};
|
||||
info.setFilestoreResponsesArray(responses.data(), &len, &len);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
|
||||
EntityIdTlv faultLoc(destId);
|
||||
info.setFaultLocation(&faultLoc);
|
||||
serializer.updateDirectiveFieldLen();
|
||||
sz = 0;
|
||||
buffer = fnBuffer.data();
|
||||
result = serializer.serialize(&buffer, &sz, fnBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
EntityId emptyId;
|
||||
EntityIdTlv emptyFaultLoc(emptyId);
|
||||
emptyInfo.setFaultLocation(&emptyFaultLoc);
|
||||
response.setFilestoreMessage(&emptyFsMsg);
|
||||
emptyInfo.setFilestoreResponsesArray(responses.data(), &len, &len);
|
||||
response2.setFilestoreMessage(&emptyFsMsg);
|
||||
FinishPduDeserializer deserializer3(fnBuffer.data(), fnBuffer.size(), emptyInfo);
|
||||
result = deserializer3.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
auto& infoRef = deserializer3.getInfo();
|
||||
REQUIRE(deserializer3.getWholePduSize() == 45);
|
||||
|
||||
size_t invalidMaxLen = 1;
|
||||
emptyInfo.setFilestoreResponsesArray(responses.data(), &len, &invalidMaxLen);
|
||||
result = deserializer3.parseData();
|
||||
REQUIRE(result == cfdp::FINISHED_CANT_PARSE_FS_RESPONSES);
|
||||
emptyInfo.setFilestoreResponsesArray(nullptr, nullptr, nullptr);
|
||||
result = deserializer3.parseData();
|
||||
REQUIRE(result == cfdp::FINISHED_CANT_PARSE_FS_RESPONSES);
|
||||
|
||||
// Clear condition code
|
||||
auto tmp = fnBuffer[11];
|
||||
fnBuffer[11] = fnBuffer[11] & ~0xf0;
|
||||
fnBuffer[11] = fnBuffer[11] | (cfdp::ConditionCode::NO_ERROR << 4);
|
||||
emptyInfo.setFilestoreResponsesArray(responses.data(), &len, &len);
|
||||
result = deserializer3.parseData();
|
||||
REQUIRE(result == cfdp::INVALID_TLV_TYPE);
|
||||
|
||||
fnBuffer[11] = tmp;
|
||||
// Invalid TLV type, should be entity ID
|
||||
fnBuffer[sz - 4] = cfdp::TlvTypes::FILESTORE_REQUEST;
|
||||
result = deserializer3.parseData();
|
||||
REQUIRE(result == cfdp::INVALID_TLV_TYPE);
|
||||
|
||||
for (size_t maxSz = 0; maxSz < 45; maxSz++) {
|
||||
FinishPduDeserializer faultyDeser(fnBuffer.data(), maxSz, emptyInfo);
|
||||
result = faultyDeser.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
}
|
81
unittests/cfdp/pdu/testKeepAlivePdu.cpp
Normal file
81
unittests/cfdp/pdu/testKeepAlivePdu.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/pdu/KeepAlivePduDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/KeepAlivePduSerializer.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
|
||||
TEST_CASE("Keep Alive PDU", "[cfdp][pdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> kaBuffer = {};
|
||||
uint8_t* buffer = kaBuffer.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(sourceId, destId, TransmissionModes::ACKNOWLEDGED, seqNum);
|
||||
|
||||
FileSize progress(0x50);
|
||||
|
||||
SECTION("Serialize") {
|
||||
KeepAlivePduSerializer serializer(pduConf, progress);
|
||||
result = serializer.serialize(&buffer, &sz, kaBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(kaBuffer[10] == cfdp::FileDirectives::KEEP_ALIVE);
|
||||
uint32_t fsRaw = 0;
|
||||
result = SerializeAdapter::deSerialize(&fsRaw, kaBuffer.data() + 11, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(fsRaw == 0x50);
|
||||
REQUIRE(sz == 15);
|
||||
REQUIRE(serializer.getWholePduSize() == 15);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 5);
|
||||
|
||||
pduConf.largeFile = true;
|
||||
serializer.updateDirectiveFieldLen();
|
||||
buffer = kaBuffer.data();
|
||||
sz = 0;
|
||||
result = serializer.serialize(&buffer, &sz, kaBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getWholePduSize() == 19);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 9);
|
||||
uint64_t fsRawLarge = 0;
|
||||
result = SerializeAdapter::deSerialize(&fsRawLarge, kaBuffer.data() + 11, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(fsRawLarge == 0x50);
|
||||
|
||||
for (size_t invalidMaxSz = 0; invalidMaxSz < sz; invalidMaxSz++) {
|
||||
buffer = kaBuffer.data();
|
||||
sz = 0;
|
||||
result = serializer.serialize(&buffer, &sz, invalidMaxSz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Deserialize") {
|
||||
KeepAlivePduSerializer serializer(pduConf, progress);
|
||||
result = serializer.serialize(&buffer, &sz, kaBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
// Set another file size
|
||||
progress.setFileSize(200, false);
|
||||
KeepAlivePduDeserializer deserializer(kaBuffer.data(), kaBuffer.size(), progress);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
auto& progRef = deserializer.getProgress();
|
||||
// Should have been overwritten
|
||||
REQUIRE(progRef.getSize() == 0x50);
|
||||
sz = deserializer.getWholePduSize();
|
||||
|
||||
// invalid max size
|
||||
for (size_t invalidMaxSz = 0; invalidMaxSz < sz; invalidMaxSz++) {
|
||||
ReturnValue_t setResult = deserializer.setData(kaBuffer.data(), invalidMaxSz);
|
||||
if (setResult == HasReturnvaluesIF::RETURN_OK) {
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
181
unittests/cfdp/pdu/testMetadataPdu.cpp
Normal file
181
unittests/cfdp/pdu/testMetadataPdu.cpp
Normal file
@ -0,0 +1,181 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#include "fsfw/cfdp/pdu/MetadataPduCreator.h"
|
||||
#include "fsfw/cfdp/pdu/MetadataPduReader.h"
|
||||
#include "fsfw/cfdp/tlv/FilestoreResponseTlv.h"
|
||||
#include "fsfw/cfdp/tlv/MessageToUserTlv.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
|
||||
TEST_CASE("Metadata PDU", "[cfdp][pdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> mdBuffer = {};
|
||||
uint8_t* buffer = mdBuffer.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(sourceId, destId, TransmissionModes::ACKNOWLEDGED, seqNum);
|
||||
|
||||
std::string firstFileName = "hello.txt";
|
||||
cfdp::Lv sourceFileName(reinterpret_cast<const uint8_t*>(firstFileName.data()),
|
||||
firstFileName.size());
|
||||
cfdp::Lv destFileName;
|
||||
FileSize fileSize(35);
|
||||
MetadataInfo info(false, ChecksumType::MODULAR, fileSize, sourceFileName, destFileName);
|
||||
|
||||
FilestoreResponseTlv response(FilestoreActionCode::CREATE_DIRECTORY, FSR_CREATE_NOT_ALLOWED,
|
||||
sourceFileName, nullptr);
|
||||
std::array<uint8_t, 3> msg = {0x41, 0x42, 0x43};
|
||||
cfdp::Tlv responseTlv;
|
||||
std::array<uint8_t, 64> responseBuf = {};
|
||||
uint8_t* responseBufPtr = responseBuf.data();
|
||||
response.convertToTlv(responseTlv, buffer, responseBuf.size(), SerializeIF::Endianness::MACHINE);
|
||||
MessageToUserTlv msgToUser(msg.data(), msg.size());
|
||||
std::array<Tlv*, 2> options{&responseTlv, &msgToUser};
|
||||
REQUIRE(options[0]->getSerializedSize() == 2 + 1 + 10 + 1);
|
||||
REQUIRE(options[1]->getSerializedSize() == 5);
|
||||
|
||||
SECTION("Serialize") {
|
||||
MetadataPduCreator serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getWholePduSize() == 27);
|
||||
REQUIRE(info.getSourceFileName().getSerializedSize() == 10);
|
||||
REQUIRE(info.getDestFileName().getSerializedSize() == 1);
|
||||
REQUIRE(info.getSerializedSize() == 16);
|
||||
REQUIRE((mdBuffer[1] << 8 | mdBuffer[2]) == 17);
|
||||
REQUIRE(mdBuffer[10] == FileDirectives::METADATA);
|
||||
// no closure requested and checksum type is modular => 0x00
|
||||
REQUIRE(mdBuffer[11] == 0x00);
|
||||
uint32_t fileSizeRaw = 0;
|
||||
result = SerializeAdapter::deSerialize(&fileSizeRaw, mdBuffer.data() + 12, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(fileSizeRaw == 35);
|
||||
REQUIRE(mdBuffer[16] == 9);
|
||||
REQUIRE(mdBuffer[17] == 'h');
|
||||
REQUIRE(mdBuffer[18] == 'e');
|
||||
REQUIRE(mdBuffer[19] == 'l');
|
||||
REQUIRE(mdBuffer[20] == 'l');
|
||||
REQUIRE(mdBuffer[21] == 'o');
|
||||
REQUIRE(mdBuffer[22] == '.');
|
||||
REQUIRE(mdBuffer[23] == 't');
|
||||
REQUIRE(mdBuffer[24] == 'x');
|
||||
REQUIRE(mdBuffer[25] == 't');
|
||||
REQUIRE(mdBuffer[26] == 0);
|
||||
|
||||
std::string otherFileName = "hello2.txt";
|
||||
cfdp::Lv otherFileNameLv(reinterpret_cast<const uint8_t*>(otherFileName.data()),
|
||||
otherFileName.size());
|
||||
info.setSourceFileName(otherFileNameLv);
|
||||
size_t sizeOfOptions = options.size();
|
||||
info.setOptionsArray(options.data(), &sizeOfOptions, &sizeOfOptions);
|
||||
REQUIRE(info.getMaxOptionsLen() == 2);
|
||||
info.setMaxOptionsLen(3);
|
||||
REQUIRE(info.getMaxOptionsLen() == 3);
|
||||
info.setChecksumType(cfdp::ChecksumType::CRC_32C);
|
||||
info.setClosureRequested(true);
|
||||
uint8_t* buffer = mdBuffer.data();
|
||||
size_t sz = 0;
|
||||
serializer.updateDirectiveFieldLen();
|
||||
|
||||
result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE((mdBuffer[1] << 8 | mdBuffer[2]) == 37);
|
||||
auto checksumType = static_cast<cfdp::ChecksumType>(mdBuffer[11] & 0x0f);
|
||||
REQUIRE(checksumType == cfdp::ChecksumType::CRC_32C);
|
||||
bool closureRequested = mdBuffer[11] >> 6 & 0x01;
|
||||
REQUIRE(closureRequested == true);
|
||||
// The size of the two options is 19. Summing up:
|
||||
// - 11 bytes of source file name
|
||||
// - 1 byte for dest file name
|
||||
// - 4 for FSS
|
||||
// - 1 leading byte.
|
||||
// - 1 byte for PDU type
|
||||
// PDU header has 10 bytes.
|
||||
// I am not going to check the options raw content, those are part of the dedicated
|
||||
// TLV unittests
|
||||
REQUIRE(sz == 10 + 37);
|
||||
for (size_t maxSz = 0; maxSz < sz; maxSz++) {
|
||||
uint8_t* buffer = mdBuffer.data();
|
||||
size_t sz = 0;
|
||||
result = serializer.serialize(&buffer, &sz, maxSz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
for (size_t initSz = 1; initSz < 47; initSz++) {
|
||||
uint8_t* buffer = mdBuffer.data();
|
||||
size_t sz = initSz;
|
||||
result = serializer.serialize(&buffer, &sz, 46, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
info.setDestFileName(destFileName);
|
||||
}
|
||||
|
||||
SECTION("Deserialize") {
|
||||
MetadataPduCreator serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
MetadataPduReader deserializer(mdBuffer.data(), mdBuffer.size(), info);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
size_t fullSize = deserializer.getWholePduSize();
|
||||
for (size_t maxSz = 0; maxSz < fullSize; maxSz++) {
|
||||
MetadataPduReader invalidSzDeser(mdBuffer.data(), maxSz, info);
|
||||
result = invalidSzDeser.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
size_t sizeOfOptions = options.size();
|
||||
size_t maxSize = 4;
|
||||
info.setOptionsArray(options.data(), &sizeOfOptions, &maxSize);
|
||||
REQUIRE(info.getOptionsLen() == 2);
|
||||
info.setChecksumType(cfdp::ChecksumType::CRC_32C);
|
||||
info.setClosureRequested(true);
|
||||
uint8_t* buffer = mdBuffer.data();
|
||||
size_t sz = 0;
|
||||
serializer.updateDirectiveFieldLen();
|
||||
|
||||
info.setSourceFileName(sourceFileName);
|
||||
result = serializer.serialize(&buffer, &sz, mdBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
MetadataPduReader deserializer2(mdBuffer.data(), mdBuffer.size(), info);
|
||||
result = deserializer2.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(options[0]->getType() == cfdp::TlvTypes::FILESTORE_RESPONSE);
|
||||
REQUIRE(options[0]->getSerializedSize() == 14);
|
||||
REQUIRE(options[1]->getType() == cfdp::TlvTypes::MSG_TO_USER);
|
||||
REQUIRE(options[1]->getSerializedSize() == 5);
|
||||
|
||||
for (size_t invalidFieldLen = 0; invalidFieldLen < 36; invalidFieldLen++) {
|
||||
mdBuffer[1] = (invalidFieldLen >> 8) & 0xff;
|
||||
mdBuffer[2] = invalidFieldLen & 0xff;
|
||||
result = deserializer2.parseData();
|
||||
if (invalidFieldLen == 17) {
|
||||
REQUIRE(info.getOptionsLen() == 0);
|
||||
}
|
||||
if (invalidFieldLen == 31) {
|
||||
REQUIRE(info.getOptionsLen() == 1);
|
||||
}
|
||||
// This is the precise length where there are no options or one option
|
||||
if (invalidFieldLen != 17 and invalidFieldLen != 31) {
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
mdBuffer[1] = (36 >> 8) & 0xff;
|
||||
mdBuffer[2] = 36 & 0xff;
|
||||
info.setOptionsArray(nullptr, nullptr, nullptr);
|
||||
REQUIRE(deserializer2.parseData() == cfdp::METADATA_CANT_PARSE_OPTIONS);
|
||||
info.setOptionsArray(options.data(), &sizeOfOptions, nullptr);
|
||||
for (size_t maxSz = 0; maxSz < 46; maxSz++) {
|
||||
MetadataPduReader invalidSzDeser(mdBuffer.data(), maxSz, info);
|
||||
if (not invalidSzDeser.isNull()) {
|
||||
result = invalidSzDeser.parseData();
|
||||
REQUIRE(result == SerializeIF::STREAM_TOO_SHORT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
152
unittests/cfdp/pdu/testNakPdu.cpp
Normal file
152
unittests/cfdp/pdu/testNakPdu.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/pdu/NakPduDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/NakPduSerializer.h"
|
||||
#include "fsfw/cfdp/pdu/PduConfig.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
|
||||
TEST_CASE("NAK PDU", "[cfdp][pdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> nakBuffer = {};
|
||||
uint8_t* buffer = nakBuffer.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(sourceId, destId, TransmissionModes::ACKNOWLEDGED, seqNum);
|
||||
|
||||
FileSize startOfScope(50);
|
||||
FileSize endOfScope(1050);
|
||||
NakInfo info(startOfScope, endOfScope);
|
||||
SECTION("Serializer") {
|
||||
NakPduSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, nakBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getSerializedSize() == 19);
|
||||
REQUIRE(serializer.FileDirectiveCreator::getSerializedSize() == 11);
|
||||
REQUIRE(sz == 19);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 9);
|
||||
REQUIRE(((nakBuffer[1] << 8) | nakBuffer[2]) == 0x09);
|
||||
REQUIRE(nakBuffer[10] == cfdp::FileDirectives::NAK);
|
||||
uint32_t scope = 0;
|
||||
result = SerializeAdapter::deSerialize(&scope, nakBuffer.data() + 11, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(scope == 50);
|
||||
result = SerializeAdapter::deSerialize(&scope, nakBuffer.data() + 15, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(scope == 1050);
|
||||
|
||||
NakInfo::SegmentRequest segReq0(cfdp::FileSize(2020), cfdp::FileSize(2520));
|
||||
NakInfo::SegmentRequest segReq1(cfdp::FileSize(2932), cfdp::FileSize(3021));
|
||||
// Now add 2 segment requests to NAK info and serialize them as well
|
||||
std::array<NakInfo::SegmentRequest, 2> segReqs = {segReq0, segReq1};
|
||||
size_t segReqsLen = segReqs.size();
|
||||
info.setSegmentRequests(segReqs.data(), &segReqsLen, &segReqsLen);
|
||||
uint8_t* buffer = nakBuffer.data();
|
||||
size_t sz = 0;
|
||||
serializer.updateDirectiveFieldLen();
|
||||
result = serializer.serialize(&buffer, &sz, nakBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getSerializedSize() == 35);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 25);
|
||||
REQUIRE(((nakBuffer[1] << 8) | nakBuffer[2]) == 25);
|
||||
uint32_t segReqScopes = 0;
|
||||
result = SerializeAdapter::deSerialize(&segReqScopes, nakBuffer.data() + 19, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(segReqScopes == 2020);
|
||||
result = SerializeAdapter::deSerialize(&segReqScopes, nakBuffer.data() + 23, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(segReqScopes == 2520);
|
||||
result = SerializeAdapter::deSerialize(&segReqScopes, nakBuffer.data() + 27, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(segReqScopes == 2932);
|
||||
result = SerializeAdapter::deSerialize(&segReqScopes, nakBuffer.data() + 31, nullptr,
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(segReqScopes == 3021);
|
||||
|
||||
for (size_t maxSz = 0; maxSz < 35; maxSz++) {
|
||||
uint8_t* buffer = nakBuffer.data();
|
||||
size_t sz = 0;
|
||||
result = serializer.serialize(&buffer, &sz, maxSz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
for (size_t sz = 35; sz > 0; sz--) {
|
||||
uint8_t* buffer = nakBuffer.data();
|
||||
size_t locSize = sz;
|
||||
result = serializer.serialize(&buffer, &locSize, 35, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == SerializeIF::BUFFER_TOO_SHORT);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Deserializer") {
|
||||
NakPduSerializer serializer(pduConf, info);
|
||||
result = serializer.serialize(&buffer, &sz, nakBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
info.getStartOfScope().setFileSize(0, false);
|
||||
info.getEndOfScope().setFileSize(0, false);
|
||||
NakPduDeserializer deserializer(nakBuffer.data(), nakBuffer.size(), info);
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserializer.getWholePduSize() == 19);
|
||||
REQUIRE(info.getStartOfScope().getSize() == 50);
|
||||
REQUIRE(info.getEndOfScope().getSize() == 1050);
|
||||
|
||||
NakInfo::SegmentRequest segReq0(cfdp::FileSize(2020), cfdp::FileSize(2520));
|
||||
NakInfo::SegmentRequest segReq1(cfdp::FileSize(2932), cfdp::FileSize(3021));
|
||||
// Now add 2 segment requests to NAK info and serialize them as well
|
||||
std::array<NakInfo::SegmentRequest, 2> segReqs = {segReq0, segReq1};
|
||||
size_t segReqsLen = segReqs.size();
|
||||
info.setSegmentRequests(segReqs.data(), &segReqsLen, &segReqsLen);
|
||||
uint8_t* buffer = nakBuffer.data();
|
||||
size_t sz = 0;
|
||||
serializer.updateDirectiveFieldLen();
|
||||
result = serializer.serialize(&buffer, &sz, nakBuffer.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
NakPduDeserializer deserializeWithSegReqs(nakBuffer.data(), nakBuffer.size(), info);
|
||||
result = deserializeWithSegReqs.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
NakInfo::SegmentRequest* segReqsPtr = nullptr;
|
||||
size_t readSegReqs = 0;
|
||||
info.getSegmentRequests(&segReqsPtr, &readSegReqs, nullptr);
|
||||
REQUIRE(readSegReqs == 2);
|
||||
REQUIRE(segReqsPtr[0].first.getSize() == 2020);
|
||||
REQUIRE(segReqsPtr[0].second.getSize() == 2520);
|
||||
REQUIRE(segReqsPtr[1].first.getSize() == 2932);
|
||||
REQUIRE(segReqsPtr[1].second.getSize() == 3021);
|
||||
REQUIRE(deserializeWithSegReqs.getPduDataFieldLen() == 25);
|
||||
REQUIRE(info.getSegmentRequestsLen() == 2);
|
||||
for (size_t idx = 0; idx < 34; idx++) {
|
||||
NakPduDeserializer faultyDeserializer(nakBuffer.data(), idx, info);
|
||||
result = faultyDeserializer.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
for (size_t pduFieldLen = 0; pduFieldLen < 25; pduFieldLen++) {
|
||||
nakBuffer[1] = (pduFieldLen >> 8) & 0xff;
|
||||
nakBuffer[2] = pduFieldLen & 0xff;
|
||||
NakPduDeserializer faultyDeserializer(nakBuffer.data(), nakBuffer.size(), info);
|
||||
result = faultyDeserializer.parseData();
|
||||
if (pduFieldLen == 9) {
|
||||
REQUIRE(info.getSegmentRequestsLen() == 0);
|
||||
} else if (pduFieldLen == 17) {
|
||||
REQUIRE(info.getSegmentRequestsLen() == 1);
|
||||
} else if (pduFieldLen == 25) {
|
||||
REQUIRE(info.getSegmentRequestsLen() == 2);
|
||||
}
|
||||
if (pduFieldLen != 9 and pduFieldLen != 17 and pduFieldLen != 25) {
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
info.setMaxSegmentRequestLen(5);
|
||||
REQUIRE(info.getSegmentRequestsMaxLen() == 5);
|
||||
}
|
||||
}
|
69
unittests/cfdp/pdu/testPromptPdu.cpp
Normal file
69
unittests/cfdp/pdu/testPromptPdu.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/pdu/PromptPduDeserializer.h"
|
||||
#include "fsfw/cfdp/pdu/PromptPduSerializer.h"
|
||||
#include "fsfw/globalfunctions/arrayprinter.h"
|
||||
|
||||
TEST_CASE("Prompt PDU", "[cfdp][pdu]") {
|
||||
using namespace cfdp;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
std::array<uint8_t, 256> rawBuf = {};
|
||||
uint8_t* buffer = rawBuf.data();
|
||||
size_t sz = 0;
|
||||
EntityId destId(WidthInBytes::TWO_BYTES, 2);
|
||||
TransactionSeqNum seqNum(WidthInBytes::TWO_BYTES, 15);
|
||||
EntityId sourceId(WidthInBytes::TWO_BYTES, 1);
|
||||
PduConfig pduConf(sourceId, destId, TransmissionModes::ACKNOWLEDGED, seqNum);
|
||||
|
||||
SECTION("Serialize") {
|
||||
PromptPduSerializer serializer(pduConf, cfdp::PromptResponseRequired::PROMPT_KEEP_ALIVE);
|
||||
result = serializer.serialize(&buffer, &sz, rawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(serializer.getWholePduSize() == 12);
|
||||
REQUIRE(sz == 12);
|
||||
REQUIRE(serializer.getPduDataFieldLen() == 2);
|
||||
REQUIRE(rawBuf[10] == FileDirectives::PROMPT);
|
||||
REQUIRE(((rawBuf[sz - 1] >> 7) & 0x01) == cfdp::PromptResponseRequired::PROMPT_KEEP_ALIVE);
|
||||
|
||||
for (size_t invalidMaxSz = 0; invalidMaxSz < sz; invalidMaxSz++) {
|
||||
uint8_t* buffer = rawBuf.data();
|
||||
size_t sz = 0;
|
||||
result = serializer.serialize(&buffer, &sz, invalidMaxSz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
for (size_t invalidSz = 1; invalidSz < sz; invalidSz++) {
|
||||
size_t locSz = invalidSz;
|
||||
uint8_t* buffer = rawBuf.data();
|
||||
result = serializer.serialize(&buffer, &locSz, sz, SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Deserialize") {
|
||||
PromptPduSerializer serializer(pduConf, cfdp::PromptResponseRequired::PROMPT_KEEP_ALIVE);
|
||||
result = serializer.serialize(&buffer, &sz, rawBuf.size(), SerializeIF::Endianness::NETWORK);
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
|
||||
PromptPduDeserializer deserializer(rawBuf.data(), rawBuf.size());
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||
REQUIRE(deserializer.getPromptResponseRequired() ==
|
||||
cfdp::PromptResponseRequired::PROMPT_KEEP_ALIVE);
|
||||
sz = deserializer.getWholePduSize();
|
||||
// Set invalid size
|
||||
rawBuf[2] = 1;
|
||||
result = deserializer.parseData();
|
||||
size_t sz2 = deserializer.getWholePduSize();
|
||||
REQUIRE(result == SerializeIF::STREAM_TOO_SHORT);
|
||||
rawBuf[2] = 2;
|
||||
|
||||
for (size_t invalidMaxSz = 0; invalidMaxSz < sz; invalidMaxSz++) {
|
||||
ReturnValue_t setResult = deserializer.setData(rawBuf.data(), invalidMaxSz);
|
||||
if (setResult == result::OK) {
|
||||
result = deserializer.parseData();
|
||||
REQUIRE(result != HasReturnvaluesIF::RETURN_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user