mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 01:18:36 +02:00
Replace concurrentqueue with ringbuffer
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#include "icsneo/communication/packet/a2bpacket.h"
|
||||
#include "icsneo/communication/message/a2bmessage.h"
|
||||
#include "icsneo/communication/packetizer.h"
|
||||
#include "icsneo/communication/ringbuffer.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <vector>
|
||||
@@ -26,6 +27,7 @@ protected:
|
||||
std::optional<Encoder> packetEncoder;
|
||||
std::optional<Packetizer> packetizer;
|
||||
std::optional<Decoder> packetDecoder;
|
||||
RingBuffer ringBuffer = RingBuffer(128);
|
||||
|
||||
std::vector<uint8_t> testBytes =
|
||||
{0xaa, 0x0c, 0x15, 0x00, 0x0b, 0x02, 0x00, 0x00,
|
||||
@@ -131,7 +133,9 @@ TEST_F(A2BEncoderDecoderTest, PacketDecoderTest)
|
||||
icsneo::PCMType::L16
|
||||
) == static_cast<icsneo::PCMSample>((0x04 << 8) | (0x08)));
|
||||
|
||||
EXPECT_TRUE(packetizer->input(recvBytes));
|
||||
ringBuffer.clear();
|
||||
ringBuffer.write(recvBytes);
|
||||
EXPECT_TRUE(packetizer->input(ringBuffer));
|
||||
auto packets = packetizer->output();
|
||||
if(packets.empty()) {
|
||||
EXPECT_TRUE(false);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "icsneo/communication/packet/i2cpacket.h"
|
||||
#include "icsneo/communication/message/i2cmessage.h"
|
||||
#include "icsneo/communication/packetizer.h"
|
||||
#include "icsneo/communication/ringbuffer.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <vector>
|
||||
@@ -30,6 +31,8 @@ protected:
|
||||
std::optional<Encoder> packetEncoder;
|
||||
std::optional<Packetizer> packetizer;
|
||||
std::optional<Decoder> packetDecoder;
|
||||
RingBuffer ringBuffer = RingBuffer(128);
|
||||
|
||||
//Read request to the device
|
||||
//Control length 1, control bytes 0x12 (I2C register to read from)
|
||||
//data length 1: blank bytes padded in that the device will fill in the reply
|
||||
@@ -73,7 +76,9 @@ TEST_F(I2CEncoderDecoderTest, PacketDecoderTest) {
|
||||
message->isTXMsg = true;
|
||||
message->timestamp = static_cast<uint64_t>(0xB0FCC1FBE62997);
|
||||
|
||||
EXPECT_TRUE(packetizer->input(recvBytes));
|
||||
ringBuffer.clear();
|
||||
ringBuffer.write(recvBytes);
|
||||
EXPECT_TRUE(packetizer->input(ringBuffer));
|
||||
auto packets = packetizer->output();
|
||||
if(packets.empty()) { EXPECT_TRUE(false); }
|
||||
EXPECT_TRUE(packetDecoder->decode(decodeMsg, packets.back()));
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "icsneo/communication/packet/linpacket.h"
|
||||
#include "icsneo/communication/message/linmessage.h"
|
||||
#include "icsneo/communication/packetizer.h"
|
||||
#include "icsneo/communication/ringbuffer.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <vector>
|
||||
@@ -31,6 +32,7 @@ protected:
|
||||
std::optional<Encoder> packetEncoder;
|
||||
std::optional<Packetizer> packetizer;
|
||||
std::optional<Decoder> packetDecoder;
|
||||
RingBuffer ringBuffer = RingBuffer(128);
|
||||
//Responder load data before response LIN 2
|
||||
// ID 0x22 pID 0xE2 length 8
|
||||
std::vector<uint8_t> testRespData =
|
||||
@@ -165,7 +167,9 @@ TEST_F(LINEncoderDecoderTest, PacketDecoderTest) {
|
||||
msg2->data = {0xaa, 0xbb, 0xcc};
|
||||
msg2->checksum = 0xcc;
|
||||
|
||||
EXPECT_TRUE(packetizer->input(recvBytes));
|
||||
ringBuffer.clear();
|
||||
ringBuffer.write(recvBytes);
|
||||
EXPECT_TRUE(packetizer->input(ringBuffer));
|
||||
auto packets = packetizer->output();
|
||||
if(packets.size() != 2) { EXPECT_TRUE(false); }
|
||||
//LIN2 frame from device
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "icsneo/communication/packet/livedatapacket.h"
|
||||
#include "icsneo/communication/message/livedatamessage.h"
|
||||
#include "icsneo/communication/packetizer.h"
|
||||
#include "icsneo/communication/ringbuffer.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <vector>
|
||||
@@ -42,6 +43,7 @@ protected:
|
||||
std::optional<Encoder> packetEncoder;
|
||||
std::optional<Packetizer> packetizer;
|
||||
std::optional<Decoder> packetDecoder;
|
||||
RingBuffer ringBuffer = RingBuffer(128);
|
||||
|
||||
const std::vector<uint8_t> testBytesSub =
|
||||
{
|
||||
@@ -157,7 +159,9 @@ TEST_F(LiveDataEncoderDecoderTest, EncodeClearCommandTest) {
|
||||
|
||||
TEST_F(LiveDataEncoderDecoderTest, DecoderStatusTest) {
|
||||
std::shared_ptr<Message> result;
|
||||
if (packetizer->input(testBytesStatus)) {
|
||||
ringBuffer.clear();
|
||||
ringBuffer.write(testBytesStatus);
|
||||
if (packetizer->input(ringBuffer)) {
|
||||
for (const auto& packet : packetizer->output()) {
|
||||
if (!packetDecoder->decode(result, packet))
|
||||
continue;
|
||||
@@ -173,7 +177,9 @@ TEST_F(LiveDataEncoderDecoderTest, DecoderStatusTest) {
|
||||
|
||||
TEST_F(LiveDataEncoderDecoderTest, DecoderResponseTest) {
|
||||
std::shared_ptr<Message> result;
|
||||
if (packetizer->input(testBytesResponse)) {
|
||||
ringBuffer.clear();
|
||||
ringBuffer.write(testBytesResponse);
|
||||
if (packetizer->input(ringBuffer)) {
|
||||
for (const auto& packet : packetizer->output()) {
|
||||
if (!packetDecoder->decode(result, packet))
|
||||
continue;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "icsneo/communication/packet/mdiopacket.h"
|
||||
#include "icsneo/communication/message/mdiomessage.h"
|
||||
#include "icsneo/communication/packetizer.h"
|
||||
#include "icsneo/communication/ringbuffer.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <vector>
|
||||
@@ -30,6 +31,7 @@ protected:
|
||||
std::optional<Encoder> packetEncoder;
|
||||
std::optional<Packetizer> packetizer;
|
||||
std::optional<Decoder> packetDecoder;
|
||||
RingBuffer ringBuffer = RingBuffer(128);
|
||||
|
||||
std::vector<uint8_t> testBytesClause22 =
|
||||
{0xAA, 0x0C, 0x11, 0x00, 0x21, 0x02, 0xAB, 0xCD,
|
||||
@@ -156,7 +158,9 @@ TEST_F(MDIOEncoderDecoderTest, PacketDecoderClause22Test) {
|
||||
message->isTXMsg = true;
|
||||
message->timestamp = static_cast<uint64_t>(0xB0FCC1FBE62997);
|
||||
|
||||
EXPECT_TRUE(packetizer->input(recvBytesClause22));
|
||||
ringBuffer.clear();
|
||||
ringBuffer.write(recvBytesClause22);
|
||||
EXPECT_TRUE(packetizer->input(ringBuffer));
|
||||
auto packets = packetizer->output();
|
||||
EXPECT_FALSE(packets.empty());
|
||||
EXPECT_TRUE(packetDecoder->decode(decodeMsg, packets.back()));
|
||||
@@ -202,7 +206,9 @@ TEST_F(MDIOEncoderDecoderTest, PacketDecoderClause45Test) {
|
||||
message->txInvalidOpcode = true;
|
||||
message->timestamp = static_cast<uint64_t>(0xB0FCC1FBE62997);
|
||||
|
||||
EXPECT_TRUE(packetizer->input(recvBytesClause45));
|
||||
ringBuffer.clear();
|
||||
ringBuffer.write(recvBytesClause45);
|
||||
EXPECT_TRUE(packetizer->input(ringBuffer));
|
||||
auto packets = packetizer->output();
|
||||
EXPECT_FALSE(packets.empty());
|
||||
EXPECT_TRUE(packetDecoder->decode(decodeMsg, packets.back()));
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
#include "icsneo/communication/ringbuffer.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
class RingBufferTest : public ::testing::Test {
|
||||
protected:
|
||||
static constexpr const size_t bufferSize = 32u;
|
||||
static constexpr const size_t testDataSize = 32u;
|
||||
RingBuffer ringBuffer = RingBuffer(bufferSize);
|
||||
void SetUp() override {
|
||||
ringBuffer.clear();
|
||||
}
|
||||
|
||||
const std::vector<uint8_t> testBytes = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31
|
||||
};
|
||||
};
|
||||
|
||||
TEST_F(RingBufferTest, ConstructorTest) {
|
||||
// Standard case, integral power of 2
|
||||
ASSERT_EQ(RingBuffer(16).capacity(), 16u);
|
||||
// Edge cases
|
||||
// SIZE_MAX - commented out because this will throw on all architectures due to the allocation that happens here.
|
||||
//ASSERT_EQ(RingBuffer(SIZE_MAX).capacity(), RingBuffer::MaxSize);
|
||||
// Zero
|
||||
ASSERT_EQ(RingBuffer(0).capacity(), 1u);
|
||||
// arbitrary number that is not a power of 2
|
||||
ASSERT_EQ(RingBuffer(60).capacity(), 64u);
|
||||
}
|
||||
|
||||
TEST_F(RingBufferTest, InitAndCapacityTest) {
|
||||
constexpr auto size = 8u;
|
||||
RingBuffer rb(size);
|
||||
ASSERT_EQ(rb.size(), 0u);
|
||||
ASSERT_EQ(rb.capacity(), size);
|
||||
}
|
||||
|
||||
TEST_F(RingBufferTest, WriteAndClearTest) {
|
||||
ASSERT_TRUE(ringBuffer.write(testBytes));
|
||||
ASSERT_EQ(ringBuffer.size(), testBytes.size());
|
||||
ringBuffer.clear();
|
||||
ASSERT_EQ(ringBuffer.size(), 0u);
|
||||
}
|
||||
|
||||
TEST_F(RingBufferTest, SimpleWriteReadTest) {
|
||||
std::vector<uint8_t> readBack(testDataSize);
|
||||
ASSERT_TRUE(ringBuffer.write(testBytes));
|
||||
ASSERT_EQ(ringBuffer.size(), testDataSize);
|
||||
ASSERT_TRUE(ringBuffer.read(readBack.data(), 0, testDataSize));
|
||||
ASSERT_EQ(readBack, testBytes);
|
||||
}
|
||||
|
||||
TEST_F(RingBufferTest, OverlappedReadWriteTest) {
|
||||
std::vector<uint8_t> readBack(testDataSize);
|
||||
std::vector<uint8_t> ignoredData(bufferSize - 3);
|
||||
ASSERT_TRUE(ringBuffer.write(ignoredData));
|
||||
ringBuffer.pop(ignoredData.size());
|
||||
ASSERT_EQ(ringBuffer.size(), 0u);
|
||||
ASSERT_TRUE(ringBuffer.write(testBytes));
|
||||
ASSERT_TRUE(ringBuffer.read(readBack.data(), 0, testDataSize));
|
||||
ASSERT_EQ(readBack, testBytes);
|
||||
}
|
||||
|
||||
TEST_F(RingBufferTest, WritePastReadCursorTest) {
|
||||
std::vector<uint8_t> readBack(ringBuffer.capacity());
|
||||
// Fill
|
||||
ASSERT_TRUE(ringBuffer.write(testBytes));
|
||||
// Read partial
|
||||
auto readSize = ringBuffer.size() - 4;
|
||||
ASSERT_TRUE(ringBuffer.read(readBack.data(), 0, readSize));
|
||||
// Now writeCursor (masked) is 0, readCursor (masked) is capacity() - 4, writing past the read cursor should fail.
|
||||
ASSERT_FALSE(ringBuffer.write(testBytes.data(), readSize + 1));
|
||||
|
||||
}
|
||||
|
||||
TEST_F(RingBufferTest, WriteWhenFullTest) {
|
||||
std::vector<uint8_t> fillData(ringBuffer.capacity());
|
||||
ASSERT_TRUE(ringBuffer.write(fillData));
|
||||
ASSERT_FALSE(ringBuffer.write(fillData.data(), 1));
|
||||
}
|
||||
|
||||
TEST_F(RingBufferTest, ReadPastEndTest) {
|
||||
uint8_t dummy = 0;
|
||||
// Single byte when empty
|
||||
ASSERT_FALSE(ringBuffer.read(&dummy, 0, 1));
|
||||
// Put in a byte
|
||||
ASSERT_TRUE(ringBuffer.write(&dummy, 1));
|
||||
// Single byte from offset when filled only to offset
|
||||
ASSERT_FALSE(ringBuffer.read(&dummy, ringBuffer.size(), 1));
|
||||
// Single byte from offset past size
|
||||
ASSERT_FALSE(ringBuffer.read(&dummy, ringBuffer.size()+1, 1));
|
||||
}
|
||||
Reference in New Issue
Block a user