Files
bacnet_stack/test/bacnet/basic/sys/ringbuf/src/main.c
T

374 lines
12 KiB
C

/*
* Copyright (c) 2020 Legrand North America, LLC.
*
* SPDX-License-Identifier: MIT
*/
/* @file
* @brief test BACnet integer encode/decode APIs
*/
#include <limits.h>
#include <zephyr/ztest.h>
#include <bacnet/basic/sys/ringbuf.h>
/**
* @addtogroup bacnet_tests
* @{
*/
/**
* @brief Test
*/
/**
* Unit Test for the ring buffer
*
* @param test_buffer - pointer to RING_BUFFER structure
* @param data_element - one data element
* @param element_size - size of one data element
* @param element_count - number of data elements in the store
*/
static void testRingAroundBuffer(
RING_BUFFER *test_buffer,
uint8_t *data_element,
unsigned element_size,
unsigned element_count)
{
volatile uint8_t *test_data;
unsigned index;
unsigned data_index;
unsigned count;
uint8_t value;
bool status;
zassert_true(Ringbuf_Empty(test_buffer), NULL);
/* test the ring around the buffer */
for (index = 0; index < element_count; index++) {
for (count = 1; count < 4; count++) {
value = (index * count) % 255;
for (data_index = 0; data_index < element_size; data_index++) {
data_element[data_index] = value;
}
status = Ringbuf_Put(test_buffer, data_element);
zassert_true(status, NULL);
zassert_equal(Ringbuf_Count(test_buffer), count, NULL);
}
for (count = 1; count < 4; count++) {
value = (index * count) % 255;
test_data = Ringbuf_Peek(test_buffer);
zassert_not_null(test_data, NULL);
if (test_data) {
for (data_index = 0; data_index < element_size; data_index++) {
zassert_equal(test_data[data_index], value, NULL);
}
}
status = Ringbuf_Pop(test_buffer, NULL);
zassert_true(status, NULL);
}
}
zassert_true(Ringbuf_Empty(test_buffer), NULL);
}
/**
* Unit Test for the ring buffer
*
* @param data_store - buffer to store elements
* @param data_element - one data element
* @param element_size - size of one data element
* @param element_count - number of data elements in the store
*/
static void testRingBuf(
uint8_t *data_store,
uint8_t *data_element,
unsigned element_size,
unsigned element_count)
{
RING_BUFFER test_buffer;
volatile uint8_t *test_data;
unsigned index;
unsigned data_index;
bool status;
status =
Ringbuf_Init(&test_buffer, data_store, element_size, element_count);
if (!status) {
return;
}
zassert_true(Ringbuf_Empty(&test_buffer), NULL);
zassert_equal(Ringbuf_Depth(&test_buffer), 0, NULL);
for (data_index = 0; data_index < element_size; data_index++) {
data_element[data_index] = data_index;
}
status = Ringbuf_Put(&test_buffer, data_element);
zassert_true(status, NULL);
zassert_false(Ringbuf_Empty(&test_buffer), NULL);
zassert_equal(Ringbuf_Depth(&test_buffer), 1, NULL);
test_data = Ringbuf_Peek(&test_buffer);
for (data_index = 0; data_index < element_size; data_index++) {
zassert_equal(test_data[data_index], data_element[data_index], NULL);
}
zassert_false(Ringbuf_Empty(&test_buffer), NULL);
(void)Ringbuf_Pop(&test_buffer, NULL);
zassert_true(Ringbuf_Empty(&test_buffer), NULL);
zassert_equal(Ringbuf_Depth(&test_buffer), 1, NULL);
/* fill to max */
for (index = 0; index < element_count; index++) {
for (data_index = 0; data_index < element_size; data_index++) {
data_element[data_index] = index;
}
status = Ringbuf_Put(&test_buffer, data_element);
zassert_true(status, NULL);
zassert_false(Ringbuf_Empty(&test_buffer), NULL);
zassert_equal(Ringbuf_Depth(&test_buffer), (index + 1), NULL);
}
zassert_equal(Ringbuf_Depth(&test_buffer), element_count, NULL);
/* verify actions on full buffer */
for (index = 0; index < element_count; index++) {
for (data_index = 0; data_index < element_size; data_index++) {
data_element[data_index] = index;
}
status = Ringbuf_Put(&test_buffer, data_element);
zassert_false(status, NULL);
zassert_false(Ringbuf_Empty(&test_buffer), NULL);
zassert_equal(Ringbuf_Depth(&test_buffer), element_count, NULL);
}
/* check buffer full */
for (index = 0; index < element_count; index++) {
test_data = Ringbuf_Peek(&test_buffer);
zassert_not_null(test_data, NULL);
if (test_data) {
for (data_index = 0; data_index < element_size; data_index++) {
zassert_equal(test_data[data_index], index, NULL);
}
}
(void)Ringbuf_Pop(&test_buffer, NULL);
}
zassert_true(Ringbuf_Empty(&test_buffer), NULL);
zassert_equal(Ringbuf_Depth(&test_buffer), element_count, NULL);
Ringbuf_Depth_Reset(&test_buffer);
zassert_equal(Ringbuf_Depth(&test_buffer), 0, NULL);
testRingAroundBuffer(
&test_buffer, data_element, element_size, element_count);
/* adjust the internal index of Ringbuf to test unsigned wrapping */
test_buffer.head = UINT_MAX - 1;
test_buffer.tail = UINT_MAX - 1;
testRingAroundBuffer(
&test_buffer, data_element, element_size, element_count);
}
/**
* Unit Test for the ring buffer with 16 data elements
*/
#if defined(CONFIG_ZTEST_NEW_API)
ZTEST(ringbuf_tests, testRingBufSizeSmall)
#else
static void testRingBufSizeSmall(void)
#endif
{
uint8_t data_element[5];
uint8_t data_store[sizeof(data_element) * NEXT_POWER_OF_2(16)];
testRingBuf(
data_store, data_element, sizeof(data_element),
sizeof(data_store) / sizeof(data_element));
}
/**
* Unit Test for the ring buffer with 32 data elements
*/
#if defined(CONFIG_ZTEST_NEW_API)
ZTEST(ringbuf_tests, testRingBufSizeLarge)
#else
static void testRingBufSizeLarge(void)
#endif
{
uint8_t data_element[16];
uint8_t data_store[sizeof(data_element) * NEXT_POWER_OF_2(99)];
testRingBuf(
data_store, data_element, sizeof(data_element),
sizeof(data_store) / sizeof(data_element));
}
/**
* Unit Test for the ring buffer with 32 data elements
*/
#if defined(CONFIG_ZTEST_NEW_API)
ZTEST(ringbuf_tests, testRingBufSizeInvalid)
#else
static void testRingBufSizeInvalid(void)
#endif
{
RING_BUFFER test_buffer;
uint8_t data_element[16];
uint8_t data_store[sizeof(data_element) * 99];
zassert_false(
Ringbuf_Init(
&test_buffer, data_store, sizeof(data_element),
sizeof(data_store) / sizeof(data_element)),
NULL);
}
#if defined(CONFIG_ZTEST_NEW_API)
ZTEST(ringbuf_tests, testRingBufPowerOfTwo)
#else
static void testRingBufPowerOfTwo(void)
#endif
{
zassert_equal(NEXT_POWER_OF_2(3), 4, NULL);
zassert_equal(NEXT_POWER_OF_2(100), 128, NULL);
zassert_equal(NEXT_POWER_OF_2(127), 128, NULL);
zassert_equal(NEXT_POWER_OF_2(128), 128, NULL);
zassert_equal(NEXT_POWER_OF_2(129), 256, NULL);
zassert_equal(NEXT_POWER_OF_2(300), 512, NULL);
zassert_equal(NEXT_POWER_OF_2(500), 512, NULL);
}
/**
* Unit Test for the ring buffer peek/pop next element
*
* @param data_store - buffer to store elements
* @param data_element - one data element
* @param element_size - size of one data element
* @param element_count - number of data elements in the store
*/
static bool testRingBufNextElement(
uint8_t *data_store,
uint8_t *data_element,
unsigned element_size,
unsigned element_count)
{
RING_BUFFER test_buffer;
volatile uint8_t *test_data;
unsigned index;
unsigned data_index;
bool status;
status =
Ringbuf_Init(&test_buffer, data_store, element_size, element_count);
if (!status) {
return false;
}
zassert_true(Ringbuf_Empty(&test_buffer), NULL);
zassert_equal(Ringbuf_Depth(&test_buffer), 0, NULL);
for (data_index = 0; data_index < element_size; data_index++) {
data_element[data_index] = data_index;
}
status = Ringbuf_Put(&test_buffer, data_element);
zassert_true(status, NULL);
zassert_false(Ringbuf_Empty(&test_buffer), NULL);
zassert_equal(Ringbuf_Depth(&test_buffer), 1, NULL);
test_data = Ringbuf_Peek(&test_buffer);
for (data_index = 0; data_index < element_size; data_index++) {
zassert_equal(test_data[data_index], data_element[data_index], NULL);
}
zassert_false(Ringbuf_Empty(&test_buffer), NULL);
(void)Ringbuf_Pop(&test_buffer, NULL);
zassert_true(Ringbuf_Empty(&test_buffer), NULL);
zassert_equal(Ringbuf_Depth(&test_buffer), 1, NULL);
/* fill to max */
for (index = 0; index < element_count; index++) {
for (data_index = 0; data_index < element_size; data_index++) {
data_element[data_index] = index;
}
status = Ringbuf_Put(&test_buffer, data_element);
zassert_true(status, NULL);
zassert_false(Ringbuf_Empty(&test_buffer), NULL);
zassert_equal(Ringbuf_Depth(&test_buffer), (index + 1), NULL);
}
zassert_equal(Ringbuf_Depth(&test_buffer), element_count, NULL);
zassert_equal(Ringbuf_Count(&test_buffer), element_count, NULL);
/* Walk through ring buffer */
test_data = Ringbuf_Peek(&test_buffer);
zassert_not_null(test_data, NULL);
for (index = 1; index < element_count; index++) {
test_data = Ringbuf_Peek_Next(&test_buffer, (uint8_t *)test_data);
zassert_not_null(test_data, NULL);
if (test_data) {
for (data_index = 0; data_index < element_size; data_index++) {
zassert_equal(test_data[data_index], index, NULL);
}
}
}
zassert_equal(Ringbuf_Count(&test_buffer), element_count, NULL);
/* Try to walk off end of buffer - should return NULL */
test_data = Ringbuf_Peek_Next(&test_buffer, (uint8_t *)test_data);
zassert_is_null(test_data, NULL);
/* Walk through ring buffer and pop alternate elements */
test_data = Ringbuf_Peek(&test_buffer);
zassert_not_null(test_data, NULL);
for (index = 1; index < element_count / 2; index++) {
test_data = Ringbuf_Peek_Next(&test_buffer, (uint8_t *)test_data);
zassert_not_null(test_data, NULL);
(void)Ringbuf_Pop_Element(&test_buffer, (uint8_t *)test_data, NULL);
test_data = Ringbuf_Peek_Next(&test_buffer, (uint8_t *)test_data);
}
zassert_equal(Ringbuf_Count(&test_buffer), element_count / 2 + 1, NULL);
/* Walk through ring buffer and check data */
test_data = Ringbuf_Peek(&test_buffer);
zassert_not_null(test_data, NULL);
for (index = 0; index < element_count / 2; index++) {
if (test_data) {
for (data_index = 0; data_index < element_size; data_index++) {
zassert_equal(test_data[data_index], index * 2, NULL);
}
}
test_data = Ringbuf_Peek_Next(&test_buffer, (uint8_t *)test_data);
zassert_not_null(test_data, NULL);
}
zassert_equal(Ringbuf_Count(&test_buffer), element_count / 2 + 1, NULL);
return true;
}
/**
* Unit Test for the ring buffer with 16 data elements
*/
#if defined(CONFIG_ZTEST_NEW_API)
ZTEST(ringbuf_tests, testRingBufNextElementSizeSmall)
#else
static void testRingBufNextElementSizeSmall(void)
#endif
{
bool status;
uint8_t data_element[5];
uint8_t data_store[sizeof(data_element) * NEXT_POWER_OF_2(16)];
status = testRingBufNextElement(
data_store, data_element, sizeof(data_element),
sizeof(data_store) / sizeof(data_element));
zassert_true(status, NULL);
}
/**
* @}
*/
#if defined(CONFIG_ZTEST_NEW_API)
ZTEST_SUITE(ringbuf_tests, NULL, NULL, NULL, NULL, NULL);
#else
void test_main(void)
{
ztest_test_suite(
ringbuf_tests, ztest_unit_test(testRingBufPowerOfTwo),
ztest_unit_test(testRingBufSizeSmall),
ztest_unit_test(testRingBufSizeLarge),
ztest_unit_test(testRingBufSizeInvalid),
ztest_unit_test(testRingBufNextElementSizeSmall));
ztest_run_test_suite(ringbuf_tests);
}
#endif