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