9cf437728e
This commit adds tests for the newly added list len APIs to the corresponding test cases. It is noted that the test functions calculate equivalent values manually using several different internal list functions. This has been left unmodified to ensure that the manual ways using each of the various for_each functions results in the same value as the new list_len() functions. Signed-off-by: J M <montytyper@msn.com>
426 lines
10 KiB
C
426 lines
10 KiB
C
/*
|
|
* Copyright (c) 2019 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/ztest.h>
|
|
#include <zephyr/sys/sflist.h>
|
|
|
|
static sys_sflist_t test_list;
|
|
static sys_sflist_t append_list;
|
|
|
|
struct container_node {
|
|
sys_sfnode_t node;
|
|
int unused;
|
|
};
|
|
|
|
static struct container_node test_node_1;
|
|
static struct container_node test_node_2;
|
|
static struct container_node test_node_3;
|
|
static struct container_node test_node_4;
|
|
|
|
static inline bool verify_emptyness(sys_sflist_t *list)
|
|
{
|
|
sys_sfnode_t *node;
|
|
sys_sfnode_t *s_node;
|
|
struct container_node *cnode;
|
|
struct container_node *s_cnode;
|
|
int count;
|
|
|
|
if (!sys_sflist_is_empty(list)) {
|
|
return false;
|
|
}
|
|
|
|
if (sys_sflist_peek_head(list)) {
|
|
return false;
|
|
}
|
|
|
|
if (sys_sflist_peek_tail(list)) {
|
|
return false;
|
|
}
|
|
|
|
if (sys_sflist_len(list) != 0) {
|
|
return false;
|
|
}
|
|
|
|
count = 0;
|
|
SYS_SFLIST_FOR_EACH_NODE(list, node) {
|
|
count++;
|
|
}
|
|
|
|
if (count) {
|
|
return false;
|
|
}
|
|
|
|
SYS_SFLIST_FOR_EACH_NODE_SAFE(list, node, s_node) {
|
|
count++;
|
|
}
|
|
|
|
if (count) {
|
|
return false;
|
|
}
|
|
|
|
count = 0;
|
|
SYS_SFLIST_FOR_EACH_CONTAINER(list, cnode, node) {
|
|
count++;
|
|
}
|
|
|
|
if (count) {
|
|
return false;
|
|
}
|
|
|
|
count = 0;
|
|
SYS_SFLIST_FOR_EACH_CONTAINER_SAFE(list, cnode, s_cnode, node) {
|
|
count++;
|
|
}
|
|
|
|
if (count) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static inline bool verify_content_amount(sys_sflist_t *list, int amount)
|
|
{
|
|
sys_sfnode_t *node;
|
|
sys_sfnode_t *s_node;
|
|
struct container_node *cnode;
|
|
struct container_node *s_cnode;
|
|
int count;
|
|
|
|
if (sys_sflist_is_empty(list)) {
|
|
return false;
|
|
}
|
|
|
|
if (!sys_sflist_peek_head(list)) {
|
|
return false;
|
|
}
|
|
|
|
if (!sys_sflist_peek_tail(list)) {
|
|
return false;
|
|
}
|
|
|
|
if (sys_sflist_len(list) != amount) {
|
|
return false;
|
|
}
|
|
|
|
count = 0;
|
|
SYS_SFLIST_FOR_EACH_NODE(list, node) {
|
|
count++;
|
|
}
|
|
|
|
if (count != amount) {
|
|
return false;
|
|
}
|
|
|
|
count = 0;
|
|
SYS_SFLIST_FOR_EACH_NODE_SAFE(list, node, s_node) {
|
|
count++;
|
|
}
|
|
|
|
if (count != amount) {
|
|
return false;
|
|
}
|
|
|
|
count = 0;
|
|
SYS_SFLIST_FOR_EACH_CONTAINER(list, cnode, node) {
|
|
count++;
|
|
}
|
|
|
|
if (count != amount) {
|
|
return false;
|
|
}
|
|
|
|
count = 0;
|
|
SYS_SFLIST_FOR_EACH_CONTAINER_SAFE(list, cnode, s_cnode, node) {
|
|
count++;
|
|
}
|
|
|
|
if (count != amount) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static inline bool verify_tail_head(sys_sflist_t *list,
|
|
sys_sfnode_t *head,
|
|
sys_sfnode_t *tail,
|
|
bool same)
|
|
{
|
|
if (sys_sflist_peek_head(list) != head) {
|
|
return false;
|
|
}
|
|
|
|
if (sys_sflist_peek_tail(list) != tail) {
|
|
return false;
|
|
}
|
|
|
|
if (same) {
|
|
if (sys_sflist_peek_head(list) != sys_sflist_peek_tail(list)) {
|
|
return false;
|
|
}
|
|
} else {
|
|
if (sys_sflist_peek_head(list) == sys_sflist_peek_tail(list)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
/**
|
|
* @addtogroup kernel_common_tests
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @brief Test singly linked list functionalities
|
|
*
|
|
* @details Test list initialization, append item to the list,
|
|
* find and remove item, prepend, append, remove list
|
|
*
|
|
* @see sys_sflist_init(), sys_sflist_append(),
|
|
* sys_sflist_find_and_remove(), sys_sflist_prepend(),
|
|
* sys_sflist_remove(), sys_sflist_get(), sys_sflist_get_not_empty(),
|
|
* sys_sflist_append_list(), sys_sflist_merge_list()
|
|
*/
|
|
ZTEST(dlist_api, test_sflist)
|
|
{
|
|
sys_sflist_init(&test_list);
|
|
|
|
zassert_true((verify_emptyness(&test_list)),
|
|
"test_list should be empty");
|
|
|
|
/* Appending node 1 */
|
|
sys_sflist_append(&test_list, &test_node_1.node);
|
|
zassert_true((verify_content_amount(&test_list, 1)),
|
|
"test_list has wrong content");
|
|
|
|
zassert_true((verify_tail_head(&test_list, &test_node_1.node,
|
|
&test_node_1.node, true)),
|
|
"test_list head/tail are wrong");
|
|
|
|
/* Finding and removing node 1 */
|
|
sys_sflist_find_and_remove(&test_list, &test_node_1.node);
|
|
zassert_true((verify_emptyness(&test_list)),
|
|
"test_list should be empty");
|
|
|
|
/* Prepending node 1 */
|
|
sys_sflist_prepend(&test_list, &test_node_1.node);
|
|
zassert_true((verify_content_amount(&test_list, 1)),
|
|
"test_list has wrong content");
|
|
|
|
zassert_true((verify_tail_head(&test_list, &test_node_1.node,
|
|
&test_node_1.node, true)),
|
|
"test_list head/tail are wrong");
|
|
|
|
/* Removing node 1 */
|
|
sys_sflist_remove(&test_list, NULL, &test_node_1.node);
|
|
zassert_true((verify_emptyness(&test_list)),
|
|
"test_list should be empty");
|
|
|
|
/* Appending node 1 */
|
|
sys_sflist_append(&test_list, &test_node_1.node);
|
|
/* Prepending node 2 */
|
|
sys_sflist_prepend(&test_list, &test_node_2.node);
|
|
|
|
zassert_true((verify_content_amount(&test_list, 2)),
|
|
"test_list has wrong content");
|
|
|
|
zassert_true((verify_tail_head(&test_list, &test_node_2.node,
|
|
&test_node_1.node, false)),
|
|
"test_list head/tail are wrong");
|
|
|
|
/* Appending node 3 */
|
|
sys_sflist_append(&test_list, &test_node_3.node);
|
|
|
|
zassert_true((verify_content_amount(&test_list, 3)),
|
|
"test_list has wrong content");
|
|
|
|
zassert_true((verify_tail_head(&test_list, &test_node_2.node,
|
|
&test_node_3.node, false)),
|
|
"test_list head/tail are wrong");
|
|
|
|
zassert_true((sys_sflist_peek_next(&test_node_2.node) ==
|
|
&test_node_1.node),
|
|
"test_list node links are wrong");
|
|
|
|
/* Inserting node 4 after node 2, peek with nocheck variant */
|
|
sys_sflist_insert(&test_list, &test_node_2.node, &test_node_4.node);
|
|
|
|
zassert_true((verify_tail_head(&test_list, &test_node_2.node,
|
|
&test_node_3.node, false)),
|
|
"test_list head/tail are wrong");
|
|
|
|
zassert_true((sys_sflist_peek_next_no_check(&test_node_2.node) ==
|
|
&test_node_4.node),
|
|
"test_list node links are wrong");
|
|
|
|
/* Finding and removing node 1 */
|
|
sys_sflist_find_and_remove(&test_list, &test_node_1.node);
|
|
zassert_true((verify_content_amount(&test_list, 3)),
|
|
"test_list has wrong content");
|
|
|
|
zassert_true((verify_tail_head(&test_list, &test_node_2.node,
|
|
&test_node_3.node, false)),
|
|
"test_list head/tail are wrong");
|
|
|
|
/* Removing node 3 */
|
|
sys_sflist_remove(&test_list, &test_node_4.node, &test_node_3.node);
|
|
zassert_true((verify_content_amount(&test_list, 2)),
|
|
"test_list has wrong content");
|
|
|
|
zassert_true((verify_tail_head(&test_list, &test_node_2.node,
|
|
&test_node_4.node, false)),
|
|
"test_list head/tail are wrong");
|
|
|
|
/* Removing node 4 */
|
|
sys_sflist_remove(&test_list, &test_node_2.node, &test_node_4.node);
|
|
zassert_true((verify_content_amount(&test_list, 1)),
|
|
"test_list has wrong content");
|
|
|
|
zassert_true((verify_tail_head(&test_list, &test_node_2.node,
|
|
&test_node_2.node, true)),
|
|
"test_list head/tail are wrong");
|
|
|
|
/* Removing node 2 */
|
|
sys_sflist_remove(&test_list, NULL, &test_node_2.node);
|
|
zassert_true((verify_emptyness(&test_list)),
|
|
"test_list should be empty");
|
|
|
|
/* test iterator from a node */
|
|
struct data_node {
|
|
sys_sfnode_t node;
|
|
int data;
|
|
} data_node[6] = {
|
|
{ .data = 0 },
|
|
{ .data = 1 },
|
|
{ .data = 2 },
|
|
{ .data = 3 },
|
|
{ .data = 4 },
|
|
{ .data = 5 },
|
|
};
|
|
sys_sfnode_t *node = NULL;
|
|
int ii;
|
|
|
|
sys_sflist_init(&test_list);
|
|
|
|
for (ii = 0; ii < 6; ii++) {
|
|
sys_sflist_append(&test_list, &data_node[ii].node);
|
|
}
|
|
|
|
ii = 0;
|
|
SYS_SFLIST_ITERATE_FROM_NODE(&test_list, node) {
|
|
ii++;
|
|
if (((struct data_node *)node)->data == 2) {
|
|
break;
|
|
}
|
|
}
|
|
zassert_equal(ii, 3, "");
|
|
|
|
ii = 0;
|
|
SYS_SFLIST_ITERATE_FROM_NODE(&test_list, node) {
|
|
ii++;
|
|
if (((struct data_node *)node)->data == 3) {
|
|
break;
|
|
}
|
|
}
|
|
zassert_equal(ii, 1, "");
|
|
|
|
ii = 0;
|
|
SYS_SFLIST_ITERATE_FROM_NODE(&test_list, node) {
|
|
ii++;
|
|
}
|
|
zassert_equal(ii, 2, "");
|
|
|
|
/* test sys_sflist_get_not_empty() and sys_sflist_get() APIs */
|
|
for (ii = 0; ii < 6; ii++) {
|
|
node = sys_sflist_get_not_empty(&test_list);
|
|
zassert_equal(((struct data_node *)node)->data, ii, "");
|
|
}
|
|
for (ii = 0; ii < 6; ii++) {
|
|
/* regenerate test_list since we just emptied it */
|
|
sys_sflist_append(&test_list, &data_node[ii].node);
|
|
}
|
|
for (ii = 0; ii < 6; ii++) {
|
|
node = sys_sflist_get(&test_list);
|
|
zassert_equal(((struct data_node *)node)->data, ii, "");
|
|
}
|
|
node = sys_sflist_get(&test_list);
|
|
zassert_equal(node, NULL, "");
|
|
|
|
/* test sys_sflist_append_list() */
|
|
sys_sflist_init(&append_list);
|
|
struct data_node data_node_append[6] = {
|
|
{ .data = 6 },
|
|
{ .data = 7 },
|
|
{ .data = 8 },
|
|
{ .data = 9 },
|
|
{ .data = 10 },
|
|
{ .data = 11 },
|
|
};
|
|
for (ii = 0; ii < 6; ii++) {
|
|
/* regenerate test_list, which we just emptied */
|
|
sys_sflist_append(&test_list, &data_node[ii].node);
|
|
/* Build append_list so that the node pointers are correct */
|
|
sys_sflist_append(&append_list, &data_node_append[ii].node);
|
|
}
|
|
sys_sflist_append_list(&test_list, &data_node_append[0].node,
|
|
&data_node_append[5].node);
|
|
for (ii = 0; ii < 12; ii++) {
|
|
node = sys_sflist_get(&test_list);
|
|
zassert_equal(((struct data_node *)node)->data, ii,
|
|
"expected %d got %d", ii,
|
|
((struct data_node *)node)->data);
|
|
}
|
|
|
|
/* test sys_sflist_merge_sflist */
|
|
sys_sflist_init(&test_list);
|
|
sys_sflist_init(&append_list);
|
|
for (ii = 0; ii < 6; ii++) {
|
|
/* regenerate both lists */
|
|
sys_sflist_append(&test_list, &data_node[ii].node);
|
|
sys_sflist_append(&append_list, &data_node_append[ii].node);
|
|
}
|
|
sys_sflist_merge_sflist(&test_list, &append_list);
|
|
for (ii = 0; ii < 12; ii++) {
|
|
node = sys_sflist_get(&test_list);
|
|
zassert_equal(((struct data_node *)node)->data, ii,
|
|
"expected %d got %d", ii,
|
|
((struct data_node *)node)->data);
|
|
}
|
|
zassert_true(sys_sflist_is_empty(&append_list),
|
|
"merged list is not empty");
|
|
|
|
/* tests for sys_sfnode_flags_get(), sys_sfnode_flags_set()
|
|
* sys_sfnode_init()
|
|
*/
|
|
sys_sflist_init(&test_list);
|
|
/* Only iterating 0..3 due to limited range of flag values */
|
|
for (ii = 0; ii < 4; ii++) {
|
|
sys_sfnode_init(&data_node[ii].node, ii);
|
|
sys_sflist_append(&test_list, &data_node[ii].node);
|
|
}
|
|
for (ii = 0; ii < 4; ii++) {
|
|
node = sys_sflist_get(&test_list);
|
|
zassert_equal(sys_sfnode_flags_get(node), ii,
|
|
"wrong flags value");
|
|
/* Place the nodes back on the list with the flags set
|
|
* in reverse order for the next test
|
|
*/
|
|
sys_sfnode_flags_set(node, 3 - ii);
|
|
sys_sflist_append(&test_list, node);
|
|
}
|
|
for (ii = 3; ii >= 0; ii--) {
|
|
node = sys_sflist_get(&test_list);
|
|
zassert_equal(sys_sfnode_flags_get(node), ii,
|
|
"wrong flags value");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|