blob: 086c9b22821c5f3800b6c086bb2468282a000151 [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
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
129/* Test handling of buffers that are too large */
130static int lib_test_abuf_large(struct unit_test_state *uts)
131{
132 struct abuf buf;
133 ulong start;
134 size_t size;
135 int delta;
136 void *ptr;
137
138 /*
139 * This crashes at present due to trying to allocate more memory than
140 * available, which breaks something on sandbox.
141 */
142 return 0;
143
144 start = ut_check_free();
145
146 /* Try an impossible size */
147 abuf_init(&buf);
148 ut_asserteq(false, abuf_realloc(&buf, CONFIG_SYS_MALLOC_LEN));
149 ut_assertnull(buf.data);
150 ut_asserteq(0, buf.size);
151 ut_asserteq(false, buf.alloced);
152
153 abuf_uninit(&buf);
154 ut_assertnull(buf.data);
155 ut_asserteq(0, buf.size);
156 ut_asserteq(false, buf.alloced);
157
158 /* Start with a normal size then try to increase it, to check realloc */
159 ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
160 ut_assertnonnull(buf.data);
161 ut_asserteq(TEST_DATA_LEN, buf.size);
162 ut_asserteq(true, buf.alloced);
163 ptr = buf.data;
164 delta = ut_check_delta(start);
165 ut_assert(delta > 0);
166
167 /* try to increase it */
168 ut_asserteq(false, abuf_realloc(&buf, CONFIG_SYS_MALLOC_LEN));
169 ut_asserteq_ptr(ptr, buf.data);
170 ut_asserteq(TEST_DATA_LEN, buf.size);
171 ut_asserteq(true, buf.alloced);
172 ut_asserteq(delta, ut_check_delta(start));
173
174 /* Check for memory leaks */
175 abuf_uninit(&buf);
176 ut_assertok(ut_check_delta(start));
177
178 /* Start with a huge unallocated buf and try to move it */
179 abuf_init(&buf);
180 abuf_map_sysmem(&buf, 0, CONFIG_SYS_MALLOC_LEN);
181 ut_asserteq(CONFIG_SYS_MALLOC_LEN, buf.size);
182 ut_asserteq(false, buf.alloced);
183 ut_assertnull(abuf_uninit_move(&buf, &size));
184
185 /* Check for memory leaks */
186 abuf_uninit(&buf);
187 ut_assertok(ut_check_delta(start));
188
189 return 0;
190}
191LIB_TEST(lib_test_abuf_large, 0);
192
193/* Test abuf_uninit_move() */
194static int lib_test_abuf_uninit_move(struct unit_test_state *uts)
195{
196 void *ptr, *orig_ptr;
197 struct abuf buf;
198 size_t size;
199 ulong start;
200 int delta;
201
202 start = ut_check_free();
203
204 /*
205 * TODO: crashes on sandbox sometimes due to an apparent bug in
206 * realloc().
207 */
208 return 0;
209
210 /* Move an empty buffer */
211 abuf_init(&buf);
212 ut_assertnull(abuf_uninit_move(&buf, &size));
213 ut_asserteq(0, size);
214 ut_assertnull(abuf_uninit_move(&buf, NULL));
215
216 /* Move an unallocated buffer */
217 abuf_set(&buf, test_data, TEST_DATA_LEN);
218 ut_assertok(ut_check_delta(start));
219 ptr = abuf_uninit_move(&buf, &size);
220 ut_asserteq(TEST_DATA_LEN, size);
221 ut_asserteq_str(ptr, test_data);
222 ut_assertnonnull(ptr);
223 ut_assertnull(buf.data);
224 ut_asserteq(0, buf.size);
225 ut_asserteq(false, buf.alloced);
226
227 /* Check that freeing it frees the only allocation */
228 delta = ut_check_delta(start);
229 ut_assert(delta > 0);
230 free(ptr);
231 ut_assertok(ut_check_delta(start));
232
233 /* Move an allocated buffer */
234 ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
235 orig_ptr = buf.data;
236 strcpy(orig_ptr, test_data);
237
238 delta = ut_check_delta(start);
239 ut_assert(delta > 0);
240 ptr = abuf_uninit_move(&buf, &size);
241 ut_asserteq(TEST_DATA_LEN, size);
242 ut_assertnonnull(ptr);
243 ut_asserteq_ptr(ptr, orig_ptr);
244 ut_asserteq_str(ptr, test_data);
245 ut_assertnull(buf.data);
246 ut_asserteq(0, buf.size);
247 ut_asserteq(false, buf.alloced);
248
249 /* Check there was no new allocation */
250 ut_asserteq(delta, ut_check_delta(start));
251
252 /* Check that freeing it frees the only allocation */
253 free(ptr);
254 ut_assertok(ut_check_delta(start));
255
256 /* Move an unallocated buffer, without the size */
257 abuf_set(&buf, test_data, TEST_DATA_LEN);
258 ut_assertok(ut_check_delta(start));
259 ptr = abuf_uninit_move(&buf, NULL);
260 ut_asserteq_str(ptr, test_data);
261
262 return 0;
263}
264LIB_TEST(lib_test_abuf_uninit_move, 0);
265
266/* Test abuf_uninit() */
267static int lib_test_abuf_uninit(struct unit_test_state *uts)
268{
269 struct abuf buf;
270
271 /* Nothing in the buffer */
272 abuf_init(&buf);
273 abuf_uninit(&buf);
274 ut_assertnull(buf.data);
275 ut_asserteq(0, buf.size);
276 ut_asserteq(false, buf.alloced);
277
278 /* Not allocated */
279 abuf_set(&buf, test_data, TEST_DATA_LEN);
280 abuf_uninit(&buf);
281 ut_assertnull(buf.data);
282 ut_asserteq(0, buf.size);
283 ut_asserteq(false, buf.alloced);
284
285 return 0;
286}
287LIB_TEST(lib_test_abuf_uninit, 0);
288
289/* Test abuf_init_set() */
290static int lib_test_abuf_init_set(struct unit_test_state *uts)
291{
292 struct abuf buf;
293
294 abuf_init_set(&buf, test_data, TEST_DATA_LEN);
295 ut_asserteq_ptr(test_data, buf.data);
296 ut_asserteq(TEST_DATA_LEN, buf.size);
297 ut_asserteq(false, buf.alloced);
298
299 return 0;
300}
301LIB_TEST(lib_test_abuf_init_set, 0);
302
303/* Test abuf_init_move() */
304static int lib_test_abuf_init_move(struct unit_test_state *uts)
305{
306 struct abuf buf;
307 void *ptr;
308
309 /*
310 * TODO: crashes on sandbox sometimes due to an apparent bug in
311 * realloc().
312 */
313 return 0;
314
315 ptr = strdup(test_data);
316 ut_assertnonnull(ptr);
317
318 free(ptr);
319
320 abuf_init_move(&buf, ptr, TEST_DATA_LEN);
321 ut_asserteq_ptr(ptr, abuf_data(&buf));
322 ut_asserteq(TEST_DATA_LEN, abuf_size(&buf));
323 ut_asserteq(true, buf.alloced);
324
325 return 0;
326}
327LIB_TEST(lib_test_abuf_init_move, 0);
328
329/* Test abuf_init() */
330static int lib_test_abuf_init(struct unit_test_state *uts)
331{
332 struct abuf buf;
333
334 buf.data = &buf;
335 buf.size = 123;
336 buf.alloced = true;
337 abuf_init(&buf);
338 ut_assertnull(buf.data);
339 ut_asserteq(0, buf.size);
340 ut_asserteq(false, buf.alloced);
341
342 return 0;
343}
344LIB_TEST(lib_test_abuf_init, 0);