blob: 42ee4c1755268a7179b8e7e832a55807ee7c17da [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 Glass67bc59d2021-09-25 07:03:07 -0600158/* Test handling of buffers that are too large */
159static 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}
220LIB_TEST(lib_test_abuf_large, 0);
221
222/* Test abuf_uninit_move() */
223static 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}
293LIB_TEST(lib_test_abuf_uninit_move, 0);
294
295/* Test abuf_uninit() */
296static 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}
316LIB_TEST(lib_test_abuf_uninit, 0);
317
318/* Test abuf_init_set() */
319static 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}
330LIB_TEST(lib_test_abuf_init_set, 0);
331
332/* Test abuf_init_move() */
333static 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}
356LIB_TEST(lib_test_abuf_init_move, 0);
357
358/* Test abuf_init() */
359static 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}
373LIB_TEST(lib_test_abuf_init, 0);