mirror of
https://github.com/nasa/fprime.git
synced 2025-12-10 00:44:37 -06:00
Add DpWriter (#2593)
* Pull in framework changes from data-products branch * Pull in changes to DpManager from data-products branch * Pull in DpWriter from data-products branch * Fix spelling * Revise FileNameString * Fix warnings in CI * Fix static analysis warnings * Fix static analysis warnings * Revise formatting and comments * Revise banner comments * Revise FileNameString per PR comment * Revise path names in config headers If a header H.hpp exists in the F Prime source base, then is dangerous. Because [project root] and [fprime root] are both in the list of include paths, it's not clear whether this means "include [project root]/config/H.hpp" or "include [fprime root]/config/H.hpp." On the other hand, or has no such ambiguity, because only one of [project root]/config and [fprime root]/config is in the list of include paths. * Revise path names in config headers If a header H.hpp exists in the F Prime source base, then `#include "config/H.hpp"` is dangerous. Because [project root] and [fprime root] are both in the list of include paths, it's not clear whether this means "include [project root]/config/H.hpp" or "include [fprime root]/config/H.hpp." On the other hand, include <config/H.hpp> or `#include "config/H.hpp"` has no such ambiguity, because only one of [project root]/config and [fprime root]/config is in the list of include paths.
This commit is contained in:
parent
40ff91d625
commit
b89b5d91c4
10
.github/actions/spelling/expect.txt
vendored
10
.github/actions/spelling/expect.txt
vendored
@ -94,6 +94,7 @@ BUFFERALLOCATIONFAILED
|
|||||||
BUFFERGETOUT
|
BUFFERGETOUT
|
||||||
BUFFERMANAGERCOMPONENTIMPLCFG
|
BUFFERMANAGERCOMPONENTIMPLCFG
|
||||||
BUFFERMGR
|
BUFFERMGR
|
||||||
|
BUFFERTOOSMALLFORPACKET
|
||||||
BUFFQUEUEIN
|
BUFFQUEUEIN
|
||||||
buffsize
|
buffsize
|
||||||
BUGLIST
|
BUGLIST
|
||||||
@ -267,6 +268,7 @@ doxyindexer
|
|||||||
doxyrules
|
doxyrules
|
||||||
doxysearch
|
doxysearch
|
||||||
Doxywizard
|
Doxywizard
|
||||||
|
DPCFG
|
||||||
dpi
|
dpi
|
||||||
DPMANAGER
|
DPMANAGER
|
||||||
DPWRITER
|
DPWRITER
|
||||||
@ -330,6 +332,7 @@ fadvise
|
|||||||
FAKELOGGER
|
FAKELOGGER
|
||||||
fallocate
|
fallocate
|
||||||
fbuild
|
fbuild
|
||||||
|
fdp
|
||||||
fdset
|
fdset
|
||||||
FEEDNAME
|
FEEDNAME
|
||||||
ffff
|
ffff
|
||||||
@ -338,8 +341,11 @@ filedown
|
|||||||
FILEDOWNLINK
|
FILEDOWNLINK
|
||||||
FILEDOWNLINKCFG
|
FILEDOWNLINKCFG
|
||||||
FILEID
|
FILEID
|
||||||
|
FILENAMESTRING
|
||||||
fileopen
|
fileopen
|
||||||
|
FILEOPENERROR
|
||||||
FILESTUBS
|
FILESTUBS
|
||||||
|
FILEWRITEERROR
|
||||||
fio
|
fio
|
||||||
Firefox
|
Firefox
|
||||||
FLDP
|
FLDP
|
||||||
@ -480,6 +486,9 @@ integertypename
|
|||||||
interoperate
|
interoperate
|
||||||
intlimits
|
intlimits
|
||||||
inttype
|
inttype
|
||||||
|
INVALIDBUFFER
|
||||||
|
INVALIDHEADER
|
||||||
|
INVALIDHEADERHASH
|
||||||
invisi
|
invisi
|
||||||
ioc
|
ioc
|
||||||
ioctl
|
ioctl
|
||||||
@ -774,6 +783,7 @@ PRMDBIMPLTESTER
|
|||||||
PRMDBLIMPLCFG
|
PRMDBLIMPLCFG
|
||||||
prmname
|
prmname
|
||||||
probs
|
probs
|
||||||
|
PROCBUFFERSENDOUT
|
||||||
PRODUCTGETIN
|
PRODUCTGETIN
|
||||||
PRODUCTREQUESTIN
|
PRODUCTREQUESTIN
|
||||||
PRODUCTRESPONSEOUT
|
PRODUCTRESPONSEOUT
|
||||||
|
|||||||
@ -58,6 +58,7 @@ namespace Fw {
|
|||||||
FW_TYPEID_INTERNAL_INTERFACE_STRING = 51, //!< interface string Buffer type id
|
FW_TYPEID_INTERNAL_INTERFACE_STRING = 51, //!< interface string Buffer type id
|
||||||
FW_TYPEID_FIXED_LENGTH_STRING = 52, //!< 256 char string Buffer type id
|
FW_TYPEID_FIXED_LENGTH_STRING = 52, //!< 256 char string Buffer type id
|
||||||
FW_TYPEID_OBJECT_NAME = 53, //!< ObjectName string Buffer type id
|
FW_TYPEID_OBJECT_NAME = 53, //!< ObjectName string Buffer type id
|
||||||
|
FW_TYPEID_FILE_NAME_STRING = 54, //!< FileName string Buffer type id
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,9 +7,9 @@
|
|||||||
# Note: using PROJECT_NAME as EXECUTABLE_NAME
|
# Note: using PROJECT_NAME as EXECUTABLE_NAME
|
||||||
####
|
####
|
||||||
|
|
||||||
set(SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/Types.fpp"
|
set(SOURCE_FILES
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/Assert.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/Assert.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/String.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/FileNameString.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/InternalInterfaceString.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/InternalInterfaceString.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/MallocAllocator.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/MallocAllocator.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/MemAllocator.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/MemAllocator.cpp"
|
||||||
@ -17,8 +17,10 @@ set(SOURCE_FILES "${CMAKE_CURRENT_LIST_DIR}/Types.fpp"
|
|||||||
"${CMAKE_CURRENT_LIST_DIR}/PolyType.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/PolyType.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/SerialBuffer.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/SerialBuffer.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/Serializable.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/Serializable.cpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/String.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/StringType.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/StringType.cpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/StringUtils.cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/StringUtils.cpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/Types.fpp"
|
||||||
)
|
)
|
||||||
set(MOD_DEPS
|
set(MOD_DEPS
|
||||||
Fw/Cfg
|
Fw/Cfg
|
||||||
|
|||||||
54
Fw/Types/FileNameString.cpp
Normal file
54
Fw/Types/FileNameString.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include "Fw/Types/FileNameString.hpp"
|
||||||
|
#include "Fw/Types/StringUtils.hpp"
|
||||||
|
|
||||||
|
namespace Fw {
|
||||||
|
|
||||||
|
FileNameString::FileNameString(const char* src) : StringBase() {
|
||||||
|
(void)Fw::StringUtils::string_copy(this->m_buf, src, sizeof(this->m_buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
FileNameString::FileNameString(const StringBase& src) : StringBase() {
|
||||||
|
(void)Fw::StringUtils::string_copy(this->m_buf, src.toChar(), sizeof(this->m_buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
FileNameString::FileNameString(const FileNameString& src) : StringBase() {
|
||||||
|
(void)Fw::StringUtils::string_copy(this->m_buf, src.toChar(), sizeof(this->m_buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
FileNameString::FileNameString() : StringBase() {
|
||||||
|
this->m_buf[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileNameString& FileNameString::operator=(const FileNameString& other) {
|
||||||
|
if (this == &other) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)Fw::StringUtils::string_copy(this->m_buf, other.toChar(), sizeof(this->m_buf));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileNameString& FileNameString::operator=(const StringBase& other) {
|
||||||
|
if (this == &other) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)Fw::StringUtils::string_copy(this->m_buf, other.toChar(), sizeof(this->m_buf));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileNameString& FileNameString::operator=(const char* other) {
|
||||||
|
Fw::StringUtils::string_copy(this->m_buf, other, sizeof(this->m_buf));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileNameString::~FileNameString() {}
|
||||||
|
|
||||||
|
const char* FileNameString::toChar() const {
|
||||||
|
return this->m_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
NATIVE_UINT_TYPE FileNameString::getCapacity() const {
|
||||||
|
return STRING_SIZE;
|
||||||
|
}
|
||||||
|
} // namespace Fw
|
||||||
37
Fw/Types/FileNameString.hpp
Normal file
37
Fw/Types/FileNameString.hpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef FW_FILENAMESTRING_HPP
|
||||||
|
#define FW_FILENAMESTRING_HPP
|
||||||
|
|
||||||
|
#include <FpConfig.hpp>
|
||||||
|
|
||||||
|
#include "Fw/Cfg/SerIds.hpp"
|
||||||
|
#include "Fw/Types/StringType.hpp"
|
||||||
|
#include "config/FppConstantsAc.hpp"
|
||||||
|
|
||||||
|
namespace Fw {
|
||||||
|
|
||||||
|
class FileNameString : public Fw::StringBase {
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
SERIALIZED_TYPE_ID = FW_TYPEID_FILE_NAME_STRING, //!< typeid for string type
|
||||||
|
STRING_SIZE = FileNameStringSize, //!< Storage for string
|
||||||
|
SERIALIZED_SIZE = STRING_SIZE + sizeof(FwBuffSizeType) //!< Serialized size is size of buffer + size field
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit FileNameString(const char* src); //!< char* source constructor
|
||||||
|
explicit FileNameString(const StringBase& src); //!< other string constructor
|
||||||
|
explicit FileNameString(const FileNameString& src); //!< String string constructor
|
||||||
|
FileNameString(); //!< default constructor
|
||||||
|
FileNameString& operator=(const FileNameString& other); //!< assignment operator
|
||||||
|
FileNameString& operator=(const StringBase& other); //!< other string assignment operator
|
||||||
|
FileNameString& operator=(const char* other); //!< char* assignment operator
|
||||||
|
~FileNameString(); //!< destructor
|
||||||
|
|
||||||
|
const char* toChar() const; //!< gets char buffer
|
||||||
|
NATIVE_UINT_TYPE getCapacity() const; //!< return buffer size
|
||||||
|
|
||||||
|
private:
|
||||||
|
char m_buf[FileNameString::STRING_SIZE]; //!< storage for string data
|
||||||
|
};
|
||||||
|
} // namespace Fw
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -9,7 +9,14 @@ namespace Test {
|
|||||||
StaticData StaticData::data;
|
StaticData StaticData::data;
|
||||||
|
|
||||||
void StaticData::setNextStatus(Os::File::Status status) {
|
void StaticData::setNextStatus(Os::File::Status status) {
|
||||||
StaticData::data.nextStatus = status;
|
StaticData::data.openStatus = status;
|
||||||
|
StaticData::data.sizeStatus = status;
|
||||||
|
StaticData::data.positionStatus = status;
|
||||||
|
StaticData::data.preallocateStatus = status;
|
||||||
|
StaticData::data.seekStatus = status;
|
||||||
|
StaticData::data.flushStatus = status;
|
||||||
|
StaticData::data.readStatus = status;
|
||||||
|
StaticData::data.writeStatus = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticData::setSizeResult(FwSignedSizeType size) {
|
void StaticData::setSizeResult(FwSignedSizeType size) {
|
||||||
@ -52,7 +59,7 @@ FileInterface::Status TestFile::open(const char *filepath, Mode open_mode, Overw
|
|||||||
StaticData::data.openOverwrite = overwrite;
|
StaticData::data.openOverwrite = overwrite;
|
||||||
StaticData::data.lastCalled = StaticData::OPEN_FN;
|
StaticData::data.lastCalled = StaticData::OPEN_FN;
|
||||||
StaticData::data.pointer = 0;
|
StaticData::data.pointer = 0;
|
||||||
return StaticData::data.nextStatus;
|
return StaticData::data.openStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestFile::close() {
|
void TestFile::close() {
|
||||||
@ -62,32 +69,32 @@ void TestFile::close() {
|
|||||||
FileInterface::Status TestFile::size(FwSignedSizeType& size_result) {
|
FileInterface::Status TestFile::size(FwSignedSizeType& size_result) {
|
||||||
StaticData::data.lastCalled = StaticData::SIZE_FN;
|
StaticData::data.lastCalled = StaticData::SIZE_FN;
|
||||||
size_result = StaticData::data.sizeResult;
|
size_result = StaticData::data.sizeResult;
|
||||||
return StaticData::data.nextStatus;
|
return StaticData::data.sizeStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInterface::Status TestFile::position(FwSignedSizeType& position_result) {
|
FileInterface::Status TestFile::position(FwSignedSizeType& position_result) {
|
||||||
StaticData::data.lastCalled = StaticData::POSITION_FN;
|
StaticData::data.lastCalled = StaticData::POSITION_FN;
|
||||||
position_result = StaticData::data.positionResult;
|
position_result = StaticData::data.positionResult;
|
||||||
return StaticData::data.nextStatus;
|
return StaticData::data.positionStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInterface::Status TestFile::preallocate(FwSignedSizeType offset, FwSignedSizeType length) {
|
FileInterface::Status TestFile::preallocate(FwSignedSizeType offset, FwSignedSizeType length) {
|
||||||
StaticData::data.preallocateOffset = offset;
|
StaticData::data.preallocateOffset = offset;
|
||||||
StaticData::data.preallocateLength = length;
|
StaticData::data.preallocateLength = length;
|
||||||
StaticData::data.lastCalled = StaticData::PREALLOCATE_FN;
|
StaticData::data.lastCalled = StaticData::PREALLOCATE_FN;
|
||||||
return StaticData::data.nextStatus;
|
return StaticData::data.preallocateStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInterface::Status TestFile::seek(FwSignedSizeType offset, SeekType seekType) {
|
FileInterface::Status TestFile::seek(FwSignedSizeType offset, SeekType seekType) {
|
||||||
StaticData::data.seekOffset = offset;
|
StaticData::data.seekOffset = offset;
|
||||||
StaticData::data.seekType = seekType;
|
StaticData::data.seekType = seekType;
|
||||||
StaticData::data.lastCalled = StaticData::SEEK_FN;
|
StaticData::data.lastCalled = StaticData::SEEK_FN;
|
||||||
return StaticData::data.nextStatus;
|
return StaticData::data.seekStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInterface::Status TestFile::flush() {
|
FileInterface::Status TestFile::flush() {
|
||||||
StaticData::data.lastCalled = StaticData::FLUSH_FN;
|
StaticData::data.lastCalled = StaticData::FLUSH_FN;
|
||||||
return StaticData::data.nextStatus;
|
return StaticData::data.flushStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInterface::Status TestFile::read(U8 *buffer, FwSignedSizeType &size, WaitType wait) {
|
FileInterface::Status TestFile::read(U8 *buffer, FwSignedSizeType &size, WaitType wait) {
|
||||||
@ -103,7 +110,7 @@ FileInterface::Status TestFile::read(U8 *buffer, FwSignedSizeType &size, WaitTyp
|
|||||||
} else {
|
} else {
|
||||||
size = StaticData::data.readSizeResult;
|
size = StaticData::data.readSizeResult;
|
||||||
}
|
}
|
||||||
return StaticData::data.nextStatus;
|
return StaticData::data.readStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInterface::Status TestFile::write(const U8* buffer, FwSignedSizeType &size, WaitType wait) {
|
FileInterface::Status TestFile::write(const U8* buffer, FwSignedSizeType &size, WaitType wait) {
|
||||||
@ -119,7 +126,7 @@ FileInterface::Status TestFile::write(const U8* buffer, FwSignedSizeType &size,
|
|||||||
} else {
|
} else {
|
||||||
size = StaticData::data.writeSizeResult;
|
size = StaticData::data.writeSizeResult;
|
||||||
}
|
}
|
||||||
return StaticData::data.nextStatus;
|
return StaticData::data.writeStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileHandle* TestFile::getHandle() {
|
FileHandle* TestFile::getHandle() {
|
||||||
|
|||||||
@ -60,8 +60,23 @@ struct StaticData {
|
|||||||
//! File pointer
|
//! File pointer
|
||||||
FwSignedSizeType pointer = 0;
|
FwSignedSizeType pointer = 0;
|
||||||
|
|
||||||
//! Next status to be returned
|
//! Status to return from open
|
||||||
Os::File::Status nextStatus = Os::File::Status::OTHER_ERROR;
|
Os::File::Status openStatus = Os::File::Status::OP_OK;
|
||||||
|
//! Status to return from size
|
||||||
|
Os::File::Status sizeStatus = Os::File::Status::OP_OK;
|
||||||
|
//! Status to return from position
|
||||||
|
Os::File::Status positionStatus = Os::File::Status::OP_OK;
|
||||||
|
//! Status to return from preallocate
|
||||||
|
Os::File::Status preallocateStatus = Os::File::Status::OP_OK;
|
||||||
|
//! Status to return from seek
|
||||||
|
Os::File::Status seekStatus = Os::File::Status::OP_OK;
|
||||||
|
//! Status to return from flush
|
||||||
|
Os::File::Status flushStatus = Os::File::Status::OP_OK;
|
||||||
|
//! Status to return from read
|
||||||
|
Os::File::Status readStatus = Os::File::Status::OP_OK;
|
||||||
|
//! Status to return from write
|
||||||
|
Os::File::Status writeStatus = Os::File::Status::OP_OK;
|
||||||
|
|
||||||
//! Return of next size call
|
//! Return of next size call
|
||||||
FwSignedSizeType sizeResult = -1;
|
FwSignedSizeType sizeResult = -1;
|
||||||
//! Return of next position call
|
//! Return of next position call
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
// \title Os/test/ut/file/SyntheticFileSystem.hpp
|
// \title Os/test/ut/file/SyntheticFileSystem.hpp
|
||||||
// \brief standard template library driven synthetic file system definitions
|
// \brief standard template library driven synthetic file system definitions
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
#include "config/FpConfig.h"
|
#include <FpConfig.h>
|
||||||
#include "Os/File.hpp"
|
#include "Os/File.hpp"
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|||||||
@ -26,6 +26,8 @@ add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/CmdSequencer/")
|
|||||||
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/CmdSplitter/")
|
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/CmdSplitter/")
|
||||||
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Deframer/")
|
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Deframer/")
|
||||||
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/DpManager/")
|
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/DpManager/")
|
||||||
|
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/DpPorts/")
|
||||||
|
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/DpWriter/")
|
||||||
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/FatalHandler/")
|
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/FatalHandler/")
|
||||||
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/FileDownlinkPorts/")
|
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/FileDownlinkPorts/")
|
||||||
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/FileDownlink/")
|
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/FileDownlink/")
|
||||||
|
|||||||
@ -13,11 +13,12 @@
|
|||||||
#ifndef Svc_Deframer_HPP
|
#ifndef Svc_Deframer_HPP
|
||||||
#define Svc_Deframer_HPP
|
#define Svc_Deframer_HPP
|
||||||
|
|
||||||
|
#include <DeframerCfg.hpp>
|
||||||
|
|
||||||
#include "Svc/Deframer/DeframerComponentAc.hpp"
|
#include "Svc/Deframer/DeframerComponentAc.hpp"
|
||||||
#include "Svc/FramingProtocol/DeframingProtocol.hpp"
|
#include "Svc/FramingProtocol/DeframingProtocol.hpp"
|
||||||
#include "Svc/FramingProtocol/DeframingProtocolInterface.hpp"
|
#include "Svc/FramingProtocol/DeframingProtocolInterface.hpp"
|
||||||
#include "Utils/Types/CircularBuffer.hpp"
|
#include "Utils/Types/CircularBuffer.hpp"
|
||||||
#include "config/DeframerCfg.hpp"
|
|
||||||
|
|
||||||
namespace Svc {
|
namespace Svc {
|
||||||
|
|
||||||
|
|||||||
@ -52,7 +52,7 @@ void DpManager::productSendIn_handler(const NATIVE_INT_TYPE portNum, FwDpIdType
|
|||||||
this->productSendOut_out(portNum, sendBuffer);
|
this->productSendOut_out(portNum, sendBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DpManager::schedIn_handler(const NATIVE_INT_TYPE portNum, NATIVE_UINT_TYPE context) {
|
void DpManager::schedIn_handler(const NATIVE_INT_TYPE portNum, U32 context) {
|
||||||
// Emit telemetry
|
// Emit telemetry
|
||||||
this->tlmWrite_NumSuccessfulAllocations(this->numSuccessfulAllocations);
|
this->tlmWrite_NumSuccessfulAllocations(this->numSuccessfulAllocations);
|
||||||
this->tlmWrite_NumFailedAllocations(this->numFailedAllocations);
|
this->tlmWrite_NumFailedAllocations(this->numFailedAllocations);
|
||||||
|
|||||||
@ -83,7 +83,7 @@ class DpManager : public DpManagerComponentBase {
|
|||||||
|
|
||||||
//! Handler implementation for schedIn
|
//! Handler implementation for schedIn
|
||||||
void schedIn_handler(const NATIVE_INT_TYPE portNum, //!< The port number
|
void schedIn_handler(const NATIVE_INT_TYPE portNum, //!< The port number
|
||||||
NATIVE_UINT_TYPE context //!< The call order
|
U32 context //!< The call order
|
||||||
) final;
|
) final;
|
||||||
|
|
||||||
PRIVATE:
|
PRIVATE:
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#ifndef Svc_AbstractState_HPP
|
#ifndef Svc_AbstractState_HPP
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
// ======================================================================
|
// ======================================================================
|
||||||
// TestMain.cpp
|
// \title DpWriterTestMain.cpp
|
||||||
|
// \author bocchino
|
||||||
|
// \brief cpp file for DpWriter component test main function
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#include "Fw/Test/UnitTest.hpp"
|
#include "Fw/Test/UnitTest.hpp"
|
||||||
|
|||||||
@ -315,6 +315,9 @@ This rule sends the `CLEAR_EVENT_THROTTLE` command.
|
|||||||
1. Apply rule `CLEAR_EVENT_THROTTLE::OK`.
|
1. Apply rule `CLEAR_EVENT_THROTTLE::OK`.
|
||||||
1. Apply rule `ProductRequestIn::BufferInvalid`
|
1. Apply rule `ProductRequestIn::BufferInvalid`
|
||||||
|
|
||||||
|
**Requirements tested:**
|
||||||
|
`SVC-DPMANAGER-006`
|
||||||
|
|
||||||
## 3. Implementation
|
## 3. Implementation
|
||||||
|
|
||||||
### 3.1. DpManagerTester and TestState
|
### 3.1. DpManagerTester and TestState
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#include "Svc/DpManager/test/ut/Rules/BufferGetStatus.hpp"
|
#include "Svc/DpManager/test/ut/Rules/BufferGetStatus.hpp"
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#ifndef Svc_BufferGetStatus_HPP
|
#ifndef Svc_BufferGetStatus_HPP
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#include "STest/Pick/Pick.hpp"
|
#include "STest/Pick/Pick.hpp"
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#ifndef Svc_CLEAR_EVENT_THROTTLE_HPP
|
#ifndef Svc_CLEAR_EVENT_THROTTLE_HPP
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#ifndef Svc_ProductGetIn_HPP
|
#ifndef Svc_ProductGetIn_HPP
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#ifndef Svc_ProductRequestIn_HPP
|
#ifndef Svc_ProductRequestIn_HPP
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#include "STest/Pick/Pick.hpp"
|
#include "STest/Pick/Pick.hpp"
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#ifndef Svc_ProductSendIn_HPP
|
#ifndef Svc_ProductSendIn_HPP
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#ifndef Svc_Rules_HPP
|
#ifndef Svc_Rules_HPP
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#include "STest/Pick/Pick.hpp"
|
#include "STest/Pick/Pick.hpp"
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#ifndef Svc_SchedIn_HPP
|
#ifndef Svc_SchedIn_HPP
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#include "Svc/DpManager/test/ut/Rules/Testers.hpp"
|
#include "Svc/DpManager/test/ut/Rules/Testers.hpp"
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#ifndef Svc_Testers_HPP
|
#ifndef Svc_Testers_HPP
|
||||||
|
|||||||
@ -6,8 +6,7 @@
|
|||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2021 California Institute of Technology.
|
// Copyright (C) 2021 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#include "STest/Scenario/BoundedScenario.hpp"
|
#include "STest/Scenario/BoundedScenario.hpp"
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#ifndef Svc_Random_HPP
|
#ifndef Svc_Random_HPP
|
||||||
|
|||||||
@ -5,9 +5,8 @@
|
|||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright (C) 2023 California Institute of Technology.
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
// acknowledged. Any commercial use must be negotiated with the Office
|
// acknowledged.
|
||||||
// of Technology Transfer at the California Institute of Technology.
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#ifndef Svc_TestState_HPP
|
#ifndef Svc_TestState_HPP
|
||||||
|
|||||||
18
Svc/DpPorts/CMakeLists.txt
Normal file
18
Svc/DpPorts/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
####
|
||||||
|
# F prime CMakeLists.txt:
|
||||||
|
#
|
||||||
|
# SOURCE_FILES: combined list of source and autocoding files
|
||||||
|
# MOD_DEPS: (optional) module dependencies
|
||||||
|
#
|
||||||
|
# Note: using PROJECT_NAME as EXECUTABLE_NAME
|
||||||
|
####
|
||||||
|
set(SOURCE_FILES
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/DpPorts.fpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(MOD_DEPS
|
||||||
|
Fw/Types
|
||||||
|
Fw/Port
|
||||||
|
)
|
||||||
|
|
||||||
|
register_fprime_module()
|
||||||
10
Svc/DpPorts/DpPorts.fpp
Normal file
10
Svc/DpPorts/DpPorts.fpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
module Svc {
|
||||||
|
|
||||||
|
@ Send a notification that a data product was written
|
||||||
|
port DpWritten(
|
||||||
|
fileName: string size FileNameStringSize @< The file name
|
||||||
|
$priority: FwDpPriorityType @< The priority
|
||||||
|
$size: FwSizeType @< The file size
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
32
Svc/DpWriter/CMakeLists.txt
Normal file
32
Svc/DpWriter/CMakeLists.txt
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
set(SOURCE_FILES
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/DpWriter.cpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/DpWriter.fpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(MOD_DEPS
|
||||||
|
Fw/Dp
|
||||||
|
)
|
||||||
|
|
||||||
|
register_fprime_module()
|
||||||
|
|
||||||
|
set(UT_SOURCE_FILES
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/DpWriter.fpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/test/ut/AbstractState.cpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/test/ut/DpWriterTestMain.cpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/test/ut/DpWriterTester.cpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/test/ut/Rules/BufferSendIn.cpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/test/ut/Rules/CLEAR_EVENT_THROTTLE.cpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/test/ut/Rules/FileOpenStatus.cpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/test/ut/Rules/FileWriteStatus.cpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/test/ut/Rules/SchedIn.cpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/test/ut/Rules/Testers.cpp"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/test/ut/Scenarios/Random.cpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(UT_MOD_DEPS
|
||||||
|
STest
|
||||||
|
)
|
||||||
|
|
||||||
|
set(UT_AUTO_HELPERS ON)
|
||||||
|
choose_fprime_implementation(Os/File Os_File_Test_Stub)
|
||||||
|
register_fprime_ut()
|
||||||
221
Svc/DpWriter/DpWriter.cpp
Normal file
221
Svc/DpWriter/DpWriter.cpp
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title DpWriter.cpp
|
||||||
|
// \author bocchino
|
||||||
|
// \brief cpp file for DpWriter component implementation class
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "Fw/Com/ComPacket.hpp"
|
||||||
|
#include "Fw/Types/Serializable.hpp"
|
||||||
|
#include "Os/File.hpp"
|
||||||
|
#include "Svc/DpWriter/DpWriter.hpp"
|
||||||
|
#include "Utils/Hash/Hash.hpp"
|
||||||
|
#include "config/DpCfg.hpp"
|
||||||
|
#include "config/FpConfig.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Construction, initialization, and destruction
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
DpWriter::DpWriter(const char* const compName) : DpWriterComponentBase(compName) {}
|
||||||
|
|
||||||
|
DpWriter::~DpWriter() {}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Handler implementations for user-defined typed input ports
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void DpWriter::bufferSendIn_handler(const NATIVE_INT_TYPE portNum, Fw::Buffer& buffer) {
|
||||||
|
Fw::Success::T status = Fw::Success::SUCCESS;
|
||||||
|
// portNum is unused
|
||||||
|
(void)portNum;
|
||||||
|
// Update num buffers received
|
||||||
|
++this->m_numBuffersReceived;
|
||||||
|
// Check that the buffer is valid
|
||||||
|
if (!buffer.isValid()) {
|
||||||
|
this->log_WARNING_HI_InvalidBuffer();
|
||||||
|
status = Fw::Success::FAILURE;
|
||||||
|
}
|
||||||
|
// Check that the buffer is large enough to hold a data product packet
|
||||||
|
const FwSizeType bufferSize = buffer.getSize();
|
||||||
|
if (status == Fw::Success::SUCCESS) {
|
||||||
|
if (bufferSize < Fw::DpContainer::MIN_PACKET_SIZE) {
|
||||||
|
this->log_WARNING_HI_BufferTooSmallForPacket(bufferSize, Fw::DpContainer::MIN_PACKET_SIZE);
|
||||||
|
status = Fw::Success::FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Set up the container and check that the header hash is valid
|
||||||
|
Fw::DpContainer container;
|
||||||
|
if (status == Fw::Success::SUCCESS) {
|
||||||
|
container.setBuffer(buffer);
|
||||||
|
Utils::HashBuffer storedHash;
|
||||||
|
Utils::HashBuffer computedHash;
|
||||||
|
status = container.checkHeaderHash(storedHash, computedHash);
|
||||||
|
if (status != Fw::Success::SUCCESS) {
|
||||||
|
this->log_WARNING_HI_InvalidHeaderHash(bufferSize, storedHash.asBigEndianU32(),
|
||||||
|
computedHash.asBigEndianU32());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Deserialize the packet header
|
||||||
|
if (status == Fw::Success::SUCCESS) {
|
||||||
|
status = this->deserializePacketHeader(buffer, container);
|
||||||
|
}
|
||||||
|
// Check that the packet size fits in the buffer
|
||||||
|
if (status == Fw::Success::SUCCESS) {
|
||||||
|
const FwSizeType packetSize = container.getPacketSize();
|
||||||
|
if (bufferSize < packetSize) {
|
||||||
|
this->log_WARNING_HI_BufferTooSmallForData(bufferSize, packetSize);
|
||||||
|
status = Fw::Success::FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Perform the requested processing
|
||||||
|
if (status == Fw::Success::SUCCESS) {
|
||||||
|
this->performProcessing(container);
|
||||||
|
}
|
||||||
|
// Construct the file name
|
||||||
|
Fw::FileNameString fileName;
|
||||||
|
if (status == Fw::Success::SUCCESS) {
|
||||||
|
const FwDpIdType containerId = container.getId();
|
||||||
|
const Fw::Time timeTag = container.getTimeTag();
|
||||||
|
fileName.format(DP_FILENAME_FORMAT, containerId, timeTag.getSeconds(), timeTag.getUSeconds());
|
||||||
|
}
|
||||||
|
FwSizeType fileSize = 0;
|
||||||
|
// Write the file
|
||||||
|
if (status == Fw::Success::SUCCESS) {
|
||||||
|
status = this->writeFile(container, fileName, fileSize);
|
||||||
|
}
|
||||||
|
// Send the DpWritten notification
|
||||||
|
if (status == Fw::Success::SUCCESS) {
|
||||||
|
this->sendNotification(container, fileName, fileSize);
|
||||||
|
}
|
||||||
|
// Deallocate the buffer
|
||||||
|
if (buffer.isValid()) {
|
||||||
|
this->deallocBufferSendOut_out(0, buffer);
|
||||||
|
}
|
||||||
|
// Update the error count
|
||||||
|
if (status != Fw::Success::SUCCESS) {
|
||||||
|
this->m_numErrors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DpWriter::schedIn_handler(const NATIVE_INT_TYPE portNum, U32 context) {
|
||||||
|
// portNum and context are not used
|
||||||
|
(void)portNum;
|
||||||
|
(void)context;
|
||||||
|
// Write telemetry
|
||||||
|
this->tlmWrite_NumBuffersReceived(this->m_numBuffersReceived);
|
||||||
|
this->tlmWrite_NumBytesWritten(this->m_numBytesWritten);
|
||||||
|
this->tlmWrite_NumSuccessfulWrites(this->m_numSuccessfulWrites);
|
||||||
|
this->tlmWrite_NumFailedWrites(this->m_numFailedWrites);
|
||||||
|
this->tlmWrite_NumErrors(this->m_numErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Handler implementations for commands
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void DpWriter::CLEAR_EVENT_THROTTLE_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
|
||||||
|
// opCode and cmdSeq are not used
|
||||||
|
(void)opCode;
|
||||||
|
(void)cmdSeq;
|
||||||
|
// Clear throttling
|
||||||
|
this->log_WARNING_HI_BufferTooSmallForData_ThrottleClear();
|
||||||
|
this->log_WARNING_HI_BufferTooSmallForPacket_ThrottleClear();
|
||||||
|
this->log_WARNING_HI_FileOpenError_ThrottleClear();
|
||||||
|
this->log_WARNING_HI_FileWriteError_ThrottleClear();
|
||||||
|
this->log_WARNING_HI_InvalidBuffer_ThrottleClear();
|
||||||
|
this->log_WARNING_HI_InvalidHeaderHash_ThrottleClear();
|
||||||
|
this->log_WARNING_HI_InvalidHeader_ThrottleClear();
|
||||||
|
// Return command response
|
||||||
|
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Private helper functions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Fw::Success::T DpWriter::deserializePacketHeader(Fw::Buffer& buffer, Fw::DpContainer& container) {
|
||||||
|
Fw::Success::T status = Fw::Success::SUCCESS;
|
||||||
|
container.setBuffer(buffer);
|
||||||
|
const Fw::SerializeStatus serialStatus = container.deserializeHeader();
|
||||||
|
if (serialStatus != Fw::FW_SERIALIZE_OK) {
|
||||||
|
this->log_WARNING_HI_InvalidHeader(static_cast<U32>(buffer.getSize()), static_cast<U32>(serialStatus));
|
||||||
|
status = Fw::Success::FAILURE;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DpWriter::performProcessing(const Fw::DpContainer& container) {
|
||||||
|
// Get the buffer
|
||||||
|
Fw::Buffer buffer = container.getBuffer();
|
||||||
|
// Get the bit mask for the processing types
|
||||||
|
const Fw::DpCfg::ProcType::SerialType procTypes = container.getProcTypes();
|
||||||
|
// Do the processing
|
||||||
|
for (FwIndexType portNum = 0; portNum < NUM_PROCBUFFERSENDOUT_OUTPUT_PORTS; ++portNum) {
|
||||||
|
if ((procTypes & (1 << portNum)) != 0) {
|
||||||
|
this->procBufferSendOut_out(portNum, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Fw::Success::T DpWriter::writeFile(const Fw::DpContainer& container,
|
||||||
|
const Fw::FileNameString& fileName,
|
||||||
|
FwSizeType& fileSize) {
|
||||||
|
Fw::Success::T status = Fw::Success::SUCCESS;
|
||||||
|
// Get the buffer
|
||||||
|
Fw::Buffer buffer = container.getBuffer();
|
||||||
|
// Get the file size
|
||||||
|
fileSize = container.getPacketSize();
|
||||||
|
// Open the file
|
||||||
|
Os::File file;
|
||||||
|
Os::File::Status fileStatus = file.open(fileName.toChar(), Os::File::OPEN_CREATE);
|
||||||
|
if (fileStatus != Os::File::OP_OK) {
|
||||||
|
this->log_WARNING_HI_FileOpenError(static_cast<U32>(fileStatus), fileName.toChar());
|
||||||
|
status = Fw::Success::FAILURE;
|
||||||
|
}
|
||||||
|
// Write the file
|
||||||
|
if (status == Fw::Success::SUCCESS) {
|
||||||
|
// Set write size to file size
|
||||||
|
// On entry to the write call, this is the number of bytes to write
|
||||||
|
// On return from the write call, this is the number of bytes written
|
||||||
|
FwSignedSizeType writeSize = fileSize;
|
||||||
|
fileStatus = file.write(buffer.getData(), writeSize);
|
||||||
|
// If a successful write occurred, then update the number of bytes written
|
||||||
|
if (fileStatus == Os::File::OP_OK) {
|
||||||
|
this->m_numBytesWritten += writeSize;
|
||||||
|
}
|
||||||
|
if ((fileStatus == Os::File::OP_OK) and (writeSize == static_cast<FwSignedSizeType>(fileSize))) {
|
||||||
|
// If the write status is success, and the number of bytes written
|
||||||
|
// is the expected number, then record the success
|
||||||
|
this->log_ACTIVITY_LO_FileWritten(writeSize, fileName.toChar());
|
||||||
|
} else {
|
||||||
|
// Otherwise record the failure
|
||||||
|
this->log_WARNING_HI_FileWriteError(static_cast<U32>(fileStatus), static_cast<U32>(writeSize),
|
||||||
|
static_cast<U32>(fileSize), fileName.toChar());
|
||||||
|
status = Fw::Success::FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Update the count of successful or failed writes
|
||||||
|
if (status == Fw::Success::SUCCESS) {
|
||||||
|
this->m_numSuccessfulWrites++;
|
||||||
|
} else {
|
||||||
|
this->m_numFailedWrites++;
|
||||||
|
}
|
||||||
|
// Return the status
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DpWriter::sendNotification(const Fw::DpContainer& container,
|
||||||
|
const Fw::FileNameString& fileName,
|
||||||
|
FwSizeType fileSize) {
|
||||||
|
if (isConnected_dpWrittenOut_OutputPort(0)) {
|
||||||
|
// Construct the file name
|
||||||
|
fileNameString portFileName(fileName.toChar());
|
||||||
|
// Get the priority
|
||||||
|
const FwDpPriorityType priority = container.getPriority();
|
||||||
|
this->dpWrittenOut_out(0, portFileName, priority, fileSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace Svc
|
||||||
157
Svc/DpWriter/DpWriter.fpp
Normal file
157
Svc/DpWriter/DpWriter.fpp
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
module Svc {
|
||||||
|
|
||||||
|
@ A component for writing data products to disk
|
||||||
|
active component DpWriter {
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# Scheduling ports
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ Schedule in port
|
||||||
|
async input port schedIn: Svc.Sched
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# Ports for handling data products
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ Port for receiving data products to write to disk
|
||||||
|
async input port bufferSendIn: Fw.BufferSend
|
||||||
|
|
||||||
|
@ Port for processing data products
|
||||||
|
output port procBufferSendOut: [DpWriterNumProcPorts] Fw.BufferSend
|
||||||
|
|
||||||
|
@ Port for sending DpWritten notifications
|
||||||
|
output port dpWrittenOut: DpWritten
|
||||||
|
|
||||||
|
@ Port for deallocating data product buffers
|
||||||
|
output port deallocBufferSendOut: Fw.BufferSend
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# F' special ports
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ Command receive port
|
||||||
|
command recv port cmdIn
|
||||||
|
|
||||||
|
@ Command registration port
|
||||||
|
command reg port cmdRegIn
|
||||||
|
|
||||||
|
@ Command response port
|
||||||
|
command resp port cmdResponseOut
|
||||||
|
|
||||||
|
@ Time get port
|
||||||
|
time get port timeGetOut
|
||||||
|
|
||||||
|
@ Telemetry port
|
||||||
|
telemetry port tlmOut
|
||||||
|
|
||||||
|
@ Event port
|
||||||
|
event port eventOut
|
||||||
|
|
||||||
|
@ Text event port
|
||||||
|
text event port textEventOut
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# Commands
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ Clear event throttling
|
||||||
|
async command CLEAR_EVENT_THROTTLE
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# Events
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ Received buffer is invalid
|
||||||
|
event InvalidBuffer \
|
||||||
|
severity warning high \
|
||||||
|
format "Received buffer is invalid" \
|
||||||
|
throttle 10
|
||||||
|
|
||||||
|
@ Received buffer is too small to hold a data product packet
|
||||||
|
event BufferTooSmallForPacket(
|
||||||
|
bufferSize: U32 @< The incoming buffer size
|
||||||
|
minSize: U32 @< The minimum required size
|
||||||
|
) \
|
||||||
|
severity warning high \
|
||||||
|
format "Received buffer has size {}; minimum required size is {}" \
|
||||||
|
throttle 10
|
||||||
|
|
||||||
|
@ The received buffer has an invalid header hash
|
||||||
|
event InvalidHeaderHash(
|
||||||
|
bufferSize: U32 @< The incoming buffer size
|
||||||
|
storedHash: U32 @< The stored hash value
|
||||||
|
computedHash: U32 @< The computed hash value
|
||||||
|
) \
|
||||||
|
severity warning high \
|
||||||
|
format "Received a buffer of size {} with an invalid header hash (stored {x}, computed {x})" \
|
||||||
|
throttle 10
|
||||||
|
|
||||||
|
@ Error occurred when deserializing the packet header
|
||||||
|
event InvalidHeader(
|
||||||
|
bufferSize: U32 @< The incoming buffer size
|
||||||
|
errorCode: U32 @< The error code
|
||||||
|
) \
|
||||||
|
severity warning high \
|
||||||
|
format "Received buffer of size {}; deserialization of packet header failed with error code {}" \
|
||||||
|
throttle 10
|
||||||
|
|
||||||
|
@ Received buffer is too small to hold the data specified in the header
|
||||||
|
event BufferTooSmallForData(
|
||||||
|
bufferSize: U32 @< The incoming buffer size
|
||||||
|
minSize: U32 @< The minimum required size
|
||||||
|
) \
|
||||||
|
severity warning high \
|
||||||
|
format "Received buffer has size {}; minimum required size is {}" \
|
||||||
|
throttle 10
|
||||||
|
|
||||||
|
@ An error occurred when opening a file
|
||||||
|
event FileOpenError(
|
||||||
|
status: U32 @< The status code returned from the open operation
|
||||||
|
file: string size FileNameStringSize @< The file
|
||||||
|
) \
|
||||||
|
severity warning high \
|
||||||
|
format "Error {} opening file {}" \
|
||||||
|
throttle 10
|
||||||
|
|
||||||
|
@ An error occurred when writing to a file
|
||||||
|
event FileWriteError(
|
||||||
|
status: U32 @< The status code returned from the write operation
|
||||||
|
bytesWritten: U32 @< The number of bytes successfully written
|
||||||
|
bytesToWrite: U32 @< The number of bytes attempted
|
||||||
|
file: string size FileNameStringSize @< The file
|
||||||
|
) \
|
||||||
|
severity warning high \
|
||||||
|
format "Error {} while writing {} of {} bytes to {}" \
|
||||||
|
throttle 10
|
||||||
|
|
||||||
|
@ File written
|
||||||
|
event FileWritten(
|
||||||
|
bytes: U32 @< The number of bytes written
|
||||||
|
file: string size FileNameStringSize @< The file name
|
||||||
|
) \
|
||||||
|
severity activity low \
|
||||||
|
format "Wrote {} bytes to file {}"
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# Telemetry
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ The number of buffers received
|
||||||
|
telemetry NumBuffersReceived: U32 update on change
|
||||||
|
|
||||||
|
@ The number of bytes written
|
||||||
|
telemetry NumBytesWritten: U64 update on change
|
||||||
|
|
||||||
|
@ The number of successful writes
|
||||||
|
telemetry NumSuccessfulWrites: U32 update on change
|
||||||
|
|
||||||
|
@ The number of failed writes
|
||||||
|
telemetry NumFailedWrites: U32 update on change
|
||||||
|
|
||||||
|
@ The number of errors
|
||||||
|
telemetry NumErrors: U32 update on change
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
115
Svc/DpWriter/DpWriter.hpp
Normal file
115
Svc/DpWriter/DpWriter.hpp
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title DpWriter.hpp
|
||||||
|
// \author bocchino
|
||||||
|
// \brief hpp file for DpWriter component implementation class
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef Svc_DpWriter_HPP
|
||||||
|
#define Svc_DpWriter_HPP
|
||||||
|
|
||||||
|
#include <DpCfg.hpp>
|
||||||
|
|
||||||
|
#include "Fw/Dp/DpContainer.hpp"
|
||||||
|
#include "Fw/Types/FileNameString.hpp"
|
||||||
|
#include "Fw/Types/String.hpp"
|
||||||
|
#include "Fw/Types/SuccessEnumAc.hpp"
|
||||||
|
#include "Svc/DpWriter/DpWriterComponentAc.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
class DpWriter : public DpWriterComponentBase {
|
||||||
|
public:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Construction, initialization, and destruction
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Construct object DpWriter
|
||||||
|
//!
|
||||||
|
DpWriter(const char* const compName //!< The component name
|
||||||
|
);
|
||||||
|
|
||||||
|
//! Destroy object DpWriter
|
||||||
|
//!
|
||||||
|
~DpWriter();
|
||||||
|
|
||||||
|
PRIVATE:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Handler implementations for user-defined typed input ports
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Handler implementation for bufferSendIn
|
||||||
|
//!
|
||||||
|
void bufferSendIn_handler(const NATIVE_INT_TYPE portNum, //!< The port number
|
||||||
|
Fw::Buffer& fwBuffer //!< The buffer
|
||||||
|
) override;
|
||||||
|
|
||||||
|
//! Handler implementation for schedIn
|
||||||
|
//!
|
||||||
|
void schedIn_handler(const NATIVE_INT_TYPE portNum, //!< The port number
|
||||||
|
U32 context //!< The call order
|
||||||
|
) override;
|
||||||
|
|
||||||
|
PRIVATE:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Handler implementations for commands
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Handler implementation for command CLEAR_EVENT_THROTTLE
|
||||||
|
//!
|
||||||
|
//! Clear event throttling
|
||||||
|
void CLEAR_EVENT_THROTTLE_cmdHandler(FwOpcodeType opCode, //!< The opcode
|
||||||
|
U32 cmdSeq //!< The command sequence number
|
||||||
|
) override;
|
||||||
|
|
||||||
|
PRIVATE:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Private helper functions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Deserialize the packet header
|
||||||
|
//! \return Success or failure
|
||||||
|
Fw::Success::T deserializePacketHeader(Fw::Buffer& buffer, //!< The packet buffer
|
||||||
|
Fw::DpContainer& container //!< The container
|
||||||
|
);
|
||||||
|
|
||||||
|
//! Perform processing on a packet buffer
|
||||||
|
void performProcessing(const Fw::DpContainer& container //!< The container
|
||||||
|
);
|
||||||
|
|
||||||
|
//! Write the file
|
||||||
|
//! \return Success or failure
|
||||||
|
Fw::Success::T writeFile(const Fw::DpContainer& container, //!< The container (input)
|
||||||
|
const Fw::FileNameString& fileName, //!< The file name
|
||||||
|
FwSizeType& fileSize //!< The file size (output)
|
||||||
|
);
|
||||||
|
|
||||||
|
//! Send the DpWritten notification
|
||||||
|
void sendNotification(const Fw::DpContainer& container, //!< The container
|
||||||
|
const Fw::FileNameString& fileName, //!< The file name
|
||||||
|
FwSizeType packetSize //!< The packet size
|
||||||
|
);
|
||||||
|
|
||||||
|
PRIVATE:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Private member variables
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! The number of buffers received
|
||||||
|
U32 m_numBuffersReceived = 0;
|
||||||
|
|
||||||
|
//! The number of bytes written
|
||||||
|
U64 m_numBytesWritten = 0;
|
||||||
|
|
||||||
|
//! The number of successful writes
|
||||||
|
U32 m_numSuccessfulWrites = 0;
|
||||||
|
|
||||||
|
//! The number of failed writes
|
||||||
|
U32 m_numFailedWrites = 0;
|
||||||
|
|
||||||
|
//! The number of errors
|
||||||
|
U32 m_numErrors = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace Svc
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -21,6 +21,11 @@ before reaching `DpWriter`.
|
|||||||
|
|
||||||
1. Write _B_ to disk.
|
1. Write _B_ to disk.
|
||||||
|
|
||||||
|
1. If a notification port is connected, then send out a notification
|
||||||
|
that the write occurred.
|
||||||
|
An instance of [`Svc::DpCatalog`](../../DpCatalog/docs/sdd.md) can
|
||||||
|
receive this notification and use it to update the data product catalog.
|
||||||
|
|
||||||
## 2. Requirements
|
## 2. Requirements
|
||||||
|
|
||||||
Requirement | Description | Rationale | Verification Method
|
Requirement | Description | Rationale | Verification Method
|
||||||
@ -29,7 +34,8 @@ SVC-DPWRITER-001 | `Svc::DpWriter` shall provide a port for receiving `Fw::Buffe
|
|||||||
SVC-DPWRITER-002 | `Svc::DpWriter` shall provide an array of ports for sending `Fw::Buffer` objects for processing. | This requirement supports downstream processing of the data in the buffer. | Unit Test
|
SVC-DPWRITER-002 | `Svc::DpWriter` shall provide an array of ports for sending `Fw::Buffer` objects for processing. | This requirement supports downstream processing of the data in the buffer. | Unit Test
|
||||||
SVC-DPWRITER-003 | On receiving a data product container _C_, `Svc::DpWriter` shall use the processing type field of the header of _C_ to select zero or more processing ports to invoke, in port order. | The processing type field is a bit mask. A one in bit `2^n` in the bit mask selects port index `n`. | Unit Test
|
SVC-DPWRITER-003 | On receiving a data product container _C_, `Svc::DpWriter` shall use the processing type field of the header of _C_ to select zero or more processing ports to invoke, in port order. | The processing type field is a bit mask. A one in bit `2^n` in the bit mask selects port index `n`. | Unit Test
|
||||||
SVC-DPWRITER-004 | On receiving an `Fw::Buffer` _B_, and after performing any requested processing on _B_, `Svc::DpWriter` shall write _B_ to disk. | The purpose of `DpWriter` is to write data products to the disk. | Unit Test
|
SVC-DPWRITER-004 | On receiving an `Fw::Buffer` _B_, and after performing any requested processing on _B_, `Svc::DpWriter` shall write _B_ to disk. | The purpose of `DpWriter` is to write data products to the disk. | Unit Test
|
||||||
SVC-DPWRITER-005 | `Svc::DpManager` shall provide telemetry that reports the number of data products written and the number of bytes written. | This requirement establishes the telemetry interface for the component. | Unit test
|
SVC-DPWRITER-005 | `Svc::DpWriter` shall provide a port for notifying other components that data products have been written. | This requirement allows `Svc::DpCatalog` or a similar component to update its catalog in real time. | Unit Test
|
||||||
|
SVC-DPWRITER-006 | `Svc::DpManager` shall provide telemetry that reports the number of buffers received, the number of data products written, the number of bytes written, the number of failed writes, and the number of errors. | This requirement establishes the telemetry interface for the component. | Unit test
|
||||||
|
|
||||||
## 3. Design
|
## 3. Design
|
||||||
|
|
||||||
@ -50,6 +56,7 @@ The diagram below shows the `DpWriter` component.
|
|||||||
| `async input` | `schedIn` | `Svc.Sched` | Schedule in port |
|
| `async input` | `schedIn` | `Svc.Sched` | Schedule in port |
|
||||||
| `async input` | `bufferSendIn` | `Fw.BufferSend` | Port for receiving data products to write to disk |
|
| `async input` | `bufferSendIn` | `Fw.BufferSend` | Port for receiving data products to write to disk |
|
||||||
| `output` | `procBufferSendOut` | `[DpWriterNumProcPorts] Fw.BufferSend` | Port for processing data products |
|
| `output` | `procBufferSendOut` | `[DpWriterNumProcPorts] Fw.BufferSend` | Port for processing data products |
|
||||||
|
| `output` | `dpWrittenOut` | `DpWritten` | Port for sending `DpWritten` notifications |
|
||||||
| `output` | `deallocBufferSendOut` | `Fw.BufferSend` | Port for deallocating data product buffers |
|
| `output` | `deallocBufferSendOut` | `Fw.BufferSend` | Port for deallocating data product buffers |
|
||||||
| `time get` | `timeGetOut` | `Fw.Time` | Time get port |
|
| `time get` | `timeGetOut` | `Fw.Time` | Time get port |
|
||||||
| `telemetry` | `tlmOut` | `Fw.Tlm` | Telemetry port |
|
| `telemetry` | `tlmOut` | `Fw.Tlm` | Telemetry port |
|
||||||
@ -66,17 +73,16 @@ The diagram below shows the `DpWriter` component.
|
|||||||
|
|
||||||
### 3.4. Compile-Time Setup
|
### 3.4. Compile-Time Setup
|
||||||
|
|
||||||
The configuration constant [`DpWriterNumProcPorts`](../../../config/AcConstants.fpp)
|
1. The configuration constant [`DpWriterNumProcPorts`](../../../config/AcConstants.fpp)
|
||||||
specifies the number of ports for connecting components that perform
|
specifies the number of ports for connecting components that perform
|
||||||
processing.
|
processing.
|
||||||
|
|
||||||
|
1. The configuration [`DP_FILENAME_FORMAT`](../../../config/DpCfg.hpp)
|
||||||
|
specifies the file name format.
|
||||||
|
|
||||||
### 3.5. Runtime Setup
|
### 3.5. Runtime Setup
|
||||||
|
|
||||||
The `config` function specifies the following constants:
|
No special runtime setup is required.
|
||||||
|
|
||||||
1. `fileNamePrefix (string)`: The prefix to use for file names.
|
|
||||||
|
|
||||||
1. `fileNameSuffix (string)`: The suffix to use for file names.
|
|
||||||
|
|
||||||
### 3.6. Port Handlers
|
### 3.6. Port Handlers
|
||||||
|
|
||||||
@ -89,16 +95,30 @@ This handler sends out the state variables as telemetry.
|
|||||||
This handler receives a mutable reference to a buffer `B`.
|
This handler receives a mutable reference to a buffer `B`.
|
||||||
It does the following:
|
It does the following:
|
||||||
|
|
||||||
1. Check that `B` is valid and that the first `sizeof(FwPacketDescriptorType)`
|
1. Check that `B` is valid. If not, emit a warning event.
|
||||||
bytes of the memory referred to by `B` hold the serialized value
|
|
||||||
[`Fw_PACKET_DP`](../../../Fw/Com/ComPacket.hpp).
|
1. If the previous step succeeded, then check that the size of `B` is large enough to
|
||||||
|
hold a data product container packet. If not, emit a warning event.
|
||||||
|
|
||||||
|
1. If the previous steps succeeded, then check that the packet
|
||||||
|
header of `B` can be successfully deserialized.
|
||||||
If not, emit a warning event.
|
If not, emit a warning event.
|
||||||
|
|
||||||
1. If step 1 succeeded, then
|
1. If the previous steps succeeded, then check that the header
|
||||||
|
hash of `B` is valid.
|
||||||
|
If not, emit a warning event.
|
||||||
|
|
||||||
|
1. If the previous steps succeeded, then check that the data
|
||||||
|
size recorded in the packet header fits within the buffer.
|
||||||
|
If not, emit a warning event.
|
||||||
|
|
||||||
|
1. If the previous steps succeeded, then
|
||||||
|
|
||||||
1. Read the `ProcType` field out of the container header stored in the
|
1. Read the `ProcType` field out of the container header stored in the
|
||||||
memory pointed to by `B`.
|
memory pointed to by `B`. Let the resulting bit mask be `M`.
|
||||||
If the value is a valid port number `N` for `procBufferSendOut`, then invoke
|
|
||||||
|
1. Visit the port numbers of `procBufferSendOut` in order.
|
||||||
|
For each port number `N`, if `N` is set in `M`, then invoke
|
||||||
`procBufferSendOut` at port number `N`, passing in `B`.
|
`procBufferSendOut` at port number `N`, passing in `B`.
|
||||||
This step updates the memory pointed to by `B` in place.
|
This step updates the memory pointed to by `B` in place.
|
||||||
|
|
||||||
@ -106,7 +126,10 @@ It does the following:
|
|||||||
Format**](#file_format) section. For the time stamp, use the time
|
Format**](#file_format) section. For the time stamp, use the time
|
||||||
provided by `timeGetOut`.
|
provided by `timeGetOut`.
|
||||||
|
|
||||||
1. Send `B` on `deallocBufferSendOut`.
|
1. If the file write succeeded and `dpWrittenOut` is connected, then send the
|
||||||
|
file name, priority, and file size out on `dpWrittenOut`.
|
||||||
|
|
||||||
|
1. If `B` is valid, then send `B` on `deallocBufferSendOut`.
|
||||||
|
|
||||||
<a name="file_format"></a>
|
<a name="file_format"></a>
|
||||||
## 4. File Format
|
## 4. File Format
|
||||||
@ -119,34 +142,42 @@ with the format described in the
|
|||||||
|
|
||||||
### 4.2. File Name
|
### 4.2. File Name
|
||||||
|
|
||||||
The name of each file consists of `fileNamePrefix` followed by an
|
The name of each file is formatted with the configurable format string
|
||||||
ID, a time stamp, and `fileNameSuffix`.
|
[`DP_FILENAME_FORMAT`](../../../config/DpCfg.hpp).
|
||||||
The ID consists of an underscore character `_` followed by the container ID.
|
The format string must contain format specifications for the following arguments,
|
||||||
The time stamp consists of an underscore character `_` followed by a seconds
|
in order.
|
||||||
value, an underscore character, and a microseconds value.
|
|
||||||
|
|
||||||
For example, suppose that the file name prefix is `container_data` and the
|
Format Specifier | Type |
|
||||||
file name suffix is `.dat`.
|
---------------- | -----|
|
||||||
Suppose that container ID is 100, the seconds value is 100000,
|
Container ID | `PRI_FwDpIdType`
|
||||||
and the microseconds value is 1000.
|
Time seconds | `PRI_u32`
|
||||||
Then the file name is `container_data_100_100000_1000.dat`.
|
Time microseconds | `PRI_u32`
|
||||||
|
|
||||||
<a name="ground_interface"></a>
|
<a name="ground_interface"></a>
|
||||||
## 5. Ground Interface
|
## 5. Ground Interface
|
||||||
|
|
||||||
### 5.1. Telemetry
|
### 5.1. Commands
|
||||||
|
|
||||||
|
| Kind | Name | Description |
|
||||||
|
|------|------|-------------|
|
||||||
|
| `async` | `CLEAR_EVENT_THROTTLE` | Clear event throttling |
|
||||||
|
|
||||||
|
### 5.2. Telemetry
|
||||||
|
|
||||||
| Name | Type | Description |
|
| Name | Type | Description |
|
||||||
|------|------|-------------|
|
|------|------|-------------|
|
||||||
| `NumDataProducts` | `U32` | The number of data products handled |
|
| `NumDataProducts` | `U32` | The number of data products handled |
|
||||||
| `NumBytes` | `U64` | The number of bytes handled |
|
| `NumBytes` | `U64` | The number of bytes handled |
|
||||||
|
|
||||||
### 5.2. Events
|
### 5.3. Events
|
||||||
|
|
||||||
| Name | Severity | Description |
|
| Name | Severity | Description |
|
||||||
|------|----------|-------------|
|
|------|----------|-------------|
|
||||||
|
| `BufferInvalid` | `warning high` | Incoming buffer is invalid |
|
||||||
| `BufferTooSmall` | `warning high` | Incoming buffer is too small to hold a data product container |
|
| `BufferTooSmall` | `warning high` | Incoming buffer is too small to hold a data product container |
|
||||||
| `InvalidPacketDescriptor` | `warning high` | Incoming buffer had an invalid packet descriptor |
|
| `InvalidPacketDescriptor` | `warning high` | Incoming buffer has an invalid packet descriptor |
|
||||||
|
| `FileOpenError` | `warning high` | An error occurred when opening a file |
|
||||||
|
| `FileWriteError` | `warning high` | An error occurred when writing to a file |
|
||||||
|
|
||||||
## 6. Example Uses
|
## 6. Example Uses
|
||||||
|
|
||||||
|
|||||||
73
Svc/DpWriter/test/ut/AbstractState.cpp
Normal file
73
Svc/DpWriter/test/ut/AbstractState.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title AbstractState.cpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief Implementation file for abstract state
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2024 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#include "Fw/Types/Assert.hpp"
|
||||||
|
#include "STest/Pick/Pick.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/AbstractState.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Public member functions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Get a data product buffer backed by m_bufferData
|
||||||
|
//! \return The buffer
|
||||||
|
Fw::Buffer AbstractState::getDpBuffer() {
|
||||||
|
// Generate the ID
|
||||||
|
const FwDpIdType id =
|
||||||
|
STest::Pick::lowerUpper(std::numeric_limits<FwDpIdType>::min(), std::numeric_limits<FwDpIdType>::max());
|
||||||
|
// Get the data size
|
||||||
|
const FwSizeType dataSize = this->getDataSize();
|
||||||
|
const FwSizeType bufferSize = Fw::DpContainer::getPacketSizeForDataSize(dataSize);
|
||||||
|
FW_ASSERT(bufferSize <= MAX_BUFFER_SIZE, static_cast<FwAssertArgType>(bufferSize),
|
||||||
|
static_cast<FwAssertArgType>(MAX_BUFFER_SIZE));
|
||||||
|
// Create the buffer
|
||||||
|
Fw::Buffer buffer(this->m_bufferData, bufferSize);
|
||||||
|
// Create the container
|
||||||
|
Fw::DpContainer container(id, buffer);
|
||||||
|
// Update the priority
|
||||||
|
const FwDpPriorityType priority = STest::Pick::lowerUpper(std::numeric_limits<FwDpPriorityType>::min(),
|
||||||
|
std::numeric_limits<FwDpPriorityType>::max());
|
||||||
|
container.setPriority(priority);
|
||||||
|
// Update the time tag
|
||||||
|
const U32 seconds = STest::Pick::any();
|
||||||
|
const U32 microseconds = STest::Pick::startLength(0, 1000000);
|
||||||
|
container.setTimeTag(Fw::Time(seconds, microseconds));
|
||||||
|
// Update the processing types
|
||||||
|
Fw::DpCfg::ProcType::SerialType procTypes = 0;
|
||||||
|
for (FwIndexType i = 0; i < Fw::DpCfg::ProcType::NUM_CONSTANTS; i++) {
|
||||||
|
const bool selector = static_cast<bool>(STest::Pick::lowerUpper(0, 1));
|
||||||
|
if (selector) {
|
||||||
|
procTypes |= (1 << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
container.setProcTypes(procTypes);
|
||||||
|
// Update the data size
|
||||||
|
container.setDataSize(dataSize);
|
||||||
|
// Serialize the header and update the header hash
|
||||||
|
container.serializeHeader();
|
||||||
|
// Randomize the data
|
||||||
|
U8* const dataPtr = &this->m_bufferData[Fw::DpContainer::DATA_OFFSET];
|
||||||
|
const FwSizeType dataUpperBound = Fw::DpContainer::DATA_OFFSET + dataSize;
|
||||||
|
FW_ASSERT(dataUpperBound <= bufferSize, dataUpperBound, bufferSize);
|
||||||
|
for (FwSizeType i = 0; i <= dataSize; i++) {
|
||||||
|
dataPtr[i] = static_cast<U8>(STest::Pick::any());
|
||||||
|
}
|
||||||
|
// Update the data hash
|
||||||
|
container.updateDataHash();
|
||||||
|
// Return the buffer
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Svc
|
||||||
134
Svc/DpWriter/test/ut/AbstractState.hpp
Normal file
134
Svc/DpWriter/test/ut/AbstractState.hpp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title AbstractState.hpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief Header file for abstract state
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2024 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef Svc_AbstractState_HPP
|
||||||
|
#define Svc_AbstractState_HPP
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "Fw/Types/Assert.hpp"
|
||||||
|
#include "Os/File.hpp"
|
||||||
|
#include "STest/Pick/Pick.hpp"
|
||||||
|
#include "Svc/DpWriter/DpWriter.hpp"
|
||||||
|
#include "TestUtils/OnChangeChannel.hpp"
|
||||||
|
#include "TestUtils/Option.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
class AbstractState {
|
||||||
|
public:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Constants
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! The minimum data size
|
||||||
|
static constexpr FwSizeType MIN_DATA_SIZE = 0;
|
||||||
|
|
||||||
|
//! The maximum data size
|
||||||
|
static constexpr FwSizeType MAX_DATA_SIZE = 1024;
|
||||||
|
|
||||||
|
//! The maximum buffer size
|
||||||
|
static constexpr FwSizeType MAX_BUFFER_SIZE = Fw::DpContainer::getPacketSizeForDataSize(MAX_DATA_SIZE);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Constructors
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Construct an AbstractState object
|
||||||
|
AbstractState()
|
||||||
|
: m_dataSizeOpt(),
|
||||||
|
m_NumBuffersReceived(0),
|
||||||
|
m_NumBytesWritten(0),
|
||||||
|
m_NumFailedWrites(0),
|
||||||
|
m_NumSuccessfulWrites(0),
|
||||||
|
m_NumErrors(0),
|
||||||
|
m_procTypes(0) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Public member functions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Get the data size
|
||||||
|
FwSizeType getDataSize() const {
|
||||||
|
return this->m_dataSizeOpt.getOrElse(STest::Pick::lowerUpper(MIN_DATA_SIZE, MAX_DATA_SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Set the data size
|
||||||
|
void setDataSize(FwSizeType dataSize) { this->m_dataSizeOpt.set(dataSize); }
|
||||||
|
|
||||||
|
//! Get a data product buffer backed by bufferData
|
||||||
|
//! \return The buffer
|
||||||
|
Fw::Buffer getDpBuffer();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Private state variables
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! The current buffer size
|
||||||
|
TestUtils::Option<FwSizeType> m_dataSizeOpt;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Public state variables
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! The number of buffers received
|
||||||
|
TestUtils::OnChangeChannel<U32> m_NumBuffersReceived;
|
||||||
|
|
||||||
|
//! The number of bytes written
|
||||||
|
TestUtils::OnChangeChannel<U64> m_NumBytesWritten;
|
||||||
|
|
||||||
|
//! The number of failed writes
|
||||||
|
TestUtils::OnChangeChannel<U32> m_NumFailedWrites;
|
||||||
|
|
||||||
|
//! The number of successful writes
|
||||||
|
TestUtils::OnChangeChannel<U32> m_NumSuccessfulWrites;
|
||||||
|
|
||||||
|
//! The number of errors
|
||||||
|
TestUtils::OnChangeChannel<U32> m_NumErrors;
|
||||||
|
|
||||||
|
//! The number of BufferTooSmallForData events since the last throttle clear
|
||||||
|
FwSizeType m_bufferTooSmallForDataEventCount = 0;
|
||||||
|
|
||||||
|
//! The number of BufferTooSmallForPacket events since the last throttle clear
|
||||||
|
FwSizeType m_bufferTooSmallForPacketEventCount = 0;
|
||||||
|
|
||||||
|
//! The number of buffer invalid events since the last throttle clear
|
||||||
|
FwSizeType m_invalidBufferEventCount = 0;
|
||||||
|
|
||||||
|
//! The number of file open error events since the last throttle clear
|
||||||
|
FwSizeType m_fileOpenErrorEventCount = 0;
|
||||||
|
|
||||||
|
//! The number of file write error events since the last throttle clear
|
||||||
|
FwSizeType m_fileWriteErrorEventCount = 0;
|
||||||
|
|
||||||
|
//! The number of invalid header hash events since the last throttle clear
|
||||||
|
FwSizeType m_invalidHeaderHashEventCount = 0;
|
||||||
|
|
||||||
|
//! The number of invalid header events since the last throttle clear
|
||||||
|
FwSizeType m_invalidHeaderEventCount = 0;
|
||||||
|
|
||||||
|
//! Data for buffers
|
||||||
|
U8 m_bufferData[MAX_BUFFER_SIZE] = {};
|
||||||
|
|
||||||
|
//! Data for write results
|
||||||
|
U8 m_writeResultData[MAX_BUFFER_SIZE] = {};
|
||||||
|
|
||||||
|
//! Bit mask for processing out port calls
|
||||||
|
Fw::DpCfg::ProcType::SerialType m_procTypes;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Svc
|
||||||
|
|
||||||
|
#endif
|
||||||
131
Svc/DpWriter/test/ut/DpWriterTestMain.cpp
Normal file
131
Svc/DpWriter/test/ut/DpWriterTestMain.cpp
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title DpWriterTestMain.cpp
|
||||||
|
// \author bocchino
|
||||||
|
// \brief cpp file for DpWriter component test main function
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "Fw/Test/UnitTest.hpp"
|
||||||
|
#include "STest/Random/Random.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/Testers.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Scenarios/Random.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
TEST(BufferSendIn, BufferTooSmallForData) {
|
||||||
|
COMMENT("Invoke bufferSendIn with a buffer that is too small to hold the data size specified in the header.");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-001");
|
||||||
|
BufferSendIn::Tester tester;
|
||||||
|
tester.BufferTooSmallForData();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BufferSendIn, BufferTooSmallForPacket) {
|
||||||
|
COMMENT("Invoke bufferSendIn with a buffer that is too small to hold a data product packet.");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-001");
|
||||||
|
BufferSendIn::Tester tester;
|
||||||
|
tester.BufferTooSmallForPacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BufferSendIn, FileOpenError) {
|
||||||
|
COMMENT("Invoke bufferSendIn with a file open error.");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-001");
|
||||||
|
BufferSendIn::Tester tester;
|
||||||
|
tester.FileOpenError();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BufferSendIn, FileWriteError) {
|
||||||
|
COMMENT("Invoke bufferSendIn with a file write error.");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-001");
|
||||||
|
BufferSendIn::Tester tester;
|
||||||
|
tester.FileWriteError();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BufferSendIn, InvalidBuffer) {
|
||||||
|
COMMENT("Invoke bufferSendIn with an invalid buffer.");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-001");
|
||||||
|
BufferSendIn::Tester tester;
|
||||||
|
tester.InvalidBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BufferSendIn, InvalidHeader) {
|
||||||
|
COMMENT("Invoke bufferSendIn with an invalid packet header.");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-001");
|
||||||
|
BufferSendIn::Tester tester;
|
||||||
|
tester.InvalidHeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BufferSendIn, InvalidHeaderHash) {
|
||||||
|
COMMENT("Invoke bufferSendIn with a buffer that has an invalid header hash.");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-001");
|
||||||
|
BufferSendIn::Tester tester;
|
||||||
|
tester.InvalidHeaderHash();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BufferSendIn, OK) {
|
||||||
|
COMMENT("Invoke bufferSendIn with nominal input.");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-001");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-002");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-003");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-004");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-005");
|
||||||
|
BufferSendIn::Tester tester;
|
||||||
|
tester.OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(CLEAR_EVENT_THROTTLE, OK) {
|
||||||
|
COMMENT("Test the CLEAR_EVENT_THROTTLE command.");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-006");
|
||||||
|
CLEAR_EVENT_THROTTLE::Tester tester;
|
||||||
|
tester.OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FileOpenStatus, Error) {
|
||||||
|
COMMENT("Set the file open status to an error value.");
|
||||||
|
FileOpenStatus::Tester tester;
|
||||||
|
tester.Error();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FileOpenStatus, OK) {
|
||||||
|
COMMENT("Set the file open status to OP_OK.");
|
||||||
|
FileOpenStatus::Tester tester;
|
||||||
|
tester.OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FileWriteStatus, Error) {
|
||||||
|
COMMENT("Set the file write status to an error value.");
|
||||||
|
FileWriteStatus::Tester tester;
|
||||||
|
tester.Error();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(FileWriteStatus, OK) {
|
||||||
|
COMMENT("Set the file write status to OP_OK.");
|
||||||
|
FileWriteStatus::Tester tester;
|
||||||
|
tester.OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Scenarios, Random) {
|
||||||
|
COMMENT("Random scenario with all rules.");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-001");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-002");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-003");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-004");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-005");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-006");
|
||||||
|
const FwSizeType numSteps = 10000;
|
||||||
|
Scenarios::Random::Tester tester;
|
||||||
|
tester.run(numSteps);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SchedIn, OK) {
|
||||||
|
COMMENT("Invoke schedIn with nominal input.");
|
||||||
|
REQUIREMENT("SVC-DPMANAGER-006");
|
||||||
|
SchedIn::Tester tester;
|
||||||
|
tester.OK();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Svc
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
|
STest::Random::seed();
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
100
Svc/DpWriter/test/ut/DpWriterTester.cpp
Normal file
100
Svc/DpWriter/test/ut/DpWriterTester.cpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title DpWriterTester.cpp
|
||||||
|
// \author bocchino
|
||||||
|
// \brief cpp file for DpWriter component test harness implementation class
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "DpWriterTester.hpp"
|
||||||
|
#include "Os/Stub/test/File.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Construction and destruction
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
DpWriterTester ::DpWriterTester()
|
||||||
|
: DpWriterGTestBase("DpWriterTester", DpWriterTester::MAX_HISTORY_SIZE), component("DpWriter") {
|
||||||
|
this->initComponents();
|
||||||
|
this->connectPorts();
|
||||||
|
Os::Stub::File::Test::StaticData::data.setNextStatus(Os::File::OP_OK);
|
||||||
|
Os::Stub::File::Test::StaticData::data.writeResult = this->abstractState.m_writeResultData;
|
||||||
|
Os::Stub::File::Test::StaticData::data.writeResultSize = sizeof(this->abstractState.m_writeResultData);
|
||||||
|
Os::Stub::File::Test::StaticData::data.pointer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DpWriterTester ::~DpWriterTester() {}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Handlers for typed from ports
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void DpWriterTester ::from_deallocBufferSendOut_handler(NATIVE_INT_TYPE portNum, Fw::Buffer& buffer) {
|
||||||
|
this->pushFromPortEntry_deallocBufferSendOut(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DpWriterTester ::from_dpWrittenOut_handler(NATIVE_INT_TYPE portNum,
|
||||||
|
const fileNameString& fileName,
|
||||||
|
FwDpPriorityType priority,
|
||||||
|
FwSizeType size) {
|
||||||
|
this->pushFromPortEntry_dpWrittenOut(fileName, priority, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DpWriterTester::from_procBufferSendOut_handler(NATIVE_INT_TYPE portNum, Fw::Buffer& buffer) {
|
||||||
|
this->pushFromPortEntry_procBufferSendOut(buffer);
|
||||||
|
this->abstractState.m_procTypes |= (1 << portNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Public member functions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void DpWriterTester::printEvents() {
|
||||||
|
this->printTextLogHistory(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Protected helper functions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Os::File::Status DpWriterTester::pickOsFileError() {
|
||||||
|
U32 u32Status = STest::Pick::lowerUpper(Os::File::OP_OK + 1, Os::File::MAX_STATUS - 1);
|
||||||
|
return static_cast<Os::File::Status>(u32Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TESTER_CHECK_CHANNEL(NAME) \
|
||||||
|
{ \
|
||||||
|
const auto changeStatus = this->abstractState.m_##NAME.updatePrev(); \
|
||||||
|
if (changeStatus == TestUtils::OnChangeStatus::CHANGED) { \
|
||||||
|
ASSERT_TLM_##NAME##_SIZE(1); \
|
||||||
|
ASSERT_TLM_##NAME(0, this->abstractState.m_##NAME.value); \
|
||||||
|
} else { \
|
||||||
|
ASSERT_TLM_##NAME##_SIZE(0); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
void DpWriterTester::constructDpFileName(FwDpIdType id, const Fw::Time& timeTag, Fw::StringBase& fileName) {
|
||||||
|
fileName.format(DP_FILENAME_FORMAT, id, timeTag.getSeconds(), timeTag.getUSeconds());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DpWriterTester::checkProcTypes(const Fw::DpContainer& container) {
|
||||||
|
FwIndexType expectedNumProcTypes = 0;
|
||||||
|
const Fw::DpCfg::ProcType::SerialType procTypes = container.getProcTypes();
|
||||||
|
for (FwIndexType i = 0; i < Fw::DpCfg::ProcType::NUM_CONSTANTS; i++) {
|
||||||
|
if (procTypes & (1 << i)) {
|
||||||
|
++expectedNumProcTypes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ASSERT_from_procBufferSendOut_SIZE(expectedNumProcTypes);
|
||||||
|
ASSERT_EQ(container.getProcTypes(), this->abstractState.m_procTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DpWriterTester::checkTelemetry() {
|
||||||
|
TESTER_CHECK_CHANNEL(NumBuffersReceived);
|
||||||
|
TESTER_CHECK_CHANNEL(NumBytesWritten);
|
||||||
|
TESTER_CHECK_CHANNEL(NumSuccessfulWrites);
|
||||||
|
TESTER_CHECK_CHANNEL(NumFailedWrites);
|
||||||
|
TESTER_CHECK_CHANNEL(NumErrors);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Svc
|
||||||
119
Svc/DpWriter/test/ut/DpWriterTester.hpp
Normal file
119
Svc/DpWriter/test/ut/DpWriterTester.hpp
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title DpWriterTester.hpp
|
||||||
|
// \author bocchino
|
||||||
|
// \brief hpp file for DpWriter component test harness implementation class
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef Svc_DpWriterTester_HPP
|
||||||
|
#define Svc_DpWriterTester_HPP
|
||||||
|
|
||||||
|
#include "Svc/DpWriter/DpWriter.hpp"
|
||||||
|
#include "Svc/DpWriter/DpWriterGTestBase.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/AbstractState.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
class DpWriterTester : public DpWriterGTestBase {
|
||||||
|
public:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Constants
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Maximum size of histories storing events, telemetry, and port outputs
|
||||||
|
static const NATIVE_INT_TYPE MAX_HISTORY_SIZE = 10;
|
||||||
|
|
||||||
|
// Instance ID supplied to the component instance under test
|
||||||
|
static const NATIVE_INT_TYPE TEST_INSTANCE_ID = 0;
|
||||||
|
|
||||||
|
// Queue depth supplied to the component instance under test
|
||||||
|
static const NATIVE_INT_TYPE TEST_INSTANCE_QUEUE_DEPTH = 10;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Construction and destruction
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Construct object DpWriterTester
|
||||||
|
DpWriterTester();
|
||||||
|
|
||||||
|
//! Destroy object DpWriterTester
|
||||||
|
~DpWriterTester();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Handlers for typed from ports
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Handler implementation for deallocBufferSendOut
|
||||||
|
void from_deallocBufferSendOut_handler(NATIVE_INT_TYPE portNum, //!< The port number
|
||||||
|
Fw::Buffer& fwBuffer //!< The buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
//! Handler implementation for dpWrittenOut
|
||||||
|
void from_dpWrittenOut_handler(NATIVE_INT_TYPE portNum, //!< The port number
|
||||||
|
const Svc::DpWrittenPortStrings::StringSize256& fileName, //!< The file name
|
||||||
|
FwDpPriorityType priority, //!< The priority
|
||||||
|
FwSizeType size //!< The file size
|
||||||
|
);
|
||||||
|
|
||||||
|
//! Handler implementation for procBufferSendOut
|
||||||
|
void from_procBufferSendOut_handler(NATIVE_INT_TYPE portNum, //!< The port number
|
||||||
|
Fw::Buffer& fwBuffer //!< The buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Public member functions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Print events
|
||||||
|
void printEvents();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Protected helper functions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Pick an Os status other than OP_OK
|
||||||
|
//! \return The status
|
||||||
|
static Os::File::Status pickOsFileError();
|
||||||
|
|
||||||
|
//! Construct a DP file name
|
||||||
|
static void constructDpFileName(FwDpIdType id, //!< The container ID (input)
|
||||||
|
const Fw::Time& timeTag, //!< The time tag (input)
|
||||||
|
Fw::StringBase& fileName //!< The file name (output)
|
||||||
|
);
|
||||||
|
|
||||||
|
//! Check processing types
|
||||||
|
void checkProcTypes(const Fw::DpContainer& container //!< The container
|
||||||
|
);
|
||||||
|
|
||||||
|
//! Check telemetry
|
||||||
|
void checkTelemetry();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Private helper functions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Connect ports
|
||||||
|
void connectPorts();
|
||||||
|
|
||||||
|
//! Initialize components
|
||||||
|
void initComponents();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Member variables
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! The abstract state for testing
|
||||||
|
AbstractState abstractState;
|
||||||
|
|
||||||
|
//! The component under test
|
||||||
|
DpWriter component;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Svc
|
||||||
|
|
||||||
|
#endif
|
||||||
403
Svc/DpWriter/test/ut/README.md
Normal file
403
Svc/DpWriter/test/ut/README.md
Normal file
@ -0,0 +1,403 @@
|
|||||||
|
# DpWriter Component Tests
|
||||||
|
|
||||||
|
## 1. Abstract State
|
||||||
|
|
||||||
|
### 1.1. Variables
|
||||||
|
|
||||||
|
| Variable | Type | Description | Initial Value |
|
||||||
|
|----------|------|-------------|---------------|
|
||||||
|
| `m_NumBuffersReceived` | `OnChangeChannel<U32>` | The number of buffers received | 0 |
|
||||||
|
| `m_NumBytesWritten` | `OnChangeChannel<U64>` | The number of bytes written | 0 |
|
||||||
|
| `m_NumErrors` | `OnChangeChannel<U32>` | The number of errors | 0 |
|
||||||
|
| `m_NumFailedWrites` | `OnChangeChannel<U32>` | The number of failed writes | 0 |
|
||||||
|
| `m_NumSuccessfulWrites` | `OnChangeChannel<U32>` | The number of successful writes | 0 |
|
||||||
|
| `m_bufferTooSmallForDataEventCount` | `FwSizeType` | The number of `BufferTooSmallForData` events since the last throttle clear |0 |
|
||||||
|
| `m_bufferTooSmallForPacketEventCount` | `FwSizeType` | The number of `BufferTooSmallForPacket` events since the last throttle clear |0 |
|
||||||
|
| `m_fileOpenErrorEventCount` | `FwSizeType` | The number of file open error events since the last throttle clear |0 |
|
||||||
|
| `m_fileWriteErrorEventCount` | `FwSizeType` | The number of file write error events since the last throttle clear |0 |
|
||||||
|
| `m_invalidBufferEventCount` | `FwSizeType` | The number of buffer invalid events since the last throttle clear |0 |
|
||||||
|
| `m_invalidHeaderEventCount` | `FwSizeType` | The number of invalid packet descriptor events since the last throttle clear |0 |
|
||||||
|
| `m_invalidHeaderHashEventCount` | `FwSizeType` | The number of invalid header hash events since the last throttle clear |0 |
|
||||||
|
|
||||||
|
## 2. Rule Groups
|
||||||
|
|
||||||
|
### 2.1. FileOpenStatus
|
||||||
|
|
||||||
|
This rule group manages the file open status in the test harness.
|
||||||
|
|
||||||
|
#### 2.1.1. OK
|
||||||
|
|
||||||
|
This rule sets the file open status to `Os::File::OP_OK`, simulating a system state
|
||||||
|
in which a file open call succeeds.
|
||||||
|
|
||||||
|
**Precondition:**
|
||||||
|
`Os::Stub::File::Test::StaticData::data.openStatus != Os::File::OP_OK`.
|
||||||
|
|
||||||
|
**Action:**
|
||||||
|
`Os::Stub::File::Test::StaticData::data.openStatus = Os::File::OP_OK`.
|
||||||
|
|
||||||
|
**Test:**
|
||||||
|
|
||||||
|
1. Apply rule `FileOpenStatus::Error`.
|
||||||
|
1. Apply rule `FileOpenStatus::OK`.
|
||||||
|
|
||||||
|
**Requirements tested:**
|
||||||
|
None (helper rule).
|
||||||
|
|
||||||
|
#### 2.1.2. Error
|
||||||
|
|
||||||
|
This rule sets the file open status to an error value, simulating a system state
|
||||||
|
in which a file open call fails.
|
||||||
|
|
||||||
|
**Precondition:**
|
||||||
|
`Os::Stub::File::Test::StaticData::data.openStatus == Os::File::OP_OK`.
|
||||||
|
|
||||||
|
**Action:**
|
||||||
|
Set `Os::Stub::File::Test::StaticData::data.openStatus` to a random
|
||||||
|
value other than `Os::File::OP_OK`.
|
||||||
|
|
||||||
|
**Test:**
|
||||||
|
|
||||||
|
1. Apply rule `FileOpenStatus::Error`.
|
||||||
|
|
||||||
|
**Requirements tested:**
|
||||||
|
None (helper rule).
|
||||||
|
|
||||||
|
### 2.2. FileWriteStatus
|
||||||
|
|
||||||
|
This rule group manages the file write status in the test harness.
|
||||||
|
|
||||||
|
#### 2.2.1. OK
|
||||||
|
|
||||||
|
This rule sets the file open status to `Os::File::OP_OK`, simulating a system state
|
||||||
|
in which a file write call succeeds.
|
||||||
|
|
||||||
|
**Precondition:**
|
||||||
|
`Os::Stub::File::Test::StaticData::data.writeStatus != Os::File::OP_OK`.
|
||||||
|
|
||||||
|
**Action:**
|
||||||
|
`Os::Stub::File::Test::StaticData::data.writeStatus = Os::File::OP_OK`.
|
||||||
|
|
||||||
|
**Test:**
|
||||||
|
|
||||||
|
1. Apply rule `FileWriteStatus::Error`.
|
||||||
|
1. Apply rule `FileWriteStatus::OK`.
|
||||||
|
|
||||||
|
**Requirements tested:**
|
||||||
|
None (helper rule).
|
||||||
|
|
||||||
|
#### 2.2.2. Error
|
||||||
|
|
||||||
|
This rule sets the file write status to an error value, simulating a system state
|
||||||
|
in which a file write call fails.
|
||||||
|
|
||||||
|
**Precondition:**
|
||||||
|
`Os::Stub::File::Test::StaticData::data.writeStatus == Os::File::OP_OK`.
|
||||||
|
|
||||||
|
**Action:**
|
||||||
|
Set `Os::Stub::File::Test::StaticData::data.writeStatus` to a random value
|
||||||
|
other than `Os::File::OP_OK`.
|
||||||
|
|
||||||
|
**Test:**
|
||||||
|
|
||||||
|
1. Apply rule `FileWriteStatus::Error`.
|
||||||
|
|
||||||
|
**Requirements tested:**
|
||||||
|
None (helper rule).
|
||||||
|
|
||||||
|
### 2.3. SchedIn
|
||||||
|
|
||||||
|
This rule group sends test input to the `schedIn` port.
|
||||||
|
|
||||||
|
#### 2.3.1. OK
|
||||||
|
|
||||||
|
This rule invokes `schedIn` with nominal input.
|
||||||
|
|
||||||
|
**Precondition:** `true`
|
||||||
|
|
||||||
|
**Action:**
|
||||||
|
|
||||||
|
1. Clear history.
|
||||||
|
1. Invoke `schedIn` with a random context.
|
||||||
|
1. Check telemetry.
|
||||||
|
|
||||||
|
**Test:**
|
||||||
|
|
||||||
|
1. Apply rule `SchedIn::OK`.
|
||||||
|
|
||||||
|
**Requirements tested:**
|
||||||
|
`SVC-DPWRITER-006`.
|
||||||
|
|
||||||
|
### 2.4. BufferSendIn
|
||||||
|
|
||||||
|
This rule group sends test input to the `bufferSendIn` port.
|
||||||
|
|
||||||
|
#### 2.4.1. OK
|
||||||
|
|
||||||
|
This rule invokes `bufferSendIn` with nominal input.
|
||||||
|
|
||||||
|
**Precondition:**
|
||||||
|
`fileOpenStatus == Os::File::OP_OK` and
|
||||||
|
`fileWriteStatus == Os::File::OP_OK`.
|
||||||
|
|
||||||
|
**Action:**
|
||||||
|
1. Clear history.
|
||||||
|
1. Update `m_NumBuffersReceived`.
|
||||||
|
1. Construct a random buffer _B_ with valid packet data and random processing bits.
|
||||||
|
1. Send _B_ to `bufferSendIn`.
|
||||||
|
1. Assert that the event history contains one element.
|
||||||
|
1. Assert that the event history for `FileWritten` contains one element.
|
||||||
|
1. Check the event arguments.
|
||||||
|
1. Check output on processing ports.
|
||||||
|
1. Check output on notification port.
|
||||||
|
1. Check output on deallocation port.
|
||||||
|
1. Verify that `Os::File::write` has been called with the expected arguments.
|
||||||
|
1. Update `m_NumBytesWritten`.
|
||||||
|
1. Update `m_NumSuccessfulWrites`.
|
||||||
|
|
||||||
|
**Test:**
|
||||||
|
1. Apply rule `BufferSendIn::OK`.
|
||||||
|
|
||||||
|
**Requirements tested:**
|
||||||
|
`SVC-DPWRITER-001`,
|
||||||
|
`SVC-DPWRITER-002`,
|
||||||
|
`SVC-DPWRITER-003`,
|
||||||
|
`SVC-DPWRITER-004`,
|
||||||
|
`SVC-DPWRITER-005`
|
||||||
|
|
||||||
|
#### 2.4.2. InvalidBuffer
|
||||||
|
|
||||||
|
This rule invokes `bufferSendIn` with an invalid buffer.
|
||||||
|
|
||||||
|
**Precondition:**
|
||||||
|
`true`
|
||||||
|
|
||||||
|
**Action:**
|
||||||
|
1. Clear history.
|
||||||
|
1. Update `m_NumBuffersReceived`.
|
||||||
|
1. Construct an invalid buffer _B_.
|
||||||
|
1. If `m_invalidBufferEventCount` < `DpWriterComponentBase::EVENTID_INVALIDBUFFER_THROTTLE`,
|
||||||
|
then
|
||||||
|
1. Assert that the event history contains one element.
|
||||||
|
1. Assert that the event history for `InvalidBuffer` contains one element.
|
||||||
|
1. Increment `m_invalidBufferEventCount`.
|
||||||
|
1. Otherwise assert that the event history is empty.
|
||||||
|
1. Verify no data product file.
|
||||||
|
1. Verify no port output.
|
||||||
|
1. Increment `m_NumErrors`.
|
||||||
|
|
||||||
|
**Test:**
|
||||||
|
1. Apply rule `BufferSendIn::InvalidBuffer`.
|
||||||
|
|
||||||
|
**Requirements tested:**
|
||||||
|
`SVC-DPWRITER-001`
|
||||||
|
|
||||||
|
#### 2.4.3. BufferTooSmallForPacket
|
||||||
|
|
||||||
|
This rule invokes `bufferSendIn` with a buffer that is too small to
|
||||||
|
hold a data product packet.
|
||||||
|
|
||||||
|
**Precondition:**
|
||||||
|
`true`
|
||||||
|
|
||||||
|
**Action:**
|
||||||
|
1. Clear history.
|
||||||
|
1. Increment `m_NumBuffersReceived`.
|
||||||
|
1. Construct a valid buffer _B_ that is too small to hold a data product packet.
|
||||||
|
1. If `m_bufferTooSmallEventCount` < `DpWriterComponentBase::EVENTID_BUFFERTOOSMALLFORPACKET_THROTTLE`,
|
||||||
|
then
|
||||||
|
1. Assert that the event history contains one element.
|
||||||
|
1. Assert that the event history for `BufferTooSmallForPacket` contains one element.
|
||||||
|
1. Check the event arguments.
|
||||||
|
1. Increment `m_bufferTooSmallEventCount`.
|
||||||
|
1. Otherwise assert that the event history is empty.
|
||||||
|
1. Assert no DP written notification.
|
||||||
|
1. Assert buffer sent for deallocation.
|
||||||
|
1. Verify no data product file.
|
||||||
|
1. Increment `m_NumErrors`.
|
||||||
|
|
||||||
|
**Requirements tested:**
|
||||||
|
`SVC-DPWRITER-001`
|
||||||
|
|
||||||
|
#### 2.4.4. InvalidHeaderHash
|
||||||
|
|
||||||
|
This rule invokes `bufferSendIn` with a buffer that has an invalid
|
||||||
|
header hash.
|
||||||
|
|
||||||
|
**Precondition:**
|
||||||
|
`true`
|
||||||
|
|
||||||
|
**Action:**
|
||||||
|
1. Clear history.
|
||||||
|
1. Increment `m_NumBuffersReceived`.
|
||||||
|
1. Construct a valid buffer _B_ that is large enough to hold a data product
|
||||||
|
packet and that has an invalid header hash.
|
||||||
|
1. If `m_invalidHeaderHashEventCount` < `DpWriterComponentBase::EVENTID_INVALIDHEADERHASH_THROTTLE`,
|
||||||
|
then
|
||||||
|
1. Assert that the event history contains one element.
|
||||||
|
1. Assert that the event history for `InvalidHeaderHash` contains one element.
|
||||||
|
1. Check the event arguments.
|
||||||
|
1. Increment `m_invalidHeaderHashEventCount`.
|
||||||
|
1. Otherwise assert that the event history is empty.
|
||||||
|
1. Assert no DP written notification.
|
||||||
|
1. Assert buffer sent for deallocation.
|
||||||
|
1. Verify no data product file.
|
||||||
|
1. Increment `m_NumErrors`.
|
||||||
|
|
||||||
|
**Test:**
|
||||||
|
1. Apply rule `BufferSendIn::BufferTooSmallForPacket`.
|
||||||
|
|
||||||
|
**Requirements tested:**
|
||||||
|
`SVC-DPWRITER-001`
|
||||||
|
|
||||||
|
#### 2.4.5. InvalidHeader
|
||||||
|
|
||||||
|
This rule invokes `bufferSendIn` with an invalid packet header.
|
||||||
|
|
||||||
|
**Precondition:**
|
||||||
|
`true`
|
||||||
|
|
||||||
|
**Action:**
|
||||||
|
1. Clear history.
|
||||||
|
1. Increment `m_NumBuffersReceived`.
|
||||||
|
1. Construct a valid buffer _B_ with an invalid packet header.
|
||||||
|
1. If `m_invalidPacketHeaderEventCount` < `DpWriterComponentBase::EVENTID_INVALIDHEADER_THROTTLE`,
|
||||||
|
then
|
||||||
|
1. Assert that the event history contains one element.
|
||||||
|
1. Assert that the event history for `InvalidHeader` contains one element.
|
||||||
|
1. Check the event arguments.
|
||||||
|
1. Increment `m_invalidPacketHeaderEventCount`.
|
||||||
|
1. Otherwise assert that the event history is empty.
|
||||||
|
1. Assert no DP written notification.
|
||||||
|
1. Assert buffer sent for deallocation.
|
||||||
|
1. Verify no data product file.
|
||||||
|
1. Increment `m_NumErrors`.
|
||||||
|
|
||||||
|
**Test:**
|
||||||
|
1. Apply rule `BufferSendIn::InvalidHeader`.
|
||||||
|
|
||||||
|
**Requirements tested:**
|
||||||
|
`SVC-DPWRITER-001`
|
||||||
|
|
||||||
|
#### 2.4.6. BufferTooSmallForData
|
||||||
|
|
||||||
|
This rule invokes `bufferSendIn` with a buffer that is too small to
|
||||||
|
hold the data size specified in the header.
|
||||||
|
|
||||||
|
**Precondition:**
|
||||||
|
`true`
|
||||||
|
|
||||||
|
**Action:**
|
||||||
|
1. Clear history.
|
||||||
|
1. Increment `m_NumBuffersReceived`.
|
||||||
|
1. Construct a valid buffer _B_ with a valid packet header, but
|
||||||
|
a data size that will not fit in _B_.
|
||||||
|
1. If `m_bufferTooSmallForDataEventCount` < `DpWriterComponentBase::EVENTID_BUFFERTOOSMALLFORDATA_THROTTLE`,
|
||||||
|
then
|
||||||
|
1. Assert that the event history contains one element.
|
||||||
|
1. Assert that the event history for `BufferTooSmallForData` contains one element.
|
||||||
|
1. Check the event arguments.
|
||||||
|
1. Increment `m_bufferTooSmallForDataEventCount`.
|
||||||
|
1. Otherwise assert that the event history is empty.
|
||||||
|
1. Assert no DP written notification.
|
||||||
|
1. Assert buffer sent for deallocation.
|
||||||
|
1. Verify no data product file.
|
||||||
|
1. Increment `m_NumErrors`.
|
||||||
|
|
||||||
|
**Test:**
|
||||||
|
1. Apply rule `BufferSendIn::BufferTooSmallForData`.
|
||||||
|
|
||||||
|
**Requirements tested:**
|
||||||
|
`SVC-DPWRITER-001`
|
||||||
|
|
||||||
|
#### 2.4.7. FileOpenError
|
||||||
|
|
||||||
|
This rule invokes `bufferSendIn` with a file open error.
|
||||||
|
|
||||||
|
**Precondition:**
|
||||||
|
`fileOpenStatus != Os::File::OP_OK`
|
||||||
|
|
||||||
|
**Action:**
|
||||||
|
1. Clear history.
|
||||||
|
1. Update `m_NumBuffersReceived`.
|
||||||
|
1. Construct a random buffer _B_ with valid packet data.
|
||||||
|
1. Send _B_ to `bufferSendIn`.
|
||||||
|
1. Assert that the event history contains one element.
|
||||||
|
1. Assert that the event history for `FileOpenError` contains one element.
|
||||||
|
1. Check the event arguments.
|
||||||
|
1. Assert no DP written notification.
|
||||||
|
1. Assert buffer sent for deallocation.
|
||||||
|
1. Verify no data product file.
|
||||||
|
1. Increment `m_NumFailedWrites`.
|
||||||
|
1. Increment `m_NumErrors`.
|
||||||
|
|
||||||
|
**Test:**
|
||||||
|
1. Apply rule `FileOpenStatus::Error`.
|
||||||
|
1. Apply rule `BufferSendIn::FileOpenError`.
|
||||||
|
|
||||||
|
**Requirements tested:**
|
||||||
|
`SVC-DPWRITER-004`
|
||||||
|
|
||||||
|
#### 2.4.8. FileWriteError
|
||||||
|
|
||||||
|
This rule invokes `bufferSendIn` with a file write error.
|
||||||
|
|
||||||
|
**Precondition:**
|
||||||
|
`fileOpenStatus == Os::File::OP_OK` and
|
||||||
|
`fileWriteStatus != Os::File::OP_OK`
|
||||||
|
|
||||||
|
**Action:**
|
||||||
|
1. Clear history.
|
||||||
|
1. Update `m_NumBuffersReceived`.
|
||||||
|
1. Construct a random buffer _B_ with valid packet data.
|
||||||
|
1. Send _B_ to `bufferSendIn`.
|
||||||
|
1. Assert that the event history contains one element.
|
||||||
|
1. Assert that the event history for `FileWriteError` contains one element.
|
||||||
|
1. Check the event arguments.
|
||||||
|
1. Assert no DP written notification.
|
||||||
|
1. Assert buffer sent for deallocation.
|
||||||
|
1. Verify no data product file.
|
||||||
|
1. Increment `m_NumFailedWrites`.
|
||||||
|
1. Increment `m_NumErrors`.
|
||||||
|
|
||||||
|
**Test:**
|
||||||
|
1. Apply rule `FileWriteStatus::Error`.
|
||||||
|
1. Apply rule `BufferSendIn::FileWriteError`.
|
||||||
|
|
||||||
|
**Requirements tested:**
|
||||||
|
`SVC-DPWRITER-004`
|
||||||
|
|
||||||
|
### 2.5. CLEAR_EVENT_THROTTLE
|
||||||
|
|
||||||
|
This rule group tests the `CLEAR_EVENT_THROTTLE` command.
|
||||||
|
|
||||||
|
#### 2.5.1. OK
|
||||||
|
|
||||||
|
This rule sends the `CLEAR_EVENT_THROTTLE` command.
|
||||||
|
|
||||||
|
**Precondition:** `true`
|
||||||
|
|
||||||
|
**Action:**
|
||||||
|
|
||||||
|
1. Clear the history.
|
||||||
|
1. Send command `CLEAR_EVENT_THROTTLE`.
|
||||||
|
1. Check the command response.
|
||||||
|
1. Assert `DpWriterComponentBase::m_InvalidBufferThrottle` == 0.
|
||||||
|
1. Set `m_bufferTooSmallForDataEventCount` = 0.
|
||||||
|
1. Set `m_bufferTooSmallForPacketEventCount` = 0.
|
||||||
|
1. Set `m_fileOpenErrorEventCount` = 0.
|
||||||
|
1. Set `m_fileWriteErrorEventCount` = 0.
|
||||||
|
1. Set `m_invalidBufferEventCount` = 0.
|
||||||
|
1. Set `m_invalidHeaderEventCount` = 0.
|
||||||
|
1. Set `m_invalidHeaderHashEventCount` = 0.
|
||||||
|
|
||||||
|
**Test:**
|
||||||
|
|
||||||
|
1. Apply rule `BufferSendIn::InvalidBuffer` `DpWriterComponentBase::EVENTID_INVALIDBUFFER_THROTTLE` + 1 times.
|
||||||
|
1. Apply rule `CLEAR_EVENT_THROTTLE::OK`.
|
||||||
|
1. Apply rule `BufferSendIn::InvalidBuffer`
|
||||||
|
|
||||||
|
## 3. Implementation
|
||||||
|
|
||||||
|
See [the DpWriter test README](../../../DpWriter/test/ut/README.md)
|
||||||
|
for a description of the pattern used to implement the tests.
|
||||||
445
Svc/DpWriter/test/ut/Rules/BufferSendIn.cpp
Normal file
445
Svc/DpWriter/test/ut/Rules/BufferSendIn.cpp
Normal file
@ -0,0 +1,445 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title BufferSendIn.cpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief BufferSendIn class implementation
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2024 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Os/Stub/test/File.hpp"
|
||||||
|
#include "STest/Pick/Pick.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/BufferSendIn.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/Testers.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Rule definitions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool TestState ::precondition__BufferSendIn__OK() const {
|
||||||
|
const auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
bool result = true;
|
||||||
|
result &= (fileData.openStatus == Os::File::Status::OP_OK);
|
||||||
|
result &= (fileData.writeStatus == Os::File::Status::OP_OK);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestState ::action__BufferSendIn__OK() {
|
||||||
|
// Clear the history
|
||||||
|
this->clearHistory();
|
||||||
|
// Reset the saved proc types
|
||||||
|
// These are updated in the from_procBufferSendOut handler
|
||||||
|
this->abstractState.m_procTypes = 0;
|
||||||
|
// Reset the file pointer in the stub file implementation
|
||||||
|
auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
fileData.pointer = 0;
|
||||||
|
// Update m_NumBuffersReceived
|
||||||
|
this->abstractState.m_NumBuffersReceived.value++;
|
||||||
|
// Construct a random buffer
|
||||||
|
Fw::Buffer buffer = this->abstractState.getDpBuffer();
|
||||||
|
// Send the buffer
|
||||||
|
this->invoke_to_bufferSendIn(0, buffer);
|
||||||
|
this->component.doDispatch();
|
||||||
|
// Deserialize the container header
|
||||||
|
Fw::DpContainer container;
|
||||||
|
container.setBuffer(buffer);
|
||||||
|
const Fw::SerializeStatus status = container.deserializeHeader();
|
||||||
|
ASSERT_EQ(status, Fw::FW_SERIALIZE_OK);
|
||||||
|
// Check events
|
||||||
|
ASSERT_EVENTS_SIZE(1);
|
||||||
|
ASSERT_EVENTS_FileWritten_SIZE(1);
|
||||||
|
Fw::FileNameString fileName;
|
||||||
|
this->constructDpFileName(container.getId(), container.getTimeTag(), fileName);
|
||||||
|
ASSERT_EVENTS_FileWritten(0, buffer.getSize(), fileName.toChar());
|
||||||
|
// Check processing types
|
||||||
|
this->checkProcTypes(container);
|
||||||
|
// Check DP notification
|
||||||
|
ASSERT_from_dpWrittenOut_SIZE(1);
|
||||||
|
ASSERT_from_dpWrittenOut(0, fileName, container.getPriority(), buffer.getSize());
|
||||||
|
// Check deallocation
|
||||||
|
ASSERT_from_deallocBufferSendOut_SIZE(1);
|
||||||
|
ASSERT_from_deallocBufferSendOut(0, buffer);
|
||||||
|
// Check file write
|
||||||
|
ASSERT_EQ(buffer.getSize(), fileData.pointer);
|
||||||
|
ASSERT_EQ(0, ::memcmp(buffer.getData(), fileData.writeResult, buffer.getSize()));
|
||||||
|
// Update m_NumBytesWritten
|
||||||
|
this->abstractState.m_NumBytesWritten.value += buffer.getSize();
|
||||||
|
// Update m_NumSuccessfulWrites
|
||||||
|
this->abstractState.m_NumSuccessfulWrites.value++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TestState ::precondition__BufferSendIn__InvalidBuffer() const {
|
||||||
|
bool result = true;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestState ::action__BufferSendIn__InvalidBuffer() {
|
||||||
|
// Clear the history
|
||||||
|
this->clearHistory();
|
||||||
|
// Reset the file pointer in the stub file implementation
|
||||||
|
auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
fileData.pointer = 0;
|
||||||
|
// Update m_NumBuffersReceived
|
||||||
|
this->abstractState.m_NumBuffersReceived.value++;
|
||||||
|
// Construct an invalid buffer
|
||||||
|
Fw::Buffer buffer;
|
||||||
|
// Send the buffer
|
||||||
|
this->invoke_to_bufferSendIn(0, buffer);
|
||||||
|
this->component.doDispatch();
|
||||||
|
// Check events
|
||||||
|
if (this->abstractState.m_invalidBufferEventCount < DpWriterComponentBase::EVENTID_INVALIDBUFFER_THROTTLE) {
|
||||||
|
ASSERT_EVENTS_SIZE(1);
|
||||||
|
ASSERT_EVENTS_InvalidBuffer_SIZE(1);
|
||||||
|
this->abstractState.m_invalidBufferEventCount++;
|
||||||
|
} else {
|
||||||
|
ASSERT_EVENTS_SIZE(0);
|
||||||
|
}
|
||||||
|
// Verify no file output
|
||||||
|
ASSERT_EQ(fileData.pointer, 0);
|
||||||
|
// Verify no port output
|
||||||
|
ASSERT_FROM_PORT_HISTORY_SIZE(0);
|
||||||
|
// Increment m_NumErrors
|
||||||
|
this->abstractState.m_NumErrors.value++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TestState ::precondition__BufferSendIn__BufferTooSmallForPacket() const {
|
||||||
|
bool result = true;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestState ::action__BufferSendIn__BufferTooSmallForPacket() {
|
||||||
|
// Clear the history
|
||||||
|
this->clearHistory();
|
||||||
|
// Reset the file pointer in the stub file implementation
|
||||||
|
auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
fileData.pointer = 0;
|
||||||
|
// Update m_NumBuffersReceived
|
||||||
|
this->abstractState.m_NumBuffersReceived.value++;
|
||||||
|
// Construct a buffer that is too small to hold a data packet
|
||||||
|
const FwSizeType minPacketSize = Fw::DpContainer::MIN_PACKET_SIZE;
|
||||||
|
ASSERT_GT(minPacketSize, 1);
|
||||||
|
const FwSizeType bufferSize = STest::Pick::lowerUpper(1, minPacketSize - 1);
|
||||||
|
Fw::Buffer buffer(this->abstractState.m_bufferData, bufferSize);
|
||||||
|
// Send the buffer
|
||||||
|
this->invoke_to_bufferSendIn(0, buffer);
|
||||||
|
this->component.doDispatch();
|
||||||
|
// Check events
|
||||||
|
if (this->abstractState.m_bufferTooSmallForPacketEventCount <
|
||||||
|
DpWriterComponentBase::EVENTID_BUFFERTOOSMALLFORPACKET_THROTTLE) {
|
||||||
|
ASSERT_EVENTS_SIZE(1);
|
||||||
|
ASSERT_EVENTS_BufferTooSmallForPacket(0, bufferSize, minPacketSize);
|
||||||
|
this->abstractState.m_bufferTooSmallForPacketEventCount++;
|
||||||
|
} else {
|
||||||
|
ASSERT_EVENTS_SIZE(0);
|
||||||
|
}
|
||||||
|
// Verify no file output
|
||||||
|
ASSERT_EQ(fileData.pointer, 0);
|
||||||
|
// Verify port output
|
||||||
|
ASSERT_FROM_PORT_HISTORY_SIZE(1);
|
||||||
|
ASSERT_from_deallocBufferSendOut(0, buffer);
|
||||||
|
// Increment m_NumErrors
|
||||||
|
this->abstractState.m_NumErrors.value++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TestState ::precondition__BufferSendIn__InvalidHeaderHash() const {
|
||||||
|
bool result = true;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestState ::action__BufferSendIn__InvalidHeaderHash() {
|
||||||
|
// Clear the history
|
||||||
|
this->clearHistory();
|
||||||
|
// Reset the file pointer in the stub file implementation
|
||||||
|
auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
fileData.pointer = 0;
|
||||||
|
// Update m_NumBuffersReceived
|
||||||
|
this->abstractState.m_NumBuffersReceived.value++;
|
||||||
|
// Construct a valid buffer
|
||||||
|
Fw::Buffer buffer = this->abstractState.getDpBuffer();
|
||||||
|
// Set up the container
|
||||||
|
Fw::DpContainer container;
|
||||||
|
container.setBuffer(buffer);
|
||||||
|
// Get the header hash
|
||||||
|
const U32 computedHash = container.getHeaderHash().asBigEndianU32();
|
||||||
|
// Perturb the header hash
|
||||||
|
const U32 storedHash = computedHash + 1;
|
||||||
|
Utils::HashBuffer storedHashBuffer;
|
||||||
|
const Fw::SerializeStatus serialStatus = storedHashBuffer.serialize(storedHash);
|
||||||
|
ASSERT_EQ(serialStatus, Fw::FW_SERIALIZE_OK);
|
||||||
|
container.setHeaderHash(storedHashBuffer);
|
||||||
|
// Send the buffer
|
||||||
|
this->invoke_to_bufferSendIn(0, buffer);
|
||||||
|
this->component.doDispatch();
|
||||||
|
// Check events
|
||||||
|
if (this->abstractState.m_invalidHeaderHashEventCount < DpWriterComponentBase::EVENTID_INVALIDHEADERHASH_THROTTLE) {
|
||||||
|
ASSERT_EVENTS_SIZE(1);
|
||||||
|
ASSERT_EVENTS_InvalidHeaderHash(0, buffer.getSize(), storedHash, computedHash);
|
||||||
|
this->abstractState.m_invalidHeaderHashEventCount++;
|
||||||
|
} else {
|
||||||
|
ASSERT_EVENTS_SIZE(0);
|
||||||
|
}
|
||||||
|
// Verify no file output
|
||||||
|
ASSERT_EQ(fileData.pointer, 0);
|
||||||
|
// Verify port output
|
||||||
|
ASSERT_FROM_PORT_HISTORY_SIZE(1);
|
||||||
|
ASSERT_from_deallocBufferSendOut(0, buffer);
|
||||||
|
// Increment m_NumErrors
|
||||||
|
this->abstractState.m_NumErrors.value++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TestState ::precondition__BufferSendIn__InvalidHeader() const {
|
||||||
|
bool result = true;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestState ::action__BufferSendIn__InvalidHeader() {
|
||||||
|
// Clear the history
|
||||||
|
this->clearHistory();
|
||||||
|
// Reset the file pointer in the stub file implementation
|
||||||
|
auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
fileData.pointer = 0;
|
||||||
|
// Update m_NumBuffersReceived
|
||||||
|
this->abstractState.m_NumBuffersReceived.value++;
|
||||||
|
// Construct a valid buffer
|
||||||
|
Fw::Buffer buffer = this->abstractState.getDpBuffer();
|
||||||
|
// Invalidate the packet descriptor
|
||||||
|
U8* const buffAddr = buffer.getData();
|
||||||
|
ASSERT_GT(static_cast<FwSizeType>(buffer.getSize()), static_cast<FwSizeType>(1));
|
||||||
|
buffAddr[0]++;
|
||||||
|
// Update the header hash
|
||||||
|
Fw::DpContainer container;
|
||||||
|
container.setBuffer(buffer);
|
||||||
|
container.updateHeaderHash();
|
||||||
|
// Send the buffer
|
||||||
|
this->invoke_to_bufferSendIn(0, buffer);
|
||||||
|
this->component.doDispatch();
|
||||||
|
// Check events
|
||||||
|
if (this->abstractState.m_invalidHeaderEventCount < DpWriterComponentBase::EVENTID_INVALIDHEADER_THROTTLE) {
|
||||||
|
ASSERT_EVENTS_SIZE(1);
|
||||||
|
ASSERT_EVENTS_InvalidHeader(0, buffer.getSize(), static_cast<U32>(Fw::FW_SERIALIZE_FORMAT_ERROR));
|
||||||
|
this->abstractState.m_invalidHeaderEventCount++;
|
||||||
|
} else {
|
||||||
|
ASSERT_EVENTS_SIZE(0);
|
||||||
|
}
|
||||||
|
// Verify no file output
|
||||||
|
ASSERT_EQ(fileData.pointer, 0);
|
||||||
|
// Verify port output
|
||||||
|
ASSERT_FROM_PORT_HISTORY_SIZE(1);
|
||||||
|
ASSERT_from_deallocBufferSendOut(0, buffer);
|
||||||
|
// Increment m_NumErrors
|
||||||
|
this->abstractState.m_NumErrors.value++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TestState ::precondition__BufferSendIn__BufferTooSmallForData() const {
|
||||||
|
bool result = true;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestState ::action__BufferSendIn__BufferTooSmallForData() {
|
||||||
|
// Clear the history
|
||||||
|
this->clearHistory();
|
||||||
|
// Reset the file pointer in the stub file implementation
|
||||||
|
auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
fileData.pointer = 0;
|
||||||
|
// Update m_NumBuffersReceived
|
||||||
|
this->abstractState.m_NumBuffersReceived.value++;
|
||||||
|
// Construct a valid buffer
|
||||||
|
Fw::Buffer buffer = this->abstractState.getDpBuffer();
|
||||||
|
// Set up the container
|
||||||
|
Fw::DpContainer container;
|
||||||
|
container.setBuffer(buffer);
|
||||||
|
// Invalidate the data size
|
||||||
|
Fw::SerializeStatus serialStatus = container.deserializeHeader();
|
||||||
|
ASSERT_EQ(serialStatus, Fw::FW_SERIALIZE_OK);
|
||||||
|
const FwSizeType dataSize =
|
||||||
|
STest::Pick::lowerUpper(AbstractState::MAX_DATA_SIZE + 1, std::numeric_limits<FwSizeStoreType>::max());
|
||||||
|
container.setDataSize(dataSize);
|
||||||
|
container.updateHeaderHash();
|
||||||
|
container.serializeHeader();
|
||||||
|
// Send the buffer
|
||||||
|
this->invoke_to_bufferSendIn(0, buffer);
|
||||||
|
this->component.doDispatch();
|
||||||
|
// Check events
|
||||||
|
if (this->abstractState.m_bufferTooSmallForDataEventCount < DpWriterComponentBase::EVENTID_INVALIDHEADER_THROTTLE) {
|
||||||
|
ASSERT_EVENTS_SIZE(1);
|
||||||
|
ASSERT_EVENTS_BufferTooSmallForData(0, buffer.getSize(), container.getPacketSize());
|
||||||
|
this->abstractState.m_bufferTooSmallForDataEventCount++;
|
||||||
|
} else {
|
||||||
|
ASSERT_EVENTS_SIZE(0);
|
||||||
|
}
|
||||||
|
// Verify no file output
|
||||||
|
ASSERT_EQ(fileData.pointer, 0);
|
||||||
|
// Verify port output
|
||||||
|
ASSERT_from_procBufferSendOut_SIZE(0);
|
||||||
|
ASSERT_from_dpWrittenOut_SIZE(0);
|
||||||
|
ASSERT_from_deallocBufferSendOut_SIZE(1);
|
||||||
|
ASSERT_from_deallocBufferSendOut(0, buffer);
|
||||||
|
// Increment m_NumErrors
|
||||||
|
this->abstractState.m_NumErrors.value++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TestState ::precondition__BufferSendIn__FileOpenError() const {
|
||||||
|
const auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
return (fileData.openStatus != Os::File::Status::OP_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestState ::action__BufferSendIn__FileOpenError() {
|
||||||
|
// Clear the history
|
||||||
|
this->clearHistory();
|
||||||
|
// Reset the saved proc types
|
||||||
|
// These are updated in the from_procBufferSendOut handler
|
||||||
|
this->abstractState.m_procTypes = 0;
|
||||||
|
// Reset the file pointer in the stub file implementation
|
||||||
|
auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
fileData.pointer = 0;
|
||||||
|
// Update m_NumBuffersReceived
|
||||||
|
this->abstractState.m_NumBuffersReceived.value++;
|
||||||
|
// Construct a valid buffer
|
||||||
|
Fw::Buffer buffer = this->abstractState.getDpBuffer();
|
||||||
|
// Set up the container
|
||||||
|
Fw::DpContainer container;
|
||||||
|
container.setBuffer(buffer);
|
||||||
|
container.deserializeHeader();
|
||||||
|
// Send the buffer
|
||||||
|
this->invoke_to_bufferSendIn(0, buffer);
|
||||||
|
this->component.doDispatch();
|
||||||
|
// Check events
|
||||||
|
if (this->abstractState.m_fileOpenErrorEventCount < DpWriterComponentBase::EVENTID_FILEOPENERROR_THROTTLE) {
|
||||||
|
ASSERT_EVENTS_SIZE(1);
|
||||||
|
Fw::FileNameString fileName;
|
||||||
|
this->constructDpFileName(container.getId(), container.getTimeTag(), fileName);
|
||||||
|
const Os::File::Status openStatus = fileData.openStatus;
|
||||||
|
ASSERT_EVENTS_FileOpenError(0, static_cast<U32>(openStatus), fileName.toChar());
|
||||||
|
this->abstractState.m_fileOpenErrorEventCount++;
|
||||||
|
} else {
|
||||||
|
ASSERT_EVENTS_SIZE(0);
|
||||||
|
}
|
||||||
|
// Verify no file output
|
||||||
|
ASSERT_EQ(fileData.pointer, 0);
|
||||||
|
// Verify port output
|
||||||
|
this->checkProcTypes(container);
|
||||||
|
ASSERT_from_dpWrittenOut_SIZE(0);
|
||||||
|
ASSERT_from_deallocBufferSendOut_SIZE(1);
|
||||||
|
ASSERT_from_deallocBufferSendOut(0, buffer);
|
||||||
|
// Increment m_NumFailedWrites
|
||||||
|
this->abstractState.m_NumFailedWrites.value++;
|
||||||
|
// Increment m_NumErrors
|
||||||
|
this->abstractState.m_NumErrors.value++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TestState ::precondition__BufferSendIn__FileWriteError() const {
|
||||||
|
const auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
bool result = true;
|
||||||
|
result &= (fileData.openStatus == Os::File::Status::OP_OK);
|
||||||
|
result &= (fileData.writeStatus != Os::File::Status::OP_OK);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestState ::action__BufferSendIn__FileWriteError() {
|
||||||
|
// Clear the history
|
||||||
|
this->clearHistory();
|
||||||
|
// Reset the saved proc types
|
||||||
|
// These are updated in the from_procBufferSendOut handler
|
||||||
|
this->abstractState.m_procTypes = 0;
|
||||||
|
// Update m_NumBuffersReceived
|
||||||
|
this->abstractState.m_NumBuffersReceived.value++;
|
||||||
|
// Construct a valid buffer
|
||||||
|
Fw::Buffer buffer = this->abstractState.getDpBuffer();
|
||||||
|
// Set up the container
|
||||||
|
Fw::DpContainer container;
|
||||||
|
container.setBuffer(buffer);
|
||||||
|
container.deserializeHeader();
|
||||||
|
// Get the file size
|
||||||
|
const FwSizeType fileSize = container.getPacketSize();
|
||||||
|
// Turn off file writing
|
||||||
|
auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
U8* const savedWriteResult = fileData.writeResult;
|
||||||
|
fileData.writeResult = nullptr;
|
||||||
|
// Adjust size result of write
|
||||||
|
fileData.writeSizeResult = STest::Pick::lowerUpper(0, fileSize);
|
||||||
|
// Send the buffer
|
||||||
|
this->invoke_to_bufferSendIn(0, buffer);
|
||||||
|
this->component.doDispatch();
|
||||||
|
// Check events
|
||||||
|
if (this->abstractState.m_fileWriteErrorEventCount < DpWriterComponentBase::EVENTID_FILEWRITEERROR_THROTTLE) {
|
||||||
|
ASSERT_EVENTS_SIZE(1);
|
||||||
|
Fw::FileNameString fileName;
|
||||||
|
this->constructDpFileName(container.getId(), container.getTimeTag(), fileName);
|
||||||
|
const Os::File::Status writeStatus = Os::Stub::File::Test::StaticData::data.writeStatus;
|
||||||
|
ASSERT_EVENTS_FileWriteError(0, static_cast<U32>(writeStatus), static_cast<U32>(fileData.writeSizeResult),
|
||||||
|
static_cast<U32>(fileSize), fileName.toChar());
|
||||||
|
this->abstractState.m_fileWriteErrorEventCount++;
|
||||||
|
} else {
|
||||||
|
ASSERT_EVENTS_SIZE(0);
|
||||||
|
}
|
||||||
|
// Verify port output
|
||||||
|
this->checkProcTypes(container);
|
||||||
|
ASSERT_from_dpWrittenOut_SIZE(0);
|
||||||
|
ASSERT_from_deallocBufferSendOut_SIZE(1);
|
||||||
|
ASSERT_from_deallocBufferSendOut(0, buffer);
|
||||||
|
// Increment m_NumFailedWrites
|
||||||
|
this->abstractState.m_NumFailedWrites.value++;
|
||||||
|
// Increment m_NumErrors
|
||||||
|
this->abstractState.m_NumErrors.value++;
|
||||||
|
// Turn on file writing
|
||||||
|
fileData.writeResult = savedWriteResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace BufferSendIn {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void Tester::BufferTooSmallForData() {
|
||||||
|
this->ruleBufferTooSmallForData.apply(this->testState);
|
||||||
|
this->testState.printEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tester::BufferTooSmallForPacket() {
|
||||||
|
this->ruleBufferTooSmallForPacket.apply(this->testState);
|
||||||
|
this->testState.printEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tester::FileOpenError() {
|
||||||
|
Testers::fileOpenStatus.ruleError.apply(this->testState);
|
||||||
|
this->ruleFileOpenError.apply(this->testState);
|
||||||
|
this->testState.printEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tester::FileWriteError() {
|
||||||
|
Testers::fileWriteStatus.ruleError.apply(this->testState);
|
||||||
|
this->ruleFileWriteError.apply(this->testState);
|
||||||
|
this->testState.printEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tester::InvalidBuffer() {
|
||||||
|
this->ruleInvalidBuffer.apply(this->testState);
|
||||||
|
this->testState.printEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tester::InvalidHeader() {
|
||||||
|
this->ruleInvalidHeader.apply(this->testState);
|
||||||
|
this->testState.printEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tester::InvalidHeaderHash() {
|
||||||
|
this->ruleInvalidHeaderHash.apply(this->testState);
|
||||||
|
this->testState.printEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tester::OK() {
|
||||||
|
this->ruleOK.apply(this->testState);
|
||||||
|
this->testState.printEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace BufferSendIn
|
||||||
|
|
||||||
|
} // namespace Svc
|
||||||
94
Svc/DpWriter/test/ut/Rules/BufferSendIn.hpp
Normal file
94
Svc/DpWriter/test/ut/Rules/BufferSendIn.hpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title BufferSendIn.hpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief BufferSendIn class interface
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2024 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef Svc_BufferSendIn_HPP
|
||||||
|
#define Svc_BufferSendIn_HPP
|
||||||
|
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/Rules.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/TestState/TestState.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
namespace BufferSendIn {
|
||||||
|
|
||||||
|
class Tester {
|
||||||
|
public:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! OK
|
||||||
|
void OK();
|
||||||
|
|
||||||
|
//! Invalid buffer
|
||||||
|
void InvalidBuffer();
|
||||||
|
|
||||||
|
//! Buffer too small for packet
|
||||||
|
void BufferTooSmallForPacket();
|
||||||
|
|
||||||
|
//! Invalid header hash
|
||||||
|
void InvalidHeaderHash();
|
||||||
|
|
||||||
|
//! Invalid header
|
||||||
|
void InvalidHeader();
|
||||||
|
|
||||||
|
//! Buffer too small for data
|
||||||
|
void BufferTooSmallForData();
|
||||||
|
|
||||||
|
//! File open error
|
||||||
|
void FileOpenError();
|
||||||
|
|
||||||
|
//! File write error
|
||||||
|
void FileWriteError();
|
||||||
|
|
||||||
|
public:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Rules
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Rule BufferSendIn::OK
|
||||||
|
Rules::BufferSendIn::OK ruleOK;
|
||||||
|
|
||||||
|
//! Rule BufferSendIn::InvalidBuffer
|
||||||
|
Rules::BufferSendIn::InvalidBuffer ruleInvalidBuffer;
|
||||||
|
|
||||||
|
//! Rule BufferSendIn::BufferTooSmallForPacket
|
||||||
|
Rules::BufferSendIn::BufferTooSmallForPacket ruleBufferTooSmallForPacket;
|
||||||
|
|
||||||
|
//! Rule BufferSendIn::InvalidHeaderHash
|
||||||
|
Rules::BufferSendIn::InvalidHeaderHash ruleInvalidHeaderHash;
|
||||||
|
|
||||||
|
//! Rule BufferSendIn::InvalidHeader
|
||||||
|
Rules::BufferSendIn::InvalidHeader ruleInvalidHeader;
|
||||||
|
|
||||||
|
//! Rule BufferSendIn::BufferTooSmallForData
|
||||||
|
Rules::BufferSendIn::BufferTooSmallForData ruleBufferTooSmallForData;
|
||||||
|
|
||||||
|
//! Rule BufferSendIn::FileOpenError
|
||||||
|
Rules::BufferSendIn::FileOpenError ruleFileOpenError;
|
||||||
|
|
||||||
|
//! Rule BufferSendIn::FileWriteError
|
||||||
|
Rules::BufferSendIn::FileWriteError ruleFileWriteError;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Public member variables
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Test state
|
||||||
|
TestState testState;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BufferSendIn
|
||||||
|
|
||||||
|
} // namespace Svc
|
||||||
|
|
||||||
|
#endif
|
||||||
71
Svc/DpWriter/test/ut/Rules/CLEAR_EVENT_THROTTLE.cpp
Normal file
71
Svc/DpWriter/test/ut/Rules/CLEAR_EVENT_THROTTLE.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title CLEAR_EVENT_THROTTLE.cpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief CLEAR_EVENT_THROTTLE class implementation
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2024 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "STest/Pick/Pick.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/CLEAR_EVENT_THROTTLE.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/Testers.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Rule definitions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool TestState ::precondition__CLEAR_EVENT_THROTTLE__OK() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestState ::action__CLEAR_EVENT_THROTTLE__OK() {
|
||||||
|
// Clear history
|
||||||
|
this->clearHistory();
|
||||||
|
// Send the command
|
||||||
|
const FwEnumStoreType instance = static_cast<FwEnumStoreType>(STest::Pick::any());
|
||||||
|
const U32 cmdSeq = STest::Pick::any();
|
||||||
|
this->sendCmd_CLEAR_EVENT_THROTTLE(instance, cmdSeq);
|
||||||
|
this->component.doDispatch();
|
||||||
|
// Check the command response
|
||||||
|
ASSERT_CMD_RESPONSE_SIZE(1);
|
||||||
|
ASSERT_CMD_RESPONSE(0, DpWriterComponentBase::OPCODE_CLEAR_EVENT_THROTTLE, cmdSeq, Fw::CmdResponse::OK);
|
||||||
|
// Check the concrete state
|
||||||
|
ASSERT_EQ(this->component.DpWriterComponentBase::m_BufferTooSmallForDataThrottle, 0);
|
||||||
|
ASSERT_EQ(this->component.DpWriterComponentBase::m_BufferTooSmallForPacketThrottle, 0);
|
||||||
|
ASSERT_EQ(this->component.DpWriterComponentBase::m_FileOpenErrorThrottle, 0);
|
||||||
|
ASSERT_EQ(this->component.DpWriterComponentBase::m_FileWriteErrorThrottle, 0);
|
||||||
|
ASSERT_EQ(this->component.DpWriterComponentBase::m_InvalidBufferThrottle, 0);
|
||||||
|
ASSERT_EQ(this->component.DpWriterComponentBase::m_InvalidHeaderHashThrottle, 0);
|
||||||
|
ASSERT_EQ(this->component.DpWriterComponentBase::m_InvalidHeaderThrottle, 0);
|
||||||
|
// Update the abstract state
|
||||||
|
this->abstractState.m_bufferTooSmallForDataEventCount = 0;
|
||||||
|
this->abstractState.m_bufferTooSmallForPacketEventCount = 0;
|
||||||
|
this->abstractState.m_fileOpenErrorEventCount = 0;
|
||||||
|
this->abstractState.m_fileWriteErrorEventCount = 0;
|
||||||
|
this->abstractState.m_invalidBufferEventCount = 0;
|
||||||
|
this->abstractState.m_invalidHeaderEventCount = 0;
|
||||||
|
this->abstractState.m_invalidHeaderHashEventCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace CLEAR_EVENT_THROTTLE {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void Tester ::OK() {
|
||||||
|
for (FwSizeType i = 0; i <= DpWriterComponentBase::EVENTID_INVALIDBUFFER_THROTTLE; i++) {
|
||||||
|
Testers::bufferSendIn.ruleInvalidBuffer.apply(this->testState);
|
||||||
|
}
|
||||||
|
this->ruleOK.apply(this->testState);
|
||||||
|
Testers::bufferSendIn.ruleInvalidBuffer.apply(this->testState);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CLEAR_EVENT_THROTTLE
|
||||||
|
|
||||||
|
} // namespace Svc
|
||||||
57
Svc/DpWriter/test/ut/Rules/CLEAR_EVENT_THROTTLE.hpp
Normal file
57
Svc/DpWriter/test/ut/Rules/CLEAR_EVENT_THROTTLE.hpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title CLEAR_EVENT_THROTTLE.hpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief CLEAR_EVENT_THROTTLE class interface
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2024 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef Svc_CLEAR_EVENT_THROTTLE_HPP
|
||||||
|
#define Svc_CLEAR_EVENT_THROTTLE_HPP
|
||||||
|
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/Rules.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/TestState/TestState.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
namespace CLEAR_EVENT_THROTTLE {
|
||||||
|
|
||||||
|
class Tester {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! OK
|
||||||
|
void OK();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Rules
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Rule CLEAR_EVENT_THROTTLE::OK
|
||||||
|
Rules::CLEAR_EVENT_THROTTLE::OK ruleOK;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Public member variables
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Test state
|
||||||
|
TestState testState;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
59
Svc/DpWriter/test/ut/Rules/FileOpenStatus.cpp
Normal file
59
Svc/DpWriter/test/ut/Rules/FileOpenStatus.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title FileOpenStatus.cpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief FileOpenStatus class implementation
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2024 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "Os/Stub/test/File.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/FileOpenStatus.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/Testers.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Rule definitions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool TestState ::precondition__FileOpenStatus__OK() const {
|
||||||
|
const auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
return (fileData.openStatus != Os::File::Status::OP_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestState ::action__FileOpenStatus__OK() {
|
||||||
|
auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
fileData.openStatus = Os::File::Status::OP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TestState ::precondition__FileOpenStatus__Error() const {
|
||||||
|
const auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
return (fileData.openStatus == Os::File::Status::OP_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestState ::action__FileOpenStatus__Error() {
|
||||||
|
auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
fileData.openStatus = DpWriterTester::pickOsFileError();
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace FileOpenStatus {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void Tester::OK() {
|
||||||
|
this->ruleError.apply(this->testState);
|
||||||
|
this->ruleOK.apply(this->testState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tester::Error() {
|
||||||
|
this->ruleError.apply(this->testState);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace FileOpenStatus
|
||||||
|
|
||||||
|
} // namespace Svc
|
||||||
63
Svc/DpWriter/test/ut/Rules/FileOpenStatus.hpp
Normal file
63
Svc/DpWriter/test/ut/Rules/FileOpenStatus.hpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title FileOpenStatus.hpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief FileOpenStatus class interface
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef Svc_FileOpenStatus_HPP
|
||||||
|
#define Svc_FileOpenStatus_HPP
|
||||||
|
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/Rules.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/TestState/TestState.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
namespace FileOpenStatus {
|
||||||
|
|
||||||
|
class Tester {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! OK
|
||||||
|
void OK();
|
||||||
|
|
||||||
|
//! Error
|
||||||
|
void Error();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Rules
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Rule FileOpenStatus::OK
|
||||||
|
Rules::FileOpenStatus::OK ruleOK;
|
||||||
|
|
||||||
|
//! Rule FileOpenStatus::Error
|
||||||
|
Rules::FileOpenStatus::Error ruleError;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Public member variables
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Test state
|
||||||
|
TestState testState;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
59
Svc/DpWriter/test/ut/Rules/FileWriteStatus.cpp
Normal file
59
Svc/DpWriter/test/ut/Rules/FileWriteStatus.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title FileWriteStatus.cpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief FileWriteStatus class implementation
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2024 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "Os/Stub/test/File.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/FileWriteStatus.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/Testers.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Rule definitions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool TestState ::precondition__FileWriteStatus__OK() const {
|
||||||
|
const auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
return (fileData.writeStatus != Os::File::Status::OP_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestState ::action__FileWriteStatus__OK() {
|
||||||
|
auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
fileData.writeStatus = Os::File::Status::OP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TestState ::precondition__FileWriteStatus__Error() const {
|
||||||
|
const auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
return (fileData.writeStatus == Os::File::Status::OP_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestState ::action__FileWriteStatus__Error() {
|
||||||
|
auto& fileData = Os::Stub::File::Test::StaticData::data;
|
||||||
|
fileData.writeStatus = DpWriterTester::pickOsFileError();
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace FileWriteStatus {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void Tester::OK() {
|
||||||
|
this->ruleError.apply(this->testState);
|
||||||
|
this->ruleOK.apply(this->testState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tester::Error() {
|
||||||
|
this->ruleError.apply(this->testState);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace FileWriteStatus
|
||||||
|
|
||||||
|
} // namespace Svc
|
||||||
63
Svc/DpWriter/test/ut/Rules/FileWriteStatus.hpp
Normal file
63
Svc/DpWriter/test/ut/Rules/FileWriteStatus.hpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title FileWriteStatus.hpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief FileWriteStatus class interface
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef Svc_FileWriteStatus_HPP
|
||||||
|
#define Svc_FileWriteStatus_HPP
|
||||||
|
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/Rules.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/TestState/TestState.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
namespace FileWriteStatus {
|
||||||
|
|
||||||
|
class Tester {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! OK
|
||||||
|
void OK();
|
||||||
|
|
||||||
|
//! Error
|
||||||
|
void Error();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Rules
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Rule FileWriteStatus::OK
|
||||||
|
Rules::FileWriteStatus::OK ruleOK;
|
||||||
|
|
||||||
|
//! Rule FileWriteStatus::Error
|
||||||
|
Rules::FileWriteStatus::Error ruleError;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Public member variables
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Test state
|
||||||
|
TestState testState;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
54
Svc/DpWriter/test/ut/Rules/Rules.hpp
Normal file
54
Svc/DpWriter/test/ut/Rules/Rules.hpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title Rules.hpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief Rules for testing DpWriter
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2024 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef Svc_Rules_HPP
|
||||||
|
#define Svc_Rules_HPP
|
||||||
|
|
||||||
|
#include "STest/Rule/Rule.hpp"
|
||||||
|
|
||||||
|
#include "Svc/DpWriter/test/ut/TestState/TestState.hpp"
|
||||||
|
|
||||||
|
#define RULES_DEF_RULE(GROUP_NAME, RULE_NAME) \
|
||||||
|
namespace GROUP_NAME { \
|
||||||
|
\
|
||||||
|
struct RULE_NAME : public STest::Rule<TestState> { \
|
||||||
|
RULE_NAME() : Rule<TestState>(#GROUP_NAME "." #RULE_NAME) {} \
|
||||||
|
\
|
||||||
|
bool precondition(const TestState& state) { return state.precondition__##GROUP_NAME##__##RULE_NAME(); } \
|
||||||
|
\
|
||||||
|
void action(TestState& state) { state.action__##GROUP_NAME##__##RULE_NAME(); } \
|
||||||
|
}; \
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
namespace Rules {
|
||||||
|
|
||||||
|
RULES_DEF_RULE(BufferSendIn, BufferTooSmallForData)
|
||||||
|
RULES_DEF_RULE(BufferSendIn, BufferTooSmallForPacket)
|
||||||
|
RULES_DEF_RULE(BufferSendIn, FileOpenError)
|
||||||
|
RULES_DEF_RULE(BufferSendIn, FileWriteError)
|
||||||
|
RULES_DEF_RULE(BufferSendIn, InvalidBuffer)
|
||||||
|
RULES_DEF_RULE(BufferSendIn, InvalidHeader)
|
||||||
|
RULES_DEF_RULE(BufferSendIn, InvalidHeaderHash)
|
||||||
|
RULES_DEF_RULE(BufferSendIn, OK)
|
||||||
|
RULES_DEF_RULE(CLEAR_EVENT_THROTTLE, OK)
|
||||||
|
RULES_DEF_RULE(FileOpenStatus, Error)
|
||||||
|
RULES_DEF_RULE(FileOpenStatus, OK)
|
||||||
|
RULES_DEF_RULE(FileWriteStatus, Error)
|
||||||
|
RULES_DEF_RULE(FileWriteStatus, OK)
|
||||||
|
RULES_DEF_RULE(SchedIn, OK)
|
||||||
|
|
||||||
|
} // namespace Rules
|
||||||
|
|
||||||
|
} // namespace Svc
|
||||||
|
|
||||||
|
#endif
|
||||||
49
Svc/DpWriter/test/ut/Rules/SchedIn.cpp
Normal file
49
Svc/DpWriter/test/ut/Rules/SchedIn.cpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title SchedIn.cpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief SchedIn class implementation
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2024 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "STest/Pick/Pick.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/SchedIn.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/Testers.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Rule definitions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool TestState ::precondition__SchedIn__OK() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestState ::action__SchedIn__OK() {
|
||||||
|
// Clear history
|
||||||
|
this->clearHistory();
|
||||||
|
// Invoke schedIn port
|
||||||
|
const U32 context = STest::Pick::any();
|
||||||
|
this->invoke_to_schedIn(0, context);
|
||||||
|
this->component.doDispatch();
|
||||||
|
// Check telemetry
|
||||||
|
this->checkTelemetry();
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace SchedIn {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void Tester ::OK() {
|
||||||
|
this->ruleOK.apply(this->testState);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace SchedIn
|
||||||
|
|
||||||
|
} // namespace Svc
|
||||||
57
Svc/DpWriter/test/ut/Rules/SchedIn.hpp
Normal file
57
Svc/DpWriter/test/ut/Rules/SchedIn.hpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title SchedIn.hpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief SchedIn class interface
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2024 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef Svc_SchedIn_HPP
|
||||||
|
#define Svc_SchedIn_HPP
|
||||||
|
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/Rules.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/TestState/TestState.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
namespace SchedIn {
|
||||||
|
|
||||||
|
class Tester {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! OK
|
||||||
|
void OK();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Rules
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Rule SchedIn::OK
|
||||||
|
Rules::SchedIn::OK ruleOK;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Public member variables
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Test state
|
||||||
|
TestState testState;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
28
Svc/DpWriter/test/ut/Rules/Testers.cpp
Normal file
28
Svc/DpWriter/test/ut/Rules/Testers.cpp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title Testers.cpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief Testers class implementation
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/Testers.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
namespace Testers {
|
||||||
|
|
||||||
|
BufferSendIn::Tester bufferSendIn;
|
||||||
|
|
||||||
|
FileOpenStatus::Tester fileOpenStatus;
|
||||||
|
|
||||||
|
FileWriteStatus::Tester fileWriteStatus;
|
||||||
|
|
||||||
|
SchedIn::Tester schedIn;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
39
Svc/DpWriter/test/ut/Rules/Testers.hpp
Normal file
39
Svc/DpWriter/test/ut/Rules/Testers.hpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title Testers.hpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief Testers class interface
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2023 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef Svc_Testers_HPP
|
||||||
|
#define Svc_Testers_HPP
|
||||||
|
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/BufferSendIn.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/CLEAR_EVENT_THROTTLE.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/FileOpenStatus.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/FileWriteStatus.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/SchedIn.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
namespace Testers {
|
||||||
|
|
||||||
|
extern BufferSendIn::Tester bufferSendIn;
|
||||||
|
|
||||||
|
extern CLEAR_EVENT_THROTTLE::Tester clearEventThrottle;
|
||||||
|
|
||||||
|
extern FileOpenStatus::Tester fileOpenStatus;
|
||||||
|
|
||||||
|
extern FileWriteStatus::Tester fileWriteStatus;
|
||||||
|
|
||||||
|
extern SchedIn::Tester schedIn;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
72
Svc/DpWriter/test/ut/Scenarios/Random.cpp
Normal file
72
Svc/DpWriter/test/ut/Scenarios/Random.cpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title Random.hpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief Random scenario
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2024 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "STest/Scenario/BoundedScenario.hpp"
|
||||||
|
#include "STest/Scenario/RandomScenario.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Rules/Rules.hpp"
|
||||||
|
#include "Svc/DpWriter/test/ut/Scenarios/Random.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
namespace Scenarios {
|
||||||
|
|
||||||
|
namespace Random {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Rule definitions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Rules::BufferSendIn::BufferTooSmallForData bufferSendInBufferTooSmallForData;
|
||||||
|
Rules::BufferSendIn::BufferTooSmallForPacket bufferSendInBufferTooSmallForPacket;
|
||||||
|
Rules::BufferSendIn::FileOpenError bufferSendInFileOpenError;
|
||||||
|
Rules::BufferSendIn::FileWriteError bufferSendInFileWriteError;
|
||||||
|
Rules::BufferSendIn::InvalidBuffer bufferSendInInvalidBuffer;
|
||||||
|
Rules::BufferSendIn::InvalidHeader bufferSendInInvalidHeader;
|
||||||
|
Rules::BufferSendIn::InvalidHeaderHash bufferSendInInvalidHeaderHash;
|
||||||
|
Rules::BufferSendIn::OK bufferSendInOK;
|
||||||
|
Rules::CLEAR_EVENT_THROTTLE::OK clearEventThrottleOK;
|
||||||
|
Rules::FileOpenStatus::Error fileOpenStatusError;
|
||||||
|
Rules::FileOpenStatus::OK fileOpenStatusOK;
|
||||||
|
Rules::FileWriteStatus::Error fileWriteStatusError;
|
||||||
|
Rules::FileWriteStatus::OK fileWriteStatusOK;
|
||||||
|
Rules::SchedIn::OK schedInOK;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void Tester ::run(FwSizeType maxNumSteps) {
|
||||||
|
STest::Rule<TestState>* rules[] = {&bufferSendInBufferTooSmallForData,
|
||||||
|
&bufferSendInBufferTooSmallForPacket,
|
||||||
|
&bufferSendInFileOpenError,
|
||||||
|
&bufferSendInFileWriteError,
|
||||||
|
&bufferSendInInvalidBuffer,
|
||||||
|
&bufferSendInInvalidHeader,
|
||||||
|
&bufferSendInInvalidHeaderHash,
|
||||||
|
&bufferSendInOK,
|
||||||
|
&clearEventThrottleOK,
|
||||||
|
&fileOpenStatusError,
|
||||||
|
&fileOpenStatusOK,
|
||||||
|
&fileWriteStatusError,
|
||||||
|
&fileWriteStatusOK,
|
||||||
|
&schedInOK};
|
||||||
|
STest::RandomScenario<TestState> scenario("RandomScenario", rules,
|
||||||
|
sizeof(rules) / sizeof(STest::RandomScenario<TestState>*));
|
||||||
|
STest::BoundedScenario<TestState> boundedScenario("BoundedRandomScenario", scenario, maxNumSteps);
|
||||||
|
const U32 numSteps = boundedScenario.run(this->testState);
|
||||||
|
printf("Ran %u steps.\n", numSteps);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Random
|
||||||
|
|
||||||
|
} // namespace Scenarios
|
||||||
|
|
||||||
|
} // namespace Svc
|
||||||
48
Svc/DpWriter/test/ut/Scenarios/Random.hpp
Normal file
48
Svc/DpWriter/test/ut/Scenarios/Random.hpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title Random.hpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief Random scenario
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2024 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef Svc_Random_HPP
|
||||||
|
#define Svc_Random_HPP
|
||||||
|
|
||||||
|
#include "Svc/DpWriter/test/ut/TestState/TestState.hpp"
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
namespace Scenarios {
|
||||||
|
|
||||||
|
namespace Random {
|
||||||
|
|
||||||
|
class Tester {
|
||||||
|
public:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Tests
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Run the random scenario
|
||||||
|
void run(FwSizeType maxNumSteps //!< The maximum number of steps
|
||||||
|
);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Private member variables
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Test state
|
||||||
|
TestState testState;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Random
|
||||||
|
|
||||||
|
} // namespace Scenarios
|
||||||
|
|
||||||
|
} // namespace Svc
|
||||||
|
|
||||||
|
#endif
|
||||||
47
Svc/DpWriter/test/ut/TestState/TestState.hpp
Normal file
47
Svc/DpWriter/test/ut/TestState/TestState.hpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title TestState.hpp
|
||||||
|
// \author Rob Bocchino
|
||||||
|
// \brief Test state for testing DpWriter
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright (C) 2024 California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef Svc_TestState_HPP
|
||||||
|
#define Svc_TestState_HPP
|
||||||
|
|
||||||
|
#include "Svc/DpWriter/test/ut/DpWriterTester.hpp"
|
||||||
|
|
||||||
|
#define TEST_STATE_DEF_RULE(GROUP_NAME, RULE_NAME) \
|
||||||
|
bool precondition__##GROUP_NAME##__##RULE_NAME() const; \
|
||||||
|
void action__##GROUP_NAME##__##RULE_NAME();
|
||||||
|
|
||||||
|
namespace Svc {
|
||||||
|
|
||||||
|
class TestState : public DpWriterTester {
|
||||||
|
public:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Rule definitions
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
TEST_STATE_DEF_RULE(BufferSendIn, BufferTooSmallForData)
|
||||||
|
TEST_STATE_DEF_RULE(BufferSendIn, BufferTooSmallForPacket)
|
||||||
|
TEST_STATE_DEF_RULE(BufferSendIn, FileOpenError)
|
||||||
|
TEST_STATE_DEF_RULE(BufferSendIn, FileWriteError)
|
||||||
|
TEST_STATE_DEF_RULE(BufferSendIn, InvalidBuffer)
|
||||||
|
TEST_STATE_DEF_RULE(BufferSendIn, InvalidHeader)
|
||||||
|
TEST_STATE_DEF_RULE(BufferSendIn, InvalidHeaderHash)
|
||||||
|
TEST_STATE_DEF_RULE(BufferSendIn, OK)
|
||||||
|
TEST_STATE_DEF_RULE(CLEAR_EVENT_THROTTLE, OK)
|
||||||
|
TEST_STATE_DEF_RULE(FileOpenStatus, Error)
|
||||||
|
TEST_STATE_DEF_RULE(FileOpenStatus, OK)
|
||||||
|
TEST_STATE_DEF_RULE(FileWriteStatus, Error)
|
||||||
|
TEST_STATE_DEF_RULE(FileWriteStatus, OK)
|
||||||
|
TEST_STATE_DEF_RULE(SchedIn, OK)
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Svc
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -13,10 +13,10 @@
|
|||||||
#ifndef TestUtils_OnChangeChannel_HPP
|
#ifndef TestUtils_OnChangeChannel_HPP
|
||||||
#define TestUtils_OnChangeChannel_HPP
|
#define TestUtils_OnChangeChannel_HPP
|
||||||
|
|
||||||
|
#include <FpConfig.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "TestUtils/Option.hpp"
|
#include "TestUtils/Option.hpp"
|
||||||
#include "config/FpConfig.hpp"
|
|
||||||
|
|
||||||
namespace TestUtils {
|
namespace TestUtils {
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
// \brief hpp file for Hash class
|
// \brief hpp file for Hash class
|
||||||
//
|
//
|
||||||
// \copyright
|
// \copyright
|
||||||
// Copyright 2009-2015, by the California Institute of Technology.
|
// Copyright 2009-2024, by the California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
||||||
// acknowledged.
|
// acknowledged.
|
||||||
//
|
//
|
||||||
@ -14,65 +14,68 @@
|
|||||||
#define UTILS_HASH_BUFFER_HPP
|
#define UTILS_HASH_BUFFER_HPP
|
||||||
|
|
||||||
#include <FpConfig.hpp>
|
#include <FpConfig.hpp>
|
||||||
#include <Fw/Types/Serializable.hpp>
|
|
||||||
#include <Fw/Types/Assert.hpp>
|
#include <Fw/Types/Assert.hpp>
|
||||||
|
#include <Fw/Types/Serializable.hpp>
|
||||||
#include <Utils/Hash/HashConfig.hpp>
|
#include <Utils/Hash/HashConfig.hpp>
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
//! \class HashBuffer
|
//! \class HashBuffer
|
||||||
//! \brief A container class for holding a hash buffer
|
//! \brief A container class for holding a hash buffer
|
||||||
|
//!
|
||||||
|
class HashBuffer : public Fw::SerializeBufferBase {
|
||||||
|
public:
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Construction and destruction
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
//! Construct a HashBuffer object
|
||||||
//!
|
//!
|
||||||
class HashBuffer : public Fw::SerializeBufferBase {
|
HashBuffer(const U8* args, NATIVE_UINT_TYPE size);
|
||||||
public:
|
HashBuffer(const HashBuffer& other);
|
||||||
// ----------------------------------------------------------------------
|
HashBuffer();
|
||||||
// Construction and destruction
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
//! Construct a HashBuffer object
|
//! Destroy a HashBuffer object
|
||||||
//!
|
//!
|
||||||
HashBuffer(const U8 *args, NATIVE_UINT_TYPE size);
|
virtual ~HashBuffer();
|
||||||
HashBuffer(const HashBuffer& other);
|
|
||||||
HashBuffer();
|
|
||||||
|
|
||||||
//! Destroy a HashBuffer object
|
// ----------------------------------------------------------------------
|
||||||
//!
|
// Public instance methods
|
||||||
virtual ~HashBuffer();
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
//! Assign a hash buffer from another hash buffer
|
||||||
// Public instance methods
|
//!
|
||||||
// ----------------------------------------------------------------------
|
HashBuffer& operator=(const HashBuffer& other);
|
||||||
|
|
||||||
//! Assign a hash buffer from another hash buffer
|
//! Compare two hash buffers for equality
|
||||||
//!
|
//!
|
||||||
HashBuffer& operator=(const HashBuffer& other);
|
bool operator==(const HashBuffer& other) const;
|
||||||
|
|
||||||
//! Compare two hash buffers for equality
|
//! Compare two hash buffers for inequality
|
||||||
//!
|
//!
|
||||||
bool operator==(const HashBuffer& other) const;
|
bool operator!=(const HashBuffer& other) const;
|
||||||
|
|
||||||
//! Compare two hash buffers for inequality
|
//! Get the total buffer length of a hash buffer
|
||||||
//!
|
//!
|
||||||
bool operator!=(const HashBuffer& other) const;
|
NATIVE_UINT_TYPE getBuffCapacity() const; // !< returns capacity, not current size, of buffer
|
||||||
|
|
||||||
//! Get the total buffer length of a hash buffer
|
//! Get a pointer to the buffer within the hash buffer
|
||||||
//!
|
//!
|
||||||
NATIVE_UINT_TYPE getBuffCapacity() const; // !< returns capacity, not current size, of buffer
|
U8* getBuffAddr();
|
||||||
|
const U8* getBuffAddr() const;
|
||||||
|
|
||||||
//! Get a pointer to the buffer within the hash buffer
|
//! Convert bytes 0 through 3 of the hash data to a big-Endian U32 value
|
||||||
//!
|
U32 asBigEndianU32() const;
|
||||||
U8* getBuffAddr();
|
|
||||||
const U8* getBuffAddr() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Private member variables
|
// Private member variables
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
//! The buffer which stores the hash digest
|
//! The buffer which stores the hash digest
|
||||||
//!
|
//!
|
||||||
U8 m_bufferData[HASH_DIGEST_LENGTH]; // packet data buffer
|
U8 m_bufferData[HASH_DIGEST_LENGTH] = {}; // packet data buffer
|
||||||
};
|
};
|
||||||
}
|
} // namespace Utils
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1,55 +1,69 @@
|
|||||||
#include <Utils/Hash/HashBuffer.hpp>
|
#include <Utils/Hash/HashBuffer.hpp>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "Fw/Types/Serializable.hpp"
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
HashBuffer::HashBuffer() {
|
HashBuffer::HashBuffer() {}
|
||||||
}
|
|
||||||
|
|
||||||
HashBuffer::HashBuffer(const U8 *args, NATIVE_UINT_TYPE size) {
|
HashBuffer::HashBuffer(const U8* args, NATIVE_UINT_TYPE size) : Fw::SerializeBufferBase() {
|
||||||
Fw::SerializeStatus stat = Fw::SerializeBufferBase::setBuff(args,size);
|
Fw::SerializeStatus stat = Fw::SerializeBufferBase::setBuff(args, size);
|
||||||
FW_ASSERT(Fw::FW_SERIALIZE_OK == stat,static_cast<NATIVE_INT_TYPE>(stat));
|
FW_ASSERT(Fw::FW_SERIALIZE_OK == stat, static_cast<NATIVE_INT_TYPE>(stat));
|
||||||
}
|
}
|
||||||
|
|
||||||
HashBuffer::~HashBuffer() {
|
HashBuffer::~HashBuffer() {}
|
||||||
}
|
|
||||||
|
|
||||||
HashBuffer::HashBuffer(const HashBuffer& other) : Fw::SerializeBufferBase() {
|
HashBuffer::HashBuffer(const HashBuffer& other) : Fw::SerializeBufferBase() {
|
||||||
Fw::SerializeStatus stat = Fw::SerializeBufferBase::setBuff(other.m_bufferData,other.getBuffLength());
|
Fw::SerializeStatus stat = Fw::SerializeBufferBase::setBuff(other.m_bufferData, other.getBuffLength());
|
||||||
FW_ASSERT(Fw::FW_SERIALIZE_OK == stat,static_cast<NATIVE_INT_TYPE>(stat));
|
FW_ASSERT(Fw::FW_SERIALIZE_OK == stat, static_cast<NATIVE_INT_TYPE>(stat));
|
||||||
}
|
}
|
||||||
|
|
||||||
HashBuffer& HashBuffer::operator=(const HashBuffer& other) {
|
HashBuffer& HashBuffer::operator=(const HashBuffer& other) {
|
||||||
if(this == &other) {
|
if (this == &other) {
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Fw::SerializeStatus stat = Fw::SerializeBufferBase::setBuff(other.m_bufferData,other.getBuffLength());
|
|
||||||
FW_ASSERT(Fw::FW_SERIALIZE_OK == stat,static_cast<NATIVE_INT_TYPE>(stat));
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HashBuffer::operator==(const HashBuffer& other) const {
|
Fw::SerializeStatus stat = Fw::SerializeBufferBase::setBuff(other.m_bufferData, other.getBuffLength());
|
||||||
if( (this->getBuffLength() == other.getBuffLength()) &&
|
FW_ASSERT(Fw::FW_SERIALIZE_OK == stat, static_cast<NATIVE_INT_TYPE>(stat));
|
||||||
(memcmp(this->getBuffAddr(), other.getBuffAddr(), this->getBuffLength()) != 0) ){
|
return *this;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HashBuffer::operator!=(const HashBuffer& other) const {
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
const U8* HashBuffer::getBuffAddr() const {
|
|
||||||
return this->m_bufferData;
|
|
||||||
}
|
|
||||||
|
|
||||||
U8* HashBuffer::getBuffAddr() {
|
|
||||||
return this->m_bufferData;
|
|
||||||
}
|
|
||||||
|
|
||||||
NATIVE_UINT_TYPE HashBuffer::getBuffCapacity() const {
|
|
||||||
return sizeof(this->m_bufferData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HashBuffer::operator==(const HashBuffer& other) const {
|
||||||
|
if ((this->getBuffLength() == other.getBuffLength()) &&
|
||||||
|
(memcmp(this->getBuffAddr(), other.getBuffAddr(), this->getBuffLength()) != 0)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HashBuffer::operator!=(const HashBuffer& other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
const U8* HashBuffer::getBuffAddr() const {
|
||||||
|
return this->m_bufferData;
|
||||||
|
}
|
||||||
|
|
||||||
|
U8* HashBuffer::getBuffAddr() {
|
||||||
|
return this->m_bufferData;
|
||||||
|
}
|
||||||
|
|
||||||
|
NATIVE_UINT_TYPE HashBuffer::getBuffCapacity() const {
|
||||||
|
return sizeof(this->m_bufferData);
|
||||||
|
}
|
||||||
|
|
||||||
|
U32 HashBuffer::asBigEndianU32() const {
|
||||||
|
U32 result = 0;
|
||||||
|
const FwSizeType bufferSize = sizeof this->m_bufferData;
|
||||||
|
const FwSizeType numBytes = std::min(bufferSize, static_cast<FwSizeType>(sizeof(U32)));
|
||||||
|
for (FwSizeType i = 0; i < numBytes; i++) {
|
||||||
|
result <<= 8;
|
||||||
|
FW_ASSERT(i < bufferSize, static_cast<FwAssertArgType>(i), static_cast<FwAssertArgType>(bufferSize));
|
||||||
|
result += this->m_bufferData[i];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
} // namespace Utils
|
||||||
|
|||||||
@ -45,6 +45,9 @@ constant DpManagerNumPorts = 5
|
|||||||
@ Size of processing port array for DpWriter
|
@ Size of processing port array for DpWriter
|
||||||
constant DpWriterNumProcPorts = 5
|
constant DpWriterNumProcPorts = 5
|
||||||
|
|
||||||
|
@ The size of a file name string
|
||||||
|
constant FileNameStringSize = 256
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
# Hub connections. Connections on all deployments should mirror these settings.
|
# Hub connections. Connections on all deployments should mirror these settings.
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
|
|||||||
22
config/DpCfg.hpp
Normal file
22
config/DpCfg.hpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// ======================================================================
|
||||||
|
// \title DpCfg.hpp
|
||||||
|
// \author bocchino
|
||||||
|
// \brief hpp file for data product configuration
|
||||||
|
//
|
||||||
|
// \copyright
|
||||||
|
// Copyright 2024, by the California Institute of Technology.
|
||||||
|
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
||||||
|
// acknowledged.
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef DPCFG_HPP
|
||||||
|
#define DPCFG_HPP
|
||||||
|
|
||||||
|
#include <FpConfig.hpp>
|
||||||
|
|
||||||
|
// The format string for a file name
|
||||||
|
// The format arguments are container ID, time seconds, and time microseconds
|
||||||
|
constexpr const char *DP_FILENAME_FORMAT = "Dp_%08" PRI_FwDpIdType "_%08" PRIu32 "_%08" PRIu32 ".fdp";
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
x
Reference in New Issue
Block a user