CFDP FSFW Integration #111
@ -40,7 +40,7 @@ ReturnValue_t CfdpDistributor::selectDestination(MessageQueueId_t& destId) {
|
|||||||
}
|
}
|
||||||
if (not destFound) {
|
if (not destFound) {
|
||||||
// TODO: Warning and event?
|
// TODO: Warning and event?
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return tmtcdistrib::NO_DESTINATION_FOUND;
|
||||||
}
|
}
|
||||||
// Packet was forwarded successfully, so do not delete it.
|
// Packet was forwarded successfully, so do not delete it.
|
||||||
accessorPair.second.release();
|
accessorPair.second.release();
|
||||||
|
@ -34,7 +34,7 @@ enum : uint8_t {
|
|||||||
FIFO_CLASS, // FF
|
FIFO_CLASS, // FF
|
||||||
MESSAGE_PROXY, // MQP
|
MESSAGE_PROXY, // MQP
|
||||||
TRIPLE_REDUNDACY_CHECK, // TRC
|
TRIPLE_REDUNDACY_CHECK, // TRC
|
||||||
PACKET_CHECK, // TCC
|
TMTC_DISTRIBUTION, // TCC
|
||||||
PACKET_DISTRIBUTION, // TCD
|
PACKET_DISTRIBUTION, // TCD
|
||||||
ACCEPTS_TELECOMMANDS_IF, // ATC
|
ACCEPTS_TELECOMMANDS_IF, // ATC
|
||||||
PUS_IF, // PUS
|
PUS_IF, // PUS
|
||||||
|
@ -19,7 +19,7 @@ ConstStorageAccessor::~ConstStorageAccessor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstStorageAccessor::ConstStorageAccessor(ConstStorageAccessor&& other)
|
ConstStorageAccessor::ConstStorageAccessor(ConstStorageAccessor&& other) noexcept
|
||||||
: constDataPointer(other.constDataPointer),
|
: constDataPointer(other.constDataPointer),
|
||||||
storeId(other.storeId),
|
storeId(other.storeId),
|
||||||
size_(other.size_),
|
size_(other.size_),
|
||||||
@ -30,7 +30,7 @@ ConstStorageAccessor::ConstStorageAccessor(ConstStorageAccessor&& other)
|
|||||||
other.store = nullptr;
|
other.store = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstStorageAccessor& ConstStorageAccessor::operator=(ConstStorageAccessor&& other) {
|
ConstStorageAccessor& ConstStorageAccessor::operator=(ConstStorageAccessor&& other) noexcept {
|
||||||
constDataPointer = other.constDataPointer;
|
constDataPointer = other.constDataPointer;
|
||||||
storeId = other.storeId;
|
storeId = other.storeId;
|
||||||
store = other.store;
|
store = other.store;
|
||||||
@ -84,7 +84,7 @@ void ConstStorageAccessor::print() const {
|
|||||||
arrayprinter::print(constDataPointer, size_);
|
arrayprinter::print(constDataPointer, size_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConstStorageAccessor::assignStore(StorageManagerIF* store) {
|
void ConstStorageAccessor::assignStore(StorageManagerIF* store_) {
|
||||||
internalState = AccessState::ASSIGNED;
|
internalState = AccessState::ASSIGNED;
|
||||||
this->store = store;
|
store = store_;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ class ConstStorageAccessor {
|
|||||||
//! StorageManager classes have exclusive access to private variables.
|
//! StorageManager classes have exclusive access to private variables.
|
||||||
friend class PoolManager;
|
friend class PoolManager;
|
||||||
friend class LocalPool;
|
friend class LocalPool;
|
||||||
|
friend class StorageManagerIF;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -30,7 +31,7 @@ class ConstStorageAccessor {
|
|||||||
* entry to access.
|
* entry to access.
|
||||||
* @param storeId
|
* @param storeId
|
||||||
*/
|
*/
|
||||||
ConstStorageAccessor(store_address_t storeId);
|
explicit ConstStorageAccessor(store_address_t storeId);
|
||||||
ConstStorageAccessor(store_address_t storeId, StorageManagerIF* store);
|
ConstStorageAccessor(store_address_t storeId, StorageManagerIF* store);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,7 +44,7 @@ class ConstStorageAccessor {
|
|||||||
* @brief Returns a pointer to the read-only data
|
* @brief Returns a pointer to the read-only data
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
const uint8_t* data() const;
|
[[nodiscard]] const uint8_t* data() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copies the read-only data to the supplied pointer
|
* @brief Copies the read-only data to the supplied pointer
|
||||||
@ -61,13 +62,13 @@ class ConstStorageAccessor {
|
|||||||
* Get the size of the data
|
* Get the size of the data
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
size_t size() const;
|
[[nodiscard]] size_t size() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the storage ID.
|
* Get the storage ID.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
store_address_t getId() const;
|
[[nodiscard]] store_address_t getId() const;
|
||||||
|
|
||||||
void print() const;
|
void print() const;
|
||||||
|
|
||||||
@ -79,8 +80,8 @@ class ConstStorageAccessor {
|
|||||||
* @param
|
* @param
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
ConstStorageAccessor& operator=(ConstStorageAccessor&&);
|
ConstStorageAccessor& operator=(ConstStorageAccessor&&) noexcept ;
|
||||||
ConstStorageAccessor(ConstStorageAccessor&&);
|
ConstStorageAccessor(ConstStorageAccessor&&) noexcept ;
|
||||||
|
|
||||||
//! The copy ctor and copy assignemnt should be deleted implicitely
|
//! The copy ctor and copy assignemnt should be deleted implicitely
|
||||||
//! according to https://foonathan.net/2019/02/special-member-functions/
|
//! according to https://foonathan.net/2019/02/special-member-functions/
|
||||||
|
@ -29,7 +29,7 @@ LocalPool::LocalPool(object_id_t setObjectId, const LocalPoolConfig& poolConfig,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalPool::~LocalPool(void) {}
|
LocalPool::~LocalPool() = default;
|
||||||
|
|
||||||
ReturnValue_t LocalPool::addData(store_address_t* storageId, const uint8_t* data, size_t size,
|
ReturnValue_t LocalPool::addData(store_address_t* storageId, const uint8_t* data, size_t size,
|
||||||
bool ignoreFault) {
|
bool ignoreFault) {
|
||||||
@ -48,22 +48,6 @@ ReturnValue_t LocalPool::getData(store_address_t packetId, const uint8_t** packe
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalPool::getData(store_address_t storeId, ConstStorageAccessor& storeAccessor) {
|
|
||||||
uint8_t* tempData = nullptr;
|
|
||||||
ReturnValue_t status = modifyData(storeId, &tempData, &storeAccessor.size_);
|
|
||||||
storeAccessor.assignStore(this);
|
|
||||||
storeAccessor.constDataPointer = tempData;
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstAccessorPair LocalPool::getData(store_address_t storeId) {
|
|
||||||
uint8_t* tempData = nullptr;
|
|
||||||
ConstStorageAccessor constAccessor(storeId, this);
|
|
||||||
ReturnValue_t status = modifyData(storeId, &tempData, &constAccessor.size_);
|
|
||||||
constAccessor.constDataPointer = tempData;
|
|
||||||
return ConstAccessorPair(status, std::move(constAccessor));
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPool::getFreeElement(store_address_t* storageId, const size_t size,
|
ReturnValue_t LocalPool::getFreeElement(store_address_t* storageId, const size_t size,
|
||||||
uint8_t** pData, bool ignoreFault) {
|
uint8_t** pData, bool ignoreFault) {
|
||||||
ReturnValue_t status = reserveSpace(size, storageId, ignoreFault);
|
ReturnValue_t status = reserveSpace(size, storageId, ignoreFault);
|
||||||
@ -75,20 +59,6 @@ ReturnValue_t LocalPool::getFreeElement(store_address_t* storageId, const size_t
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessorPair LocalPool::modifyData(store_address_t storeId) {
|
|
||||||
StorageAccessor accessor(storeId, this);
|
|
||||||
ReturnValue_t status = modifyData(storeId, &accessor.dataPointer, &accessor.size_);
|
|
||||||
accessor.assignConstPointer();
|
|
||||||
return AccessorPair(status, std::move(accessor));
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPool::modifyData(store_address_t storeId, StorageAccessor& storeAccessor) {
|
|
||||||
storeAccessor.assignStore(this);
|
|
||||||
ReturnValue_t status = modifyData(storeId, &storeAccessor.dataPointer, &storeAccessor.size_);
|
|
||||||
storeAccessor.assignConstPointer();
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t LocalPool::modifyData(store_address_t storeId, uint8_t** packetPtr, size_t* size) {
|
ReturnValue_t LocalPool::modifyData(store_address_t storeId, uint8_t** packetPtr, size_t* size) {
|
||||||
ReturnValue_t status = RETURN_FAILED;
|
ReturnValue_t status = RETURN_FAILED;
|
||||||
if (storeId.poolIndex >= NUMBER_OF_SUBPOOLS) {
|
if (storeId.poolIndex >= NUMBER_OF_SUBPOOLS) {
|
||||||
@ -197,7 +167,7 @@ void LocalPool::clearStore() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t LocalPool::reserveSpace(const size_t size, store_address_t* storeId,
|
ReturnValue_t LocalPool::reserveSpace(size_t size, store_address_t* storeId,
|
||||||
bool ignoreFault) {
|
bool ignoreFault) {
|
||||||
ReturnValue_t status = getSubPoolIndex(size, &storeId->poolIndex);
|
ReturnValue_t status = getSubPoolIndex(size, &storeId->poolIndex);
|
||||||
if (status != RETURN_OK) {
|
if (status != RETURN_OK) {
|
||||||
@ -349,3 +319,27 @@ bool LocalPool::hasDataAtId(store_address_t storeId) const {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t LocalPool::getFreeElement(store_address_t* storeId, size_t size, uint8_t** pData) {
|
||||||
|
return StorageManagerIF::getFreeElement(storeId, size, pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstAccessorPair LocalPool::getData(store_address_t storeId) {
|
||||||
|
return StorageManagerIF::getData(storeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t LocalPool::addData(store_address_t* storeId, const uint8_t* data, size_t size) {
|
||||||
|
return StorageManagerIF::addData(storeId, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t LocalPool::getData(store_address_t storeId, ConstStorageAccessor& accessor) {
|
||||||
|
return StorageManagerIF::getData(storeId, accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t LocalPool::modifyData(store_address_t storeId, StorageAccessor& accessor) {
|
||||||
|
return StorageManagerIF::modifyData(storeId, accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessorPair LocalPool::modifyData(store_address_t storeId) {
|
||||||
|
return StorageManagerIF::modifyData(storeId);
|
||||||
|
}
|
||||||
|
@ -87,21 +87,23 @@ class LocalPool : public SystemObject, public StorageManagerIF {
|
|||||||
* Documentation: See StorageManagerIF.h
|
* Documentation: See StorageManagerIF.h
|
||||||
*/
|
*/
|
||||||
ReturnValue_t addData(store_address_t* storeId, const uint8_t* data, size_t size,
|
ReturnValue_t addData(store_address_t* storeId, const uint8_t* data, size_t size,
|
||||||
bool ignoreFault = false) override;
|
bool ignoreFault) override;
|
||||||
|
ReturnValue_t addData(store_address_t* storeId, const uint8_t* data, size_t size) override;
|
||||||
|
|
||||||
|
ReturnValue_t getFreeElement(store_address_t* storeId, size_t size, uint8_t** pData) override;
|
||||||
ReturnValue_t getFreeElement(store_address_t* storeId, size_t size, uint8_t** pData,
|
ReturnValue_t getFreeElement(store_address_t* storeId, size_t size, uint8_t** pData,
|
||||||
bool ignoreFault = false) override;
|
bool ignoreFault) override;
|
||||||
|
|
||||||
ConstAccessorPair getData(store_address_t storeId) override;
|
ConstAccessorPair getData(store_address_t storeId) override;
|
||||||
ReturnValue_t getData(store_address_t storeId, ConstStorageAccessor& constAccessor) override;
|
ReturnValue_t getData(store_address_t storeId, ConstStorageAccessor& accessor) override;
|
||||||
ReturnValue_t getData(store_address_t storeId, const uint8_t** packet_ptr, size_t* size) override;
|
ReturnValue_t getData(store_address_t storeId, const uint8_t** packet_ptr, size_t* size) override;
|
||||||
|
|
||||||
AccessorPair modifyData(store_address_t storeId) override;
|
AccessorPair modifyData(store_address_t storeId) override;
|
||||||
ReturnValue_t modifyData(store_address_t storeId, StorageAccessor& storeAccessor) override;
|
|
||||||
ReturnValue_t modifyData(store_address_t storeId, uint8_t** packet_ptr, size_t* size) override;
|
ReturnValue_t modifyData(store_address_t storeId, uint8_t** packet_ptr, size_t* size) override;
|
||||||
|
ReturnValue_t modifyData(store_address_t storeId, StorageAccessor& accessor) override;
|
||||||
|
|
||||||
virtual ReturnValue_t deleteData(store_address_t storeId) override;
|
ReturnValue_t deleteData(store_address_t storeId) override;
|
||||||
virtual ReturnValue_t deleteData(uint8_t* ptr, size_t size,
|
ReturnValue_t deleteData(uint8_t* ptr, size_t size, store_address_t* storeId) override;
|
||||||
store_address_t* storeId = nullptr) override;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the total size of allocated memory for pool data.
|
* Get the total size of allocated memory for pool data.
|
||||||
@ -131,8 +133,8 @@ class LocalPool : public SystemObject, public StorageManagerIF {
|
|||||||
* Get number sub pools. Each pool has pages with a specific bucket size.
|
* Get number sub pools. Each pool has pages with a specific bucket size.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
max_subpools_t getNumberOfSubPools() const override;
|
[[nodiscard]] max_subpools_t getNumberOfSubPools() const override;
|
||||||
bool hasDataAtId(store_address_t storeId) const override;
|
[[nodiscard]] bool hasDataAtId(store_address_t storeId) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
@ -142,7 +144,7 @@ class LocalPool : public SystemObject, public StorageManagerIF {
|
|||||||
* @return - #RETURN_OK on success,
|
* @return - #RETURN_OK on success,
|
||||||
* - the return codes of #getPoolIndex or #findEmpty otherwise.
|
* - the return codes of #getPoolIndex or #findEmpty otherwise.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t reserveSpace(const size_t size, store_address_t* address, bool ignoreFault);
|
virtual ReturnValue_t reserveSpace(size_t size, store_address_t* address, bool ignoreFault);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
@ -10,7 +10,7 @@ StorageAccessor::StorageAccessor(store_address_t storeId) : ConstStorageAccessor
|
|||||||
StorageAccessor::StorageAccessor(store_address_t storeId, StorageManagerIF* store)
|
StorageAccessor::StorageAccessor(store_address_t storeId, StorageManagerIF* store)
|
||||||
: ConstStorageAccessor(storeId, store) {}
|
: ConstStorageAccessor(storeId, store) {}
|
||||||
|
|
||||||
StorageAccessor& StorageAccessor::operator=(StorageAccessor&& other) {
|
StorageAccessor& StorageAccessor::operator=(StorageAccessor&& other) noexcept {
|
||||||
// Call the parent move assignment and also assign own member.
|
// Call the parent move assignment and also assign own member.
|
||||||
dataPointer = other.dataPointer;
|
dataPointer = other.dataPointer;
|
||||||
ConstStorageAccessor::operator=(std::move(other));
|
ConstStorageAccessor::operator=(std::move(other));
|
||||||
@ -18,7 +18,7 @@ StorageAccessor& StorageAccessor::operator=(StorageAccessor&& other) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call the parent move ctor and also transfer own member.
|
// Call the parent move ctor and also transfer own member.
|
||||||
StorageAccessor::StorageAccessor(StorageAccessor&& other)
|
StorageAccessor::StorageAccessor(StorageAccessor&& other) noexcept
|
||||||
: ConstStorageAccessor(std::move(other)), dataPointer(other.dataPointer) {}
|
: ConstStorageAccessor(std::move(other)), dataPointer(other.dataPointer) {}
|
||||||
|
|
||||||
ReturnValue_t StorageAccessor::getDataCopy(uint8_t* pointer, size_t maxSize) {
|
ReturnValue_t StorageAccessor::getDataCopy(uint8_t* pointer, size_t maxSize) {
|
||||||
|
@ -12,9 +12,10 @@ class StorageAccessor : public ConstStorageAccessor {
|
|||||||
//! StorageManager classes have exclusive access to private variables.
|
//! StorageManager classes have exclusive access to private variables.
|
||||||
friend class PoolManager;
|
friend class PoolManager;
|
||||||
friend class LocalPool;
|
friend class LocalPool;
|
||||||
|
friend class StorageManagerIF;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StorageAccessor(store_address_t storeId);
|
explicit StorageAccessor(store_address_t storeId);
|
||||||
StorageAccessor(store_address_t storeId, StorageManagerIF* store);
|
StorageAccessor(store_address_t storeId, StorageManagerIF* store);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,8 +26,8 @@ class StorageAccessor : public ConstStorageAccessor {
|
|||||||
* @param
|
* @param
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
StorageAccessor& operator=(StorageAccessor&&);
|
StorageAccessor& operator=(StorageAccessor&&) noexcept ;
|
||||||
StorageAccessor(StorageAccessor&&);
|
StorageAccessor(StorageAccessor&&) noexcept ;
|
||||||
|
|
||||||
ReturnValue_t write(uint8_t* data, size_t size, uint16_t offset = 0);
|
ReturnValue_t write(uint8_t* data, size_t size, uint16_t offset = 0);
|
||||||
uint8_t* data();
|
uint8_t* data();
|
||||||
|
@ -68,7 +68,12 @@ class StorageManagerIF : public HasReturnvaluesIF {
|
|||||||
* storageId is unchanged then.
|
* storageId is unchanged then.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t addData(store_address_t* storageId, const uint8_t* data, size_t size,
|
virtual ReturnValue_t addData(store_address_t* storageId, const uint8_t* data, size_t size,
|
||||||
bool ignoreFault = false) = 0;
|
bool ignoreFault) = 0;
|
||||||
|
|
||||||
|
virtual ReturnValue_t addData(store_address_t* storageId, const uint8_t* data, size_t size) {
|
||||||
|
return addData(storageId, data, size, false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief With deleteData, the storageManager frees the memory region
|
* @brief With deleteData, the storageManager frees the memory region
|
||||||
* identified by packet_id.
|
* identified by packet_id.
|
||||||
@ -88,8 +93,10 @@ class StorageManagerIF : public HasReturnvaluesIF {
|
|||||||
* @li failure code if deletion did not work
|
* @li failure code if deletion did not work
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t deleteData(uint8_t* buffer, size_t size,
|
virtual ReturnValue_t deleteData(uint8_t* buffer, size_t size,
|
||||||
store_address_t* storeId = nullptr) = 0;
|
store_address_t* storeId) = 0;
|
||||||
|
virtual ReturnValue_t deleteData(uint8_t* buffer, size_t size) {
|
||||||
|
return deleteData(buffer, size, nullptr);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief Access the data by supplying a store ID.
|
* @brief Access the data by supplying a store ID.
|
||||||
* @details
|
* @details
|
||||||
@ -98,7 +105,13 @@ class StorageManagerIF : public HasReturnvaluesIF {
|
|||||||
* @param storeId
|
* @param storeId
|
||||||
* @return Pair of return value and a ConstStorageAccessor instance
|
* @return Pair of return value and a ConstStorageAccessor instance
|
||||||
*/
|
*/
|
||||||
virtual ConstAccessorPair getData(store_address_t storeId) = 0;
|
virtual ConstAccessorPair getData(store_address_t storeId) {
|
||||||
|
uint8_t* tempData = nullptr;
|
||||||
|
ConstStorageAccessor constAccessor(storeId, this);
|
||||||
|
ReturnValue_t status = modifyData(storeId, &tempData, &constAccessor.size_);
|
||||||
|
constAccessor.constDataPointer = tempData;
|
||||||
|
return {status, std::move(constAccessor)};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Access the data by supplying a store ID and a helper
|
* @brief Access the data by supplying a store ID and a helper
|
||||||
@ -107,7 +120,13 @@ class StorageManagerIF : public HasReturnvaluesIF {
|
|||||||
* @param constAccessor Wrapper function to access store data.
|
* @param constAccessor Wrapper function to access store data.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t getData(store_address_t storeId, ConstStorageAccessor& constAccessor) = 0;
|
virtual ReturnValue_t getData(store_address_t storeId, ConstStorageAccessor& accessor) {
|
||||||
|
uint8_t* tempData = nullptr;
|
||||||
|
ReturnValue_t status = modifyData(storeId, &tempData, &accessor.size_);
|
||||||
|
accessor.assignStore(this);
|
||||||
|
accessor.constDataPointer = tempData;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief getData returns an address to data and the size of the data
|
* @brief getData returns an address to data and the size of the data
|
||||||
@ -128,7 +147,12 @@ class StorageManagerIF : public HasReturnvaluesIF {
|
|||||||
* @param storeId
|
* @param storeId
|
||||||
* @return Pair of return value and StorageAccessor helper
|
* @return Pair of return value and StorageAccessor helper
|
||||||
*/
|
*/
|
||||||
virtual AccessorPair modifyData(store_address_t storeId) = 0;
|
virtual AccessorPair modifyData(store_address_t storeId) {
|
||||||
|
StorageAccessor accessor(storeId, this);
|
||||||
|
ReturnValue_t status = modifyData(storeId, &accessor.dataPointer, &accessor.size_);
|
||||||
|
accessor.assignConstPointer();
|
||||||
|
return {status, std::move(accessor)};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modify data by supplying a store ID and a StorageAccessor helper instance.
|
* Modify data by supplying a store ID and a StorageAccessor helper instance.
|
||||||
@ -136,7 +160,12 @@ class StorageManagerIF : public HasReturnvaluesIF {
|
|||||||
* @param accessor Helper class to access the modifiable data.
|
* @param accessor Helper class to access the modifiable data.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t modifyData(store_address_t storeId, StorageAccessor& accessor) = 0;
|
virtual ReturnValue_t modifyData(store_address_t storeId, StorageAccessor& accessor) {
|
||||||
|
accessor.assignStore(this);
|
||||||
|
ReturnValue_t status = modifyData(storeId, &accessor.dataPointer, &accessor.size_);
|
||||||
|
accessor.assignConstPointer();
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get pointer and size of modifiable data by supplying the storeId
|
* Get pointer and size of modifiable data by supplying the storeId
|
||||||
@ -155,13 +184,17 @@ class StorageManagerIF : public HasReturnvaluesIF {
|
|||||||
* written to p_data!
|
* written to p_data!
|
||||||
* @param storageId A pointer to the storageId to retrieve.
|
* @param storageId A pointer to the storageId to retrieve.
|
||||||
* @param size The size of the space to be reserved.
|
* @param size The size of the space to be reserved.
|
||||||
* @param p_data A pointer to the element data is returned here.
|
* @param dataPtr A pointer to the element data is returned here.
|
||||||
* @return Returns @li RETURN_OK if data was added.
|
* @return Returns @li RETURN_OK if data was added.
|
||||||
* @li RETURN_FAILED if data could not be added.
|
* @li RETURN_FAILED if data could not be added.
|
||||||
* storageId is unchanged then.
|
* storageId is unchanged then.
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t getFreeElement(store_address_t* storageId, size_t size, uint8_t** p_data,
|
virtual ReturnValue_t getFreeElement(store_address_t* storageId, size_t size, uint8_t** dataPtr,
|
||||||
bool ignoreFault = false) = 0;
|
bool ignoreFault) = 0;
|
||||||
|
|
||||||
|
virtual ReturnValue_t getFreeElement(store_address_t* storageId, size_t size, uint8_t** dataPtr) {
|
||||||
|
return getFreeElement(storageId, size, dataPtr, false);
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] virtual bool hasDataAtId(store_address_t storeId) const = 0;
|
[[nodiscard]] virtual bool hasDataAtId(store_address_t storeId) const = 0;
|
||||||
|
|
||||||
|
@ -9,12 +9,13 @@
|
|||||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||||
|
|
||||||
namespace tmtcdistrib {
|
namespace tmtcdistrib {
|
||||||
static const uint8_t INTERFACE_ID = CLASS_ID::PACKET_CHECK;
|
static const uint8_t INTERFACE_ID = CLASS_ID::TMTC_DISTRIBUTION;
|
||||||
static constexpr ReturnValue_t INVALID_CCSDS_VERSION = MAKE_RETURN_CODE(0);
|
static constexpr ReturnValue_t NO_DESTINATION_FOUND = result::makeCode(INTERFACE_ID, 0);
|
||||||
static constexpr ReturnValue_t INVALID_APID = MAKE_RETURN_CODE(1);
|
static constexpr ReturnValue_t INVALID_CCSDS_VERSION = MAKE_RETURN_CODE(1);
|
||||||
static constexpr ReturnValue_t INVALID_PACKET_TYPE = MAKE_RETURN_CODE(2);
|
static constexpr ReturnValue_t INVALID_APID = MAKE_RETURN_CODE(2);
|
||||||
static constexpr ReturnValue_t INVALID_SEC_HEADER_FIELD = MAKE_RETURN_CODE(3);
|
static constexpr ReturnValue_t INVALID_PACKET_TYPE = MAKE_RETURN_CODE(3);
|
||||||
static constexpr ReturnValue_t INCORRECT_PRIMARY_HEADER = MAKE_RETURN_CODE(4);
|
static constexpr ReturnValue_t INVALID_SEC_HEADER_FIELD = MAKE_RETURN_CODE(4);
|
||||||
|
static constexpr ReturnValue_t INCORRECT_PRIMARY_HEADER = MAKE_RETURN_CODE(5);
|
||||||
|
|
||||||
static constexpr ReturnValue_t INCOMPLETE_PACKET = MAKE_RETURN_CODE(5);
|
static constexpr ReturnValue_t INCOMPLETE_PACKET = MAKE_RETURN_CODE(5);
|
||||||
static constexpr ReturnValue_t INVALID_PUS_VERSION = MAKE_RETURN_CODE(6);
|
static constexpr ReturnValue_t INVALID_PUS_VERSION = MAKE_RETURN_CODE(6);
|
||||||
|
@ -37,7 +37,7 @@ TEST_CASE("CFDP Distributor", "[cfdp][distributor]") {
|
|||||||
CHECK(distributor.getRequestQueue() == queue.getId());
|
CHECK(distributor.getRequestQueue() == queue.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Register Listener") {
|
SECTION("Packet Forwarding") {
|
||||||
CHECK(distributor.initialize() == result::OK);
|
CHECK(distributor.initialize() == result::OK);
|
||||||
CHECK(distributor.registerTcDestination(obswEntityId, tcAcceptor) == result::OK);
|
CHECK(distributor.registerTcDestination(obswEntityId, tcAcceptor) == result::OK);
|
||||||
size_t serLen = 0;
|
size_t serLen = 0;
|
||||||
|
@ -13,4 +13,5 @@ target_sources(
|
|||||||
AcceptsTmMock.cpp
|
AcceptsTmMock.cpp
|
||||||
PusDistributorMock.cpp
|
PusDistributorMock.cpp
|
||||||
CcsdsCheckerMock.cpp
|
CcsdsCheckerMock.cpp
|
||||||
AcceptsTcMock.cpp)
|
AcceptsTcMock.cpp
|
||||||
|
StorageManagerMock.cpp)
|
||||||
|
32
unittests/mocks/StorageManagerMock.cpp
Normal file
32
unittests/mocks/StorageManagerMock.cpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#include "StorageManagerMock.h"
|
||||||
|
|
||||||
|
ReturnValue_t StorageManagerMock::addData(store_address_t *storageId, const uint8_t *data,
|
||||||
|
size_t size, bool ignoreFault) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ReturnValue_t StorageManagerMock::deleteData(store_address_t packet_id) { return 0; }
|
||||||
|
|
||||||
|
ReturnValue_t StorageManagerMock::deleteData(uint8_t *buffer, size_t size,
|
||||||
|
store_address_t *storeId) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t StorageManagerMock::getData(store_address_t packet_id, const uint8_t **packet_ptr,
|
||||||
|
size_t *size) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t StorageManagerMock::modifyData(store_address_t packet_id, uint8_t **packet_ptr,
|
||||||
|
size_t *size) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ReturnValue_t StorageManagerMock::getFreeElement(store_address_t *storageId, size_t size,
|
||||||
|
uint8_t **p_data, bool ignoreFault) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bool StorageManagerMock::hasDataAtId(store_address_t storeId) const { return false; }
|
||||||
|
void StorageManagerMock::clearStore() {}
|
||||||
|
void StorageManagerMock::clearSubPool(uint8_t poolIndex) {}
|
||||||
|
void StorageManagerMock::getFillCount(uint8_t *buffer, uint8_t *bytesWritten) {}
|
||||||
|
size_t StorageManagerMock::getTotalSize(size_t *additionalSize) { return 0; }
|
||||||
|
StorageManagerIF::max_subpools_t StorageManagerMock::getNumberOfSubPools() const { return 0; }
|
24
unittests/mocks/StorageManagerMock.h
Normal file
24
unittests/mocks/StorageManagerMock.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef FSFW_TESTS_STORAGEMANAGERMOCK_H
|
||||||
|
#define FSFW_TESTS_STORAGEMANAGERMOCK_H
|
||||||
|
|
||||||
|
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||||
|
|
||||||
|
class StorageManagerMock: public StorageManagerIF {
|
||||||
|
public:
|
||||||
|
ReturnValue_t addData(store_address_t *storageId, const uint8_t *data, size_t size,
|
||||||
|
bool ignoreFault) override;
|
||||||
|
ReturnValue_t deleteData(store_address_t packet_id) override;
|
||||||
|
ReturnValue_t deleteData(uint8_t *buffer, size_t size, store_address_t *storeId) override;
|
||||||
|
ReturnValue_t getData(store_address_t packet_id, const uint8_t **packet_ptr,
|
||||||
|
size_t *size) override;
|
||||||
|
ReturnValue_t modifyData(store_address_t packet_id, uint8_t **packet_ptr, size_t *size) override;
|
||||||
|
ReturnValue_t getFreeElement(store_address_t *storageId, size_t size, uint8_t **p_data,
|
||||||
|
bool ignoreFault) override;
|
||||||
|
[[nodiscard]] bool hasDataAtId(store_address_t storeId) const override;
|
||||||
|
void clearStore() override;
|
||||||
|
void clearSubPool(uint8_t poolIndex) override;
|
||||||
|
void getFillCount(uint8_t *buffer, uint8_t *bytesWritten) override;
|
||||||
|
size_t getTotalSize(size_t *additionalSize) override;
|
||||||
|
[[nodiscard]] max_subpools_t getNumberOfSubPools() const override;
|
||||||
|
};
|
||||||
|
#endif // FSFW_TESTS_STORAGEMANAGERMOCK_H
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
TEST_CASE("Pool Accessor", "[pool-accessor]") {
|
TEST_CASE("Pool Accessor", "[pool-accessor]") {
|
||||||
LocalPool::LocalPoolConfig poolCfg = {{1, 10}};
|
LocalPool::LocalPoolConfig poolCfg = {{1, 10}};
|
||||||
LocalPool SimplePool = LocalPool(0, poolCfg);
|
LocalPool simplePool = LocalPool(0, poolCfg);
|
||||||
std::array<uint8_t, 20> testDataArray{};
|
std::array<uint8_t, 20> testDataArray{};
|
||||||
std::array<uint8_t, 20> receptionArray{};
|
std::array<uint8_t, 20> receptionArray{};
|
||||||
store_address_t testStoreId;
|
store_address_t testStoreId;
|
||||||
@ -20,9 +20,9 @@ TEST_CASE("Pool Accessor", "[pool-accessor]") {
|
|||||||
size_t size = 10;
|
size_t size = 10;
|
||||||
|
|
||||||
SECTION("Simple tests getter functions") {
|
SECTION("Simple tests getter functions") {
|
||||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||||
REQUIRE(result == result::OK);
|
REQUIRE(result == result::OK);
|
||||||
auto resultPair = SimplePool.getData(testStoreId);
|
auto resultPair = simplePool.getData(testStoreId);
|
||||||
REQUIRE(resultPair.first == result::OK);
|
REQUIRE(resultPair.first == result::OK);
|
||||||
resultPair.second.getDataCopy(receptionArray.data(), 20);
|
resultPair.second.getDataCopy(receptionArray.data(), 20);
|
||||||
CHECK(resultPair.second.getId() == testStoreId);
|
CHECK(resultPair.second.getId() == testStoreId);
|
||||||
@ -38,18 +38,18 @@ TEST_CASE("Pool Accessor", "[pool-accessor]") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto resultPairLoc = SimplePool.getData(testStoreId);
|
auto resultPairLoc = simplePool.getData(testStoreId);
|
||||||
REQUIRE(resultPairLoc.first == result::OK);
|
REQUIRE(resultPairLoc.first == result::OK);
|
||||||
// data should be deleted when accessor goes out of scope.
|
// data should be deleted when accessor goes out of scope.
|
||||||
}
|
}
|
||||||
resultPair = SimplePool.getData(testStoreId);
|
resultPair = simplePool.getData(testStoreId);
|
||||||
REQUIRE(resultPair.first == (int)StorageManagerIF::DATA_DOES_NOT_EXIST);
|
REQUIRE(resultPair.first == (int)StorageManagerIF::DATA_DOES_NOT_EXIST);
|
||||||
|
|
||||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||||
REQUIRE(result == result::OK);
|
REQUIRE(result == result::OK);
|
||||||
{
|
{
|
||||||
ConstStorageAccessor constAccessor(testStoreId);
|
ConstStorageAccessor constAccessor(testStoreId);
|
||||||
result = SimplePool.getData(testStoreId, constAccessor);
|
result = simplePool.getData(testStoreId, constAccessor);
|
||||||
REQUIRE(result == result::OK);
|
REQUIRE(result == result::OK);
|
||||||
constAccessor.getDataCopy(receptionArray.data(), 20);
|
constAccessor.getDataCopy(receptionArray.data(), 20);
|
||||||
for (size_t i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
@ -57,17 +57,17 @@ TEST_CASE("Pool Accessor", "[pool-accessor]") {
|
|||||||
}
|
}
|
||||||
// likewise, data should be deleted when accessor gets out of scope.
|
// likewise, data should be deleted when accessor gets out of scope.
|
||||||
}
|
}
|
||||||
resultPair = SimplePool.getData(testStoreId);
|
resultPair = simplePool.getData(testStoreId);
|
||||||
REQUIRE(resultPair.first == (int)StorageManagerIF::DATA_DOES_NOT_EXIST);
|
REQUIRE(resultPair.first == (int)StorageManagerIF::DATA_DOES_NOT_EXIST);
|
||||||
|
|
||||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||||
{
|
{
|
||||||
resultPair = SimplePool.getData(testStoreId);
|
resultPair = simplePool.getData(testStoreId);
|
||||||
REQUIRE(resultPair.first == result::OK);
|
REQUIRE(resultPair.first == result::OK);
|
||||||
resultPair.second.release();
|
resultPair.second.release();
|
||||||
// now data should not be deleted anymore
|
// now data should not be deleted anymore
|
||||||
}
|
}
|
||||||
resultPair = SimplePool.getData(testStoreId);
|
resultPair = simplePool.getData(testStoreId);
|
||||||
REQUIRE(resultPair.first == result::OK);
|
REQUIRE(resultPair.first == result::OK);
|
||||||
resultPair.second.getDataCopy(receptionArray.data(), 20);
|
resultPair.second.getDataCopy(receptionArray.data(), 20);
|
||||||
for (size_t i = 0; i < size; i++) {
|
for (size_t i = 0; i < size; i++) {
|
||||||
@ -76,11 +76,11 @@ TEST_CASE("Pool Accessor", "[pool-accessor]") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Simple tests modify functions") {
|
SECTION("Simple tests modify functions") {
|
||||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||||
REQUIRE(result == result::OK);
|
REQUIRE(result == result::OK);
|
||||||
{
|
{
|
||||||
StorageAccessor accessor(testStoreId);
|
StorageAccessor accessor(testStoreId);
|
||||||
result = SimplePool.modifyData(testStoreId, accessor);
|
result = simplePool.modifyData(testStoreId, accessor);
|
||||||
REQUIRE(result == result::OK);
|
REQUIRE(result == result::OK);
|
||||||
CHECK(accessor.getId() == testStoreId);
|
CHECK(accessor.getId() == testStoreId);
|
||||||
CHECK(accessor.size() == 10);
|
CHECK(accessor.size() == 10);
|
||||||
@ -94,13 +94,13 @@ TEST_CASE("Pool Accessor", "[pool-accessor]") {
|
|||||||
}
|
}
|
||||||
// data should be deleted when accessor goes out of scope
|
// data should be deleted when accessor goes out of scope
|
||||||
}
|
}
|
||||||
auto resultPair = SimplePool.getData(testStoreId);
|
auto resultPair = simplePool.getData(testStoreId);
|
||||||
REQUIRE(resultPair.first == (int)StorageManagerIF::DATA_DOES_NOT_EXIST);
|
REQUIRE(resultPair.first == (int)StorageManagerIF::DATA_DOES_NOT_EXIST);
|
||||||
|
|
||||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||||
REQUIRE(result == result::OK);
|
REQUIRE(result == result::OK);
|
||||||
{
|
{
|
||||||
auto resultPairLoc = SimplePool.modifyData(testStoreId);
|
auto resultPairLoc = simplePool.modifyData(testStoreId);
|
||||||
REQUIRE(resultPairLoc.first == result::OK);
|
REQUIRE(resultPairLoc.first == result::OK);
|
||||||
CHECK(resultPairLoc.second.getId() == testStoreId);
|
CHECK(resultPairLoc.second.getId() == testStoreId);
|
||||||
CHECK(resultPairLoc.second.size() == 10);
|
CHECK(resultPairLoc.second.size() == 10);
|
||||||
@ -116,22 +116,22 @@ TEST_CASE("Pool Accessor", "[pool-accessor]") {
|
|||||||
resultPairLoc.second.release();
|
resultPairLoc.second.release();
|
||||||
// data should not be deleted when accessor goes out of scope
|
// data should not be deleted when accessor goes out of scope
|
||||||
}
|
}
|
||||||
resultPair = SimplePool.getData(testStoreId);
|
resultPair = simplePool.getData(testStoreId);
|
||||||
REQUIRE(resultPair.first == result::OK);
|
REQUIRE(resultPair.first == result::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Write tests") {
|
SECTION("Write tests") {
|
||||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||||
REQUIRE(result == result::OK);
|
REQUIRE(result == result::OK);
|
||||||
{
|
{
|
||||||
auto resultPair = SimplePool.modifyData(testStoreId);
|
auto resultPair = simplePool.modifyData(testStoreId);
|
||||||
REQUIRE(resultPair.first == result::OK);
|
REQUIRE(resultPair.first == result::OK);
|
||||||
testDataArray[9] = 42;
|
testDataArray[9] = 42;
|
||||||
resultPair.second.write(testDataArray.data(), 10, 0);
|
resultPair.second.write(testDataArray.data(), 10, 0);
|
||||||
// now data should not be deleted
|
// now data should not be deleted
|
||||||
resultPair.second.release();
|
resultPair.second.release();
|
||||||
}
|
}
|
||||||
auto resultConstPair = SimplePool.getData(testStoreId);
|
auto resultConstPair = simplePool.getData(testStoreId);
|
||||||
REQUIRE(resultConstPair.first == result::OK);
|
REQUIRE(resultConstPair.first == result::OK);
|
||||||
|
|
||||||
resultConstPair.second.getDataCopy(receptionArray.data(), 10);
|
resultConstPair.second.getDataCopy(receptionArray.data(), 10);
|
||||||
@ -140,7 +140,7 @@ TEST_CASE("Pool Accessor", "[pool-accessor]") {
|
|||||||
}
|
}
|
||||||
CHECK(receptionArray[9] == 42);
|
CHECK(receptionArray[9] == 42);
|
||||||
|
|
||||||
auto resultPair = SimplePool.modifyData(testStoreId);
|
auto resultPair = simplePool.modifyData(testStoreId);
|
||||||
REQUIRE(resultPair.first == result::OK);
|
REQUIRE(resultPair.first == result::OK);
|
||||||
result = resultPair.second.write(testDataArray.data(), 20, 0);
|
result = resultPair.second.write(testDataArray.data(), 20, 0);
|
||||||
REQUIRE(result == result::FAILED);
|
REQUIRE(result == result::FAILED);
|
||||||
@ -150,7 +150,7 @@ TEST_CASE("Pool Accessor", "[pool-accessor]") {
|
|||||||
std::memset(testDataArray.data(), 42, 5);
|
std::memset(testDataArray.data(), 42, 5);
|
||||||
result = resultPair.second.write(testDataArray.data(), 5, 5);
|
result = resultPair.second.write(testDataArray.data(), 5, 5);
|
||||||
REQUIRE(result == result::OK);
|
REQUIRE(result == result::OK);
|
||||||
resultConstPair = SimplePool.getData(testStoreId);
|
resultConstPair = simplePool.getData(testStoreId);
|
||||||
resultPair.second.getDataCopy(receptionArray.data(), 20);
|
resultPair.second.getDataCopy(receptionArray.data(), 20);
|
||||||
for (size_t i = 5; i < 10; i++) {
|
for (size_t i = 5; i < 10; i++) {
|
||||||
CHECK(receptionArray[i] == 42);
|
CHECK(receptionArray[i] == 42);
|
||||||
@ -158,7 +158,7 @@ TEST_CASE("Pool Accessor", "[pool-accessor]") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SECTION("Operators") {
|
SECTION("Operators") {
|
||||||
result = SimplePool.addData(&testStoreId, testDataArray.data(), size);
|
result = simplePool.addData(&testStoreId, testDataArray.data(), size);
|
||||||
REQUIRE(result == result::OK);
|
REQUIRE(result == result::OK);
|
||||||
{
|
{
|
||||||
StorageAccessor accessor(testStoreId);
|
StorageAccessor accessor(testStoreId);
|
||||||
@ -169,7 +169,7 @@ TEST_CASE("Pool Accessor", "[pool-accessor]") {
|
|||||||
size_t size = 6;
|
size_t size = 6;
|
||||||
result = accessor.write(data.data(), data.size());
|
result = accessor.write(data.data(), data.size());
|
||||||
REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED);
|
REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED);
|
||||||
result = SimplePool.modifyData(testStoreId, accessor2);
|
result = simplePool.modifyData(testStoreId, accessor2);
|
||||||
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
REQUIRE(result == HasReturnvaluesIF::RETURN_OK);
|
||||||
CHECK(accessor2.getId() == testStoreId);
|
CHECK(accessor2.getId() == testStoreId);
|
||||||
CHECK(accessor2.size() == 10);
|
CHECK(accessor2.size() == 10);
|
||||||
|
Loading…
Reference in New Issue
Block a user