Merge tag 'u-boot-imx-20211020' of https://source.denx.de/u-boot/custodians/u-boot-imx
[platform/kernel/u-boot.git] / test / lib / abuf.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2021 Google LLC
4  * Written by Simon Glass <sjg@chromium.org>
5  */
6
7 #include <common.h>
8 #include <abuf.h>
9 #include <mapmem.h>
10 #include <test/lib.h>
11 #include <test/test.h>
12 #include <test/ut.h>
13
14 static char test_data[] = "1234";
15 #define TEST_DATA_LEN   sizeof(test_data)
16
17 /* Test abuf_set() */
18 static int lib_test_abuf_set(struct unit_test_state *uts)
19 {
20         struct abuf buf;
21         ulong start;
22
23         start = ut_check_free();
24
25         abuf_init(&buf);
26         abuf_set(&buf, test_data, TEST_DATA_LEN);
27         ut_asserteq_ptr(test_data, buf.data);
28         ut_asserteq(TEST_DATA_LEN, buf.size);
29         ut_asserteq(false, buf.alloced);
30
31         /* Force it to allocate */
32         ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN + 1));
33         ut_assertnonnull(buf.data);
34         ut_asserteq(TEST_DATA_LEN + 1, buf.size);
35         ut_asserteq(true, buf.alloced);
36
37         /* Now set it again, to force it to free */
38         abuf_set(&buf, test_data, TEST_DATA_LEN);
39         ut_asserteq_ptr(test_data, buf.data);
40         ut_asserteq(TEST_DATA_LEN, buf.size);
41         ut_asserteq(false, buf.alloced);
42
43         /* Check for memory leaks */
44         ut_assertok(ut_check_delta(start));
45
46         return 0;
47 }
48 LIB_TEST(lib_test_abuf_set, 0);
49
50 /* Test abuf_map_sysmem() */
51 static int lib_test_abuf_map_sysmem(struct unit_test_state *uts)
52 {
53         struct abuf buf;
54         ulong addr;
55
56         abuf_init(&buf);
57         addr = 0x100;
58         abuf_map_sysmem(&buf, addr, TEST_DATA_LEN);
59
60         ut_asserteq_ptr(map_sysmem(0x100, 0), buf.data);
61         ut_asserteq(TEST_DATA_LEN, buf.size);
62         ut_asserteq(false, buf.alloced);
63
64         return 0;
65 }
66 LIB_TEST(lib_test_abuf_map_sysmem, 0);
67
68 /* Test abuf_realloc() */
69 static int lib_test_abuf_realloc(struct unit_test_state *uts)
70 {
71         struct abuf buf;
72         ulong start;
73         void *ptr;
74
75         /*
76          * TODO: crashes on sandbox sometimes due to an apparent bug in
77          * realloc().
78          */
79         return 0;
80
81         start = ut_check_free();
82
83         abuf_init(&buf);
84
85         /* Allocate an empty buffer */
86         ut_asserteq(true, abuf_realloc(&buf, 0));
87         ut_assertnull(buf.data);
88         ut_asserteq(0, buf.size);
89         ut_asserteq(false, buf.alloced);
90
91         /* Allocate a non-empty abuf */
92         ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
93         ut_assertnonnull(buf.data);
94         ut_asserteq(TEST_DATA_LEN, buf.size);
95         ut_asserteq(true, buf.alloced);
96         ptr = buf.data;
97
98         /*
99          * Make it smaller; the pointer should remain the same. Note this relies
100          * on knowledge of how U-Boot's realloc() works
101          */
102         ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN - 1));
103         ut_asserteq(TEST_DATA_LEN - 1, buf.size);
104         ut_asserteq(true, buf.alloced);
105         ut_asserteq_ptr(ptr, buf.data);
106
107         /*
108          * Make it larger, forcing reallocation. Note this relies on knowledge
109          * of how U-Boot's realloc() works
110          */
111         ut_asserteq(true, abuf_realloc(&buf, 0x1000));
112         ut_assert(buf.data != ptr);
113         ut_asserteq(0x1000, buf.size);
114         ut_asserteq(true, buf.alloced);
115
116         /* Free it */
117         ut_asserteq(true, abuf_realloc(&buf, 0));
118         ut_assertnull(buf.data);
119         ut_asserteq(0, buf.size);
120         ut_asserteq(false, buf.alloced);
121
122         /* Check for memory leaks */
123         ut_assertok(ut_check_delta(start));
124
125         return 0;
126 }
127 LIB_TEST(lib_test_abuf_realloc, 0);
128
129 /* Test handling of buffers that are too large */
130 static int lib_test_abuf_large(struct unit_test_state *uts)
131 {
132         struct abuf buf;
133         ulong start;
134         size_t size;
135         int delta;
136         void *ptr;
137
138         /*
139          * This crashes at present due to trying to allocate more memory than
140          * available, which breaks something on sandbox.
141          */
142         return 0;
143
144         start = ut_check_free();
145
146         /* Try an impossible size */
147         abuf_init(&buf);
148         ut_asserteq(false, abuf_realloc(&buf, CONFIG_SYS_MALLOC_LEN));
149         ut_assertnull(buf.data);
150         ut_asserteq(0, buf.size);
151         ut_asserteq(false, buf.alloced);
152
153         abuf_uninit(&buf);
154         ut_assertnull(buf.data);
155         ut_asserteq(0, buf.size);
156         ut_asserteq(false, buf.alloced);
157
158         /* Start with a normal size then try to increase it, to check realloc */
159         ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
160         ut_assertnonnull(buf.data);
161         ut_asserteq(TEST_DATA_LEN, buf.size);
162         ut_asserteq(true, buf.alloced);
163         ptr = buf.data;
164         delta = ut_check_delta(start);
165         ut_assert(delta > 0);
166
167         /* try to increase it */
168         ut_asserteq(false, abuf_realloc(&buf, CONFIG_SYS_MALLOC_LEN));
169         ut_asserteq_ptr(ptr, buf.data);
170         ut_asserteq(TEST_DATA_LEN, buf.size);
171         ut_asserteq(true, buf.alloced);
172         ut_asserteq(delta, ut_check_delta(start));
173
174         /* Check for memory leaks */
175         abuf_uninit(&buf);
176         ut_assertok(ut_check_delta(start));
177
178         /* Start with a huge unallocated buf and try to move it */
179         abuf_init(&buf);
180         abuf_map_sysmem(&buf, 0, CONFIG_SYS_MALLOC_LEN);
181         ut_asserteq(CONFIG_SYS_MALLOC_LEN, buf.size);
182         ut_asserteq(false, buf.alloced);
183         ut_assertnull(abuf_uninit_move(&buf, &size));
184
185         /* Check for memory leaks */
186         abuf_uninit(&buf);
187         ut_assertok(ut_check_delta(start));
188
189         return 0;
190 }
191 LIB_TEST(lib_test_abuf_large, 0);
192
193 /* Test abuf_uninit_move() */
194 static int lib_test_abuf_uninit_move(struct unit_test_state *uts)
195 {
196         void *ptr, *orig_ptr;
197         struct abuf buf;
198         size_t size;
199         ulong start;
200         int delta;
201
202         start = ut_check_free();
203
204         /*
205          * TODO: crashes on sandbox sometimes due to an apparent bug in
206          * realloc().
207          */
208         return 0;
209
210         /* Move an empty buffer */
211         abuf_init(&buf);
212         ut_assertnull(abuf_uninit_move(&buf, &size));
213         ut_asserteq(0, size);
214         ut_assertnull(abuf_uninit_move(&buf, NULL));
215
216         /* Move an unallocated buffer */
217         abuf_set(&buf, test_data, TEST_DATA_LEN);
218         ut_assertok(ut_check_delta(start));
219         ptr = abuf_uninit_move(&buf, &size);
220         ut_asserteq(TEST_DATA_LEN, size);
221         ut_asserteq_str(ptr, test_data);
222         ut_assertnonnull(ptr);
223         ut_assertnull(buf.data);
224         ut_asserteq(0, buf.size);
225         ut_asserteq(false, buf.alloced);
226
227         /* Check that freeing it frees the only allocation */
228         delta = ut_check_delta(start);
229         ut_assert(delta > 0);
230         free(ptr);
231         ut_assertok(ut_check_delta(start));
232
233         /* Move an allocated buffer */
234         ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
235         orig_ptr = buf.data;
236         strcpy(orig_ptr, test_data);
237
238         delta = ut_check_delta(start);
239         ut_assert(delta > 0);
240         ptr = abuf_uninit_move(&buf, &size);
241         ut_asserteq(TEST_DATA_LEN, size);
242         ut_assertnonnull(ptr);
243         ut_asserteq_ptr(ptr, orig_ptr);
244         ut_asserteq_str(ptr, test_data);
245         ut_assertnull(buf.data);
246         ut_asserteq(0, buf.size);
247         ut_asserteq(false, buf.alloced);
248
249         /* Check there was no new allocation */
250         ut_asserteq(delta, ut_check_delta(start));
251
252         /* Check that freeing it frees the only allocation */
253         free(ptr);
254         ut_assertok(ut_check_delta(start));
255
256         /* Move an unallocated buffer, without the size */
257         abuf_set(&buf, test_data, TEST_DATA_LEN);
258         ut_assertok(ut_check_delta(start));
259         ptr = abuf_uninit_move(&buf, NULL);
260         ut_asserteq_str(ptr, test_data);
261
262         return 0;
263 }
264 LIB_TEST(lib_test_abuf_uninit_move, 0);
265
266 /* Test abuf_uninit() */
267 static int lib_test_abuf_uninit(struct unit_test_state *uts)
268 {
269         struct abuf buf;
270
271         /* Nothing in the buffer */
272         abuf_init(&buf);
273         abuf_uninit(&buf);
274         ut_assertnull(buf.data);
275         ut_asserteq(0, buf.size);
276         ut_asserteq(false, buf.alloced);
277
278         /* Not allocated */
279         abuf_set(&buf, test_data, TEST_DATA_LEN);
280         abuf_uninit(&buf);
281         ut_assertnull(buf.data);
282         ut_asserteq(0, buf.size);
283         ut_asserteq(false, buf.alloced);
284
285         return 0;
286 }
287 LIB_TEST(lib_test_abuf_uninit, 0);
288
289 /* Test abuf_init_set() */
290 static int lib_test_abuf_init_set(struct unit_test_state *uts)
291 {
292         struct abuf buf;
293
294         abuf_init_set(&buf, test_data, TEST_DATA_LEN);
295         ut_asserteq_ptr(test_data, buf.data);
296         ut_asserteq(TEST_DATA_LEN, buf.size);
297         ut_asserteq(false, buf.alloced);
298
299         return 0;
300 }
301 LIB_TEST(lib_test_abuf_init_set, 0);
302
303 /* Test abuf_init_move() */
304 static int lib_test_abuf_init_move(struct unit_test_state *uts)
305 {
306         struct abuf buf;
307         void *ptr;
308
309         /*
310          * TODO: crashes on sandbox sometimes due to an apparent bug in
311          * realloc().
312          */
313         return 0;
314
315         ptr = strdup(test_data);
316         ut_assertnonnull(ptr);
317
318         free(ptr);
319
320         abuf_init_move(&buf, ptr, TEST_DATA_LEN);
321         ut_asserteq_ptr(ptr, abuf_data(&buf));
322         ut_asserteq(TEST_DATA_LEN, abuf_size(&buf));
323         ut_asserteq(true, buf.alloced);
324
325         return 0;
326 }
327 LIB_TEST(lib_test_abuf_init_move, 0);
328
329 /* Test abuf_init() */
330 static int lib_test_abuf_init(struct unit_test_state *uts)
331 {
332         struct abuf buf;
333
334         buf.data = &buf;
335         buf.size = 123;
336         buf.alloced = true;
337         abuf_init(&buf);
338         ut_assertnull(buf.data);
339         ut_asserteq(0, buf.size);
340         ut_asserteq(false, buf.alloced);
341
342         return 0;
343 }
344 LIB_TEST(lib_test_abuf_init, 0);