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