Files
openairinterface5g/radio/zmq/tests/test_ring_buffer.cpp
Bartosz Podrygajlo 46c120651f ZMQ radio
This commit introduces ZMQ-based radio library. Each pair of RX/TX antennas is
represented by a ZMQ REQ/REP socket pair which streams continuous IQ samples
from radio start until stop.

Usage:
Simplest configuration is to connect OAI NR UE to OAI GNB with the same number
of antennas - by inverting the RX and TX channels in ZMQ radio configuration the
gNBs TX is mapped to UEs RX antennas and vice versa.
2026-04-22 22:34:02 +02:00

222 lines
5.2 KiB
C++

/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#include <gtest/gtest.h>
#include "ring_buffer.h"
TEST(CircularBuffer, simplePushPop)
{
ring_buffer cb(10);
cf_t data[10];
for (int i = 0; i < 10; i++) {
data[i] = { (float)i, (float)(i + 1)};
}
ASSERT_EQ(cb.push_samples(data, 10), 0);
cf_t read_data[10];
ASSERT_EQ(cb.pop_samples(read_data, 10), 10);
for (int i = 0; i < 10; i++) {
ASSERT_EQ(read_data[i].r, data[i].r);
ASSERT_EQ(read_data[i].i, data[i].i);
}
ASSERT_EQ(cb.size(), 0);
ASSERT_EQ(cb.pop_samples(read_data, 10), 0);
}
TEST(CircularBuffer, overflow)
{
ring_buffer cb(10);
cf_t data[15];
for (int i = 0; i < 15; i++) {
data[i] = {(float)i, (float)(i + 1)};
}
ASSERT_EQ(cb.push_samples(data, 15), 5);
cf_t read_data[10];
ASSERT_EQ(cb.pop_samples(read_data, 10), 10);
// The first 5 samples are lost due to overflow
for (int i = 0; i < 10; i++) {
ASSERT_EQ(read_data[i].r, i + 5);
ASSERT_EQ(read_data[i].i, i + 6);
}
}
TEST(CircularBuffer, partialPop)
{
ring_buffer cb(10);
cf_t data[10];
for (int i = 0; i < 10; i++) {
data[i] = {(float)i, (float)(i + 1)};
}
ASSERT_EQ(cb.push_samples(data, 10), 0);
cf_t read_data[5];
ASSERT_EQ(cb.pop_samples(read_data, 5), 5);
for (int i = 0; i < 5; i++) {
ASSERT_EQ(read_data[i].r, i);
ASSERT_EQ(read_data[i].i, i + 1);
}
ASSERT_EQ(cb.size(), 5);
ASSERT_EQ(cb.pop_samples(read_data, 5), 5);
for (int i = 0; i < 5; i++) {
ASSERT_EQ(read_data[i].r, i + 5);
ASSERT_EQ(read_data[i].i, i + 6);
}
}
TEST(CircularBuffer, popMore)
{
ring_buffer cb(10);
cf_t data[10];
for (int i = 0; i < 10; i++) {
data[i] = {(float)i, (float)(i + 1)};
}
cb.push_samples(data, 10);
cf_t read_data[15];
ASSERT_EQ(cb.pop_samples(read_data, 15), 10);
for (int i = 0; i < 10; i++) {
ASSERT_EQ(read_data[i].r, i);
ASSERT_EQ(read_data[i].i, i + 1);
}
}
TEST(CircularBuffer, newOverflow)
{
ring_buffer cb(10);
cf_t data1[8];
for (int i = 0; i < 8; i++) {
data1[i] = {(float)i, (float)(i + 1)};
}
ASSERT_EQ(cb.push_samples(data1, 8), 0);
cf_t data2[4];
for (int i = 0; i < 4; i++) {
data2[i] = {(float)(i + 8), (float)(i + 9)};
}
ASSERT_EQ(cb.push_samples(data2, 4), 2);
cf_t read_data[10];
ASSERT_EQ(cb.pop_samples(read_data, 10), 10);
// The first 2 samples are lost due to overflow
for (int i = 0; i < 8; i++) {
ASSERT_EQ(read_data[i].r, i + 2);
ASSERT_EQ(read_data[i].i, i + 3);
}
ASSERT_EQ(read_data[8].r, 10);
ASSERT_EQ(read_data[8].i, 11);
ASSERT_EQ(read_data[9].r, 11);
ASSERT_EQ(read_data[9].i, 12);
}
TEST(overflow_buffer, simplePushPop)
{
overflow_buffer pb(10);
cf_t data[10];
for (int i = 0; i < 10; i++) {
data[i] = {(float)i, (float)(i + 1)};
}
pb.push_samples(data, 10);
ASSERT_EQ(pb.size(), 10);
cf_t read_data[10];
ASSERT_EQ(pb.pop_samples(read_data, 10), 10);
for (int i = 0; i < 10; i++) {
ASSERT_EQ(read_data[i].r, i);
ASSERT_EQ(read_data[i].i, i + 1);
}
}
TEST(overflow_buffer, zeros_to_send)
{
overflow_buffer pb(10);
pb.push_zeros(10);
cf_t data[5];
for (int i = 0; i < 5; i++) {
data[i] = {(float)i, (float)(i + 1)};
}
pb.push_samples(data, 5);
ASSERT_EQ(pb.size(), 15);
cf_t read_data[10];
ASSERT_EQ(pb.pop_samples(read_data, 10), 10);
for (int i = 0; i < 10; i++) {
ASSERT_EQ(read_data[i].r, 0);
ASSERT_EQ(read_data[i].i, 0);
}
ASSERT_EQ(pb.pop_samples(read_data, 10), 5);
for (int i = 0; i < 5; i++) {
ASSERT_EQ(read_data[i].r, i);
ASSERT_EQ(read_data[i].i, i + 1);
}
}
TEST(overflow_buffer, no_zeros_to_send)
{
overflow_buffer pb(10);
cf_t data[10];
for (int i = 0; i < 10; i++) {
data[i] = {(float)i, (float)(i + 1)};
}
pb.push_samples(data, 10);
ASSERT_EQ(pb.size(), 10);
cf_t read_data[10];
ASSERT_EQ(pb.pop_samples(read_data, 10), 10);
for (int i = 0; i < 10; i++) {
ASSERT_EQ(read_data[i].r, i);
ASSERT_EQ(read_data[i].i, i + 1);
}
}
TEST(overflow_buffer, overflow)
{
overflow_buffer pb(10);
cf_t data[15];
for (int i = 0; i < 15; i++) {
data[i] = {(float)i, (float)(i + 1)};
}
pb.push_samples(data, 15);
ASSERT_EQ(pb.size(), 15);
cf_t read_data[15];
ASSERT_EQ(pb.pop_samples(read_data, 15), 15);
// The first 5 samples were lost due to overflow.
int i = 0;
for (; i < 5; i++) {
ASSERT_EQ(read_data[i].r, 0);
ASSERT_EQ(read_data[i].i, 0);
}
for (; i < 15; i++) {
ASSERT_EQ(read_data[i].r, i);
ASSERT_EQ(read_data[i].i, i + 1);
}
ASSERT_EQ(pb.size(), 0);
}
TEST(overflow_buffer, push_zeros)
{
overflow_buffer pb(10);
pb.push_zeros(5);
ASSERT_EQ(pb.size(), 5);
cf_t data[5];
for (int i = 0; i < 5; i++) {
data[i] = {(float)i, (float)(i + 1)};
}
pb.push_samples(data, 5);
ASSERT_EQ(pb.size(), 10);
cf_t read_data[10];
ASSERT_EQ(pb.pop_samples(read_data, 10), 10);
for (int i = 0; i < 10; i++) {
if (i < 5) {
ASSERT_EQ(read_data[i].r, 0);
ASSERT_EQ(read_data[i].i, 0);
} else {
ASSERT_EQ(read_data[i].r, data[i - 5].r);
ASSERT_EQ(read_data[i].i, data[i - 5].i);
}
}
ASSERT_EQ(pb.size(), 0);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}