113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci#include "curlcheck.h" 2513498266Sopenharmony_ci 2613498266Sopenharmony_ci#include "llist.h" 2713498266Sopenharmony_ci 2813498266Sopenharmony_cistatic struct Curl_llist llist; 2913498266Sopenharmony_ci 3013498266Sopenharmony_cistatic struct Curl_llist llist_destination; 3113498266Sopenharmony_ci 3213498266Sopenharmony_cistatic void test_Curl_llist_dtor(void *key, void *value) 3313498266Sopenharmony_ci{ 3413498266Sopenharmony_ci /* used by the llist API, does nothing here */ 3513498266Sopenharmony_ci (void)key; 3613498266Sopenharmony_ci (void)value; 3713498266Sopenharmony_ci} 3813498266Sopenharmony_ci 3913498266Sopenharmony_cistatic CURLcode unit_setup(void) 4013498266Sopenharmony_ci{ 4113498266Sopenharmony_ci Curl_llist_init(&llist, test_Curl_llist_dtor); 4213498266Sopenharmony_ci Curl_llist_init(&llist_destination, test_Curl_llist_dtor); 4313498266Sopenharmony_ci return CURLE_OK; 4413498266Sopenharmony_ci} 4513498266Sopenharmony_ci 4613498266Sopenharmony_cistatic void unit_stop(void) 4713498266Sopenharmony_ci{ 4813498266Sopenharmony_ci} 4913498266Sopenharmony_ci 5013498266Sopenharmony_ciUNITTEST_START 5113498266Sopenharmony_ci{ 5213498266Sopenharmony_ci int unusedData_case1 = 1; 5313498266Sopenharmony_ci int unusedData_case2 = 2; 5413498266Sopenharmony_ci int unusedData_case3 = 3; 5513498266Sopenharmony_ci struct Curl_llist_element case1_list; 5613498266Sopenharmony_ci struct Curl_llist_element case2_list; 5713498266Sopenharmony_ci struct Curl_llist_element case3_list; 5813498266Sopenharmony_ci struct Curl_llist_element case4_list; 5913498266Sopenharmony_ci struct Curl_llist_element *head; 6013498266Sopenharmony_ci struct Curl_llist_element *element_next; 6113498266Sopenharmony_ci struct Curl_llist_element *element_prev; 6213498266Sopenharmony_ci struct Curl_llist_element *to_remove; 6313498266Sopenharmony_ci size_t llist_size = Curl_llist_count(&llist); 6413498266Sopenharmony_ci 6513498266Sopenharmony_ci /** 6613498266Sopenharmony_ci * testing llist_init 6713498266Sopenharmony_ci * case 1: 6813498266Sopenharmony_ci * list initiation 6913498266Sopenharmony_ci * @assumptions: 7013498266Sopenharmony_ci * 1: list size will be 0 7113498266Sopenharmony_ci * 2: list head will be NULL 7213498266Sopenharmony_ci * 3: list tail will be NULL 7313498266Sopenharmony_ci * 4: list dtor will be NULL 7413498266Sopenharmony_ci */ 7513498266Sopenharmony_ci 7613498266Sopenharmony_ci fail_unless(llist.size == 0, "list initial size should be zero"); 7713498266Sopenharmony_ci fail_unless(llist.head == NULL, "list head should initiate to NULL"); 7813498266Sopenharmony_ci fail_unless(llist.tail == NULL, "list tail should initiate to NULL"); 7913498266Sopenharmony_ci fail_unless(llist.dtor == test_Curl_llist_dtor, 8013498266Sopenharmony_ci "list dtor should initiate to test_Curl_llist_dtor"); 8113498266Sopenharmony_ci 8213498266Sopenharmony_ci /** 8313498266Sopenharmony_ci * testing Curl_llist_insert_next 8413498266Sopenharmony_ci * case 1: 8513498266Sopenharmony_ci * list is empty 8613498266Sopenharmony_ci * @assumptions: 8713498266Sopenharmony_ci * 1: list size will be 1 8813498266Sopenharmony_ci * 2: list head will hold the data "unusedData_case1" 8913498266Sopenharmony_ci * 3: list tail will be the same as list head 9013498266Sopenharmony_ci */ 9113498266Sopenharmony_ci 9213498266Sopenharmony_ci Curl_llist_insert_next(&llist, llist.head, &unusedData_case1, &case1_list); 9313498266Sopenharmony_ci 9413498266Sopenharmony_ci fail_unless(Curl_llist_count(&llist) == 1, 9513498266Sopenharmony_ci "List size should be 1 after adding a new element"); 9613498266Sopenharmony_ci /* test that the list head data holds my unusedData */ 9713498266Sopenharmony_ci fail_unless(llist.head->ptr == &unusedData_case1, 9813498266Sopenharmony_ci "head ptr should be first entry"); 9913498266Sopenharmony_ci /* same goes for the list tail */ 10013498266Sopenharmony_ci fail_unless(llist.tail == llist.head, 10113498266Sopenharmony_ci "tail and head should be the same"); 10213498266Sopenharmony_ci 10313498266Sopenharmony_ci /** 10413498266Sopenharmony_ci * testing Curl_llist_insert_next 10513498266Sopenharmony_ci * case 2: 10613498266Sopenharmony_ci * list has 1 element, adding one element after the head 10713498266Sopenharmony_ci * @assumptions: 10813498266Sopenharmony_ci * 1: the element next to head should be our newly created element 10913498266Sopenharmony_ci * 2: the list tail should be our newly created element 11013498266Sopenharmony_ci */ 11113498266Sopenharmony_ci 11213498266Sopenharmony_ci Curl_llist_insert_next(&llist, llist.head, 11313498266Sopenharmony_ci &unusedData_case3, &case3_list); 11413498266Sopenharmony_ci fail_unless(llist.head->next->ptr == &unusedData_case3, 11513498266Sopenharmony_ci "the node next to head is not getting set correctly"); 11613498266Sopenharmony_ci fail_unless(llist.tail->ptr == &unusedData_case3, 11713498266Sopenharmony_ci "the list tail is not getting set correctly"); 11813498266Sopenharmony_ci 11913498266Sopenharmony_ci /** 12013498266Sopenharmony_ci * testing Curl_llist_insert_next 12113498266Sopenharmony_ci * case 3: 12213498266Sopenharmony_ci * list has >1 element, adding one element after "NULL" 12313498266Sopenharmony_ci * @assumptions: 12413498266Sopenharmony_ci * 1: the element next to head should be our newly created element 12513498266Sopenharmony_ci * 2: the list tail should different from newly created element 12613498266Sopenharmony_ci */ 12713498266Sopenharmony_ci 12813498266Sopenharmony_ci Curl_llist_insert_next(&llist, llist.head, 12913498266Sopenharmony_ci &unusedData_case2, &case2_list); 13013498266Sopenharmony_ci fail_unless(llist.head->next->ptr == &unusedData_case2, 13113498266Sopenharmony_ci "the node next to head is not getting set correctly"); 13213498266Sopenharmony_ci /* better safe than sorry, check that the tail isn't corrupted */ 13313498266Sopenharmony_ci fail_unless(llist.tail->ptr != &unusedData_case2, 13413498266Sopenharmony_ci "the list tail is not getting set correctly"); 13513498266Sopenharmony_ci 13613498266Sopenharmony_ci /* unit tests for Curl_llist_remove */ 13713498266Sopenharmony_ci 13813498266Sopenharmony_ci /** 13913498266Sopenharmony_ci * case 1: 14013498266Sopenharmony_ci * list has >1 element, removing head 14113498266Sopenharmony_ci * @assumptions: 14213498266Sopenharmony_ci * 1: list size will be decremented by one 14313498266Sopenharmony_ci * 2: head will be the head->next 14413498266Sopenharmony_ci * 3: "new" head's previous will be NULL 14513498266Sopenharmony_ci */ 14613498266Sopenharmony_ci 14713498266Sopenharmony_ci head = llist.head; 14813498266Sopenharmony_ci abort_unless(head, "llist.head is NULL"); 14913498266Sopenharmony_ci element_next = head->next; 15013498266Sopenharmony_ci llist_size = Curl_llist_count(&llist); 15113498266Sopenharmony_ci 15213498266Sopenharmony_ci Curl_llist_remove(&llist, llist.head, NULL); 15313498266Sopenharmony_ci 15413498266Sopenharmony_ci fail_unless(Curl_llist_count(&llist) == (llist_size-1), 15513498266Sopenharmony_ci "llist size not decremented as expected"); 15613498266Sopenharmony_ci fail_unless(llist.head == element_next, 15713498266Sopenharmony_ci "llist new head not modified properly"); 15813498266Sopenharmony_ci abort_unless(llist.head, "llist.head is NULL"); 15913498266Sopenharmony_ci fail_unless(llist.head->prev == NULL, 16013498266Sopenharmony_ci "new head previous not set to null"); 16113498266Sopenharmony_ci 16213498266Sopenharmony_ci /** 16313498266Sopenharmony_ci * case 2: 16413498266Sopenharmony_ci * removing non head element, with list having >=2 elements 16513498266Sopenharmony_ci * @setup: 16613498266Sopenharmony_ci * 1: insert another element to the list to make element >=2 16713498266Sopenharmony_ci * @assumptions: 16813498266Sopenharmony_ci * 1: list size will be decremented by one ; tested 16913498266Sopenharmony_ci * 2: element->previous->next will be element->next 17013498266Sopenharmony_ci * 3: element->next->previous will be element->previous 17113498266Sopenharmony_ci */ 17213498266Sopenharmony_ci Curl_llist_insert_next(&llist, llist.head, &unusedData_case3, 17313498266Sopenharmony_ci &case4_list); 17413498266Sopenharmony_ci llist_size = Curl_llist_count(&llist); 17513498266Sopenharmony_ci fail_unless(llist_size == 3, "should be 3 list members"); 17613498266Sopenharmony_ci 17713498266Sopenharmony_ci to_remove = llist.head->next; 17813498266Sopenharmony_ci abort_unless(to_remove, "to_remove is NULL"); 17913498266Sopenharmony_ci element_next = to_remove->next; 18013498266Sopenharmony_ci element_prev = to_remove->prev; 18113498266Sopenharmony_ci Curl_llist_remove(&llist, to_remove, NULL); 18213498266Sopenharmony_ci fail_unless(element_prev->next == element_next, 18313498266Sopenharmony_ci "element previous->next is not being adjusted"); 18413498266Sopenharmony_ci abort_unless(element_next, "element_next is NULL"); 18513498266Sopenharmony_ci fail_unless(element_next->prev == element_prev, 18613498266Sopenharmony_ci "element next->previous is not being adjusted"); 18713498266Sopenharmony_ci 18813498266Sopenharmony_ci /** 18913498266Sopenharmony_ci * case 3: 19013498266Sopenharmony_ci * removing the tail with list having >=1 element 19113498266Sopenharmony_ci * @assumptions 19213498266Sopenharmony_ci * 1: list size will be decremented by one ;tested 19313498266Sopenharmony_ci * 2: element->previous->next will be element->next ;tested 19413498266Sopenharmony_ci * 3: element->next->previous will be element->previous ;tested 19513498266Sopenharmony_ci * 4: list->tail will be tail->previous 19613498266Sopenharmony_ci */ 19713498266Sopenharmony_ci 19813498266Sopenharmony_ci to_remove = llist.tail; 19913498266Sopenharmony_ci element_prev = to_remove->prev; 20013498266Sopenharmony_ci Curl_llist_remove(&llist, to_remove, NULL); 20113498266Sopenharmony_ci fail_unless(llist.tail == element_prev, 20213498266Sopenharmony_ci "llist tail is not being adjusted when removing tail"); 20313498266Sopenharmony_ci 20413498266Sopenharmony_ci /** 20513498266Sopenharmony_ci * case 4: 20613498266Sopenharmony_ci * removing head with list having 1 element 20713498266Sopenharmony_ci * @assumptions: 20813498266Sopenharmony_ci * 1: list size will be decremented by one ;tested 20913498266Sopenharmony_ci * 2: list head will be null 21013498266Sopenharmony_ci * 3: list tail will be null 21113498266Sopenharmony_ci */ 21213498266Sopenharmony_ci 21313498266Sopenharmony_ci to_remove = llist.head; 21413498266Sopenharmony_ci Curl_llist_remove(&llist, to_remove, NULL); 21513498266Sopenharmony_ci fail_unless(llist.head == NULL, 21613498266Sopenharmony_ci "llist head is not NULL while the llist is empty"); 21713498266Sopenharmony_ci fail_unless(llist.tail == NULL, 21813498266Sopenharmony_ci "llist tail is not NULL while the llist is empty"); 21913498266Sopenharmony_ci 22013498266Sopenharmony_ci Curl_llist_destroy(&llist, NULL); 22113498266Sopenharmony_ci Curl_llist_destroy(&llist_destination, NULL); 22213498266Sopenharmony_ci} 22313498266Sopenharmony_ciUNITTEST_STOP 224