Files
bacnet_stack/test/bacnet/basic/sys/ringbuf/src/main.c
T
Greg Shue 19869dccdb Feature/zephyr ztest (#118)
* Leverage (older) embedded unit tests into external unit tests build upon copy of Zephyr's ztest library and CMake.

* Expand top-level CMake build to run external unit tests.

* Expand Zephyr module extension to run external unit tests via west or sanitycheck.

Co-authored-by: Gregory Shue <gregory.shue@legrand.us>
2020-09-16 07:33:34 -05:00

353 lines
11 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 <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 bool 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 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);
/* 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);
return true;
}
/**
* Unit Test for the ring buffer with 16 data elements
*/
static void testRingBufSizeSmall(void)
{
bool status;
uint8_t data_element[5];
uint8_t data_store[sizeof(data_element) * NEXT_POWER_OF_2(16)];
status = testRingBuf(data_store, data_element, sizeof(data_element),
sizeof(data_store) / sizeof(data_element));
zassert_true(status, NULL);
}
/**
* Unit Test for the ring buffer with 32 data elements
*/
static void testRingBufSizeLarge(void)
{
bool status;
uint8_t data_element[16];
uint8_t data_store[sizeof(data_element) * NEXT_POWER_OF_2(99)];
status = testRingBuf(data_store, data_element, sizeof(data_element),
sizeof(data_store) / sizeof(data_element));
zassert_true(status, NULL);
}
/**
* Unit Test for the ring buffer with 32 data elements
*/
static void testRingBufSizeInvalid(void)
{
bool status;
uint8_t data_element[16];
uint8_t data_store[sizeof(data_element) * 99];
status = testRingBuf(data_store, data_element, sizeof(data_element),
sizeof(data_store) / sizeof(data_element));
zassert_false(status, NULL);
}
static void testRingBufPowerOfTwo(void)
{
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
*/
static void testRingBufNextElementSizeSmall(void)
{
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);
}
/**
* @}
*/
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);
}