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>
This commit is contained in:
Greg Shue
2020-09-16 05:33:34 -07:00
committed by GitHub
parent a7b2e94cb7
commit 19869dccdb
399 changed files with 21885 additions and 5 deletions
+33
View File
@@ -0,0 +1,33 @@
# SPDX-License-Identifier: MIT
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
get_filename_component(basename ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(test_${basename}
VERSION 1.0.0
LANGUAGES C)
string(REGEX REPLACE "/bacnet/[a-zA-Z_/-]*$" "" TST_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(ZTST_DIR "${TST_DIR}/ztest/src")
string(REGEX REPLACE "/test$" "/src" SRC_DIR ${TST_DIR})
add_compile_definitions(
BIG_ENDIAN=0
CONFIG_ZTEST=1
)
include_directories(
${SRC_DIR}
${TST_DIR}/ztest/include
)
add_executable(${PROJECT_NAME}
# File(s) under test
${SRC_DIR}/bacnet/basic/sys/fifo.c
# Support files and stubs (pathname alphabetical)
# Test and test library files
./src/main.c
${ZTST_DIR}/ztest_mock.c
${ZTST_DIR}/ztest.c
)
+147
View File
@@ -0,0 +1,147 @@
/*
* 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/fifo.h>
/**
* @addtogroup bacnet_tests
* @{
*/
/**
* @brief Unit Test for the FIFO buffer
*/
static void testFIFOBuffer(void)
{
/* FIFO data structure */
FIFO_BUFFER test_buffer = { 0 };
/* FIFO data store. Note: size must be a power of two! */
volatile uint8_t data_store[64] = { 0 };
uint8_t add_data[40] = { "RoseSteveLouPatRachelJessicaDaniAmyHerb" };
uint8_t test_add_data[40] = { 0 };
uint8_t test_data = 0;
unsigned index = 0;
unsigned count = 0;
bool status = 0;
FIFO_Init(&test_buffer, data_store, sizeof(data_store));
zassert_true(FIFO_Empty(&test_buffer), NULL);
/* load the buffer */
for (test_data = 0; test_data < sizeof(data_store); test_data++) {
zassert_false(FIFO_Full(&test_buffer), NULL);
zassert_true(FIFO_Available(&test_buffer, 1), NULL);
status = FIFO_Put(&test_buffer, test_data);
zassert_true(status, NULL);
zassert_false(FIFO_Empty(&test_buffer), NULL);
}
/* not able to put any more */
zassert_true(FIFO_Full(&test_buffer), NULL);
zassert_false(FIFO_Available(&test_buffer, 1), NULL);
status = FIFO_Put(&test_buffer, 42);
zassert_false(status, NULL);
/* unload the buffer */
for (index = 0; index < sizeof(data_store); index++) {
zassert_false(FIFO_Empty(&test_buffer), NULL);
test_data = FIFO_Peek(&test_buffer);
zassert_equal(test_data, index, NULL);
test_data = FIFO_Get(&test_buffer);
zassert_equal(test_data, index, NULL);
zassert_true(FIFO_Available(&test_buffer, 1), NULL);
zassert_false(FIFO_Full(&test_buffer), NULL);
}
zassert_true(FIFO_Empty(&test_buffer), NULL);
test_data = FIFO_Get(&test_buffer);
zassert_equal(test_data, 0, NULL);
test_data = FIFO_Peek(&test_buffer);
zassert_equal(test_data, 0, NULL);
zassert_true(FIFO_Empty(&test_buffer), NULL);
/* test the ring around the buffer */
for (index = 0; index < sizeof(data_store); index++) {
zassert_true(FIFO_Empty(&test_buffer), NULL);
zassert_true(FIFO_Available(&test_buffer, 4), NULL);
for (count = 1; count < 4; count++) {
test_data = count;
status = FIFO_Put(&test_buffer, test_data);
zassert_true(status, NULL);
zassert_false(FIFO_Empty(&test_buffer), NULL);
}
for (count = 1; count < 4; count++) {
zassert_false(FIFO_Empty(&test_buffer), NULL);
test_data = FIFO_Peek(&test_buffer);
zassert_equal(test_data, count, NULL);
test_data = FIFO_Get(&test_buffer);
zassert_equal(test_data, count, NULL);
}
}
zassert_true(FIFO_Empty(&test_buffer), NULL);
/* test Add */
zassert_true(FIFO_Available(&test_buffer, sizeof(add_data)), NULL);
status = FIFO_Add(&test_buffer, add_data, sizeof(add_data));
zassert_true(status, NULL);
count = FIFO_Count(&test_buffer);
zassert_equal(count, sizeof(add_data), NULL);
zassert_false(FIFO_Empty(&test_buffer), NULL);
for (index = 0; index < sizeof(add_data); index++) {
/* unload the buffer */
zassert_false(FIFO_Empty(&test_buffer), NULL);
test_data = FIFO_Peek(&test_buffer);
zassert_equal(test_data, add_data[index], NULL);
test_data = FIFO_Get(&test_buffer);
zassert_equal(test_data, add_data[index], NULL);
}
zassert_true(FIFO_Empty(&test_buffer), NULL);
/* test Pull */
zassert_true(FIFO_Available(&test_buffer, sizeof(add_data)), NULL);
status = FIFO_Add(&test_buffer, add_data, sizeof(add_data));
zassert_true(status, NULL);
count = FIFO_Count(&test_buffer);
zassert_equal(count, sizeof(add_data), NULL);
zassert_false(FIFO_Empty(&test_buffer), NULL);
count = FIFO_Pull(&test_buffer, &test_add_data[0], sizeof(test_add_data));
zassert_true(FIFO_Empty(&test_buffer), NULL);
zassert_equal(count, sizeof(test_add_data), NULL);
for (index = 0; index < sizeof(add_data); index++) {
zassert_equal(test_add_data[index], add_data[index], NULL);
}
zassert_true(FIFO_Available(&test_buffer, sizeof(add_data)), NULL);
status = FIFO_Add(&test_buffer, test_add_data, sizeof(add_data));
zassert_true(status, NULL);
zassert_false(FIFO_Empty(&test_buffer), NULL);
for (index = 0; index < sizeof(add_data); index++) {
count = FIFO_Pull(&test_buffer, &test_add_data[0], 1);
zassert_equal(count, 1, NULL);
zassert_equal(test_add_data[0], add_data[index], NULL);
}
zassert_true(FIFO_Empty(&test_buffer), NULL);
/* test flush */
status = FIFO_Add(&test_buffer, test_add_data, sizeof(test_add_data));
zassert_true(status, NULL);
zassert_false(FIFO_Empty(&test_buffer), NULL);
FIFO_Flush(&test_buffer);
zassert_true(FIFO_Empty(&test_buffer), NULL);
return;
}
/**
* @}
*/
void test_main(void)
{
ztest_test_suite(fifo_tests,
ztest_unit_test(testFIFOBuffer)
);
ztest_run_test_suite(fifo_tests);
}
@@ -0,0 +1,33 @@
# SPDX-License-Identifier: MIT
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
get_filename_component(basename ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(test_${basename}
VERSION 1.0.0
LANGUAGES C)
string(REGEX REPLACE "/bacnet/[a-zA-Z_/-]*$" "" TST_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(ZTST_DIR "${TST_DIR}/ztest/src")
string(REGEX REPLACE "/test$" "/src" SRC_DIR ${TST_DIR})
add_compile_definitions(
BIG_ENDIAN=0
CONFIG_ZTEST=1
)
include_directories(
${SRC_DIR}
${TST_DIR}/ztest/include
)
add_executable(${PROJECT_NAME}
# File(s) under test
${SRC_DIR}/bacnet/basic/sys/filename.c
# Support files and stubs (pathname alphabetical)
# Test and test library files
./src/main.c
${ZTST_DIR}/ztest_mock.c
${ZTST_DIR}/ztest.c
)
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2020 Legrand North America, LLC.
*
* SPDX-License-Identifier: MIT
*/
/* @file
* @brief test BACnet integer encode/decode APIs
*/
#include <ztest.h>
#include <bacnet/basic/sys/filename.h>
/**
* @addtogroup bacnet_tests
* @{
*/
/**
* @brief Test
*/
static void testFilename(void)
{
char *data1 = "c:\\Joshua\\run";
char *data2 = "/home/Anna/run";
char *data3 = "c:\\Program Files\\Christopher\\run.exe";
char *data4 = "//Mary/data/run";
char *data5 = "bin\\run";
char *filename = NULL;
filename = filename_remove_path(data1);
zassert_equal(strcmp("run", filename), 0, NULL);
filename = filename_remove_path(data2);
zassert_equal(strcmp("run", filename), 0, NULL);
filename = filename_remove_path(data3);
zassert_equal(strcmp("run.exe", filename), 0, NULL);
filename = filename_remove_path(data4);
zassert_equal(strcmp("run", filename), 0, NULL);
filename = filename_remove_path(data5);
zassert_equal(strcmp("run", filename), 0, NULL);
return;
}
/**
* @}
*/
void test_main(void)
{
ztest_test_suite(filename_tests,
ztest_unit_test(testFilename)
);
ztest_run_test_suite(filename_tests);
}
+33
View File
@@ -0,0 +1,33 @@
# SPDX-License-Identifier: MIT
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
get_filename_component(basename ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(test_${basename}
VERSION 1.0.0
LANGUAGES C)
string(REGEX REPLACE "/bacnet/[a-zA-Z_/-]*$" "" TST_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(ZTST_DIR "${TST_DIR}/ztest/src")
string(REGEX REPLACE "/test$" "/src" SRC_DIR ${TST_DIR})
add_compile_definitions(
BIG_ENDIAN=0
CONFIG_ZTEST=1
)
include_directories(
${SRC_DIR}
${TST_DIR}/ztest/include
)
add_executable(${PROJECT_NAME}
# File(s) under test
${SRC_DIR}/bacnet/basic/sys/key.c
# Support files and stubs (pathname alphabetical)
# Test and test library files
./src/main.c
${ZTST_DIR}/ztest_mock.c
${ZTST_DIR}/ztest.c
)
+63
View File
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2020 Legrand North America, LLC.
*
* SPDX-License-Identifier: MIT
*/
/* @file
* @brief test BACnet integer encode/decode APIs
*/
#include <ztest.h>
#include <bacnet/basic/sys/key.h>
/**
* @addtogroup bacnet_tests
* @{
*/
/**
* @brief Test the encode and decode macros
*/
static void testKeySample(void)
{
int type, id;
int type_list[] = { 0, 1, KEY_TYPE_MAX / 2, KEY_TYPE_MAX - 1, -1 };
int id_list[] = { 0, 1, KEY_ID_MAX / 2, KEY_ID_MAX - 1, -1 };
int type_index = 0;
int id_index = 0;
int decoded_type;
int decoded_id;
KEY key;
while (type_list[type_index] != -1) {
while (id_list[id_index] != -1) {
type = type_list[type_index];
id = id_list[id_index];
key = KEY_ENCODE(type, id);
decoded_type = KEY_DECODE_TYPE(key);
decoded_id = KEY_DECODE_ID(key);
zassert_equal(decoded_type, type, NULL);
zassert_equal(decoded_id, id, NULL);
id_index++;
}
id_index = 0;
type_index++;
}
return;
}
/**
* @}
*/
void test_main(void)
{
ztest_test_suite(key_tests,
ztest_unit_test(testKeySample)
);
ztest_run_test_suite(key_tests);
}
@@ -0,0 +1,33 @@
# SPDX-License-Identifier: MIT
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
get_filename_component(basename ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(test_${basename}
VERSION 1.0.0
LANGUAGES C)
string(REGEX REPLACE "/bacnet/[a-zA-Z_/-]*$" "" TST_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(ZTST_DIR "${TST_DIR}/ztest/src")
string(REGEX REPLACE "/test$" "/src" SRC_DIR ${TST_DIR})
add_compile_definitions(
BIG_ENDIAN=0
CONFIG_ZTEST=1
)
include_directories(
${SRC_DIR}
${TST_DIR}/ztest/include
)
add_executable(${PROJECT_NAME}
# File(s) under test
${SRC_DIR}/bacnet/basic/sys/keylist.c
# Support files and stubs (pathname alphabetical)
# Test and test library files
./src/main.c
${ZTST_DIR}/ztest_mock.c
${ZTST_DIR}/ztest.c
)
+303
View File
@@ -0,0 +1,303 @@
/*
* Copyright (c) 2020 Legrand North America, LLC.
*
* SPDX-License-Identifier: MIT
*/
/* @file
* @brief test BACnet integer encode/decode APIs
*/
#include <ztest.h>
#include <bacnet/basic/sys/keylist.h>
/**
* @addtogroup bacnet_tests
* @{
*/
/**
* @brief Test the FIFO
*/
static void testKeyListFIFO(void)
{
OS_Keylist list;
KEY key;
int index;
char *data1 = "Joshua";
char *data2 = "Anna";
char *data3 = "Mary";
char *data;
list = Keylist_Create();
zassert_not_null(list, NULL);
key = 0;
index = Keylist_Data_Add(list, key, data1);
zassert_equal(index, 0, NULL);
index = Keylist_Data_Add(list, key, data2);
zassert_equal(index, 0, NULL);
index = Keylist_Data_Add(list, key, data3);
zassert_equal(index, 0, NULL);
zassert_equal(Keylist_Count(list), 3, NULL);
data = Keylist_Data_Pop(list);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data1), 0, NULL);
data = Keylist_Data_Pop(list);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data2), 0, NULL);
data = Keylist_Data_Pop(list);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data3), 0, NULL);
data = Keylist_Data_Pop(list);
zassert_equal(data, NULL, NULL);
data = Keylist_Data_Pop(list);
zassert_equal(data, NULL, NULL);
Keylist_Delete(list);
return;
}
/* test the FILO */
static void testKeyListFILO(void)
{
OS_Keylist list;
KEY key;
int index;
char *data1 = "Joshua";
char *data2 = "Anna";
char *data3 = "Mary";
char *data;
list = Keylist_Create();
zassert_not_null(list, NULL);
key = 0;
index = Keylist_Data_Add(list, key, data1);
zassert_equal(index, 0, NULL);
index = Keylist_Data_Add(list, key, data2);
zassert_equal(index, 0, NULL);
index = Keylist_Data_Add(list, key, data3);
zassert_equal(index, 0, NULL);
zassert_equal(Keylist_Count(list), 3, NULL);
data = Keylist_Data_Delete_By_Index(list, 0);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data3), 0, NULL);
data = Keylist_Data_Delete_By_Index(list, 0);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data2), 0, NULL);
data = Keylist_Data_Delete_By_Index(list, 0);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data1), 0, NULL);
data = Keylist_Data_Delete_By_Index(list, 0);
zassert_equal(data, NULL, NULL);
data = Keylist_Data_Delete_By_Index(list, 0);
zassert_equal(data, NULL, NULL);
Keylist_Delete(list);
return;
}
static void testKeyListDataKey(void)
{
OS_Keylist list;
KEY key;
KEY test_key;
int index;
char *data1 = "Joshua";
char *data2 = "Anna";
char *data3 = "Mary";
char *data;
list = Keylist_Create();
zassert_not_null(list, NULL);
key = 1;
index = Keylist_Data_Add(list, key, data1);
zassert_equal(index, 0, NULL);
test_key = Keylist_Key(list, index);
zassert_equal(test_key, key, NULL);
key = 2;
index = Keylist_Data_Add(list, key, data2);
zassert_equal(index, 1, NULL);
test_key = Keylist_Key(list, index);
zassert_equal(test_key, key, NULL);
key = 3;
index = Keylist_Data_Add(list, key, data3);
zassert_equal(index, 2, NULL);
test_key = Keylist_Key(list, index);
zassert_equal(test_key, key, NULL);
zassert_equal(Keylist_Count(list), 3, NULL);
/* look at the data */
key = 2;
data = Keylist_Data(list, key);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data2), 0, NULL);
key = 1;
data = Keylist_Data(list, key);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data1), 0, NULL);
key = 3;
data = Keylist_Data(list, key);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data3), 0, NULL);
/* work the data */
key = 2;
data = Keylist_Data_Delete(list, key);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data2), 0, NULL);
data = Keylist_Data_Delete(list, key);
zassert_equal(data, NULL, NULL);
zassert_equal(Keylist_Count(list), 2, NULL);
key = 1;
data = Keylist_Data(list, key);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data1), 0, NULL);
key = 3;
data = Keylist_Data(list, key);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data3), 0, NULL);
/* cleanup */
do {
data = Keylist_Data_Pop(list);
} while (data);
Keylist_Delete(list);
return;
}
static void testKeyListDataIndex(void)
{
OS_Keylist list;
KEY key;
int index;
char *data1 = "Joshua";
char *data2 = "Anna";
char *data3 = "Mary";
char *data;
list = Keylist_Create();
zassert_not_null(list, NULL);
key = 0;
index = Keylist_Data_Add(list, key, data1);
zassert_equal(index, 0, NULL);
index = Keylist_Data_Add(list, key, data2);
zassert_equal(index, 0, NULL);
index = Keylist_Data_Add(list, key, data3);
zassert_equal(index, 0, NULL);
zassert_equal(Keylist_Count(list), 3, NULL);
/* look at the data */
data = Keylist_Data_Index(list, 0);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data3), 0, NULL);
data = Keylist_Data_Index(list, 1);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data2), 0, NULL);
data = Keylist_Data_Index(list, 2);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data1), 0, NULL);
/* work the data */
data = Keylist_Data_Delete_By_Index(list, 1);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data2), 0, NULL);
zassert_equal(Keylist_Count(list), 2, NULL);
data = Keylist_Data_Index(list, 0);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data3), 0, NULL);
data = Keylist_Data_Index(list, 1);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data1), 0, NULL);
data = Keylist_Data_Delete_By_Index(list, 1);
zassert_not_null(data, NULL);
zassert_equal(strcmp(data, data1), 0, NULL);
data = Keylist_Data_Delete_By_Index(list, 1);
zassert_equal(data, NULL, NULL);
/* cleanup */
do {
data = Keylist_Data_Pop(list);
} while (data);
Keylist_Delete(list);
return;
}
/* test access of a lot of entries */
static void testKeyListLarge(void)
{
int data1 = 42;
int *data;
OS_Keylist list;
KEY key;
int index;
const unsigned num_keys = 1024 * 16;
list = Keylist_Create();
if (!list)
return;
for (key = 0; key < num_keys; key++) {
index = Keylist_Data_Add(list, key, &data1);
}
for (key = 0; key < num_keys; key++) {
data = Keylist_Data(list, key);
zassert_equal(*data, data1, NULL);
}
for (index = 0; index < num_keys; index++) {
data = Keylist_Data_Index(list, index);
zassert_equal(*data, data1, NULL);
}
Keylist_Delete(list);
return;
}
/**
* @}
*/
void test_main(void)
{
ztest_test_suite(keylist_tests,
ztest_unit_test(testKeyListFIFO),
ztest_unit_test(testKeyListFILO),
ztest_unit_test(testKeyListDataKey),
ztest_unit_test(testKeyListDataIndex),
ztest_unit_test(testKeyListLarge)
);
ztest_run_test_suite(keylist_tests);
}
@@ -0,0 +1,33 @@
# SPDX-License-Identifier: MIT
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
get_filename_component(basename ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(test_${basename}
VERSION 1.0.0
LANGUAGES C)
string(REGEX REPLACE "/bacnet/[a-zA-Z_/-]*$" "" TST_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(ZTST_DIR "${TST_DIR}/ztest/src")
string(REGEX REPLACE "/test$" "/src" SRC_DIR ${TST_DIR})
add_compile_definitions(
BIG_ENDIAN=0
CONFIG_ZTEST=1
)
include_directories(
${SRC_DIR}
${TST_DIR}/ztest/include
)
add_executable(${PROJECT_NAME}
# File(s) under test
${SRC_DIR}/bacnet/basic/sys/ringbuf.c
# Support files and stubs (pathname alphabetical)
# Test and test library files
./src/main.c
${ZTST_DIR}/ztest_mock.c
${ZTST_DIR}/ztest.c
)
+352
View File
@@ -0,0 +1,352 @@
/*
* 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);
}
+33
View File
@@ -0,0 +1,33 @@
# SPDX-License-Identifier: MIT
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
get_filename_component(basename ${CMAKE_CURRENT_SOURCE_DIR} NAME)
project(test_${basename}
VERSION 1.0.0
LANGUAGES C)
string(REGEX REPLACE "/bacnet/[a-zA-Z_/-]*$" "" TST_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(ZTST_DIR "${TST_DIR}/ztest/src")
string(REGEX REPLACE "/test$" "/src" SRC_DIR ${TST_DIR})
add_compile_definitions(
BIG_ENDIAN=0
CONFIG_ZTEST=1
)
include_directories(
${SRC_DIR}
${TST_DIR}/ztest/include
)
add_executable(${PROJECT_NAME}
# File(s) under test
${SRC_DIR}/bacnet/basic/sys/sbuf.c
# Support files and stubs (pathname alphabetical)
# Test and test library files
./src/main.c
${ZTST_DIR}/ztest_mock.c
${ZTST_DIR}/ztest.c
)
+85
View File
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2020 Legrand North America, LLC.
*
* SPDX-License-Identifier: MIT
*/
/* @file
* @brief test BACnet integer encode/decode APIs
*/
#include <ztest.h>
#include <bacnet/basic/sys/sbuf.h>
/**
* @addtogroup bacnet_tests
* @{
*/
/**
* @brief Test
*/
static void testStaticBuffer(void)
{
STATIC_BUFFER sbuffer;
char *data1 = "Joshua";
char *data2 = "Anna";
char *data3 = "Christopher";
char *data4 = "Mary";
char data_buffer[480] = "";
char test_data_buffer[480] = "";
char *data;
unsigned count;
sbuf_init(&sbuffer, NULL, 0);
zassert_true(sbuf_empty(&sbuffer), NULL);
zassert_equal(sbuf_data(&sbuffer), NULL, NULL);
zassert_equal(sbuf_size(&sbuffer), 0, NULL);
zassert_equal(sbuf_count(&sbuffer), 0, NULL);
zassert_false(sbuf_append(&sbuffer, data1, strlen(data1)), NULL);
sbuf_init(&sbuffer, data_buffer, sizeof(data_buffer));
zassert_true(sbuf_empty(&sbuffer), NULL);
zassert_equal(sbuf_data(&sbuffer), data_buffer, NULL);
zassert_equal(sbuf_size(&sbuffer), sizeof(data_buffer), NULL);
zassert_equal(sbuf_count(&sbuffer), 0, NULL);
zassert_true(sbuf_append(&sbuffer, data1, strlen(data1)), NULL);
zassert_true(sbuf_append(&sbuffer, data2, strlen(data2)), NULL);
zassert_true(sbuf_append(&sbuffer, data3, strlen(data3)), NULL);
zassert_true(sbuf_append(&sbuffer, data4, strlen(data4)), NULL);
strcat(test_data_buffer, data1);
strcat(test_data_buffer, data2);
strcat(test_data_buffer, data3);
strcat(test_data_buffer, data4);
zassert_equal(sbuf_count(&sbuffer), strlen(test_data_buffer), NULL);
data = sbuf_data(&sbuffer);
count = sbuf_count(&sbuffer);
zassert_equal(memcmp(data, test_data_buffer, count), 0, NULL);
zassert_equal(count, strlen(test_data_buffer), NULL);
zassert_true(sbuf_truncate(&sbuffer, 0), NULL);
zassert_equal(sbuf_count(&sbuffer), 0, NULL);
zassert_equal(sbuf_size(&sbuffer), sizeof(data_buffer), NULL);
zassert_true(sbuf_append(&sbuffer, data4, strlen(data4)), NULL);
data = sbuf_data(&sbuffer);
count = sbuf_count(&sbuffer);
zassert_equal(memcmp(data, data4, count), 0, NULL);
zassert_equal(count, strlen(data4), NULL);
return;
}
/**
* @}
*/
void test_main(void)
{
ztest_test_suite(sbuf_tests,
ztest_unit_test(testStaticBuffer)
);
ztest_run_test_suite(sbuf_tests);
}