1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker * _ _ ____ _
3*6236dae4SAndroid Build Coastguard Worker * Project ___| | | | _ \| |
4*6236dae4SAndroid Build Coastguard Worker * / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker * | (__| |_| | _ <| |___
6*6236dae4SAndroid Build Coastguard Worker * \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker *
8*6236dae4SAndroid Build Coastguard Worker * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker *
10*6236dae4SAndroid Build Coastguard Worker * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker *
14*6236dae4SAndroid Build Coastguard Worker * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker *
18*6236dae4SAndroid Build Coastguard Worker * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker *
21*6236dae4SAndroid Build Coastguard Worker * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker *
23*6236dae4SAndroid Build Coastguard Worker ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker #include "curlcheck.h"
25*6236dae4SAndroid Build Coastguard Worker
26*6236dae4SAndroid Build Coastguard Worker #include "llist.h"
27*6236dae4SAndroid Build Coastguard Worker
28*6236dae4SAndroid Build Coastguard Worker static struct Curl_llist llist;
29*6236dae4SAndroid Build Coastguard Worker
30*6236dae4SAndroid Build Coastguard Worker static struct Curl_llist llist_destination;
31*6236dae4SAndroid Build Coastguard Worker
test_Curl_llist_dtor(void * key,void * value)32*6236dae4SAndroid Build Coastguard Worker static void test_Curl_llist_dtor(void *key, void *value)
33*6236dae4SAndroid Build Coastguard Worker {
34*6236dae4SAndroid Build Coastguard Worker /* used by the llist API, does nothing here */
35*6236dae4SAndroid Build Coastguard Worker (void)key;
36*6236dae4SAndroid Build Coastguard Worker (void)value;
37*6236dae4SAndroid Build Coastguard Worker }
38*6236dae4SAndroid Build Coastguard Worker
unit_setup(void)39*6236dae4SAndroid Build Coastguard Worker static CURLcode unit_setup(void)
40*6236dae4SAndroid Build Coastguard Worker {
41*6236dae4SAndroid Build Coastguard Worker Curl_llist_init(&llist, test_Curl_llist_dtor);
42*6236dae4SAndroid Build Coastguard Worker Curl_llist_init(&llist_destination, test_Curl_llist_dtor);
43*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
44*6236dae4SAndroid Build Coastguard Worker }
45*6236dae4SAndroid Build Coastguard Worker
unit_stop(void)46*6236dae4SAndroid Build Coastguard Worker static void unit_stop(void)
47*6236dae4SAndroid Build Coastguard Worker {
48*6236dae4SAndroid Build Coastguard Worker }
49*6236dae4SAndroid Build Coastguard Worker
50*6236dae4SAndroid Build Coastguard Worker UNITTEST_START
51*6236dae4SAndroid Build Coastguard Worker {
52*6236dae4SAndroid Build Coastguard Worker int unusedData_case1 = 1;
53*6236dae4SAndroid Build Coastguard Worker int unusedData_case2 = 2;
54*6236dae4SAndroid Build Coastguard Worker int unusedData_case3 = 3;
55*6236dae4SAndroid Build Coastguard Worker struct Curl_llist_node case1_list;
56*6236dae4SAndroid Build Coastguard Worker struct Curl_llist_node case2_list;
57*6236dae4SAndroid Build Coastguard Worker struct Curl_llist_node case3_list;
58*6236dae4SAndroid Build Coastguard Worker struct Curl_llist_node case4_list;
59*6236dae4SAndroid Build Coastguard Worker struct Curl_llist_node *head;
60*6236dae4SAndroid Build Coastguard Worker struct Curl_llist_node *element_next;
61*6236dae4SAndroid Build Coastguard Worker struct Curl_llist_node *element_prev;
62*6236dae4SAndroid Build Coastguard Worker struct Curl_llist_node *to_remove;
63*6236dae4SAndroid Build Coastguard Worker size_t llist_size = Curl_llist_count(&llist);
64*6236dae4SAndroid Build Coastguard Worker
65*6236dae4SAndroid Build Coastguard Worker /**
66*6236dae4SAndroid Build Coastguard Worker * testing llist_init
67*6236dae4SAndroid Build Coastguard Worker * case 1:
68*6236dae4SAndroid Build Coastguard Worker * list initiation
69*6236dae4SAndroid Build Coastguard Worker * @assumptions:
70*6236dae4SAndroid Build Coastguard Worker * 1: list size will be 0
71*6236dae4SAndroid Build Coastguard Worker * 2: list head will be NULL
72*6236dae4SAndroid Build Coastguard Worker * 3: list tail will be NULL
73*6236dae4SAndroid Build Coastguard Worker * 4: list dtor will be NULL
74*6236dae4SAndroid Build Coastguard Worker */
75*6236dae4SAndroid Build Coastguard Worker
76*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_llist_count(&llist) == 0,
77*6236dae4SAndroid Build Coastguard Worker "list initial size should be zero");
78*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_llist_head(&llist) == NULL,
79*6236dae4SAndroid Build Coastguard Worker "list head should initiate to NULL");
80*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_llist_tail(&llist) == NULL,
81*6236dae4SAndroid Build Coastguard Worker "list tail should initiate to NULL");
82*6236dae4SAndroid Build Coastguard Worker
83*6236dae4SAndroid Build Coastguard Worker /**
84*6236dae4SAndroid Build Coastguard Worker * testing Curl_llist_insert_next
85*6236dae4SAndroid Build Coastguard Worker * case 1:
86*6236dae4SAndroid Build Coastguard Worker * list is empty
87*6236dae4SAndroid Build Coastguard Worker * @assumptions:
88*6236dae4SAndroid Build Coastguard Worker * 1: list size will be 1
89*6236dae4SAndroid Build Coastguard Worker * 2: list head will hold the data "unusedData_case1"
90*6236dae4SAndroid Build Coastguard Worker * 3: list tail will be the same as list head
91*6236dae4SAndroid Build Coastguard Worker */
92*6236dae4SAndroid Build Coastguard Worker
93*6236dae4SAndroid Build Coastguard Worker Curl_llist_insert_next(&llist, Curl_llist_head(&llist), &unusedData_case1,
94*6236dae4SAndroid Build Coastguard Worker &case1_list);
95*6236dae4SAndroid Build Coastguard Worker
96*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_llist_count(&llist) == 1,
97*6236dae4SAndroid Build Coastguard Worker "List size should be 1 after adding a new element");
98*6236dae4SAndroid Build Coastguard Worker /* test that the list head data holds my unusedData */
99*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_node_elem(Curl_llist_head(&llist)) == &unusedData_case1,
100*6236dae4SAndroid Build Coastguard Worker "head ptr should be first entry");
101*6236dae4SAndroid Build Coastguard Worker /* same goes for the list tail */
102*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_llist_tail(&llist) == Curl_llist_head(&llist),
103*6236dae4SAndroid Build Coastguard Worker "tail and head should be the same");
104*6236dae4SAndroid Build Coastguard Worker
105*6236dae4SAndroid Build Coastguard Worker /**
106*6236dae4SAndroid Build Coastguard Worker * testing Curl_llist_insert_next
107*6236dae4SAndroid Build Coastguard Worker * case 2:
108*6236dae4SAndroid Build Coastguard Worker * list has 1 element, adding one element after the head
109*6236dae4SAndroid Build Coastguard Worker * @assumptions:
110*6236dae4SAndroid Build Coastguard Worker * 1: the element next to head should be our newly created element
111*6236dae4SAndroid Build Coastguard Worker * 2: the list tail should be our newly created element
112*6236dae4SAndroid Build Coastguard Worker */
113*6236dae4SAndroid Build Coastguard Worker
114*6236dae4SAndroid Build Coastguard Worker Curl_llist_insert_next(&llist, Curl_llist_head(&llist),
115*6236dae4SAndroid Build Coastguard Worker &unusedData_case3, &case3_list);
116*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_node_elem(Curl_node_next(Curl_llist_head(&llist))) ==
117*6236dae4SAndroid Build Coastguard Worker &unusedData_case3,
118*6236dae4SAndroid Build Coastguard Worker "the node next to head is not getting set correctly");
119*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_node_elem(Curl_llist_tail(&llist)) == &unusedData_case3,
120*6236dae4SAndroid Build Coastguard Worker "the list tail is not getting set correctly");
121*6236dae4SAndroid Build Coastguard Worker
122*6236dae4SAndroid Build Coastguard Worker /**
123*6236dae4SAndroid Build Coastguard Worker * testing Curl_llist_insert_next
124*6236dae4SAndroid Build Coastguard Worker * case 3:
125*6236dae4SAndroid Build Coastguard Worker * list has >1 element, adding one element after "NULL"
126*6236dae4SAndroid Build Coastguard Worker * @assumptions:
127*6236dae4SAndroid Build Coastguard Worker * 1: the element next to head should be our newly created element
128*6236dae4SAndroid Build Coastguard Worker * 2: the list tail should different from newly created element
129*6236dae4SAndroid Build Coastguard Worker */
130*6236dae4SAndroid Build Coastguard Worker
131*6236dae4SAndroid Build Coastguard Worker Curl_llist_insert_next(&llist, Curl_llist_head(&llist),
132*6236dae4SAndroid Build Coastguard Worker &unusedData_case2, &case2_list);
133*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_node_elem(Curl_node_next(Curl_llist_head(&llist))) ==
134*6236dae4SAndroid Build Coastguard Worker &unusedData_case2,
135*6236dae4SAndroid Build Coastguard Worker "the node next to head is not getting set correctly");
136*6236dae4SAndroid Build Coastguard Worker /* better safe than sorry, check that the tail isn't corrupted */
137*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_node_elem(Curl_llist_tail(&llist)) != &unusedData_case2,
138*6236dae4SAndroid Build Coastguard Worker "the list tail is not getting set correctly");
139*6236dae4SAndroid Build Coastguard Worker
140*6236dae4SAndroid Build Coastguard Worker /* unit tests for Curl_node_remove */
141*6236dae4SAndroid Build Coastguard Worker
142*6236dae4SAndroid Build Coastguard Worker /**
143*6236dae4SAndroid Build Coastguard Worker * case 1:
144*6236dae4SAndroid Build Coastguard Worker * list has >1 element, removing head
145*6236dae4SAndroid Build Coastguard Worker * @assumptions:
146*6236dae4SAndroid Build Coastguard Worker * 1: list size will be decremented by one
147*6236dae4SAndroid Build Coastguard Worker * 2: head will be the head->next
148*6236dae4SAndroid Build Coastguard Worker * 3: "new" head's previous will be NULL
149*6236dae4SAndroid Build Coastguard Worker */
150*6236dae4SAndroid Build Coastguard Worker
151*6236dae4SAndroid Build Coastguard Worker head = Curl_llist_head(&llist);
152*6236dae4SAndroid Build Coastguard Worker abort_unless(head, "llist.head is NULL");
153*6236dae4SAndroid Build Coastguard Worker element_next = Curl_node_next(head);
154*6236dae4SAndroid Build Coastguard Worker llist_size = Curl_llist_count(&llist);
155*6236dae4SAndroid Build Coastguard Worker
156*6236dae4SAndroid Build Coastguard Worker Curl_node_remove(Curl_llist_head(&llist));
157*6236dae4SAndroid Build Coastguard Worker
158*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_llist_count(&llist) == (llist_size-1),
159*6236dae4SAndroid Build Coastguard Worker "llist size not decremented as expected");
160*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_llist_head(&llist) == element_next,
161*6236dae4SAndroid Build Coastguard Worker "llist new head not modified properly");
162*6236dae4SAndroid Build Coastguard Worker abort_unless(Curl_llist_head(&llist), "llist.head is NULL");
163*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_node_prev(Curl_llist_head(&llist)) == NULL,
164*6236dae4SAndroid Build Coastguard Worker "new head previous not set to null");
165*6236dae4SAndroid Build Coastguard Worker
166*6236dae4SAndroid Build Coastguard Worker /**
167*6236dae4SAndroid Build Coastguard Worker * case 2:
168*6236dae4SAndroid Build Coastguard Worker * removing non head element, with list having >=2 elements
169*6236dae4SAndroid Build Coastguard Worker * @setup:
170*6236dae4SAndroid Build Coastguard Worker * 1: insert another element to the list to make element >=2
171*6236dae4SAndroid Build Coastguard Worker * @assumptions:
172*6236dae4SAndroid Build Coastguard Worker * 1: list size will be decremented by one ; tested
173*6236dae4SAndroid Build Coastguard Worker * 2: element->previous->next will be element->next
174*6236dae4SAndroid Build Coastguard Worker * 3: element->next->previous will be element->previous
175*6236dae4SAndroid Build Coastguard Worker */
176*6236dae4SAndroid Build Coastguard Worker Curl_llist_insert_next(&llist, Curl_llist_head(&llist), &unusedData_case3,
177*6236dae4SAndroid Build Coastguard Worker &case4_list);
178*6236dae4SAndroid Build Coastguard Worker llist_size = Curl_llist_count(&llist);
179*6236dae4SAndroid Build Coastguard Worker fail_unless(llist_size == 3, "should be 3 list members");
180*6236dae4SAndroid Build Coastguard Worker
181*6236dae4SAndroid Build Coastguard Worker to_remove = Curl_node_next(Curl_llist_head(&llist));
182*6236dae4SAndroid Build Coastguard Worker abort_unless(to_remove, "to_remove is NULL");
183*6236dae4SAndroid Build Coastguard Worker element_next = Curl_node_next(to_remove);
184*6236dae4SAndroid Build Coastguard Worker element_prev = Curl_node_prev(to_remove);
185*6236dae4SAndroid Build Coastguard Worker Curl_node_uremove(to_remove, NULL);
186*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_node_next(element_prev) == element_next,
187*6236dae4SAndroid Build Coastguard Worker "element previous->next is not being adjusted");
188*6236dae4SAndroid Build Coastguard Worker abort_unless(element_next, "element_next is NULL");
189*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_node_prev(element_next) == element_prev,
190*6236dae4SAndroid Build Coastguard Worker "element next->previous is not being adjusted");
191*6236dae4SAndroid Build Coastguard Worker
192*6236dae4SAndroid Build Coastguard Worker /**
193*6236dae4SAndroid Build Coastguard Worker * case 3:
194*6236dae4SAndroid Build Coastguard Worker * removing the tail with list having >=1 element
195*6236dae4SAndroid Build Coastguard Worker * @assumptions
196*6236dae4SAndroid Build Coastguard Worker * 1: list size will be decremented by one ;tested
197*6236dae4SAndroid Build Coastguard Worker * 2: element->previous->next will be element->next ;tested
198*6236dae4SAndroid Build Coastguard Worker * 3: element->next->previous will be element->previous ;tested
199*6236dae4SAndroid Build Coastguard Worker * 4: list->tail will be tail->previous
200*6236dae4SAndroid Build Coastguard Worker */
201*6236dae4SAndroid Build Coastguard Worker
202*6236dae4SAndroid Build Coastguard Worker to_remove = Curl_llist_tail(&llist);
203*6236dae4SAndroid Build Coastguard Worker element_prev = Curl_node_prev(to_remove);
204*6236dae4SAndroid Build Coastguard Worker Curl_node_remove(to_remove);
205*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_llist_tail(&llist) == element_prev,
206*6236dae4SAndroid Build Coastguard Worker "llist tail is not being adjusted when removing tail");
207*6236dae4SAndroid Build Coastguard Worker
208*6236dae4SAndroid Build Coastguard Worker /**
209*6236dae4SAndroid Build Coastguard Worker * case 4:
210*6236dae4SAndroid Build Coastguard Worker * removing head with list having 1 element
211*6236dae4SAndroid Build Coastguard Worker * @assumptions:
212*6236dae4SAndroid Build Coastguard Worker * 1: list size will be decremented by one ;tested
213*6236dae4SAndroid Build Coastguard Worker * 2: list head will be null
214*6236dae4SAndroid Build Coastguard Worker * 3: list tail will be null
215*6236dae4SAndroid Build Coastguard Worker */
216*6236dae4SAndroid Build Coastguard Worker
217*6236dae4SAndroid Build Coastguard Worker to_remove = Curl_llist_head(&llist);
218*6236dae4SAndroid Build Coastguard Worker Curl_node_remove(to_remove);
219*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_llist_head(&llist) == NULL,
220*6236dae4SAndroid Build Coastguard Worker "llist head is not NULL while the llist is empty");
221*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_llist_tail(&llist) == NULL,
222*6236dae4SAndroid Build Coastguard Worker "llist tail is not NULL while the llist is empty");
223*6236dae4SAndroid Build Coastguard Worker
224*6236dae4SAndroid Build Coastguard Worker /**
225*6236dae4SAndroid Build Coastguard Worker * testing Curl_llist_append
226*6236dae4SAndroid Build Coastguard Worker * case 1:
227*6236dae4SAndroid Build Coastguard Worker * list is empty
228*6236dae4SAndroid Build Coastguard Worker * @assumptions:
229*6236dae4SAndroid Build Coastguard Worker * 1: the element next to head should be our newly created element
230*6236dae4SAndroid Build Coastguard Worker * 2: the list tail should different from newly created element
231*6236dae4SAndroid Build Coastguard Worker */
232*6236dae4SAndroid Build Coastguard Worker Curl_llist_append(&llist, &unusedData_case1, &case1_list);
233*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_llist_count(&llist) == 1,
234*6236dae4SAndroid Build Coastguard Worker "List size should be 1 after appending a new element");
235*6236dae4SAndroid Build Coastguard Worker /* test that the list head data holds my unusedData */
236*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_node_elem(Curl_llist_head(&llist)) == &unusedData_case1,
237*6236dae4SAndroid Build Coastguard Worker "head ptr should be first entry");
238*6236dae4SAndroid Build Coastguard Worker /* same goes for the list tail */
239*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_llist_tail(&llist) == Curl_llist_head(&llist),
240*6236dae4SAndroid Build Coastguard Worker "tail and head should be the same");
241*6236dae4SAndroid Build Coastguard Worker
242*6236dae4SAndroid Build Coastguard Worker /**
243*6236dae4SAndroid Build Coastguard Worker * testing Curl_llist_append
244*6236dae4SAndroid Build Coastguard Worker * case 2:
245*6236dae4SAndroid Build Coastguard Worker * list is not empty
246*6236dae4SAndroid Build Coastguard Worker * @assumptions:
247*6236dae4SAndroid Build Coastguard Worker * 1: the list head-next should be the newly created element
248*6236dae4SAndroid Build Coastguard Worker * 2: the list tail should be the newly created element
249*6236dae4SAndroid Build Coastguard Worker */
250*6236dae4SAndroid Build Coastguard Worker Curl_llist_append(&llist, &unusedData_case2, &case2_list);
251*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_node_elem(Curl_node_next(Curl_llist_head(&llist))) ==
252*6236dae4SAndroid Build Coastguard Worker &unusedData_case2,
253*6236dae4SAndroid Build Coastguard Worker "the node next to head is not getting set correctly");
254*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_node_elem(Curl_llist_tail(&llist)) == &unusedData_case2,
255*6236dae4SAndroid Build Coastguard Worker "the list tail is not getting set correctly");
256*6236dae4SAndroid Build Coastguard Worker
257*6236dae4SAndroid Build Coastguard Worker /**
258*6236dae4SAndroid Build Coastguard Worker * testing Curl_llist_append
259*6236dae4SAndroid Build Coastguard Worker * case 3:
260*6236dae4SAndroid Build Coastguard Worker * list is has 2 members
261*6236dae4SAndroid Build Coastguard Worker * @assumptions:
262*6236dae4SAndroid Build Coastguard Worker * 1: the list head-next should remain the same
263*6236dae4SAndroid Build Coastguard Worker * 2: the list tail should be the newly created element
264*6236dae4SAndroid Build Coastguard Worker */
265*6236dae4SAndroid Build Coastguard Worker Curl_llist_append(&llist, &unusedData_case3, &case3_list);
266*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_node_elem(Curl_node_next(Curl_llist_head(&llist))) ==
267*6236dae4SAndroid Build Coastguard Worker &unusedData_case2,
268*6236dae4SAndroid Build Coastguard Worker "the node next to head did not stay the same");
269*6236dae4SAndroid Build Coastguard Worker fail_unless(Curl_node_elem(Curl_llist_tail(&llist)) == &unusedData_case3,
270*6236dae4SAndroid Build Coastguard Worker "the list tail is not getting set correctly");
271*6236dae4SAndroid Build Coastguard Worker
272*6236dae4SAndroid Build Coastguard Worker Curl_llist_destroy(&llist, NULL);
273*6236dae4SAndroid Build Coastguard Worker Curl_llist_destroy(&llist_destination, NULL);
274*6236dae4SAndroid Build Coastguard Worker }
275*6236dae4SAndroid Build Coastguard Worker UNITTEST_STOP
276