Skip to content

Commit

Permalink
Add first pass at UTs
Browse files Browse the repository at this point in the history
  • Loading branch information
thomas-bc committed Jan 31, 2025
1 parent bcde1ee commit 44f4292
Show file tree
Hide file tree
Showing 13 changed files with 441 additions and 14 deletions.
14 changes: 14 additions & 0 deletions Svc/Deframer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,17 @@ set(MOD_DEPS
)

register_fprime_module()


#### UTs ####
set(UT_SOURCE_FILES
"${CMAKE_CURRENT_LIST_DIR}/Deframer.fpp"
"${CMAKE_CURRENT_LIST_DIR}/test/ut/DeframerTester.cpp"
"${CMAKE_CURRENT_LIST_DIR}/test/ut/DeframerTestMain.cpp"
)
set(UT_MOD_DEPS
STest
)
set(UT_AUTO_HELPERS ON)

register_fprime_ut()
7 changes: 6 additions & 1 deletion Svc/Deframer/Deframer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "Svc/Deframer/Deframer.hpp"
#include "FpConfig.hpp"
#include "Fw/Types/Assert.hpp"

namespace Svc {

Expand All @@ -23,7 +24,11 @@ Deframer ::~Deframer() {}

void Deframer ::framedIn_handler(FwIndexType portNum, Fw::Buffer& data, Fw::Buffer& context) {

// TODO: add asserts?
// Add checks to ensure that the data is a valid F' frame ??
// Seems like this component should be able to do that on its own without relying
// on an upstream component (the F´ accumulator)
FW_ASSERT(data.getSize() >= FrameConfig::HEADER_SIZE + FrameConfig::CHECKSUM_SIZE);

data.setData(data.getData() + FrameConfig::HEADER_SIZE);
data.setSize(data.getSize() - FrameConfig::HEADER_SIZE - FrameConfig::CHECKSUM_SIZE);

Expand Down
29 changes: 29 additions & 0 deletions Svc/Deframer/test/ut/DeframerTestMain.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// ======================================================================
// \title DeframerTestMain.cpp
// \author chammard
// \brief cpp file for Deframer component test main function
// ======================================================================

#include "DeframerTester.hpp"
#include "STest/Random/Random.hpp"

TEST(Deframer, NominalFrame) {
Svc::DeframerTester tester;
tester.testNominalFrame();
}

TEST(Deframer, TruncatedFrame) {
Svc::DeframerTester tester;
tester.testTruncatedFrame();
}

TEST(Deframer, ZeroSizeFrame) {
Svc::DeframerTester tester;
tester.testZeroSizeFrame();
}

int main(int argc, char** argv) {
STest::Random::seed();
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
67 changes: 67 additions & 0 deletions Svc/Deframer/test/ut/DeframerTester.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// ======================================================================
// \title DeframerTester.cpp
// \author chammard
// \brief cpp file for Deframer component test harness implementation class
// ======================================================================

#include "DeframerTester.hpp"
#include "STest/Random/Random.hpp"

namespace Svc {

// ----------------------------------------------------------------------
// Construction and destruction
// ----------------------------------------------------------------------

DeframerTester ::DeframerTester()
: DeframerGTestBase("DeframerTester", DeframerTester::MAX_HISTORY_SIZE), component("Deframer") {
this->initComponents();
this->connectPorts();
}

DeframerTester ::~DeframerTester() {}

// ----------------------------------------------------------------------
// Tests
// ----------------------------------------------------------------------

void DeframerTester ::testNominalFrame() {
// Get random byte of data
U8 randomByte = STest::Random::lowerUpper(0, 255);
// | F´ start word | Length (= 1) | Data | Checksum (4 bytes) |
U8 data[13] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x01, randomByte, 0x00, 0x00, 0x00, 0x00};
this->mockReceiveData(data, sizeof(data));

// Assert that something was emitted on the deframedOut port
ASSERT_from_deframedOut_SIZE(1);
// Assert that the data that was emitted on deframedOut is equal to Data field above (randomByte)
ASSERT_EQ(this->fromPortHistory_deframedOut->at(0).data.getData()[0], randomByte);
}

void DeframerTester::testTruncatedFrame() {
// Send a truncated frame, too short to be valid
U8 data[11] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
ASSERT_DEATH(this->mockReceiveData(data, sizeof(data)), "Deframer.cpp");
ASSERT_from_deframedOut_SIZE(0);
}

void DeframerTester::testZeroSizeFrame() {
// Send a null frame, too short to be valid
U8 data[0] = {};
ASSERT_DEATH(this->mockReceiveData(data, sizeof(data)), "Deframer.cpp");
ASSERT_from_deframedOut_SIZE(0);
}

// ----------------------------------------------------------------------
// Test Helpers
// ----------------------------------------------------------------------

void DeframerTester::mockReceiveData(U8* data, FwSizeType size) {
Fw::Buffer nullContext;
Fw::Buffer buffer;
buffer.setData(data);
buffer.setSize(size);
this->invoke_to_framedIn(0, buffer, nullContext);
}

} // namespace Svc
77 changes: 77 additions & 0 deletions Svc/Deframer/test/ut/DeframerTester.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// ======================================================================
// \title DeframerTester.hpp
// \author chammard
// \brief hpp file for Deframer component test harness implementation class
// ======================================================================

#ifndef Svc_DeframerTester_HPP
#define Svc_DeframerTester_HPP

#include "Svc/Deframer/Deframer.hpp"
#include "Svc/Deframer/DeframerGTestBase.hpp"

namespace Svc {

class DeframerTester : public DeframerGTestBase {
public:
// ----------------------------------------------------------------------
// Constants
// ----------------------------------------------------------------------

// Maximum size of histories storing events, telemetry, and port outputs
static const FwSizeType MAX_HISTORY_SIZE = 10;

// Instance ID supplied to the component instance under test
static const FwEnumStoreType TEST_INSTANCE_ID = 0;

public:
// ----------------------------------------------------------------------
// Construction and destruction
// ----------------------------------------------------------------------

//! Construct object DeframerTester
DeframerTester();

//! Destroy object DeframerTester
~DeframerTester();

public:
// ----------------------------------------------------------------------
// Tests
// ----------------------------------------------------------------------

//! Test receiving a nominal frame
void testNominalFrame();

//! Test receiving a truncated frame
void testTruncatedFrame();

//! Test receiving a zero size frame
void testZeroSizeFrame();

private:
// ----------------------------------------------------------------------
// Helper functions
// ----------------------------------------------------------------------

//! Connect ports
void connectPorts();

//! Initialize components
void initComponents();

void mockReceiveData(U8* data, FwSizeType size);


private:
// ----------------------------------------------------------------------
// Member variables
// ----------------------------------------------------------------------

//! The component under test
Deframer component;
};

} // namespace Svc

#endif
19 changes: 13 additions & 6 deletions Svc/FrameAccumulator/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@ set(SOURCE_FILES
"${CMAKE_CURRENT_LIST_DIR}/FrameAccumulator.cpp"
)

# Uncomment and add any modules that this component depends on, else
# they might not be available when cmake tries to build this component.
register_fprime_module()

# set(MOD_DEPS
# Add your dependencies here
# )
#### UTS ####
set(UT_SOURCE_FILES
"${CMAKE_CURRENT_LIST_DIR}/FrameAccumulator.fpp"
"${CMAKE_CURRENT_LIST_DIR}/test/ut/FrameAccumulatorTester.cpp"
"${CMAKE_CURRENT_LIST_DIR}/test/ut/FrameAccumulatorTestMain.cpp"
)
set(UT_MOD_DEPS
Utils/Types
STest
)
set(UT_AUTO_HELPERS ON)

register_fprime_module()
register_fprime_ut()
3 changes: 2 additions & 1 deletion Svc/FrameAccumulator/FrameAccumulator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define Svc_FrameAccumulator_HPP

#include "Fw/Types/MemAllocator.hpp"
#include "Utils/Types/CircularBuffer.hpp"
#include "Svc/FrameAccumulator/FrameAccumulatorComponentAc.hpp"
#include "Svc/FrameAccumulator/FrameDetector.hpp"

Expand Down Expand Up @@ -46,7 +47,7 @@ class FrameAccumulator : public FrameAccumulatorComponentBase {
void dataIn_handler(FwIndexType portNum, //!< The port number
Fw::Buffer& recvBuffer,
const Drv::RecvStatus& recvStatus) override;
private:
PRIVATE:
//! \brief process raw buffer
//! \return raw data buffer
void processBuffer(Fw::Buffer& buffer);
Expand Down
2 changes: 1 addition & 1 deletion Svc/FrameAccumulator/FrameDetector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace Svc {
//!
//! \param data: circular buffer with read-only access
//! \param size_out: set as output to caller indicating size when appropriate
//! \return status of the detection to be pared with size_out
//! \return status of the detection to be paired with size_out
virtual Status detect(const Types::CircularBuffer& data, FwSizeType& size_out) const = 0;
};

Expand Down
29 changes: 29 additions & 0 deletions Svc/FrameAccumulator/test/ut/FrameAccumulatorTestMain.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// ======================================================================
// \title FrameAccumulatorTestMain.cpp
// \author chammard
// \brief cpp file for FrameAccumulator component test main function
// ======================================================================

#include "FrameAccumulatorTester.hpp"
#include "STest/Random/Random.hpp"

TEST(FrameAccumulator, TestFrameDetected) {
Svc::FrameAccumulatorTester tester;
tester.testFrameDetected();
}

TEST(FrameAccumulator, TestMoreDataNeeded) {
Svc::FrameAccumulatorTester tester;
tester.testMoreDataNeeded();
}

TEST(FrameAccumulator, TestNoFrameDetected) {
Svc::FrameAccumulatorTester tester;
tester.testNoFrameDetected();
}

int main(int argc, char** argv) {
STest::Random::seed();
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
101 changes: 101 additions & 0 deletions Svc/FrameAccumulator/test/ut/FrameAccumulatorTester.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// ======================================================================
// \title FrameAccumulatorTester.cpp
// \author chammard
// \brief cpp file for FrameAccumulator component test harness implementation class
// ======================================================================

#include "FrameAccumulatorTester.hpp"
#include "STest/Random/Random.hpp"



namespace Svc {

// ----------------------------------------------------------------------
// Construction and destruction
// ----------------------------------------------------------------------

FrameAccumulatorTester ::FrameAccumulatorTester()
: FrameAccumulatorGTestBase("FrameAccumulatorTester", FrameAccumulatorTester::MAX_HISTORY_SIZE),
component("FrameAccumulator") {
this->initComponents();
this->connectPorts();
component.configure(this->mockDetector, 1, this->mallocator, 2048);
}

FrameAccumulatorTester ::~FrameAccumulatorTester() {}

// ----------------------------------------------------------------------
// Tests
// ----------------------------------------------------------------------

void FrameAccumulatorTester ::testFrameDetected() {
// Prepare a random size buffer
U32 buffer_size = STest::Random::lowerUpper(1, 1024);
U8 data[buffer_size];
Fw::Buffer buffer(data, buffer_size);
// Set the mock detector to report success of size_out = buffer_size
this->mockDetector.next_status = FrameDetector::Status::FRAME_DETECTED;
this->mockDetector.next_size_out = buffer_size;
// Receive the buffer on dataIn
this->invoke_to_dataIn(0, buffer, Drv::RecvStatus::RECV_OK);
// Checks
ASSERT_from_dataDeallocate_SIZE(1); // input buffer was deallocated
ASSERT_from_frameOut_SIZE(1); // frame was sent
ASSERT_EQ(this->component.m_inRing.get_allocated_size(), 0); // no data left in ring buffer
ASSERT_EQ(this->fromPortHistory_frameOut->at(0).data.getSize(), buffer_size); // all data was sent out
}

void FrameAccumulatorTester ::testMoreDataNeeded() {
// Prepare a random size buffer
U32 buffer_size = STest::Random::lowerUpper(1, 1024);
U8 data[buffer_size];
Fw::Buffer buffer(data, buffer_size);
// Set the mock detector to report more data needed
this->mockDetector.next_status = FrameDetector::Status::MORE_DATA_NEEDED;
this->mockDetector.next_size_out = buffer_size + 1;
// Receive the buffer on dataIn
this->invoke_to_dataIn(0, buffer, Drv::RecvStatus::RECV_OK);
// Checks
ASSERT_from_dataDeallocate_SIZE(1); // input buffer was deallocated
ASSERT_from_frameOut_SIZE(0); // frame was not sent (waiting on more data)
ASSERT_EQ(this->component.m_inRing.get_allocated_size(), buffer_size); // data left in ring buffer
}

void FrameAccumulatorTester ::testNoFrameDetected() {
// Prepare a random size buffer
U32 buffer_size = STest::Random::lowerUpper(1, 1024);
U8 data[buffer_size];
Fw::Buffer buffer(data, buffer_size);
// Set the mock detector
this->mockDetector.next_status = FrameDetector::Status::NO_FRAME_DETECTED;
this->mockDetector.next_size_out = 0;
// Receive the buffer on dataIn
this->invoke_to_dataIn(0, buffer, Drv::RecvStatus::RECV_OK);
// Checks
ASSERT_from_dataDeallocate_SIZE(1); // input buffer was deallocated
ASSERT_from_frameOut_SIZE(0); // No frame was sent out
ASSERT_EQ(this->component.m_inRing.get_allocated_size(), 0); // all data was consumed and discarded
}

// ----------------------------------------------------------------------
// Helpers
// ----------------------------------------------------------------------


// ----------------------------------------------------------------------
// Port handler overrides
// ----------------------------------------------------------------------
Fw::Buffer FrameAccumulatorTester ::from_frameAllocate_handler(
FwIndexType portNum,
U32 size
)
{
this->pushFromPortEntry_frameAllocate(size);
this->m_buffer.setData(this->m_buffer_slot);
this->m_buffer.setSize(size);
::memset(this->m_buffer.getData(), 0, size);
return this->m_buffer;
}

} // namespace Svc
Loading

0 comments on commit 44f4292

Please sign in to comment.