#include #include #include "fsfw/cfdp.h" #include "fsfw/cfdp/CfdpMessage.h" #include "fsfw/cfdp/handler/PutRequest.h" #include "fsfw/cfdp/handler/SourceHandler.h" #include "fsfw/cfdp/pdu/EofPduCreator.h" #include "fsfw/cfdp/pdu/FileDataCreator.h" #include "fsfw/cfdp/pdu/MetadataPduCreator.h" #include "fsfw/cfdp/pdu/MetadataPduReader.h" #include "fsfw/globalfunctions/arrayprinter.h" #include "fsfw/storagemanager/StorageManagerIF.h" #include "fsfw/tmtcservices/TmTcMessage.h" #include "fsfw/util/SeqCountProvider.h" #include "mocks/AcceptsTmMock.h" #include "mocks/EventReportingProxyMock.h" #include "mocks/FilesystemMock.h" #include "mocks/MessageQueueMock.h" #include "mocks/StorageManagerMock.h" #include "mocks/cfdp/FaultHandlerMock.h" #include "mocks/cfdp/RemoteConfigTableMock.h" #include "mocks/cfdp/UserMock.h" TEST_CASE("CFDP Source Handler", "[cfdp]") { using namespace cfdp; using namespace returnvalue; using namespace std::filesystem; MessageQueueId_t destQueueId = 2; AcceptsTmMock tmReceiver(destQueueId); MessageQueueMock mqMock(destQueueId); EntityId localId = EntityId(UnsignedByteField(2)); EntityId remoteId = EntityId(UnsignedByteField(3)); FaultHandlerMock fhMock; LocalEntityCfg localEntityCfg(localId, IndicationCfg(), fhMock); FilesystemMock fsMock; UserMock userMock(fsMock); SeqCountProviderU16 seqCountProvider; SourceHandlerParams dp(localEntityCfg, userMock, seqCountProvider); EventReportingProxyMock eventReporterMock; LocalPool::LocalPoolConfig storeCfg = {{10, 32}, {10, 64}, {10, 128}, {10, 1024}}; StorageManagerMock tcStore(2, storeCfg); StorageManagerMock tmStore(3, storeCfg); FsfwParams fp(tmReceiver, &mqMock, &eventReporterMock); fp.tcStore = &tcStore; fp.tmStore = &tmStore; auto sourceHandler = SourceHandler(dp, fp); CHECK(sourceHandler.initialize() == OK); SECTION("Test Basic") { CHECK(sourceHandler.getState() == CfdpState::IDLE); CHECK(sourceHandler.getStep() == SourceHandler::TransactionStep::IDLE); } SECTION("Transfer empty file") { RemoteEntityCfg cfg; EntityId id(cfdp::WidthInBytes::TWO_BYTES, 5); cfg.remoteId = id; std::string srcFileName = "/tmp/cfdp-test.txt"; std::string destFileName = "/tmp/cfdp-test2.txt"; FilesystemParams srcFileNameFs(srcFileName.c_str()); fsMock.createFile(srcFileNameFs); cfdp::StringLv srcNameLv(srcFileNameFs.path, std::strlen(srcFileNameFs.path)); FilesystemParams destFileNameFs(destFileName.c_str()); cfdp::StringLv destNameLv(destFileNameFs.path, std::strlen(destFileNameFs.path)); PutRequest putRequest(id, srcNameLv, destNameLv); CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK); SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine(); // Verify metadata PDU was sent. CHECK(fsmResult.packetsSent == 1); CHECK(mqMock.numberOfSentMessages() == 1); TmTcMessage tmtcMessage; REQUIRE(mqMock.getNextSentMessage(destQueueId, tmtcMessage) == OK); auto accessor = tmStore.getData(tmtcMessage.getStorageId()); REQUIRE(accessor.first == OK); const uint8_t* pduPtr = accessor.second.data(); CHECK(accessor.second.size() == 55); MetadataGenericInfo metadataInfo; MetadataPduReader metadataReader(pduPtr, accessor.second.size(), metadataInfo, nullptr, 0); REQUIRE(metadataReader.parseData() == OK); std::string srcNameRead = metadataReader.getSourceFileName().getString(); CHECK(srcNameRead == srcFileName); std::string destNameRead = metadataReader.getDestFileName().getString(); CHECK(destNameRead == destFileName); CHECK(metadataInfo.getChecksumType() == ChecksumType::NULL_CHECKSUM); CHECK(metadataInfo.getFileSize().value() == 0); CHECK(!metadataInfo.isClosureRequested()); // Verify EOF PDU was sent. No file data PDU is sent for an empty file. } }