Filesystem and CFDP updates
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
target_sources(
|
||||
${FSFW_TEST_TGT} PRIVATE testCfdp.cpp testOtherTlvs.cpp
|
||||
testReservedMsgCreator.cpp testTlv.cpp testLvs.cpp)
|
||||
${FSFW_TEST_TGT}
|
||||
PRIVATE testCfdp.cpp testOtherTlvs.cpp testReservedMsgCreator.cpp testTlv.cpp
|
||||
testLvs.cpp PduSenderMock.cpp)
|
||||
|
||||
add_subdirectory(handler)
|
||||
add_subdirectory(pdu)
|
||||
|
1
unittests/cfdp/PduSenderMock.cpp
Normal file
1
unittests/cfdp/PduSenderMock.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "PduSenderMock.h"
|
36
unittests/cfdp/PduSenderMock.h
Normal file
36
unittests/cfdp/PduSenderMock.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
|
||||
#include "fsfw/cfdp/handler/PduSenderIF.h"
|
||||
|
||||
struct SentPdu {
|
||||
cfdp::PduType pduType;
|
||||
std::optional<cfdp::FileDirective> fileDirective;
|
||||
std::vector<uint8_t> rawPdu;
|
||||
};
|
||||
|
||||
class PduSenderMock : public cfdp::PduSenderIF {
|
||||
public:
|
||||
ReturnValue_t sendPdu(cfdp::PduType pduType, std::optional<cfdp::FileDirective> fileDirective,
|
||||
|
||||
const uint8_t* pdu, size_t pduSize) override {
|
||||
SentPdu sentPdu;
|
||||
sentPdu.pduType = pduType;
|
||||
sentPdu.fileDirective = fileDirective;
|
||||
sentPdu.rawPdu = std::vector(pdu, pdu + pduSize);
|
||||
sentPdus.push_back(sentPdu);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
std::optional<SentPdu> getNextSentPacket() {
|
||||
if (sentPdus.empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
SentPdu nextPdu = sentPdus.front();
|
||||
sentPdus.pop_front();
|
||||
return nextPdu;
|
||||
}
|
||||
|
||||
std::deque<SentPdu> sentPdus;
|
||||
};
|
31
unittests/cfdp/handler/OwnedPduPacket.h
Normal file
31
unittests/cfdp/handler/OwnedPduPacket.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "fsfw/cfdp/definitions.h"
|
||||
#include "fsfw/cfdp/handler/PduPacketIF.h"
|
||||
|
||||
namespace cfdp {
|
||||
|
||||
class OwnedPduPacket : public PduPacketIF {
|
||||
public:
|
||||
OwnedPduPacket(PduType pduType, std::optional<FileDirective> fileDirective, const uint8_t* rawPdu,
|
||||
size_t pduLen)
|
||||
: pduType(pduType), fileDirective(fileDirective), rawPdu(rawPdu, rawPdu + pduLen) {}
|
||||
|
||||
[[nodiscard]] cfdp::PduType getPduType() const override { return pduType; };
|
||||
[[nodiscard]] std::optional<cfdp::FileDirective> getFileDirective() const override {
|
||||
return fileDirective;
|
||||
};
|
||||
[[nodiscard]] const uint8_t* getRawPduData(size_t& pduLen) const override {
|
||||
pduLen = rawPdu.size();
|
||||
return rawPdu.data();
|
||||
}
|
||||
|
||||
PduType pduType;
|
||||
std::optional<FileDirective> fileDirective;
|
||||
std::vector<uint8_t> rawPdu;
|
||||
};
|
||||
|
||||
} // namespace cfdp
|
@ -4,6 +4,8 @@
|
||||
#include <random>
|
||||
#include <utility>
|
||||
|
||||
#include "OwnedPduPacket.h"
|
||||
#include "cfdp/PduSenderMock.h"
|
||||
#include "fsfw/cfdp.h"
|
||||
#include "fsfw/cfdp/pdu/EofPduCreator.h"
|
||||
#include "fsfw/cfdp/pdu/FileDataCreator.h"
|
||||
@ -23,60 +25,49 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") {
|
||||
MessageQueueId_t destQueueId = 2;
|
||||
AcceptsTmMock tmReceiver(destQueueId);
|
||||
MessageQueueMock mqMock(destQueueId);
|
||||
EntityId localId = EntityId(UnsignedByteField<uint16_t>(2));
|
||||
EntityId remoteId = EntityId(UnsignedByteField<uint16_t>(3));
|
||||
auto localId = EntityId(UnsignedByteField<uint16_t>(2));
|
||||
auto remoteId = EntityId(UnsignedByteField<uint16_t>(3));
|
||||
FaultHandlerMock fhMock;
|
||||
LocalEntityCfg localEntityCfg(localId, IndicationCfg(), fhMock);
|
||||
FilesystemMock fsMock;
|
||||
UserMock userMock(fsMock);
|
||||
RemoteConfigTableMock remoteCfgTableMock;
|
||||
PacketInfoList<64> packetInfoList;
|
||||
LostSegmentsList<128> lostSegmentsList;
|
||||
DestHandlerParams dp(localEntityCfg, userMock, remoteCfgTableMock, packetInfoList,
|
||||
lostSegmentsList);
|
||||
DestHandlerParams dp(localEntityCfg, userMock, remoteCfgTableMock, lostSegmentsList);
|
||||
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);
|
||||
PduSenderMock senderMock;
|
||||
FsfwParams fp(&eventReporterMock);
|
||||
RemoteEntityCfg cfg(remoteId);
|
||||
remoteCfgTableMock.addRemoteConfig(cfg);
|
||||
fp.tcStore = &tcStore;
|
||||
fp.tmStore = &tmStore;
|
||||
uint8_t* buf = nullptr;
|
||||
std::array<uint8_t, 4096> pduBuf{};
|
||||
size_t serLen = 0;
|
||||
store_address_t storeId;
|
||||
PduConfig conf;
|
||||
auto destHandler = DestHandler(dp, fp);
|
||||
CHECK(destHandler.initialize() == OK);
|
||||
auto destHandler = DestHandler(senderMock, 4096, dp, fp);
|
||||
|
||||
auto metadataPreparation = [&](Fss cfdpFileSize, ChecksumType checksumType) {
|
||||
std::string srcNameString = "hello.txt";
|
||||
std::string destNameString = "hello-cpy.txt";
|
||||
const std::string srcNameString = "hello.txt";
|
||||
const std::string destNameString = "hello-cpy.txt";
|
||||
StringLv srcName(srcNameString);
|
||||
StringLv destName(destNameString);
|
||||
MetadataGenericInfo info(false, checksumType, std::move(cfdpFileSize));
|
||||
TransactionSeqNum seqNum(UnsignedByteField<uint16_t>(1));
|
||||
const TransactionSeqNum seqNum(UnsignedByteField<uint16_t>(1));
|
||||
conf.sourceId = remoteId;
|
||||
conf.destId = localId;
|
||||
conf.mode = TransmissionMode::UNACKNOWLEDGED;
|
||||
conf.seqNum = seqNum;
|
||||
MetadataPduCreator metadataCreator(conf, info, srcName, destName, nullptr, 0);
|
||||
REQUIRE(tcStore.getFreeElement(&storeId, metadataCreator.getSerializedSize(), &buf) == OK);
|
||||
REQUIRE(metadataCreator.serialize(buf, serLen, metadataCreator.getSerializedSize()) == OK);
|
||||
PacketInfo packetInfo(metadataCreator.getPduType(), storeId,
|
||||
metadataCreator.getDirectiveCode());
|
||||
packetInfoList.push_back(packetInfo);
|
||||
const MetadataPduCreator metadataCreator(conf, info, srcName, destName, nullptr, 0);
|
||||
REQUIRE(metadataCreator.serialize(pduBuf.data(), serLen, metadataCreator.getSerializedSize()) ==
|
||||
OK);
|
||||
return OwnedPduPacket(metadataCreator.getPduType(), metadataCreator.getDirectiveCode(),
|
||||
pduBuf.data(), serLen);
|
||||
};
|
||||
|
||||
auto metadataCheck = [&](const cfdp::DestHandler::FsmResult& res, const char* sourceName,
|
||||
const char* destName, size_t fileLen) {
|
||||
REQUIRE(res.result == OK);
|
||||
REQUIRE(res.callStatus == CallStatus::CALL_AGAIN);
|
||||
REQUIRE(res.errors == 0);
|
||||
// Assert that the packet was deleted after handling
|
||||
REQUIRE(not tcStore.hasDataAtId(storeId));
|
||||
REQUIRE(packetInfoList.empty());
|
||||
REQUIRE(userMock.metadataRecvd.size() == 1);
|
||||
auto& idMetadataPair = userMock.metadataRecvd.back();
|
||||
REQUIRE(idMetadataPair.first == destHandler.getTransactionId());
|
||||
@ -94,10 +85,10 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") {
|
||||
auto eofPreparation = [&](Fss cfdpFileSize, uint32_t crc) {
|
||||
EofInfo eofInfo(cfdp::ConditionCode::NO_ERROR, crc, std::move(cfdpFileSize));
|
||||
EofPduCreator eofCreator(conf, eofInfo);
|
||||
REQUIRE(tcStore.getFreeElement(&storeId, eofCreator.getSerializedSize(), &buf) == OK);
|
||||
REQUIRE(eofCreator.serialize(buf, serLen, eofCreator.getSerializedSize()) == OK);
|
||||
PacketInfo packetInfo(eofCreator.getPduType(), storeId, eofCreator.getDirectiveCode());
|
||||
packetInfoList.push_back(packetInfo);
|
||||
REQUIRE(eofCreator.serialize(pduBuf.data(), serLen, eofCreator.getSerializedSize()) == OK);
|
||||
OwnedPduPacket packet(eofCreator.getPduType(), eofCreator.getDirectiveCode(), pduBuf.data(),
|
||||
serLen);
|
||||
return packet;
|
||||
};
|
||||
|
||||
auto eofCheck = [&](const cfdp::DestHandler::FsmResult& res, const TransactionId& id) {
|
||||
@ -105,9 +96,6 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") {
|
||||
REQUIRE(res.state == CfdpState::IDLE);
|
||||
REQUIRE(res.errors == 0);
|
||||
REQUIRE(res.step == DestHandler::TransactionStep::IDLE);
|
||||
// Assert that the packet was deleted after handling
|
||||
REQUIRE(not tcStore.hasDataAtId(storeId));
|
||||
REQUIRE(packetInfoList.empty());
|
||||
REQUIRE(userMock.eofRecvdRecvd.size() == 1);
|
||||
auto& eofId = userMock.eofRecvdRecvd.back();
|
||||
CHECK(eofId == id);
|
||||
@ -122,10 +110,6 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") {
|
||||
REQUIRE(res.result == OK);
|
||||
REQUIRE(res.state == CfdpState::BUSY_CLASS_1_NACKED);
|
||||
REQUIRE(res.step == DestHandler::TransactionStep::RECEIVING_FILE_DATA_PDUS);
|
||||
for (const auto id : idsToCheck) {
|
||||
REQUIRE(not tcStore.hasDataAtId(id));
|
||||
}
|
||||
REQUIRE(packetInfoList.empty());
|
||||
};
|
||||
|
||||
SECTION("State") {
|
||||
@ -134,62 +118,59 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") {
|
||||
}
|
||||
|
||||
SECTION("Idle State Machine Iteration") {
|
||||
auto res = destHandler.stateMachine();
|
||||
CHECK(res.result == OK);
|
||||
CHECK(res.callStatus == CallStatus::CALL_AFTER_DELAY);
|
||||
CHECK(res.errors == 0);
|
||||
auto [packetsSent, result, step, state, errors, errorCodes] =
|
||||
destHandler.stateMachineNoPacket();
|
||||
CHECK(result == OK);
|
||||
CHECK(errors == 0);
|
||||
CHECK(destHandler.getCfdpState() == CfdpState::IDLE);
|
||||
CHECK(destHandler.getTransactionStep() == DestHandler::TransactionStep::IDLE);
|
||||
}
|
||||
|
||||
SECTION("Empty File Transfer") {
|
||||
const DestHandler::FsmResult& res = destHandler.stateMachine();
|
||||
const DestHandler::FsmResult& res = destHandler.stateMachineNoPacket();
|
||||
CHECK(res.result == OK);
|
||||
Fss cfdpFileSize(0);
|
||||
metadataPreparation(cfdpFileSize, ChecksumType::NULL_CHECKSUM);
|
||||
destHandler.stateMachine();
|
||||
auto packet = metadataPreparation(cfdpFileSize, ChecksumType::NULL_CHECKSUM);
|
||||
destHandler.stateMachine(packet);
|
||||
metadataCheck(res, "hello.txt", "hello-cpy.txt", 0);
|
||||
destHandler.stateMachine();
|
||||
REQUIRE(res.callStatus == CallStatus::CALL_AFTER_DELAY);
|
||||
destHandler.stateMachine(packet);
|
||||
// REQUIRE(res.callStatus == CallStatus::CALL_AFTER_DELAY);
|
||||
auto transactionId = destHandler.getTransactionId();
|
||||
eofPreparation(cfdpFileSize, 0);
|
||||
auto ownedEofPacket = eofPreparation(cfdpFileSize, 0);
|
||||
// After EOF, operation is done because no closure was requested
|
||||
destHandler.stateMachine();
|
||||
destHandler.stateMachine(ownedEofPacket);
|
||||
eofCheck(res, transactionId);
|
||||
}
|
||||
|
||||
SECTION("Small File Transfer") {
|
||||
const DestHandler::FsmResult& res = destHandler.stateMachine();
|
||||
const DestHandler::FsmResult& res = destHandler.stateMachineNoPacket();
|
||||
CHECK(res.result == OK);
|
||||
std::string fileData = "hello test data";
|
||||
etl::crc32 crcCalc;
|
||||
crcCalc.add(fileData.begin(), fileData.end());
|
||||
uint32_t crc32 = crcCalc.value();
|
||||
Fss cfdpFileSize(fileData.size());
|
||||
metadataPreparation(cfdpFileSize, ChecksumType::CRC_32);
|
||||
destHandler.stateMachine();
|
||||
auto metadataPacket = metadataPreparation(cfdpFileSize, ChecksumType::CRC_32);
|
||||
destHandler.stateMachine(metadataPacket);
|
||||
metadataCheck(res, "hello.txt", "hello-cpy.txt", fileData.size());
|
||||
destHandler.stateMachine();
|
||||
REQUIRE(res.callStatus == CallStatus::CALL_AFTER_DELAY);
|
||||
destHandler.stateMachineNoPacket();
|
||||
auto transactionId = destHandler.getTransactionId();
|
||||
Fss offset(0);
|
||||
FileDataInfo fdPduInfo(offset, reinterpret_cast<const uint8_t*>(fileData.data()),
|
||||
fileData.size());
|
||||
FileDataCreator fdPduCreator(conf, fdPduInfo);
|
||||
REQUIRE(tcStore.getFreeElement(&storeId, fdPduCreator.getSerializedSize(), &buf) == OK);
|
||||
REQUIRE(fdPduCreator.serialize(buf, serLen, fdPduCreator.getSerializedSize()) == OK);
|
||||
PacketInfo packetInfo(fdPduCreator.getPduType(), storeId, std::nullopt);
|
||||
packetInfoList.push_back(packetInfo);
|
||||
destHandler.stateMachine();
|
||||
REQUIRE(fdPduCreator.serialize(pduBuf.data(), serLen, fdPduCreator.getSerializedSize()) == OK);
|
||||
OwnedPduPacket fdPdu(fdPduCreator.getPduType(), std::nullopt, pduBuf.data(), serLen);
|
||||
destHandler.stateMachine(fdPdu);
|
||||
fileDataPduCheck(res, {storeId});
|
||||
eofPreparation(cfdpFileSize, crc32);
|
||||
auto eofPacket = eofPreparation(cfdpFileSize, crc32);
|
||||
// After EOF, operation is done because no closure was requested
|
||||
destHandler.stateMachine();
|
||||
destHandler.stateMachine(eofPacket);
|
||||
eofCheck(res, transactionId);
|
||||
}
|
||||
|
||||
SECTION("Segmented File Transfer") {
|
||||
const DestHandler::FsmResult& res = destHandler.stateMachine();
|
||||
const DestHandler::FsmResult& res = destHandler.stateMachineNoPacket();
|
||||
CHECK(res.result == OK);
|
||||
std::random_device dev;
|
||||
std::mt19937 rng(dev());
|
||||
@ -202,43 +183,40 @@ TEST_CASE("CFDP Dest Handler", "[cfdp]") {
|
||||
crcCalc.add(largerFileData.begin(), largerFileData.end());
|
||||
uint32_t crc32 = crcCalc.value();
|
||||
Fss cfdpFileSize(largerFileData.size());
|
||||
metadataPreparation(cfdpFileSize, ChecksumType::CRC_32);
|
||||
destHandler.stateMachine();
|
||||
auto metaPacket = metadataPreparation(cfdpFileSize, ChecksumType::CRC_32);
|
||||
destHandler.stateMachine(metaPacket);
|
||||
metadataCheck(res, "hello.txt", "hello-cpy.txt", largerFileData.size());
|
||||
destHandler.stateMachine();
|
||||
REQUIRE(res.callStatus == CallStatus::CALL_AFTER_DELAY);
|
||||
destHandler.stateMachineNoPacket();
|
||||
auto transactionId = destHandler.getTransactionId();
|
||||
|
||||
std::vector<store_address_t> idsToCheck;
|
||||
{
|
||||
Fss offset(0);
|
||||
FileDataInfo fdPduInfo(offset, reinterpret_cast<const uint8_t*>(largerFileData.data()),
|
||||
largerFileData.size() / 2);
|
||||
FileDataInfo fdPduInfo(offset, (largerFileData.data()), largerFileData.size() / 2);
|
||||
FileDataCreator fdPduCreator(conf, fdPduInfo);
|
||||
REQUIRE(tcStore.getFreeElement(&storeId, fdPduCreator.getSerializedSize(), &buf) == OK);
|
||||
REQUIRE(fdPduCreator.serialize(buf, serLen, fdPduCreator.getSerializedSize()) == OK);
|
||||
PacketInfo packetInfo(fdPduCreator.getPduType(), storeId, std::nullopt);
|
||||
REQUIRE(fdPduCreator.serialize(pduBuf.data(), serLen, fdPduCreator.getSerializedSize()) ==
|
||||
OK);
|
||||
idsToCheck.push_back(storeId);
|
||||
packetInfoList.push_back(packetInfo);
|
||||
OwnedPduPacket fdPdu(fdPduCreator.getPduType(), std::nullopt, pduBuf.data(), serLen);
|
||||
destHandler.stateMachine(fdPdu);
|
||||
}
|
||||
|
||||
{
|
||||
Fss offset(512);
|
||||
FileDataInfo fdPduInfo(offset, reinterpret_cast<const uint8_t*>(largerFileData.data() + 512),
|
||||
largerFileData.size() / 2);
|
||||
FileDataInfo fdPduInfo(offset, largerFileData.data() + 512, largerFileData.size() / 2);
|
||||
FileDataCreator fdPduCreator(conf, fdPduInfo);
|
||||
REQUIRE(tcStore.getFreeElement(&storeId, fdPduCreator.getSerializedSize(), &buf) == OK);
|
||||
REQUIRE(fdPduCreator.serialize(buf, serLen, fdPduCreator.getSerializedSize()) == OK);
|
||||
PacketInfo packetInfo(fdPduCreator.getPduType(), storeId, std::nullopt);
|
||||
REQUIRE(fdPduCreator.serialize(pduBuf.data(), serLen, fdPduCreator.getSerializedSize()) ==
|
||||
OK);
|
||||
idsToCheck.push_back(storeId);
|
||||
packetInfoList.push_back(packetInfo);
|
||||
OwnedPduPacket fdPdu(fdPduCreator.getPduType(), std::nullopt, pduBuf.data(), serLen);
|
||||
destHandler.stateMachine(fdPdu);
|
||||
}
|
||||
|
||||
destHandler.stateMachine();
|
||||
destHandler.stateMachineNoPacket();
|
||||
fileDataPduCheck(res, idsToCheck);
|
||||
eofPreparation(cfdpFileSize, crc32);
|
||||
auto eofPacket = eofPreparation(cfdpFileSize, crc32);
|
||||
// After EOF, operation is done because no closure was requested
|
||||
destHandler.stateMachine();
|
||||
destHandler.stateMachine(eofPacket);
|
||||
eofCheck(res, transactionId);
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
#include <array>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "fsfw/cfdp/CfdpMessage.h"
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <filesystem>
|
||||
#include <random>
|
||||
|
||||
#include "cfdp/PduSenderMock.h"
|
||||
#include "fsfw/cfdp.h"
|
||||
#include "fsfw/cfdp/handler/PutRequest.h"
|
||||
#include "fsfw/cfdp/handler/SourceHandler.h"
|
||||
@ -27,13 +28,13 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
|
||||
using namespace cfdp;
|
||||
using namespace returnvalue;
|
||||
using namespace std::filesystem;
|
||||
const size_t MAX_FILE_SEGMENT_SIZE = 255;
|
||||
constexpr size_t MAX_FILE_SEGMENT_SIZE = 255;
|
||||
|
||||
MessageQueueId_t destQueueId = 2;
|
||||
AcceptsTmMock tmReceiver(destQueueId);
|
||||
MessageQueueMock mqMock(destQueueId);
|
||||
EntityId localId = EntityId(UnsignedByteField<uint16_t>(2));
|
||||
EntityId remoteId = EntityId(UnsignedByteField<uint16_t>(5));
|
||||
// MessageQueueMock mqMock(destQueueId);
|
||||
auto localId = EntityId(UnsignedByteField<uint16_t>(2));
|
||||
auto remoteId = EntityId(UnsignedByteField<uint16_t>(5));
|
||||
FaultHandlerMock fhMock;
|
||||
LocalEntityCfg localEntityCfg(localId, IndicationCfg(), fhMock);
|
||||
FilesystemMock fsMock;
|
||||
@ -41,49 +42,37 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
|
||||
SeqCountProviderU16 seqCountProvider;
|
||||
SourceHandlerParams dp(localEntityCfg, userMock, seqCountProvider);
|
||||
|
||||
PduSenderMock pduSender;
|
||||
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);
|
||||
FsfwParams fp(&eventReporterMock);
|
||||
auto sourceHandler = SourceHandler(pduSender, 4096, dp, fp);
|
||||
|
||||
RemoteEntityCfg cfg;
|
||||
cfg.maxFileSegmentLen = MAX_FILE_SEGMENT_SIZE;
|
||||
cfg.remoteId = remoteId;
|
||||
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));
|
||||
fsMock.createFile(srcFileName.c_str());
|
||||
cfdp::StringLv srcNameLv(srcFileName.c_str(), srcFileName.length());
|
||||
FilesystemParams destFileNameFs(destFileName.c_str());
|
||||
cfdp::StringLv destNameLv(destFileNameFs.path, std::strlen(destFileNameFs.path));
|
||||
PutRequest putRequest(remoteId, srcNameLv, destNameLv);
|
||||
CHECK(sourceHandler.initialize() == OK);
|
||||
|
||||
auto onePduSentCheck = [&](const SourceHandler::FsmResult& fsmResult, TmTcMessage& tmtcMessage,
|
||||
const uint8_t** pduPtr) {
|
||||
auto onePduSentCheck = [&](const SourceHandler::FsmResult& fsmResult) {
|
||||
CHECK(fsmResult.errors == 0);
|
||||
CHECK(fsmResult.packetsSent == 1);
|
||||
CHECK(mqMock.numberOfSentMessages() == 1);
|
||||
REQUIRE(mqMock.getNextSentMessage(destQueueId, tmtcMessage) == OK);
|
||||
auto accessor = tmStore.getData(tmtcMessage.getStorageId());
|
||||
REQUIRE(accessor.first == OK);
|
||||
*pduPtr = accessor.second.data();
|
||||
return std::move(accessor);
|
||||
};
|
||||
auto genericMetadataCheck = [&](const SourceHandler::FsmResult& fsmResult,
|
||||
size_t expectedFileSize, uint16_t expectedSeqNum) {
|
||||
CHECK(fsmResult.errors == 0);
|
||||
CHECK(fsmResult.callStatus == CallStatus::CALL_AGAIN);
|
||||
TmTcMessage tmtcMessage;
|
||||
const uint8_t* pduPtr;
|
||||
auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr);
|
||||
CHECK(accessor.second.size() == 55);
|
||||
auto optNextPacket = pduSender.getNextSentPacket();
|
||||
CHECK(optNextPacket.has_value());
|
||||
const auto& [pduType, fileDirective, rawPdu] = *optNextPacket;
|
||||
CHECK(rawPdu.size() == 55);
|
||||
MetadataGenericInfo metadataInfo;
|
||||
MetadataPduReader metadataReader(pduPtr, accessor.second.size(), metadataInfo, nullptr, 0);
|
||||
MetadataPduReader metadataReader(rawPdu.data(), rawPdu.size(), metadataInfo, nullptr, 0);
|
||||
REQUIRE(metadataReader.parseData() == OK);
|
||||
std::string srcNameRead = metadataReader.getSourceFileName().getString();
|
||||
CHECK(srcNameRead == srcFileName);
|
||||
@ -107,20 +96,19 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
|
||||
}
|
||||
CHECK(metadataInfo.getFileSize().value() == expectedFileSize);
|
||||
CHECK(!metadataInfo.isClosureRequested());
|
||||
mqMock.clearMessages();
|
||||
};
|
||||
auto genericEofCheck = [&](const SourceHandler::FsmResult& fsmResult, size_t expectedFileSize,
|
||||
uint32_t expectedChecksum, uint16_t expectedSeqNum) {
|
||||
CHECK(fsmResult.errors == 0);
|
||||
CHECK(fsmResult.callStatus == CallStatus::CALL_AGAIN);
|
||||
onePduSentCheck(fsmResult);
|
||||
TmTcMessage tmtcMessage;
|
||||
const uint8_t* pduPtr;
|
||||
auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr);
|
||||
auto optNextPacket = pduSender.getNextSentPacket();
|
||||
CHECK(optNextPacket.has_value());
|
||||
const auto& [pduType, fileDirective, rawPdu] = *optNextPacket;
|
||||
// 10 byte PDU header, 1 byte directive field, 1 byte condition code, 4 byte checksum,
|
||||
// 4 byte FSS
|
||||
CHECK(accessor.second.size() == 20);
|
||||
CHECK(rawPdu.size() == 20);
|
||||
EofInfo eofInfo;
|
||||
EofPduReader eofReader(pduPtr, accessor.second.size(), eofInfo);
|
||||
EofPduReader eofReader(rawPdu.data(), rawPdu.size(), eofInfo);
|
||||
REQUIRE(eofReader.parseData() == OK);
|
||||
TransactionSeqNum seqNum;
|
||||
eofReader.getTransactionSeqNum(seqNum);
|
||||
@ -133,8 +121,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
|
||||
CHECK(eofInfo.getFileSize().value() == expectedFileSize);
|
||||
};
|
||||
auto genericNoticeOfCompletionCheck = [&](const SourceHandler::FsmResult& fsmResult,
|
||||
uint16_t expectedSeqNum) {
|
||||
CHECK(fsmResult.callStatus == CallStatus::DONE);
|
||||
const uint16_t expectedSeqNum) {
|
||||
CHECK(userMock.finishedRecvd.size() == 1);
|
||||
CHECK(userMock.finishedRecvd.back().first ==
|
||||
TransactionId(localId, TransactionSeqNum(cfdp::WidthInBytes::TWO_BYTES, expectedSeqNum)));
|
||||
@ -151,41 +138,43 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
|
||||
CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK);
|
||||
|
||||
size_t expectedFileSize = 0;
|
||||
const SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine();
|
||||
const SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachineNoPacket();
|
||||
// Verify metadata PDU was sent.
|
||||
genericMetadataCheck(fsmResult, expectedFileSize, 0);
|
||||
|
||||
sourceHandler.stateMachine();
|
||||
sourceHandler.stateMachineNoPacket();
|
||||
// Verify EOF PDU was sent. No file data PDU is sent for an empty file and the checksum is 0.
|
||||
genericEofCheck(fsmResult, expectedFileSize, 0, 0);
|
||||
|
||||
// Verify notice of completion.
|
||||
sourceHandler.stateMachine();
|
||||
sourceHandler.stateMachineNoPacket();
|
||||
genericNoticeOfCompletionCheck(fsmResult, 0);
|
||||
}
|
||||
|
||||
SECTION("Transfer small file") {
|
||||
uint16_t expectedSeqNum = 0;
|
||||
fsMock.createFile(srcFileNameFs);
|
||||
fsMock.createFile(srcFileName.c_str());
|
||||
std::string fileContent = "hello world\n";
|
||||
size_t expectedFileSize = fileContent.size();
|
||||
FileOpParams params(srcFileName.c_str(), expectedFileSize);
|
||||
fsMock.writeToFile(params, reinterpret_cast<const uint8_t*>(fileContent.data()));
|
||||
fsMock.writeToFile(srcFileName.c_str(), 0, reinterpret_cast<const uint8_t*>(fileContent.data()),
|
||||
expectedFileSize);
|
||||
CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK);
|
||||
const SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine();
|
||||
const SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachineNoPacket();
|
||||
|
||||
// Verify metadata PDU was sent.
|
||||
genericMetadataCheck(fsmResult, expectedFileSize, expectedSeqNum);
|
||||
|
||||
// Verify that a small file data PDU was sent.
|
||||
sourceHandler.stateMachine();
|
||||
TmTcMessage tmtcMessage;
|
||||
const uint8_t* pduPtr;
|
||||
auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr);
|
||||
sourceHandler.stateMachineNoPacket();
|
||||
|
||||
onePduSentCheck(fsmResult);
|
||||
auto optNextPacket = pduSender.getNextSentPacket();
|
||||
CHECK(optNextPacket.has_value());
|
||||
const auto& [pduType, fileDirective, rawPdu] = *optNextPacket;
|
||||
FileDataInfo fdInfo;
|
||||
FileDataReader fdReader(pduPtr, accessor.second.size(), fdInfo);
|
||||
FileDataReader fdReader(rawPdu.data(), rawPdu.size(), fdInfo);
|
||||
// 10 byte PDU header, 4 byte offset, 12 bytes file data.
|
||||
CHECK(accessor.second.size() == 26);
|
||||
CHECK(rawPdu.size() == 26);
|
||||
CHECK(fdReader.parseData() == OK);
|
||||
CHECK(fdInfo.getOffset().value() == 0);
|
||||
size_t fileSize = 0;
|
||||
@ -194,9 +183,8 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
|
||||
CHECK(fileData != nullptr);
|
||||
std::string dataReadBack(reinterpret_cast<const char*>(fileData), fileSize);
|
||||
CHECK(dataReadBack == fileContent);
|
||||
mqMock.clearMessages();
|
||||
|
||||
sourceHandler.stateMachine();
|
||||
sourceHandler.stateMachineNoPacket();
|
||||
|
||||
etl::crc32 crcCalc;
|
||||
crcCalc.add(fileContent.data(), fileContent.data() + fileContent.size());
|
||||
@ -204,7 +192,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
|
||||
genericEofCheck(fsmResult, expectedFileSize, crcCalc.value(), expectedSeqNum);
|
||||
|
||||
// Verify notice of completion.
|
||||
sourceHandler.stateMachine();
|
||||
sourceHandler.stateMachineNoPacket();
|
||||
genericNoticeOfCompletionCheck(fsmResult, expectedSeqNum);
|
||||
}
|
||||
|
||||
@ -220,25 +208,26 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
|
||||
val = distU8(rng);
|
||||
}
|
||||
size_t expectedFileSize = largerFileData.size();
|
||||
fsMock.createFile(srcFileNameFs);
|
||||
FileOpParams params(srcFileName.c_str(), expectedFileSize);
|
||||
fsMock.writeToFile(params, reinterpret_cast<const uint8_t*>(largerFileData.data()));
|
||||
fsMock.createFile(srcFileName.c_str());
|
||||
fsMock.writeToFile(srcFileName.c_str(), 0, largerFileData.data(), largerFileData.size());
|
||||
CHECK(sourceHandler.transactionStart(putRequest, cfg) == OK);
|
||||
const SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachine();
|
||||
const SourceHandler::FsmResult& fsmResult = sourceHandler.stateMachineNoPacket();
|
||||
// Verify metadata PDU was sent.
|
||||
genericMetadataCheck(fsmResult, expectedFileSize, expectedSeqNum);
|
||||
|
||||
// Check first file data PDU. It should have the maximum file segment size.
|
||||
sourceHandler.stateMachine();
|
||||
TmTcMessage tmtcMessage;
|
||||
const uint8_t* pduPtr;
|
||||
sourceHandler.stateMachineNoPacket();
|
||||
|
||||
onePduSentCheck(fsmResult);
|
||||
auto optNextPacket = pduSender.getNextSentPacket();
|
||||
CHECK(optNextPacket.has_value());
|
||||
const auto& [pduType, fileDirective, rawPdu] = *optNextPacket;
|
||||
FileDataInfo fdInfo;
|
||||
{
|
||||
CHECK(fsmResult.callStatus == CallStatus::CALL_AGAIN);
|
||||
auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr);
|
||||
FileDataReader fdReader(pduPtr, accessor.second.size(), fdInfo);
|
||||
// auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr);
|
||||
FileDataReader fdReader(rawPdu.data(), rawPdu.size(), fdInfo);
|
||||
// 10 byte PDU header, 4 byte offset, 255 byte file data
|
||||
CHECK(accessor.second.size() == 269);
|
||||
CHECK(rawPdu.size() == 269);
|
||||
CHECK(fdReader.parseData() == OK);
|
||||
CHECK(fdInfo.getOffset().value() == 0);
|
||||
size_t fileSize = 0;
|
||||
@ -249,16 +238,16 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
|
||||
CHECK(fileData[i] == largerFileData[i]);
|
||||
}
|
||||
}
|
||||
mqMock.clearMessages();
|
||||
|
||||
// Check second file data PDU.
|
||||
sourceHandler.stateMachine();
|
||||
sourceHandler.stateMachineNoPacket();
|
||||
{
|
||||
CHECK(fsmResult.callStatus == CallStatus::CALL_AGAIN);
|
||||
auto accessor = onePduSentCheck(fsmResult, tmtcMessage, &pduPtr);
|
||||
FileDataReader fdReader(pduPtr, accessor.second.size(), fdInfo);
|
||||
optNextPacket = pduSender.getNextSentPacket();
|
||||
CHECK(optNextPacket.has_value());
|
||||
const auto& [pduType, fileDirective, rawPdu] = *optNextPacket;
|
||||
FileDataReader fdReader(rawPdu.data(), rawPdu.size(), fdInfo);
|
||||
// 10 byte PDU header, 4 byte offset, remaining file data (400 - 255 == 145).
|
||||
CHECK(accessor.second.size() == 10 + 4 + largerFileData.size() - MAX_FILE_SEGMENT_SIZE);
|
||||
CHECK(rawPdu.size() == 10 + 4 + largerFileData.size() - MAX_FILE_SEGMENT_SIZE);
|
||||
CHECK(fdReader.parseData() == OK);
|
||||
CHECK(fdInfo.getOffset().value() == MAX_FILE_SEGMENT_SIZE);
|
||||
size_t fileDataSize = 0;
|
||||
@ -269,10 +258,9 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
|
||||
CHECK(fileData[i] == largerFileData[MAX_FILE_SEGMENT_SIZE + i]);
|
||||
}
|
||||
}
|
||||
mqMock.clearMessages();
|
||||
|
||||
// Check EOF and verify checksum.
|
||||
sourceHandler.stateMachine();
|
||||
sourceHandler.stateMachineNoPacket();
|
||||
|
||||
etl::crc32 crcCalc;
|
||||
crcCalc.add(largerFileData.data(), largerFileData.data() + largerFileData.size());
|
||||
@ -280,7 +268,7 @@ TEST_CASE("CFDP Source Handler", "[cfdp]") {
|
||||
genericEofCheck(fsmResult, expectedFileSize, crcCalc.value(), expectedSeqNum);
|
||||
|
||||
// Verify notice of completion.
|
||||
sourceHandler.stateMachine();
|
||||
sourceHandler.stateMachineNoPacket();
|
||||
genericNoticeOfCompletionCheck(fsmResult, expectedSeqNum);
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
#include "fsfw/cfdp/pdu/FinishedInfo.h"
|
||||
#include "fsfw/cfdp/pdu/FinishedPduCreator.h"
|
||||
#include "fsfw/cfdp/pdu/HeaderCreator.h"
|
||||
#include "fsfw/cfdp/pdu/PduHeaderReader.h"
|
||||
#include "fsfw/cfdp/pdu/HeaderReader.h"
|
||||
#include "fsfw/returnvalues/returnvalue.h"
|
||||
|
||||
using namespace returnvalue;
|
||||
|
@ -13,8 +13,8 @@ TEST_CASE("Array List", "[containers]") {
|
||||
ArrayList<uint16_t> list(20);
|
||||
struct TestClass {
|
||||
public:
|
||||
TestClass(){};
|
||||
TestClass(uint32_t number1, uint64_t number2) : number1(number1), number2(number2){};
|
||||
TestClass() {};
|
||||
TestClass(uint32_t number1, uint64_t number2) : number1(number1), number2(number2) {};
|
||||
uint32_t number1 = -1;
|
||||
uint64_t number2 = -1;
|
||||
bool operator==(const TestClass& other) {
|
||||
|
@ -97,9 +97,9 @@ TEST_CASE("FixedOrderedMultimap Non Trivial Type", "[TestFixedOrderedMultimapNon
|
||||
|
||||
class TestClass {
|
||||
public:
|
||||
TestClass(){};
|
||||
TestClass(uint32_t number1, uint64_t number2) : number1(number1), number2(number2){};
|
||||
~TestClass(){};
|
||||
TestClass() {};
|
||||
TestClass(uint32_t number1, uint64_t number2) : number1(number1), number2(number2) {};
|
||||
~TestClass() {};
|
||||
|
||||
bool operator==(const TestClass& lhs) {
|
||||
return ((this->number1 == lhs.number1) and (this->number2 == lhs.number2));
|
||||
|
@ -10,7 +10,7 @@ TEST_CASE("Filesystem Mock", "[mocks]") {
|
||||
|
||||
SECTION("Create File") {
|
||||
FilesystemParams params("hello.txt");
|
||||
CHECK(fsMock.createFile(params) == returnvalue::OK);
|
||||
CHECK(fsMock.createFile("hello.txt") == returnvalue::OK);
|
||||
auto iter = fsMock.fileMap.find("hello.txt");
|
||||
REQUIRE(iter != fsMock.fileMap.end());
|
||||
FilesystemMock::FileInfo &stats = iter->second;
|
||||
@ -21,8 +21,8 @@ TEST_CASE("Filesystem Mock", "[mocks]") {
|
||||
SECTION("Write to File") {
|
||||
std::string testData = "test data";
|
||||
FileOpParams params("hello.txt", testData.size());
|
||||
CHECK(fsMock.writeToFile(params, reinterpret_cast<const uint8_t *>(testData.data())) ==
|
||||
returnvalue::OK);
|
||||
CHECK(fsMock.writeToFile("hello.txt", 0, reinterpret_cast<const uint8_t *>(testData.data()),
|
||||
testData.size()) == returnvalue::OK);
|
||||
auto iter = fsMock.fileMap.find("hello.txt");
|
||||
REQUIRE(iter != fsMock.fileMap.end());
|
||||
FilesystemMock::FileInfo &stats = iter->second;
|
||||
@ -38,7 +38,7 @@ TEST_CASE("Filesystem Mock", "[mocks]") {
|
||||
|
||||
SECTION("Create Directory") {
|
||||
FilesystemParams params("hello");
|
||||
CHECK(fsMock.createDirectory(params) == returnvalue::OK);
|
||||
CHECK(fsMock.createDirectory("hello") == returnvalue::OK);
|
||||
REQUIRE(not fsMock.dirMap.empty());
|
||||
auto iter = fsMock.dirMap.find("hello");
|
||||
REQUIRE(iter != fsMock.dirMap.end());
|
||||
|
@ -25,15 +25,13 @@ TEST_CASE("Host Filesystem", "[hal][host]") {
|
||||
REQUIRE_NOTHROW(fs::remove_all(dir0));
|
||||
|
||||
SECTION("Create file") {
|
||||
FilesystemParams params(file0.c_str());
|
||||
REQUIRE(hostFs.createFile(params) == returnvalue::OK);
|
||||
REQUIRE(hostFs.createFile(file0.c_str()) == returnvalue::OK);
|
||||
CHECK(fs::is_regular_file(file0));
|
||||
REQUIRE(fs::exists(file0));
|
||||
}
|
||||
|
||||
SECTION("Remove File") {
|
||||
FilesystemParams params(file0.c_str());
|
||||
REQUIRE(hostFs.createFile(params) == returnvalue::OK);
|
||||
REQUIRE(hostFs.createFile(file0.c_str()) == returnvalue::OK);
|
||||
CHECK(fs::is_regular_file(file0));
|
||||
REQUIRE(fs::exists(file0));
|
||||
REQUIRE(hostFs.removeFile(file0.c_str()) == returnvalue::OK);
|
||||
@ -41,23 +39,20 @@ TEST_CASE("Host Filesystem", "[hal][host]") {
|
||||
}
|
||||
|
||||
SECTION("Create Directory") {
|
||||
FilesystemParams params(dir0.c_str());
|
||||
REQUIRE(hostFs.createDirectory(params) == returnvalue::OK);
|
||||
REQUIRE(hostFs.createDirectory(dir0.c_str()) == returnvalue::OK);
|
||||
CHECK(fs::is_directory(dir0));
|
||||
REQUIRE(fs::exists(dir0));
|
||||
}
|
||||
|
||||
SECTION("Remove Directory") {
|
||||
FilesystemParams params(dir0.c_str());
|
||||
REQUIRE(hostFs.createDirectory(params) == returnvalue::OK);
|
||||
REQUIRE(hostFs.createDirectory(dir0.c_str()) == returnvalue::OK);
|
||||
REQUIRE(fs::exists(dir0));
|
||||
REQUIRE(hostFs.removeDirectory(params) == returnvalue::OK);
|
||||
REQUIRE(hostFs.removeDirectory(dir0.c_str(), false, nullptr) == returnvalue::OK);
|
||||
REQUIRE(not fs::exists(dir0));
|
||||
}
|
||||
|
||||
SECTION("Rename File") {
|
||||
FilesystemParams params(file0.c_str());
|
||||
REQUIRE(hostFs.createFile(params) == returnvalue::OK);
|
||||
REQUIRE(hostFs.createFile(file0.c_str()) == returnvalue::OK);
|
||||
CHECK(fs::is_regular_file(file0));
|
||||
REQUIRE(fs::exists(file0));
|
||||
REQUIRE(hostFs.rename(file0.c_str(), file1.c_str()) == returnvalue::OK);
|
||||
@ -65,12 +60,11 @@ TEST_CASE("Host Filesystem", "[hal][host]") {
|
||||
|
||||
SECTION("Write To File") {
|
||||
std::string data = "hello world!";
|
||||
FileOpParams params(file0.c_str(), data.size());
|
||||
REQUIRE(hostFs.createFile(params.fsParams) == returnvalue::OK);
|
||||
REQUIRE(hostFs.createFile(file0.c_str()) == returnvalue::OK);
|
||||
CHECK(fs::is_regular_file(file0));
|
||||
REQUIRE(fs::exists(file0));
|
||||
CHECK(hostFs.writeToFile(params, reinterpret_cast<const uint8_t*>(data.c_str())) ==
|
||||
returnvalue::OK);
|
||||
CHECK(hostFs.writeToFile(file0.c_str(), 0, reinterpret_cast<const uint8_t*>(data.c_str()),
|
||||
data.size()) == returnvalue::OK);
|
||||
CHECK(fs::file_size(file0) == data.size());
|
||||
ifstream ifile(file0);
|
||||
std::array<char, 524> readBuf{};
|
||||
@ -87,14 +81,13 @@ TEST_CASE("Host Filesystem", "[hal][host]") {
|
||||
for (uint8_t& byte : randData) {
|
||||
byte = distU8(rng);
|
||||
}
|
||||
FileOpParams params(file0.c_str(), randData.size() - 256);
|
||||
REQUIRE(hostFs.createFile(params.fsParams) == returnvalue::OK);
|
||||
REQUIRE(hostFs.createFile(file0.c_str()) == returnvalue::OK);
|
||||
CHECK(fs::is_regular_file(file0));
|
||||
REQUIRE(fs::exists(file0));
|
||||
// Write first file chunk
|
||||
CHECK(hostFs.writeToFile(params, randData.cbegin()) == returnvalue::OK);
|
||||
params.offset = 256;
|
||||
CHECK(hostFs.writeToFile(params, randData.cbegin() + 256) == returnvalue::OK);
|
||||
CHECK(hostFs.writeToFile(file0.c_str(), 0, randData.cbegin(), randData.size() - 256) ==
|
||||
returnvalue::OK);
|
||||
CHECK(hostFs.writeToFile(file0.c_str(), 256, randData.cbegin() + 256, 256) == returnvalue::OK);
|
||||
std::ifstream rf(file0, ios::binary);
|
||||
std::array<uint8_t, 512> readBack{};
|
||||
REQUIRE(std::filesystem::file_size(file0) == 512);
|
||||
@ -106,8 +99,7 @@ TEST_CASE("Host Filesystem", "[hal][host]") {
|
||||
|
||||
SECTION("Read From File") {
|
||||
std::string data = "hello world!";
|
||||
FileOpParams params(file0.c_str(), data.size());
|
||||
REQUIRE(hostFs.createFile(params.fsParams) == returnvalue::OK);
|
||||
REQUIRE(hostFs.createFile(file0.c_str()) == returnvalue::OK);
|
||||
CHECK(fs::is_regular_file(file0));
|
||||
ofstream of(file0);
|
||||
of.write(data.c_str(), static_cast<unsigned int>(data.size()));
|
||||
@ -116,8 +108,10 @@ TEST_CASE("Host Filesystem", "[hal][host]") {
|
||||
REQUIRE(fs::exists(file0));
|
||||
std::array<uint8_t, 256> readBuf{};
|
||||
uint8_t* readPtr = readBuf.data();
|
||||
size_t readSize = 0;
|
||||
CHECK(hostFs.readFromFile(params, &readPtr, readSize, readBuf.size()) == returnvalue::OK);
|
||||
size_t readSize = data.size();
|
||||
size_t actuallyRead = 0;
|
||||
CHECK(hostFs.readFromFile(file0.c_str(), 0, readSize, readPtr, actuallyRead, readBuf.size()) ==
|
||||
returnvalue::OK);
|
||||
std::string readBackString(reinterpret_cast<const char*>(readBuf.data()));
|
||||
CHECK(readSize == data.size());
|
||||
CHECK(data == readBackString);
|
||||
@ -125,21 +119,21 @@ TEST_CASE("Host Filesystem", "[hal][host]") {
|
||||
|
||||
SECTION("Invalid Input does not crash") {
|
||||
FileOpParams params(nullptr, 10);
|
||||
REQUIRE(hostFs.createFile(params.fsParams) != returnvalue::OK);
|
||||
REQUIRE(hostFs.createDirectory(params.fsParams) != returnvalue::OK);
|
||||
REQUIRE(hostFs.createFile(params.fsParams) != returnvalue::OK);
|
||||
REQUIRE(hostFs.removeDirectory(params.fsParams) != returnvalue::OK);
|
||||
REQUIRE(hostFs.createFile(nullptr) != returnvalue::OK);
|
||||
REQUIRE(hostFs.createDirectory(nullptr) != returnvalue::OK);
|
||||
REQUIRE(hostFs.createFile(nullptr) != returnvalue::OK);
|
||||
REQUIRE(hostFs.removeDirectory(nullptr, false, nullptr) != returnvalue::OK);
|
||||
REQUIRE(hostFs.removeFile(nullptr) != returnvalue::OK);
|
||||
REQUIRE(hostFs.rename(nullptr, nullptr) != returnvalue::OK);
|
||||
REQUIRE(hostFs.writeToFile(params, nullptr) != returnvalue::OK);
|
||||
REQUIRE(hostFs.writeToFile(nullptr, 0, nullptr, 0) != returnvalue::OK);
|
||||
size_t readLen = 0;
|
||||
REQUIRE(hostFs.readFromFile(params, nullptr, readLen, 20) != returnvalue::OK);
|
||||
REQUIRE(hostFs.readFromFile(nullptr, 0, 0, nullptr, readLen, 20) != returnvalue::OK);
|
||||
}
|
||||
|
||||
SECTION("Create File but already exists") {
|
||||
FilesystemParams params(file0.c_str());
|
||||
REQUIRE(hostFs.createFile(params) == returnvalue::OK);
|
||||
REQUIRE(hostFs.createFile(params) == HasFileSystemIF::FILE_ALREADY_EXISTS);
|
||||
REQUIRE(hostFs.createFile(file0.c_str()) == returnvalue::OK);
|
||||
REQUIRE(hostFs.createFile(file0.c_str()) == HasFileSystemIF::FILE_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
SECTION("Remove File but does not exist") {
|
||||
@ -148,36 +142,35 @@ TEST_CASE("Host Filesystem", "[hal][host]") {
|
||||
|
||||
SECTION("Create Directory but already exists") {
|
||||
FileOpParams params(file0.c_str(), 12);
|
||||
REQUIRE(hostFs.createDirectory(params.fsParams) == returnvalue::OK);
|
||||
REQUIRE(hostFs.createDirectory(params.fsParams) == HasFileSystemIF::DIRECTORY_ALREADY_EXISTS);
|
||||
REQUIRE(hostFs.createDirectory(file0.c_str()) == returnvalue::OK);
|
||||
REQUIRE(hostFs.createDirectory(file0.c_str()) == HasFileSystemIF::DIRECTORY_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
SECTION("Remove Directory but does not exist") {
|
||||
FilesystemParams params(dir0.c_str());
|
||||
REQUIRE(hostFs.removeDirectory(params) == HasFileSystemIF::DIRECTORY_DOES_NOT_EXIST);
|
||||
REQUIRE(hostFs.removeDirectory(dir0.c_str(), false, nullptr) ==
|
||||
HasFileSystemIF::DIRECTORY_DOES_NOT_EXIST);
|
||||
}
|
||||
|
||||
SECTION("Remove Directory but is file") {
|
||||
ofstream of(file0);
|
||||
FilesystemParams params(file0.c_str());
|
||||
REQUIRE(hostFs.removeDirectory(params) == HasFileSystemIF::NOT_A_DIRECTORY);
|
||||
REQUIRE(hostFs.removeDirectory(file0.c_str(), false, nullptr) ==
|
||||
HasFileSystemIF::NOT_A_DIRECTORY);
|
||||
}
|
||||
|
||||
SECTION("Read from file but does not exist") {
|
||||
std::string data = "hello world!";
|
||||
FileOpParams params(file0.c_str(), data.size());
|
||||
std::array<uint8_t, 10> readBuf{};
|
||||
std::array<uint8_t, 16> readBuf{};
|
||||
uint8_t* readPtr = readBuf.data();
|
||||
size_t readSize = 0;
|
||||
CHECK(hostFs.readFromFile(params, &readPtr, readSize, readBuf.size()) ==
|
||||
CHECK(hostFs.readFromFile(file0.c_str(), 0, data.size(), readPtr, readSize, readBuf.size()) ==
|
||||
HasFileSystemIF::FILE_DOES_NOT_EXIST);
|
||||
}
|
||||
|
||||
SECTION("Write to file but does not exist") {
|
||||
std::string data = "hello world!";
|
||||
FileOpParams params(file0.c_str(), data.size());
|
||||
CHECK(hostFs.writeToFile(params, reinterpret_cast<const uint8_t*>(data.c_str())) ==
|
||||
HasFileSystemIF::FILE_DOES_NOT_EXIST);
|
||||
CHECK(hostFs.writeToFile(file0.c_str(), 0, reinterpret_cast<const uint8_t*>(data.c_str()),
|
||||
data.size()) == HasFileSystemIF::FILE_DOES_NOT_EXIST);
|
||||
}
|
||||
|
||||
SECTION("Remove recursively") {
|
||||
@ -185,7 +178,7 @@ TEST_CASE("Host Filesystem", "[hal][host]") {
|
||||
ofstream of(fileInDir0);
|
||||
CHECK(fs::is_directory(dir0));
|
||||
CHECK(fs::is_regular_file(fileInDir0));
|
||||
REQUIRE(hostFs.removeDirectory(FilesystemParams(dir0.c_str()), true) == returnvalue::OK);
|
||||
REQUIRE(hostFs.removeDirectory(dir0.c_str(), true, nullptr) == returnvalue::OK);
|
||||
CHECK(not fs::is_directory(dir0));
|
||||
CHECK(not fs::is_regular_file(fileInDir0));
|
||||
}
|
||||
@ -195,12 +188,12 @@ TEST_CASE("Host Filesystem", "[hal][host]") {
|
||||
ofstream of(fileInDir0);
|
||||
CHECK(fs::is_directory(dir0));
|
||||
CHECK(fs::is_regular_file(fileInDir0));
|
||||
REQUIRE(hostFs.removeDirectory(FilesystemParams(dir0.c_str())) ==
|
||||
REQUIRE(hostFs.removeDirectory(dir0.c_str(), false, nullptr) ==
|
||||
HasFileSystemIF::DIRECTORY_NOT_EMPTY);
|
||||
}
|
||||
|
||||
SECTION("Create directory with parent directory") {
|
||||
CHECK(hostFs.createDirectory(FilesystemParams(dirWithParent.c_str()), true) == returnvalue::OK);
|
||||
CHECK(hostFs.createDirectory(dirWithParent.c_str(), true, nullptr) == returnvalue::OK);
|
||||
CHECK(fs::is_directory(dir0));
|
||||
CHECK(fs::is_directory(dirWithParent));
|
||||
}
|
||||
@ -216,10 +209,9 @@ TEST_CASE("Host Filesystem", "[hal][host]") {
|
||||
std::array<uint8_t, 15> readBuf{};
|
||||
uint8_t* readPtr = readBuf.data();
|
||||
size_t readSize = 0;
|
||||
CHECK(hostFs.readFromFile(params, &readPtr, readSize, 5) == SerializeIF::BUFFER_TOO_SHORT);
|
||||
readSize = 10;
|
||||
CHECK(hostFs.readFromFile(params, &readPtr, readSize, readBuf.size()) ==
|
||||
CHECK(hostFs.readFromFile(file0.c_str(), 0, data.size(), readPtr, readSize, 5) ==
|
||||
SerializeIF::BUFFER_TOO_SHORT);
|
||||
;
|
||||
}
|
||||
|
||||
REQUIRE_NOTHROW(fs::remove(file0));
|
||||
|
@ -4,9 +4,7 @@
|
||||
|
||||
DeviceHandlerMock::DeviceHandlerMock(object_id_t objectId, object_id_t deviceCommunication,
|
||||
CookieIF *comCookie, FailureIsolationBase *fdirInstance)
|
||||
: DeviceHandlerBase(objectId, deviceCommunication, comCookie, fdirInstance) {
|
||||
setMode(MODE_ON);
|
||||
}
|
||||
: DeviceHandlerBase(objectId, deviceCommunication, comCookie, fdirInstance) {}
|
||||
|
||||
DeviceHandlerMock::~DeviceHandlerMock() = default;
|
||||
|
||||
@ -101,3 +99,12 @@ ReturnValue_t DeviceHandlerMock::enablePeriodicReply(DeviceCommandId_t replyId)
|
||||
ReturnValue_t DeviceHandlerMock::disablePeriodicReply(DeviceCommandId_t replyId) {
|
||||
return updatePeriodicReply(false, replyId);
|
||||
}
|
||||
|
||||
ReturnValue_t DeviceHandlerMock::initialize() {
|
||||
ReturnValue_t result = DeviceHandlerBase::initialize();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
setMode(MODE_ON);
|
||||
return result;
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ class DeviceHandlerMock : public DeviceHandlerBase {
|
||||
ReturnValue_t enablePeriodicReply(DeviceCommandId_t replyId);
|
||||
ReturnValue_t disablePeriodicReply(DeviceCommandId_t replyId);
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
protected:
|
||||
void doStartUp() override;
|
||||
void doShutDown() override;
|
||||
|
@ -1,60 +1,58 @@
|
||||
#include "FilesystemMock.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
|
||||
#include "fsfw/serialize/SerializeIF.h"
|
||||
|
||||
ReturnValue_t FilesystemMock::feedFile(const std::string &filename, std::ifstream &file) {
|
||||
ReturnValue_t FilesystemMock::feedFile(const std::string& filename, std::ifstream& file) {
|
||||
if (not std::filesystem::exists(filename)) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
size_t fileSize = std::filesystem::file_size(filename);
|
||||
FileOpParams params(filename.c_str(), fileSize);
|
||||
std::vector<uint8_t> rawData(fileSize);
|
||||
file.read(reinterpret_cast<char *>(rawData.data()), static_cast<unsigned int>(rawData.size()));
|
||||
createOrAddToFile(params, rawData.data());
|
||||
file.read(reinterpret_cast<char*>(rawData.data()), static_cast<unsigned int>(rawData.size()));
|
||||
createOrAddToFile(filename.data(), 0, rawData.data(), rawData.size());
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t FilesystemMock::writeToFile(FileOpParams params, const uint8_t *data) {
|
||||
createOrAddToFile(params, data);
|
||||
ReturnValue_t FilesystemMock::writeToFile(const char* path, size_t offset, const uint8_t* data,
|
||||
size_t size) {
|
||||
createOrAddToFile(path, offset, data, size);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t FilesystemMock::readFromFile(FileOpParams params, uint8_t **buffer, size_t &readSize,
|
||||
size_t maxSize) {
|
||||
std::string filename(params.path());
|
||||
auto iter = fileMap.find(filename);
|
||||
ReturnValue_t FilesystemMock::readFromFile(const char* path, size_t offset, size_t size,
|
||||
uint8_t* buffer, size_t& readSize, size_t maxSize) {
|
||||
const std::string filename(path);
|
||||
const auto iter = fileMap.find(filename);
|
||||
if (iter == fileMap.end()) {
|
||||
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
|
||||
} else {
|
||||
FileInfo &info = iter->second;
|
||||
size_t readLen = params.size;
|
||||
if (params.offset + params.size > info.fileRaw.size()) {
|
||||
if (params.offset > info.fileRaw.size()) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
readLen = info.fileRaw.size() - params.offset;
|
||||
}
|
||||
if (readSize + readLen > maxSize) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
std::copy(info.fileRaw.data() + params.offset, info.fileRaw.data() + params.offset + readLen,
|
||||
*buffer);
|
||||
*buffer += readLen;
|
||||
readSize += readLen;
|
||||
}
|
||||
auto& [fileSegQueue, fileRaw] = iter->second;
|
||||
size_t readLen = size;
|
||||
if (offset + size > fileRaw.size()) {
|
||||
if (offset > fileRaw.size()) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
readLen = fileRaw.size() - offset;
|
||||
}
|
||||
if (readSize + readLen > maxSize) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
// std::copy(info.fileRaw.data() + offset, info.fileRaw.data() + offset + readLen, *buffer);
|
||||
std::memcpy(buffer, fileRaw.data() + offset, readLen);
|
||||
readSize = readLen;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t FilesystemMock::createFile(FilesystemParams params, const uint8_t *data,
|
||||
size_t size) {
|
||||
FileOpParams params2(params.path, size);
|
||||
createOrAddToFile(params2, data);
|
||||
ReturnValue_t FilesystemMock::createFile(const char* path, const uint8_t* data, size_t size) {
|
||||
createOrAddToFile(path, 0, data, size);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t FilesystemMock::removeFile(const char *path, FileSystemArgsIF *args) {
|
||||
ReturnValue_t FilesystemMock::removeFile(const char* path, FileSystemArgsIF* args) {
|
||||
std::string filename(path);
|
||||
auto iter = fileMap.find(filename);
|
||||
if (iter == fileMap.end()) {
|
||||
@ -65,56 +63,58 @@ ReturnValue_t FilesystemMock::removeFile(const char *path, FileSystemArgsIF *arg
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t FilesystemMock::createDirectory(FilesystemParams params, bool createParentDirs) {
|
||||
std::string dirPath = params.path;
|
||||
ReturnValue_t FilesystemMock::createDirectory(const char* path, bool createParentDirs,
|
||||
FileSystemArgsIF* args) {
|
||||
std::string dirPath = path;
|
||||
dirMap[dirPath].createCallCount++;
|
||||
dirMap[dirPath].wihParentDir.push(createParentDirs);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t FilesystemMock::removeDirectory(FilesystemParams params, bool deleteRecurively) {
|
||||
std::string dirPath = params.path;
|
||||
ReturnValue_t FilesystemMock::removeDirectory(const char* path, bool deleteRecurively,
|
||||
FileSystemArgsIF* args) {
|
||||
std::string dirPath = path;
|
||||
dirMap[dirPath].delCallCount++;
|
||||
dirMap[dirPath].recursiveDeletion.push(deleteRecurively);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t FilesystemMock::rename(const char *oldPath, const char *newPath,
|
||||
FileSystemArgsIF *args) {
|
||||
ReturnValue_t FilesystemMock::rename(const char* oldPath, const char* newPath,
|
||||
FileSystemArgsIF* args) {
|
||||
renameQueue.emplace(oldPath, newPath);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void FilesystemMock::createOrAddToFile(FileOpParams params, const uint8_t *data) {
|
||||
std::string filename(params.path());
|
||||
void FilesystemMock::createOrAddToFile(const char* path, size_t offset, const uint8_t* data,
|
||||
size_t dataSize) {
|
||||
std::string filename(path);
|
||||
auto iter = fileMap.find(filename);
|
||||
if (iter == fileMap.end()) {
|
||||
FileSegmentQueue queue;
|
||||
if (params.size > 0) {
|
||||
queue.emplace(filename, params.offset, data, params.size);
|
||||
if (dataSize > 0) {
|
||||
queue.emplace(filename, offset, data, dataSize);
|
||||
}
|
||||
FileInfo info;
|
||||
info.fileSegQueue = queue;
|
||||
if (data != nullptr) {
|
||||
info.fileRaw.insert(info.fileRaw.end(), data, data + params.size);
|
||||
info.fileRaw.insert(info.fileRaw.end(), data, data + dataSize);
|
||||
}
|
||||
fileMap.emplace(filename, info);
|
||||
} else {
|
||||
FileInfo &info = iter->second;
|
||||
info.fileSegQueue.emplace(filename, params.offset, data, params.size);
|
||||
FileInfo& info = iter->second;
|
||||
info.fileSegQueue.emplace(filename, offset, data, dataSize);
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
// Easiest case: append data to the end
|
||||
if (params.offset == info.fileRaw.size()) {
|
||||
info.fileRaw.insert(info.fileRaw.end(), data, data + params.size);
|
||||
if (offset == info.fileRaw.size()) {
|
||||
info.fileRaw.insert(info.fileRaw.end(), data, data + dataSize);
|
||||
} else {
|
||||
size_t totalNewLen = params.offset + params.size;
|
||||
size_t totalNewLen = offset + dataSize;
|
||||
if (totalNewLen > info.fileRaw.size()) {
|
||||
info.fileRaw.resize(params.offset + params.size);
|
||||
info.fileRaw.resize(offset + dataSize);
|
||||
}
|
||||
std::copy(data, data + params.size,
|
||||
info.fileRaw.begin() + static_cast<unsigned int>(params.offset));
|
||||
std::copy(data, data + dataSize, info.fileRaw.begin() + static_cast<unsigned int>(offset));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -126,8 +126,8 @@ void FilesystemMock::reset() {
|
||||
std::swap(renameQueue, empty);
|
||||
}
|
||||
|
||||
bool FilesystemMock::fileExists(FilesystemParams params) {
|
||||
std::string filename(params.path);
|
||||
bool FilesystemMock::fileExists(const char* path, FileSystemArgsIF* args) {
|
||||
std::string filename(path);
|
||||
auto iter = fileMap.find(filename);
|
||||
if (iter == fileMap.end()) {
|
||||
return false;
|
||||
@ -135,20 +135,21 @@ bool FilesystemMock::fileExists(FilesystemParams params) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ReturnValue_t FilesystemMock::truncateFile(FilesystemParams params) {
|
||||
truncateCalledOnFile = params.path;
|
||||
ReturnValue_t FilesystemMock::truncateFile(const char* path, FileSystemArgsIF* args) {
|
||||
truncateCalledOnFile = path;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t FilesystemMock::getBaseFilename(FilesystemParams params, char *nameBuf, size_t maxLen,
|
||||
size_t &baseNameLen) {
|
||||
ReturnValue_t FilesystemMock::getBaseFilename(const char* path, char* nameBuf, size_t maxLen,
|
||||
size_t& baseNameLen) {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
bool FilesystemMock::isDirectory(const char *path) { return false; }
|
||||
ReturnValue_t FilesystemMock::isDirectory(const char* path, bool& isDirectory) { return false; }
|
||||
|
||||
bool FilesystemMock::getFileSize(FilesystemParams params, size_t &fileSize) {
|
||||
std::string filename(params.path);
|
||||
ReturnValue_t FilesystemMock::getFileSize(const char* path, uint64_t& fileSize,
|
||||
FileSystemArgsIF* args) {
|
||||
std::string filename(path);
|
||||
auto iter = fileMap.find(filename);
|
||||
if (iter != fileMap.end()) {
|
||||
fileSize = iter->second.fileRaw.size();
|
||||
|
@ -20,7 +20,7 @@
|
||||
class FilesystemMock : public HasFileSystemIF {
|
||||
public:
|
||||
struct FileWriteInfo {
|
||||
FileWriteInfo(std::string filename, size_t offset, const uint8_t *data, size_t len)
|
||||
FileWriteInfo(std::string filename, size_t offset, const uint8_t* data, size_t len)
|
||||
: filename(std::move(filename)), offset(offset) {
|
||||
this->data.insert(this->data.end(), data, data + len);
|
||||
}
|
||||
@ -54,24 +54,34 @@ class FilesystemMock : public HasFileSystemIF {
|
||||
};
|
||||
std::queue<RenameInfo> renameQueue;
|
||||
std::string truncateCalledOnFile;
|
||||
ReturnValue_t feedFile(const std::string &filename, std::ifstream &file);
|
||||
ReturnValue_t feedFile(const std::string& filename, std::ifstream& file);
|
||||
|
||||
ReturnValue_t getBaseFilename(FilesystemParams params, char *nameBuf, size_t maxLen,
|
||||
size_t &baseNameLen) override;
|
||||
ReturnValue_t getBaseFilename(const char* path, char* nameBuf, size_t maxLen,
|
||||
size_t& baseNameLen) override;
|
||||
|
||||
bool isDirectory(const char *path) override;
|
||||
bool fileExists(FilesystemParams params) override;
|
||||
ReturnValue_t truncateFile(FilesystemParams params) override;
|
||||
bool getFileSize(FilesystemParams params, size_t &fileSize) override;
|
||||
ReturnValue_t isDirectory(const char* path, bool& isDirectory) override;
|
||||
|
||||
ReturnValue_t writeToFile(FileOpParams params, const uint8_t *data) override;
|
||||
ReturnValue_t readFromFile(FileOpParams params, uint8_t **buffer, size_t &readSize,
|
||||
size_t maxSize) override;
|
||||
ReturnValue_t createFile(FilesystemParams params, const uint8_t *data, size_t size) override;
|
||||
ReturnValue_t removeFile(const char *path, FileSystemArgsIF *args) override;
|
||||
ReturnValue_t createDirectory(FilesystemParams params, bool createParentDirs) override;
|
||||
ReturnValue_t removeDirectory(FilesystemParams params, bool deleteRecurively) override;
|
||||
ReturnValue_t rename(const char *oldPath, const char *newPath, FileSystemArgsIF *args) override;
|
||||
bool fileExists(const char* path, FileSystemArgsIF* args) override;
|
||||
|
||||
ReturnValue_t truncateFile(const char* path, FileSystemArgsIF* args) override;
|
||||
|
||||
ReturnValue_t getFileSize(const char* path, uint64_t& fileSize, FileSystemArgsIF* args) override;
|
||||
|
||||
ReturnValue_t writeToFile(const char* path, size_t offset, const uint8_t* data,
|
||||
size_t size) override;
|
||||
|
||||
ReturnValue_t readFromFile(const char* path, size_t offset, size_t size, uint8_t* buffer,
|
||||
size_t& readSize, size_t maxSize) override;
|
||||
|
||||
ReturnValue_t createFile(const char* path, const uint8_t* data, size_t size) override;
|
||||
ReturnValue_t removeFile(const char* path, FileSystemArgsIF* args) override;
|
||||
|
||||
ReturnValue_t createDirectory(const char* path, bool createParentDirs,
|
||||
FileSystemArgsIF* args) override;
|
||||
|
||||
ReturnValue_t removeDirectory(const char* path, bool deleteRecurively,
|
||||
FileSystemArgsIF* args) override;
|
||||
ReturnValue_t rename(const char* oldPath, const char* newPath, FileSystemArgsIF* args) override;
|
||||
|
||||
void reset();
|
||||
|
||||
@ -80,7 +90,7 @@ class FilesystemMock : public HasFileSystemIF {
|
||||
using HasFileSystemIF::readFromFile;
|
||||
|
||||
private:
|
||||
void createOrAddToFile(FileOpParams params, const uint8_t *data);
|
||||
void createOrAddToFile(const char* path, size_t offset, const uint8_t* data, size_t dataSize);
|
||||
};
|
||||
|
||||
#endif // FSFW_MOCKS_FILESYSTEMMOCK_H
|
||||
|
@ -82,13 +82,15 @@ TEST_CASE("CCSDS Creator", "[ccsds-creator]") {
|
||||
CHECK(buf[5] == 0xFF);
|
||||
}
|
||||
|
||||
SECTION("Setting data length 0 is ignored") {
|
||||
SECTION("Setting data length 0") {
|
||||
SpacePacketCreator creator = SpacePacketCreator(
|
||||
ccsds::PacketType::TC, true, 0xFFFF, ccsds::SequenceFlags::FIRST_SEGMENT, 0x34, 0x22);
|
||||
creator.setCcsdsLenFromTotalDataFieldLen(0);
|
||||
REQUIRE(creator.getPacketDataLen() == 0x22);
|
||||
// Will result in field length 0.
|
||||
REQUIRE(creator.getPacketDataLen() == 0);
|
||||
// Will also result in field length 0.
|
||||
creator.setCcsdsLenFromTotalDataFieldLen(1);
|
||||
REQUIRE(creator.getPacketDataLen() == 0x00);
|
||||
REQUIRE(creator.getPacketDataLen() == 0);
|
||||
}
|
||||
|
||||
SECTION("Invalid APID") {
|
||||
|
Reference in New Issue
Block a user