blob: 1715a22584c280b79d99f10be533a11442dad206 [file] [log] [blame]
Simon Glasse1edadf2024-07-30 08:39:37 -06001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2023 Google LLC
4 * Written by Simon Glass <sjg@chromium.org>
5 */
6
7#include <alist.h>
8#include <string.h>
9#include <test/lib.h>
10#include <test/test.h>
11#include <test/ut.h>
12
13struct my_struct {
14 uint val;
15 uint other_val;
16};
17
18enum {
19 obj_size = sizeof(struct my_struct),
20};
21
22/* Test alist_init() */
23static int lib_test_alist_init(struct unit_test_state *uts)
24{
25 struct alist lst;
26 ulong start;
27
28 start = ut_check_free();
29
30 /* with a size of 0, the fields should be inited, with no memory used */
31 memset(&lst, '\xff', sizeof(lst));
32 ut_assert(alist_init_struct(&lst, struct my_struct));
33 ut_asserteq_ptr(NULL, lst.data);
34 ut_asserteq(0, lst.count);
35 ut_asserteq(0, lst.alloc);
36 ut_assertok(ut_check_delta(start));
37 alist_uninit(&lst);
38 ut_asserteq_ptr(NULL, lst.data);
39 ut_asserteq(0, lst.count);
40 ut_asserteq(0, lst.alloc);
41
42 /* use an impossible size */
43 ut_asserteq(false, alist_init(&lst, obj_size,
44 CONFIG_SYS_MALLOC_LEN));
45 ut_assertnull(lst.data);
46 ut_asserteq(0, lst.count);
47 ut_asserteq(0, lst.alloc);
48
49 /* use a small size */
50 ut_assert(alist_init(&lst, obj_size, 4));
51 ut_assertnonnull(lst.data);
52 ut_asserteq(0, lst.count);
53 ut_asserteq(4, lst.alloc);
54
55 /* free it */
56 alist_uninit(&lst);
57 ut_asserteq_ptr(NULL, lst.data);
58 ut_asserteq(0, lst.count);
59 ut_asserteq(0, lst.alloc);
60 ut_assertok(ut_check_delta(start));
61
62 /* Check for memory leaks */
63 ut_assertok(ut_check_delta(start));
64
65 return 0;
66}
67LIB_TEST(lib_test_alist_init, 0);
68
69/* Test alist_get() and alist_getd() */
70static int lib_test_alist_get(struct unit_test_state *uts)
71{
72 struct alist lst;
73 ulong start;
74 void *ptr;
75
76 start = ut_check_free();
77
78 ut_assert(alist_init(&lst, obj_size, 3));
79 ut_asserteq(0, lst.count);
80 ut_asserteq(3, lst.alloc);
81
82 ut_assertnull(alist_get_ptr(&lst, 2));
83 ut_assertnull(alist_get_ptr(&lst, 3));
84
85 ptr = alist_ensure_ptr(&lst, 1);
86 ut_assertnonnull(ptr);
87 ut_asserteq(2, lst.count);
88 ptr = alist_ensure_ptr(&lst, 2);
89 ut_asserteq(3, lst.count);
90 ut_assertnonnull(ptr);
91
92 ptr = alist_ensure_ptr(&lst, 3);
93 ut_assertnonnull(ptr);
94 ut_asserteq(4, lst.count);
95 ut_asserteq(6, lst.alloc);
96
97 ut_assertnull(alist_get_ptr(&lst, 4));
98
99 alist_uninit(&lst);
100
101 /* Check for memory leaks */
102 ut_assertok(ut_check_delta(start));
103
104 return 0;
105}
106LIB_TEST(lib_test_alist_get, 0);
107
108/* Test alist_has() */
109static int lib_test_alist_has(struct unit_test_state *uts)
110{
111 struct alist lst;
112 ulong start;
113 void *ptr;
114
115 start = ut_check_free();
116
117 ut_assert(alist_init(&lst, obj_size, 3));
118
119 ut_assert(!alist_has(&lst, 0));
120 ut_assert(!alist_has(&lst, 1));
121 ut_assert(!alist_has(&lst, 2));
122 ut_assert(!alist_has(&lst, 3));
123
124 /* create a new one to force expansion */
125 ptr = alist_ensure_ptr(&lst, 4);
126 ut_assertnonnull(ptr);
127
128 ut_assert(alist_has(&lst, 0));
129 ut_assert(alist_has(&lst, 1));
130 ut_assert(alist_has(&lst, 2));
131 ut_assert(alist_has(&lst, 3));
132 ut_assert(alist_has(&lst, 4));
133 ut_assert(!alist_has(&lst, 5));
134
135 alist_uninit(&lst);
136
137 /* Check for memory leaks */
138 ut_assertok(ut_check_delta(start));
139
140 return 0;
141}
142LIB_TEST(lib_test_alist_has, 0);
143
144/* Test alist_ensure() */
145static int lib_test_alist_ensure(struct unit_test_state *uts)
146{
147 struct my_struct *ptr3, *ptr4;
148 struct alist lst;
149 ulong start;
150
151 start = ut_check_free();
152
153 ut_assert(alist_init_struct(&lst, struct my_struct));
154 ut_asserteq(obj_size, lst.obj_size);
155 ut_asserteq(0, lst.count);
156 ut_asserteq(0, lst.alloc);
157 ptr3 = alist_ensure_ptr(&lst, 3);
158 ut_asserteq(4, lst.count);
159 ut_asserteq(4, lst.alloc);
160 ut_assertnonnull(ptr3);
161 ptr3->val = 3;
162
163 ptr4 = alist_ensure_ptr(&lst, 4);
164 ut_asserteq(8, lst.alloc);
165 ut_asserteq(5, lst.count);
166 ut_assertnonnull(ptr4);
167 ptr4->val = 4;
168 ut_asserteq(4, alist_get(&lst, 4, struct my_struct)->val);
169
170 ut_asserteq_ptr(ptr4, alist_ensure(&lst, 4, struct my_struct));
171
172 alist_ensure(&lst, 4, struct my_struct)->val = 44;
173 ut_asserteq(44, alist_get(&lst, 4, struct my_struct)->val);
174 ut_asserteq(3, alist_get(&lst, 3, struct my_struct)->val);
175 ut_assertnull(alist_get(&lst, 7, struct my_struct));
176 ut_asserteq(8, lst.alloc);
177 ut_asserteq(5, lst.count);
178
179 /* add some more, checking handling of malloc() failure */
180 malloc_enable_testing(0);
181 ut_assertnonnull(alist_ensure(&lst, 7, struct my_struct));
182 ut_assertnull(alist_ensure(&lst, 8, struct my_struct));
183 malloc_disable_testing();
184
185 lst.flags &= ~ALISTF_FAIL;
186 ut_assertnonnull(alist_ensure(&lst, 8, struct my_struct));
187 ut_asserteq(16, lst.alloc);
188 ut_asserteq(9, lst.count);
189
190 alist_uninit(&lst);
191
192 /* Check for memory leaks */
193 ut_assertok(ut_check_delta(start));
194
195 return 0;
196}
197LIB_TEST(lib_test_alist_ensure, 0);
198
199/* Test alist_add() bits not tested by lib_test_alist_ensure() */
200static int lib_test_alist_add(struct unit_test_state *uts)
201{
202 struct my_struct data, *ptr, *ptr2;
203 const struct my_struct *chk;
204 struct alist lst;
205 ulong start;
206
207 start = ut_check_free();
208
209 ut_assert(alist_init_struct(&lst, struct my_struct));
210
211 data.val = 123;
212 data.other_val = 456;
213 ptr = alist_add(&lst, data);
214 ut_assertnonnull(ptr);
215 ut_asserteq(4, lst.alloc);
216 ut_asserteq(1, lst.count);
217
218 ut_asserteq(123, ptr->val);
219 ut_asserteq(456, ptr->other_val);
220
221 ptr2 = alist_add_placeholder(&lst);
222 ut_assertnonnull(ptr2);
223
224 ptr2->val = 321;
225 ptr2->other_val = 654;
226
227 chk = alist_get(&lst, 1, struct my_struct);
228 ut_asserteq(321, chk->val);
229 ut_asserteq(654, chk->other_val);
230
231 ptr2 = alist_getw(&lst, 1, struct my_struct);
232 ut_asserteq(321, ptr2->val);
233 ut_asserteq(654, ptr2->other_val);
234
235 alist_uninit(&lst);
236
237 /* Check for memory leaks */
238 ut_assertok(ut_check_delta(start));
239
240 return 0;
241}
242LIB_TEST(lib_test_alist_add, 0);
Simon Glass805c19b2024-10-19 09:21:44 -0600243
244/* Test alist_next() */
245static int lib_test_alist_next(struct unit_test_state *uts)
246{
247 const struct my_struct *ptr;
248 struct my_struct data, *ptr2;
249 struct alist lst;
250 ulong start;
251
252 start = ut_check_free();
253
254 ut_assert(alist_init_struct(&lst, struct my_struct));
255 data.val = 123;
256 data.other_val = 0;
257 alist_add(&lst, data);
258
259 data.val = 321;
260 alist_add(&lst, data);
261
262 data.val = 789;
263 alist_add(&lst, data);
264
265 ptr = alist_get(&lst, 0, struct my_struct);
266 ut_assertnonnull(ptr);
267 ut_asserteq(123, ptr->val);
268
269 ptr = alist_next(&lst, ptr);
270 ut_assertnonnull(ptr);
271 ut_asserteq(321, ptr->val);
272
273 ptr2 = (struct my_struct *)ptr;
274 ptr2 = alist_nextw(&lst, ptr2);
275 ut_assertnonnull(ptr2);
276
277 ptr = alist_next(&lst, ptr);
278 ut_assertnonnull(ptr);
279 ut_asserteq(789, ptr->val);
280 ut_asserteq_ptr(ptr, ptr2);
281 ptr2->val = 89;
282 ut_asserteq(89, ptr->val);
283
284 ptr = alist_next(&lst, ptr);
285 ut_assertnull(ptr);
286
287 alist_uninit(&lst);
288
289 /* Check for memory leaks */
290 ut_assertok(ut_check_delta(start));
291
292 return 0;
293}
294LIB_TEST(lib_test_alist_next, 0);
Simon Glass8fbacd52024-10-19 09:21:45 -0600295
296/* Test alist_for_each() */
297static int lib_test_alist_for_each(struct unit_test_state *uts)
298{
299 const struct my_struct *ptr;
300 struct my_struct data, *ptr2;
301 struct alist lst;
302 ulong start;
303 int sum;
304
305 start = ut_check_free();
306
307 ut_assert(alist_init_struct(&lst, struct my_struct));
308 ut_asserteq_ptr(NULL, alist_end(&lst, struct my_struct));
309
310 sum = 0;
311 alist_for_each(ptr, &lst)
312 sum++;
313 ut_asserteq(0, sum);
314
315 alist_for_each(ptr, &lst)
316 sum++;
317 ut_asserteq(0, sum);
318
319 /* add three items */
320 data.val = 1;
321 data.other_val = 0;
322 alist_add(&lst, data);
323
324 ptr = lst.data;
325 ut_asserteq_ptr(ptr + 1, alist_end(&lst, struct my_struct));
326
327 data.val = 2;
328 alist_add(&lst, data);
329 ut_asserteq_ptr(ptr + 2, alist_end(&lst, struct my_struct));
330
331 data.val = 3;
332 alist_add(&lst, data);
333 ut_asserteq_ptr(ptr + 3, alist_end(&lst, struct my_struct));
334
335 /* check alist_chk_ptr() */
336 ut_asserteq(true, alist_chk_ptr(&lst, ptr + 2));
337 ut_asserteq(false, alist_chk_ptr(&lst, ptr + 3));
338 ut_asserteq(false, alist_chk_ptr(&lst, ptr + 4));
339 ut_asserteq(true, alist_chk_ptr(&lst, ptr));
340 ut_asserteq(false, alist_chk_ptr(&lst, ptr - 1));
341
342 /* sum all items */
343 sum = 0;
344 alist_for_each(ptr, &lst)
345 sum += ptr->val;
346 ut_asserteq(6, sum);
347
348 /* increment all items */
349 alist_for_each(ptr2, &lst)
350 ptr2->val += 1;
351
352 /* sum all items again */
353 sum = 0;
354 alist_for_each(ptr, &lst)
355 sum += ptr->val;
356 ut_asserteq(9, sum);
357
358 ptr = lst.data;
359 ut_asserteq_ptr(ptr + 3, alist_end(&lst, struct my_struct));
360
361 alist_uninit(&lst);
362
363 /* Check for memory leaks */
364 ut_assertok(ut_check_delta(start));
365
366 return 0;
367}
368LIB_TEST(lib_test_alist_for_each, 0);