Convert CONFIG_SYS_MAX_FLASH_SECT to Kconfig
[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 abuf_realloc() on an non-allocated buffer of zero size */
130 static int lib_test_abuf_realloc_size(struct unit_test_state *uts)
131 {
132         struct abuf buf;
133         ulong start;
134
135         start = ut_check_free();
136
137         abuf_init(&buf);
138
139         /* Allocate some space */
140         ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
141         ut_assertnonnull(buf.data);
142         ut_asserteq(TEST_DATA_LEN, buf.size);
143         ut_asserteq(true, buf.alloced);
144
145         /* Free it */
146         ut_asserteq(true, abuf_realloc(&buf, 0));
147         ut_assertnull(buf.data);
148         ut_asserteq(0, buf.size);
149         ut_asserteq(false, buf.alloced);
150
151         /* Check for memory leaks */
152         ut_assertok(ut_check_delta(start));
153
154         return 0;
155 }
156 LIB_TEST(lib_test_abuf_realloc_size, 0);
157
158 /* Test handling of buffers that are too large */
159 static int lib_test_abuf_large(struct unit_test_state *uts)
160 {
161         struct abuf buf;
162         ulong start;
163         size_t size;
164         int delta;
165         void *ptr;
166
167         /*
168          * This crashes at present due to trying to allocate more memory than
169          * available, which breaks something on sandbox.
170          */
171         return 0;
172
173         start = ut_check_free();
174
175         /* Try an impossible size */
176         abuf_init(&buf);
177         ut_asserteq(false, abuf_realloc(&buf, CONFIG_SYS_MALLOC_LEN));
178         ut_assertnull(buf.data);
179         ut_asserteq(0, buf.size);
180         ut_asserteq(false, buf.alloced);
181
182         abuf_uninit(&buf);
183         ut_assertnull(buf.data);
184         ut_asserteq(0, buf.size);
185         ut_asserteq(false, buf.alloced);
186
187         /* Start with a normal size then try to increase it, to check realloc */
188         ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
189         ut_assertnonnull(buf.data);
190         ut_asserteq(TEST_DATA_LEN, buf.size);
191         ut_asserteq(true, buf.alloced);
192         ptr = buf.data;
193         delta = ut_check_delta(start);
194         ut_assert(delta > 0);
195
196         /* try to increase it */
197         ut_asserteq(false, abuf_realloc(&buf, CONFIG_SYS_MALLOC_LEN));
198         ut_asserteq_ptr(ptr, buf.data);
199         ut_asserteq(TEST_DATA_LEN, buf.size);
200         ut_asserteq(true, buf.alloced);
201         ut_asserteq(delta, ut_check_delta(start));
202
203         /* Check for memory leaks */
204         abuf_uninit(&buf);
205         ut_assertok(ut_check_delta(start));
206
207         /* Start with a huge unallocated buf and try to move it */
208         abuf_init(&buf);
209         abuf_map_sysmem(&buf, 0, CONFIG_SYS_MALLOC_LEN);
210         ut_asserteq(CONFIG_SYS_MALLOC_LEN, buf.size);
211         ut_asserteq(false, buf.alloced);
212         ut_assertnull(abuf_uninit_move(&buf, &size));
213
214         /* Check for memory leaks */
215         abuf_uninit(&buf);
216         ut_assertok(ut_check_delta(start));
217
218         return 0;
219 }
220 LIB_TEST(lib_test_abuf_large, 0);
221
222 /* Test abuf_uninit_move() */
223 static int lib_test_abuf_uninit_move(struct unit_test_state *uts)
224 {
225         void *ptr, *orig_ptr;
226         struct abuf buf;
227         size_t size;
228         ulong start;
229         int delta;
230
231         start = ut_check_free();
232
233         /*
234          * TODO: crashes on sandbox sometimes due to an apparent bug in
235          * realloc().
236          */
237         return 0;
238
239         /* Move an empty buffer */
240         abuf_init(&buf);
241         ut_assertnull(abuf_uninit_move(&buf, &size));
242         ut_asserteq(0, size);
243         ut_assertnull(abuf_uninit_move(&buf, NULL));
244
245         /* Move an unallocated buffer */
246         abuf_set(&buf, test_data, TEST_DATA_LEN);
247         ut_assertok(ut_check_delta(start));
248         ptr = abuf_uninit_move(&buf, &size);
249         ut_asserteq(TEST_DATA_LEN, size);
250         ut_asserteq_str(ptr, test_data);
251         ut_assertnonnull(ptr);
252         ut_assertnull(buf.data);
253         ut_asserteq(0, buf.size);
254         ut_asserteq(false, buf.alloced);
255
256         /* Check that freeing it frees the only allocation */
257         delta = ut_check_delta(start);
258         ut_assert(delta > 0);
259         free(ptr);
260         ut_assertok(ut_check_delta(start));
261
262         /* Move an allocated buffer */
263         ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
264         orig_ptr = buf.data;
265         strcpy(orig_ptr, test_data);
266
267         delta = ut_check_delta(start);
268         ut_assert(delta > 0);
269         ptr = abuf_uninit_move(&buf, &size);
270         ut_asserteq(TEST_DATA_LEN, size);
271         ut_assertnonnull(ptr);
272         ut_asserteq_ptr(ptr, orig_ptr);
273         ut_asserteq_str(ptr, test_data);
274         ut_assertnull(buf.data);
275         ut_asserteq(0, buf.size);
276         ut_asserteq(false, buf.alloced);
277
278         /* Check there was no new allocation */
279         ut_asserteq(delta, ut_check_delta(start));
280
281         /* Check that freeing it frees the only allocation */
282         free(ptr);
283         ut_assertok(ut_check_delta(start));
284
285         /* Move an unallocated buffer, without the size */
286         abuf_set(&buf, test_data, TEST_DATA_LEN);
287         ut_assertok(ut_check_delta(start));
288         ptr = abuf_uninit_move(&buf, NULL);
289         ut_asserteq_str(ptr, test_data);
290
291         return 0;
292 }
293 LIB_TEST(lib_test_abuf_uninit_move, 0);
294
295 /* Test abuf_uninit() */
296 static int lib_test_abuf_uninit(struct unit_test_state *uts)
297 {
298         struct abuf buf;
299
300         /* Nothing in the buffer */
301         abuf_init(&buf);
302         abuf_uninit(&buf);
303         ut_assertnull(buf.data);
304         ut_asserteq(0, buf.size);
305         ut_asserteq(false, buf.alloced);
306
307         /* Not allocated */
308         abuf_set(&buf, test_data, TEST_DATA_LEN);
309         abuf_uninit(&buf);
310         ut_assertnull(buf.data);
311         ut_asserteq(0, buf.size);
312         ut_asserteq(false, buf.alloced);
313
314         return 0;
315 }
316 LIB_TEST(lib_test_abuf_uninit, 0);
317
318 /* Test abuf_init_set() */
319 static int lib_test_abuf_init_set(struct unit_test_state *uts)
320 {
321         struct abuf buf;
322
323         abuf_init_set(&buf, test_data, TEST_DATA_LEN);
324         ut_asserteq_ptr(test_data, buf.data);
325         ut_asserteq(TEST_DATA_LEN, buf.size);
326         ut_asserteq(false, buf.alloced);
327
328         return 0;
329 }
330 LIB_TEST(lib_test_abuf_init_set, 0);
331
332 /* Test abuf_init_move() */
333 static int lib_test_abuf_init_move(struct unit_test_state *uts)
334 {
335         struct abuf buf;
336         void *ptr;
337
338         /*
339          * TODO: crashes on sandbox sometimes due to an apparent bug in
340          * realloc().
341          */
342         return 0;
343
344         ptr = strdup(test_data);
345         ut_assertnonnull(ptr);
346
347         free(ptr);
348
349         abuf_init_move(&buf, ptr, TEST_DATA_LEN);
350         ut_asserteq_ptr(ptr, abuf_data(&buf));
351         ut_asserteq(TEST_DATA_LEN, abuf_size(&buf));
352         ut_asserteq(true, buf.alloced);
353
354         return 0;
355 }
356 LIB_TEST(lib_test_abuf_init_move, 0);
357
358 /* Test abuf_init() */
359 static int lib_test_abuf_init(struct unit_test_state *uts)
360 {
361         struct abuf buf;
362
363         buf.data = &buf;
364         buf.size = 123;
365         buf.alloced = true;
366         abuf_init(&buf);
367         ut_assertnull(buf.data);
368         ut_asserteq(0, buf.size);
369         ut_asserteq(false, buf.alloced);
370
371         return 0;
372 }
373 LIB_TEST(lib_test_abuf_init, 0);