blob: 42803b20e2a1e4c5293588afd12ec441ce61e72e [file] [log] [blame]
Simon Glass67bc59d2021-09-25 07:03:07 -06001// 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
14static char test_data[] = "1234";
15#define TEST_DATA_LEN sizeof(test_data)
16
17/* Test abuf_set() */
18static 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}
48LIB_TEST(lib_test_abuf_set, 0);
49
50/* Test abuf_map_sysmem() */
51static 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}
66LIB_TEST(lib_test_abuf_map_sysmem, 0);
67
68/* Test abuf_realloc() */
69static 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}
127LIB_TEST(lib_test_abuf_realloc, 0);
128
Simon Glass99aca9e2022-02-28 12:08:22 -0700129/* Test abuf_realloc() on an non-allocated buffer of zero size */
130static 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}
156LIB_TEST(lib_test_abuf_realloc_size, 0);
157
Simon Glass34ecba12023-08-14 16:40:22 -0600158/* Test abuf_realloc_inc() */
159static int lib_test_abuf_realloc_inc(struct unit_test_state *uts)
160{
161 struct abuf buf;
162 ulong start;
163
164 start = ut_check_free();
165
166 abuf_init(&buf);
167 ut_asserteq(0, buf.size);
168 ut_asserteq(false, buf.alloced);
169
170 abuf_realloc_inc(&buf, 20);
171 ut_asserteq(20, buf.size);
172 ut_asserteq(true, buf.alloced);
173
174 abuf_uninit(&buf);
175
176 /* Check for memory leaks */
177 ut_assertok(ut_check_delta(start));
178
179 return 0;
180}
181LIB_TEST(lib_test_abuf_realloc_inc, 0);
182
Simon Glass67bc59d2021-09-25 07:03:07 -0600183/* Test handling of buffers that are too large */
184static int lib_test_abuf_large(struct unit_test_state *uts)
185{
186 struct abuf buf;
187 ulong start;
188 size_t size;
189 int delta;
190 void *ptr;
191
192 /*
193 * This crashes at present due to trying to allocate more memory than
194 * available, which breaks something on sandbox.
195 */
196 return 0;
197
198 start = ut_check_free();
199
200 /* Try an impossible size */
201 abuf_init(&buf);
202 ut_asserteq(false, abuf_realloc(&buf, CONFIG_SYS_MALLOC_LEN));
203 ut_assertnull(buf.data);
204 ut_asserteq(0, buf.size);
205 ut_asserteq(false, buf.alloced);
206
207 abuf_uninit(&buf);
208 ut_assertnull(buf.data);
209 ut_asserteq(0, buf.size);
210 ut_asserteq(false, buf.alloced);
211
212 /* Start with a normal size then try to increase it, to check realloc */
213 ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
214 ut_assertnonnull(buf.data);
215 ut_asserteq(TEST_DATA_LEN, buf.size);
216 ut_asserteq(true, buf.alloced);
217 ptr = buf.data;
218 delta = ut_check_delta(start);
219 ut_assert(delta > 0);
220
221 /* try to increase it */
222 ut_asserteq(false, abuf_realloc(&buf, CONFIG_SYS_MALLOC_LEN));
223 ut_asserteq_ptr(ptr, buf.data);
224 ut_asserteq(TEST_DATA_LEN, buf.size);
225 ut_asserteq(true, buf.alloced);
226 ut_asserteq(delta, ut_check_delta(start));
227
228 /* Check for memory leaks */
229 abuf_uninit(&buf);
230 ut_assertok(ut_check_delta(start));
231
232 /* Start with a huge unallocated buf and try to move it */
233 abuf_init(&buf);
234 abuf_map_sysmem(&buf, 0, CONFIG_SYS_MALLOC_LEN);
235 ut_asserteq(CONFIG_SYS_MALLOC_LEN, buf.size);
236 ut_asserteq(false, buf.alloced);
237 ut_assertnull(abuf_uninit_move(&buf, &size));
238
239 /* Check for memory leaks */
240 abuf_uninit(&buf);
241 ut_assertok(ut_check_delta(start));
242
243 return 0;
244}
245LIB_TEST(lib_test_abuf_large, 0);
246
247/* Test abuf_uninit_move() */
248static int lib_test_abuf_uninit_move(struct unit_test_state *uts)
249{
250 void *ptr, *orig_ptr;
251 struct abuf buf;
252 size_t size;
253 ulong start;
254 int delta;
255
256 start = ut_check_free();
257
258 /*
259 * TODO: crashes on sandbox sometimes due to an apparent bug in
260 * realloc().
261 */
262 return 0;
263
264 /* Move an empty buffer */
265 abuf_init(&buf);
266 ut_assertnull(abuf_uninit_move(&buf, &size));
267 ut_asserteq(0, size);
268 ut_assertnull(abuf_uninit_move(&buf, NULL));
269
270 /* Move an unallocated buffer */
271 abuf_set(&buf, test_data, TEST_DATA_LEN);
272 ut_assertok(ut_check_delta(start));
273 ptr = abuf_uninit_move(&buf, &size);
274 ut_asserteq(TEST_DATA_LEN, size);
275 ut_asserteq_str(ptr, test_data);
276 ut_assertnonnull(ptr);
277 ut_assertnull(buf.data);
278 ut_asserteq(0, buf.size);
279 ut_asserteq(false, buf.alloced);
280
281 /* Check that freeing it frees the only allocation */
282 delta = ut_check_delta(start);
283 ut_assert(delta > 0);
284 free(ptr);
285 ut_assertok(ut_check_delta(start));
286
287 /* Move an allocated buffer */
288 ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
289 orig_ptr = buf.data;
290 strcpy(orig_ptr, test_data);
291
292 delta = ut_check_delta(start);
293 ut_assert(delta > 0);
294 ptr = abuf_uninit_move(&buf, &size);
295 ut_asserteq(TEST_DATA_LEN, size);
296 ut_assertnonnull(ptr);
297 ut_asserteq_ptr(ptr, orig_ptr);
298 ut_asserteq_str(ptr, test_data);
299 ut_assertnull(buf.data);
300 ut_asserteq(0, buf.size);
301 ut_asserteq(false, buf.alloced);
302
303 /* Check there was no new allocation */
304 ut_asserteq(delta, ut_check_delta(start));
305
306 /* Check that freeing it frees the only allocation */
307 free(ptr);
308 ut_assertok(ut_check_delta(start));
309
310 /* Move an unallocated buffer, without the size */
311 abuf_set(&buf, test_data, TEST_DATA_LEN);
312 ut_assertok(ut_check_delta(start));
313 ptr = abuf_uninit_move(&buf, NULL);
314 ut_asserteq_str(ptr, test_data);
315
316 return 0;
317}
318LIB_TEST(lib_test_abuf_uninit_move, 0);
319
320/* Test abuf_uninit() */
321static int lib_test_abuf_uninit(struct unit_test_state *uts)
322{
323 struct abuf buf;
324
325 /* Nothing in the buffer */
326 abuf_init(&buf);
327 abuf_uninit(&buf);
328 ut_assertnull(buf.data);
329 ut_asserteq(0, buf.size);
330 ut_asserteq(false, buf.alloced);
331
332 /* Not allocated */
333 abuf_set(&buf, test_data, TEST_DATA_LEN);
334 abuf_uninit(&buf);
335 ut_assertnull(buf.data);
336 ut_asserteq(0, buf.size);
337 ut_asserteq(false, buf.alloced);
338
339 return 0;
340}
341LIB_TEST(lib_test_abuf_uninit, 0);
342
343/* Test abuf_init_set() */
344static int lib_test_abuf_init_set(struct unit_test_state *uts)
345{
346 struct abuf buf;
347
348 abuf_init_set(&buf, test_data, TEST_DATA_LEN);
349 ut_asserteq_ptr(test_data, buf.data);
350 ut_asserteq(TEST_DATA_LEN, buf.size);
351 ut_asserteq(false, buf.alloced);
352
353 return 0;
354}
355LIB_TEST(lib_test_abuf_init_set, 0);
356
357/* Test abuf_init_move() */
358static int lib_test_abuf_init_move(struct unit_test_state *uts)
359{
360 struct abuf buf;
361 void *ptr;
362
363 /*
364 * TODO: crashes on sandbox sometimes due to an apparent bug in
365 * realloc().
366 */
367 return 0;
368
369 ptr = strdup(test_data);
370 ut_assertnonnull(ptr);
371
372 free(ptr);
373
374 abuf_init_move(&buf, ptr, TEST_DATA_LEN);
375 ut_asserteq_ptr(ptr, abuf_data(&buf));
376 ut_asserteq(TEST_DATA_LEN, abuf_size(&buf));
377 ut_asserteq(true, buf.alloced);
378
379 return 0;
380}
381LIB_TEST(lib_test_abuf_init_move, 0);
382
383/* Test abuf_init() */
384static int lib_test_abuf_init(struct unit_test_state *uts)
385{
386 struct abuf buf;
387
388 buf.data = &buf;
389 buf.size = 123;
390 buf.alloced = true;
391 abuf_init(&buf);
392 ut_assertnull(buf.data);
393 ut_asserteq(0, buf.size);
394 ut_asserteq(false, buf.alloced);
395
396 return 0;
397}
398LIB_TEST(lib_test_abuf_init, 0);