/* * Copyright (c) 2017 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include #include static sys_dlist_t test_list; struct container_node { sys_dnode_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_dlist_t *list) { sys_dnode_t *node; sys_dnode_t *s_node; struct container_node *cnode; struct container_node *s_cnode; int count; if (!sys_dlist_is_empty(list)) { return false; } if (sys_dlist_peek_head(list)) { return false; } if (sys_dlist_peek_tail(list)) { return false; } if (sys_dlist_len(list) != 0) { return false; } count = 0; SYS_DLIST_FOR_EACH_NODE(list, node) { count++; } if (count) { return false; } SYS_DLIST_FOR_EACH_NODE_SAFE(list, node, s_node) { count++; } if (count) { return false; } count = 0; SYS_DLIST_FOR_EACH_CONTAINER(list, cnode, node) { count++; } if (count) { return false; } count = 0; SYS_DLIST_FOR_EACH_CONTAINER_SAFE(list, cnode, s_cnode, node) { count++; } if (count) { return false; } return true; } static inline bool verify_content_amount(sys_dlist_t *list, int amount) { sys_dnode_t *node; sys_dnode_t *s_node; struct container_node *cnode; struct container_node *s_cnode; int count; if (sys_dlist_is_empty(list)) { return false; } if (!sys_dlist_peek_head(list)) { return false; } if (!sys_dlist_peek_tail(list)) { return false; } if (sys_dlist_len(list) != amount) { return false; } count = 0; SYS_DLIST_FOR_EACH_NODE(list, node) { count++; } if (count != amount) { return false; } count = 0; SYS_DLIST_FOR_EACH_NODE_SAFE(list, node, s_node) { count++; } if (count != amount) { return false; } count = 0; SYS_DLIST_FOR_EACH_CONTAINER(list, cnode, node) { count++; } if (count != amount) { return false; } count = 0; SYS_DLIST_FOR_EACH_CONTAINER_SAFE(list, cnode, s_cnode, node) { count++; } if (count != amount) { return false; } return true; } static inline bool verify_tail_head(sys_dlist_t *list, sys_dnode_t *head, sys_dnode_t *tail, bool same) { if (sys_dlist_peek_head(list) != head) { return false; } if (sys_dlist_peek_tail(list) != tail) { return false; } if (same) { if (sys_dlist_peek_head(list) != sys_dlist_peek_tail(list)) { return false; } } else { if (sys_dlist_peek_head(list) == sys_dlist_peek_tail(list)) { return false; } } return true; } /** * @addtogroup unit_tests * @{ */ /** * @brief Verify doubly linked list functionalities * * @see sys_dlist_append(), sys_dlist_remove(), sys_dlist_prepend(), * sys_dlist_remove(), sys_dlist_insert(), sys_dlist_peek_next() * SYS_DLIST_ITERATE_FROM_NODE() */ ZTEST(dlist_api, test_dlist) { sys_dlist_init(&test_list); zassert_true((verify_emptyness(&test_list)), "test_list should be empty"); /* Appending node 1 */ sys_dlist_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 */ zassert_true(sys_dnode_is_linked(&test_node_1.node), "node1 is not linked"); sys_dlist_remove(&test_node_1.node); zassert_true((verify_emptyness(&test_list)), "test_list should be empty"); zassert_false(sys_dnode_is_linked(&test_node_1.node), "node1 is still linked"); /* Prepending node 1 */ sys_dlist_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_dlist_remove(&test_node_1.node); zassert_true((verify_emptyness(&test_list)), "test_list should be empty"); /* Appending node 1 */ sys_dlist_append(&test_list, &test_node_1.node); /* Prepending node 2 */ sys_dlist_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_dlist_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_dlist_peek_next(&test_list, &test_node_2.node) == &test_node_1.node), "test_list node links are wrong"); /* Inserting node 4 after node 2 */ sys_dlist_insert(test_node_2.node.next, &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_dlist_peek_next(&test_list, &test_node_2.node) == &test_node_4.node), "test_list node links are wrong"); /* Finding and removing node 1 */ sys_dlist_remove(&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_dlist_remove(&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_dlist_remove(&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_dlist_remove(&test_node_2.node); zassert_true((verify_emptyness(&test_list)), "test_list should be empty"); /* test iterator from a node */ struct data_node { sys_dnode_t node; int data; } data_node[6] = { { .data = 0 }, { .data = 1 }, { .data = 2 }, { .data = 3 }, { .data = 4 }, { .data = 5 }, }; sys_dnode_t *node = NULL; int ii; sys_dlist_init(&test_list); for (ii = 0; ii < 6; ii++) { sys_dlist_append(&test_list, &data_node[ii].node); } ii = 0; SYS_DLIST_ITERATE_FROM_NODE(&test_list, node) { ii++; if (((struct data_node *)node)->data == 2) { break; } } zassert_equal(ii, 3, ""); ii = 0; SYS_DLIST_ITERATE_FROM_NODE(&test_list, node) { ii++; if (((struct data_node *)node)->data == 3) { break; } } zassert_equal(ii, 1, ""); ii = 0; SYS_DLIST_ITERATE_FROM_NODE(&test_list, node) { ii++; } zassert_equal(ii, 2, ""); } int cond(sys_dnode_t *node, void *data) { return (node == data) ? 1 : 0; } /** * @brief Verify doubly linked list functionalities * * @see sys_dlist_is_head(),sys_dlist_is_tail(), * sys_dlist_has_multiple_nodes(),sys_dlist_get() * sys_dlist_peek_head_not_empty(),sys_dlist_insert_at(), * sys_dlist_peek_prev(), */ ZTEST(dlist_api, test_dlist2) { struct container_node test_node[6]; struct container_node insert_node; struct container_node insert_node2; /* Initialize */ memset(test_node, 0, sizeof(test_node)); memset(&insert_node, 0, sizeof(insert_node)); memset(&insert_node2, 0, sizeof(insert_node2)); sys_dlist_init(&test_list); /* Check if the dlist is empty */ zassert_true(sys_dlist_get(&test_list) == NULL, "Get a empty dilst, NULL will be returned"); /* Check if a node can append as head if dlist is empty */ sys_dlist_insert_at(&test_list, &insert_node.node, cond, &test_node[2].node); zassert_true(test_list.head == &insert_node.node, ""); zassert_true(test_list.tail == &insert_node.node, ""); /* Re-initialize and insert nodes */ sys_dlist_init(&test_list); for (int i = 0; i < 5; i++) { sys_dlist_append(&test_list, &test_node[i].node); } zassert_true(sys_dlist_peek_head_not_empty(&test_list) != NULL, "dlist appended incorrectly"); zassert_true(sys_dlist_is_head(&test_list, &test_node[0].node), "dlist appended incorrectly"); zassert_true(sys_dlist_is_tail(&test_list, &test_node[4].node), "dlist appended incorrectly"); zassert_true(sys_dlist_has_multiple_nodes(&test_list), "dlist appended incorrectly"); zassert_true(sys_dlist_peek_prev(&test_list, &test_node[2].node) == &test_node[1].node, "dlist appended incorrectly"); zassert_true(sys_dlist_peek_prev(&test_list, &test_node[0].node) == NULL, "dlist appended incorrectly"); zassert_true(sys_dlist_peek_prev(&test_list, NULL) == NULL, "dlist appended incorrectly"); zassert_true(sys_dlist_get(&test_list) == &test_node[0].node, "Get a dilst, head will be returned"); /* Check if a node can insert in front of known nodes */ sys_dlist_insert_at(&test_list, &insert_node.node, cond, &test_node[2].node); zassert_true(sys_dlist_peek_next(&test_list, &test_node[1].node) == &insert_node.node, " "); /* Check if a node can append if the node is unknown */ sys_dlist_insert_at(&test_list, &insert_node2.node, cond, &test_node[5].node); zassert_true(sys_dlist_peek_next(&test_list, &test_node[4].node) == &insert_node2.node, " "); } /** * @} */