blob: b38690fe1a994ea5de75c6772d0afcc8e580c53b [file] [log] [blame]
Simon Glass143fa862021-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
Simon Glass143fa862021-09-25 07:03:07 -06007#include <abuf.h>
8#include <mapmem.h>
9#include <test/lib.h>
10#include <test/test.h>
11#include <test/ut.h>
12
13static char test_data[] = "1234";
14#define TEST_DATA_LEN sizeof(test_data)
15
16/* Test abuf_set() */
17static int lib_test_abuf_set(struct unit_test_state *uts)
18{
19 struct abuf buf;
20 ulong start;
21
22 start = ut_check_free();
23
24 abuf_init(&buf);
25 abuf_set(&buf, test_data, TEST_DATA_LEN);
26 ut_asserteq_ptr(test_data, buf.data);
27 ut_asserteq(TEST_DATA_LEN, buf.size);
28 ut_asserteq(false, buf.alloced);
29
30 /* Force it to allocate */
31 ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN + 1));
32 ut_assertnonnull(buf.data);
33 ut_asserteq(TEST_DATA_LEN + 1, buf.size);
34 ut_asserteq(true, buf.alloced);
35
36 /* Now set it again, to force it to free */
37 abuf_set(&buf, test_data, TEST_DATA_LEN);
38 ut_asserteq_ptr(test_data, buf.data);
39 ut_asserteq(TEST_DATA_LEN, buf.size);
40 ut_asserteq(false, buf.alloced);
41
42 /* Check for memory leaks */
43 ut_assertok(ut_check_delta(start));
44
45 return 0;
46}
47LIB_TEST(lib_test_abuf_set, 0);
48
Simon Glasse3a938e2025-01-10 17:00:03 -070049/* Test abuf_init_const() */
50static int lib_test_abuf_init_const(struct unit_test_state *uts)
51{
52 struct abuf buf;
53 ulong start;
54 void *ptr;
55
56 start = ut_check_free();
57
58 ptr = map_sysmem(0x100, 0);
59
60 abuf_init_const(&buf, ptr, 10);
61 ut_asserteq_ptr(ptr, buf.data);
62 ut_asserteq(10, buf.size);
63
64 /* No memory should have been allocated */
65 ut_assertok(ut_check_delta(start));
66
67 return 0;
68}
69LIB_TEST(lib_test_abuf_init_const, 0);
70
Simon Glassb63269b2025-01-10 17:00:01 -070071/* Test abuf_map_sysmem() and abuf_addr() */
Simon Glass143fa862021-09-25 07:03:07 -060072static int lib_test_abuf_map_sysmem(struct unit_test_state *uts)
73{
74 struct abuf buf;
75 ulong addr;
76
77 abuf_init(&buf);
78 addr = 0x100;
79 abuf_map_sysmem(&buf, addr, TEST_DATA_LEN);
80
81 ut_asserteq_ptr(map_sysmem(0x100, 0), buf.data);
82 ut_asserteq(TEST_DATA_LEN, buf.size);
83 ut_asserteq(false, buf.alloced);
84
Simon Glassb63269b2025-01-10 17:00:01 -070085 ut_asserteq(addr, abuf_addr(&buf));
86
Simon Glass143fa862021-09-25 07:03:07 -060087 return 0;
88}
89LIB_TEST(lib_test_abuf_map_sysmem, 0);
90
91/* Test abuf_realloc() */
92static int lib_test_abuf_realloc(struct unit_test_state *uts)
93{
94 struct abuf buf;
95 ulong start;
96 void *ptr;
97
98 /*
99 * TODO: crashes on sandbox sometimes due to an apparent bug in
100 * realloc().
101 */
102 return 0;
103
104 start = ut_check_free();
105
106 abuf_init(&buf);
107
108 /* Allocate an empty buffer */
109 ut_asserteq(true, abuf_realloc(&buf, 0));
110 ut_assertnull(buf.data);
111 ut_asserteq(0, buf.size);
112 ut_asserteq(false, buf.alloced);
113
114 /* Allocate a non-empty abuf */
115 ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
116 ut_assertnonnull(buf.data);
117 ut_asserteq(TEST_DATA_LEN, buf.size);
118 ut_asserteq(true, buf.alloced);
119 ptr = buf.data;
120
121 /*
122 * Make it smaller; the pointer should remain the same. Note this relies
123 * on knowledge of how U-Boot's realloc() works
124 */
125 ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN - 1));
126 ut_asserteq(TEST_DATA_LEN - 1, buf.size);
127 ut_asserteq(true, buf.alloced);
128 ut_asserteq_ptr(ptr, buf.data);
129
130 /*
131 * Make it larger, forcing reallocation. Note this relies on knowledge
132 * of how U-Boot's realloc() works
133 */
134 ut_asserteq(true, abuf_realloc(&buf, 0x1000));
135 ut_assert(buf.data != ptr);
136 ut_asserteq(0x1000, buf.size);
137 ut_asserteq(true, buf.alloced);
138
139 /* Free it */
140 ut_asserteq(true, abuf_realloc(&buf, 0));
141 ut_assertnull(buf.data);
142 ut_asserteq(0, buf.size);
143 ut_asserteq(false, buf.alloced);
144
145 /* Check for memory leaks */
146 ut_assertok(ut_check_delta(start));
147
148 return 0;
149}
150LIB_TEST(lib_test_abuf_realloc, 0);
151
Simon Glass00a05e22022-02-28 12:08:22 -0700152/* Test abuf_realloc() on an non-allocated buffer of zero size */
153static int lib_test_abuf_realloc_size(struct unit_test_state *uts)
154{
155 struct abuf buf;
156 ulong start;
157
158 start = ut_check_free();
159
160 abuf_init(&buf);
161
162 /* Allocate some space */
163 ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
164 ut_assertnonnull(buf.data);
165 ut_asserteq(TEST_DATA_LEN, buf.size);
166 ut_asserteq(true, buf.alloced);
167
168 /* Free it */
169 ut_asserteq(true, abuf_realloc(&buf, 0));
170 ut_assertnull(buf.data);
171 ut_asserteq(0, buf.size);
172 ut_asserteq(false, buf.alloced);
173
174 /* Check for memory leaks */
175 ut_assertok(ut_check_delta(start));
176
177 return 0;
178}
179LIB_TEST(lib_test_abuf_realloc_size, 0);
180
Simon Glass733c2622023-08-14 16:40:22 -0600181/* Test abuf_realloc_inc() */
182static int lib_test_abuf_realloc_inc(struct unit_test_state *uts)
183{
184 struct abuf buf;
185 ulong start;
186
187 start = ut_check_free();
188
189 abuf_init(&buf);
190 ut_asserteq(0, buf.size);
191 ut_asserteq(false, buf.alloced);
192
193 abuf_realloc_inc(&buf, 20);
194 ut_asserteq(20, buf.size);
195 ut_asserteq(true, buf.alloced);
196
197 abuf_uninit(&buf);
198
199 /* Check for memory leaks */
200 ut_assertok(ut_check_delta(start));
201
202 return 0;
203}
204LIB_TEST(lib_test_abuf_realloc_inc, 0);
205
Simon Glass143fa862021-09-25 07:03:07 -0600206/* Test handling of buffers that are too large */
207static int lib_test_abuf_large(struct unit_test_state *uts)
208{
209 struct abuf buf;
210 ulong start;
211 size_t size;
212 int delta;
213 void *ptr;
214
215 /*
216 * This crashes at present due to trying to allocate more memory than
217 * available, which breaks something on sandbox.
218 */
219 return 0;
220
221 start = ut_check_free();
222
223 /* Try an impossible size */
224 abuf_init(&buf);
225 ut_asserteq(false, abuf_realloc(&buf, CONFIG_SYS_MALLOC_LEN));
226 ut_assertnull(buf.data);
227 ut_asserteq(0, buf.size);
228 ut_asserteq(false, buf.alloced);
229
230 abuf_uninit(&buf);
231 ut_assertnull(buf.data);
232 ut_asserteq(0, buf.size);
233 ut_asserteq(false, buf.alloced);
234
235 /* Start with a normal size then try to increase it, to check realloc */
236 ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
237 ut_assertnonnull(buf.data);
238 ut_asserteq(TEST_DATA_LEN, buf.size);
239 ut_asserteq(true, buf.alloced);
240 ptr = buf.data;
241 delta = ut_check_delta(start);
242 ut_assert(delta > 0);
243
244 /* try to increase it */
245 ut_asserteq(false, abuf_realloc(&buf, CONFIG_SYS_MALLOC_LEN));
246 ut_asserteq_ptr(ptr, buf.data);
247 ut_asserteq(TEST_DATA_LEN, buf.size);
248 ut_asserteq(true, buf.alloced);
249 ut_asserteq(delta, ut_check_delta(start));
250
251 /* Check for memory leaks */
252 abuf_uninit(&buf);
253 ut_assertok(ut_check_delta(start));
254
255 /* Start with a huge unallocated buf and try to move it */
256 abuf_init(&buf);
257 abuf_map_sysmem(&buf, 0, CONFIG_SYS_MALLOC_LEN);
258 ut_asserteq(CONFIG_SYS_MALLOC_LEN, buf.size);
259 ut_asserteq(false, buf.alloced);
260 ut_assertnull(abuf_uninit_move(&buf, &size));
261
262 /* Check for memory leaks */
263 abuf_uninit(&buf);
264 ut_assertok(ut_check_delta(start));
265
266 return 0;
267}
268LIB_TEST(lib_test_abuf_large, 0);
269
270/* Test abuf_uninit_move() */
271static int lib_test_abuf_uninit_move(struct unit_test_state *uts)
272{
273 void *ptr, *orig_ptr;
274 struct abuf buf;
275 size_t size;
276 ulong start;
277 int delta;
278
279 start = ut_check_free();
280
281 /*
282 * TODO: crashes on sandbox sometimes due to an apparent bug in
283 * realloc().
284 */
285 return 0;
286
287 /* Move an empty buffer */
288 abuf_init(&buf);
289 ut_assertnull(abuf_uninit_move(&buf, &size));
290 ut_asserteq(0, size);
291 ut_assertnull(abuf_uninit_move(&buf, NULL));
292
293 /* Move an unallocated buffer */
294 abuf_set(&buf, test_data, TEST_DATA_LEN);
295 ut_assertok(ut_check_delta(start));
296 ptr = abuf_uninit_move(&buf, &size);
297 ut_asserteq(TEST_DATA_LEN, size);
298 ut_asserteq_str(ptr, test_data);
299 ut_assertnonnull(ptr);
300 ut_assertnull(buf.data);
301 ut_asserteq(0, buf.size);
302 ut_asserteq(false, buf.alloced);
303
304 /* Check that freeing it frees the only allocation */
305 delta = ut_check_delta(start);
306 ut_assert(delta > 0);
307 free(ptr);
308 ut_assertok(ut_check_delta(start));
309
310 /* Move an allocated buffer */
311 ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
312 orig_ptr = buf.data;
313 strcpy(orig_ptr, test_data);
314
315 delta = ut_check_delta(start);
316 ut_assert(delta > 0);
317 ptr = abuf_uninit_move(&buf, &size);
318 ut_asserteq(TEST_DATA_LEN, size);
319 ut_assertnonnull(ptr);
320 ut_asserteq_ptr(ptr, orig_ptr);
321 ut_asserteq_str(ptr, test_data);
322 ut_assertnull(buf.data);
323 ut_asserteq(0, buf.size);
324 ut_asserteq(false, buf.alloced);
325
326 /* Check there was no new allocation */
327 ut_asserteq(delta, ut_check_delta(start));
328
329 /* Check that freeing it frees the only allocation */
330 free(ptr);
331 ut_assertok(ut_check_delta(start));
332
333 /* Move an unallocated buffer, without the size */
334 abuf_set(&buf, test_data, TEST_DATA_LEN);
335 ut_assertok(ut_check_delta(start));
336 ptr = abuf_uninit_move(&buf, NULL);
337 ut_asserteq_str(ptr, test_data);
338
339 return 0;
340}
341LIB_TEST(lib_test_abuf_uninit_move, 0);
342
343/* Test abuf_uninit() */
344static int lib_test_abuf_uninit(struct unit_test_state *uts)
345{
346 struct abuf buf;
347
348 /* Nothing in the buffer */
349 abuf_init(&buf);
350 abuf_uninit(&buf);
351 ut_assertnull(buf.data);
352 ut_asserteq(0, buf.size);
353 ut_asserteq(false, buf.alloced);
354
355 /* Not allocated */
356 abuf_set(&buf, test_data, TEST_DATA_LEN);
357 abuf_uninit(&buf);
358 ut_assertnull(buf.data);
359 ut_asserteq(0, buf.size);
360 ut_asserteq(false, buf.alloced);
361
362 return 0;
363}
364LIB_TEST(lib_test_abuf_uninit, 0);
365
366/* Test abuf_init_set() */
367static int lib_test_abuf_init_set(struct unit_test_state *uts)
368{
369 struct abuf buf;
370
371 abuf_init_set(&buf, test_data, TEST_DATA_LEN);
372 ut_asserteq_ptr(test_data, buf.data);
373 ut_asserteq(TEST_DATA_LEN, buf.size);
374 ut_asserteq(false, buf.alloced);
375
376 return 0;
377}
378LIB_TEST(lib_test_abuf_init_set, 0);
379
380/* Test abuf_init_move() */
381static int lib_test_abuf_init_move(struct unit_test_state *uts)
382{
383 struct abuf buf;
384 void *ptr;
385
386 /*
387 * TODO: crashes on sandbox sometimes due to an apparent bug in
388 * realloc().
389 */
390 return 0;
391
392 ptr = strdup(test_data);
393 ut_assertnonnull(ptr);
394
395 free(ptr);
396
397 abuf_init_move(&buf, ptr, TEST_DATA_LEN);
398 ut_asserteq_ptr(ptr, abuf_data(&buf));
399 ut_asserteq(TEST_DATA_LEN, abuf_size(&buf));
400 ut_asserteq(true, buf.alloced);
401
402 return 0;
403}
404LIB_TEST(lib_test_abuf_init_move, 0);
405
406/* Test abuf_init() */
407static int lib_test_abuf_init(struct unit_test_state *uts)
408{
409 struct abuf buf;
410
411 buf.data = &buf;
412 buf.size = 123;
413 buf.alloced = true;
414 abuf_init(&buf);
415 ut_assertnull(buf.data);
416 ut_asserteq(0, buf.size);
417 ut_asserteq(false, buf.alloced);
418
419 return 0;
420}
421LIB_TEST(lib_test_abuf_init, 0);