tests/test_buffer.c

changeset 789
9b2f5661bebd
child 792
3ca984931e1d
equal deleted inserted replaced
788:b34ff44e6433 789:9b2f5661bebd
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2023 Mike Becker, Olaf Wintermann All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "cx/test.h"
30 #include "util_allocator.h"
31
32 #include "cx/buffer.h"
33
34 static CX_TEST_SUBROUTINE(expect_default_flush_config, CxBuffer *buf) {
35 CX_TEST_ASSERT(buf->flush_blkmax == 0);
36 CX_TEST_ASSERT(buf->flush_blksize == 4096);
37 CX_TEST_ASSERT(buf->flush_threshold == SIZE_MAX);
38 CX_TEST_ASSERT(buf->flush_func == NULL);
39 CX_TEST_ASSERT(buf->flush_target == NULL);
40 }
41
42 CX_TEST(test_buffer_init_wrap_space) {
43 CxTestingAllocator talloc;
44 cx_testing_allocator_init(&talloc);
45 CxAllocator *alloc = &talloc.base;
46 CX_TEST_DO {
47 CxBuffer buf;
48 void *space = cxMalloc(alloc, 16);
49 cxBufferInit(&buf, space, 16, alloc, CX_BUFFER_DEFAULT);
50 CX_TEST_CALL_SUBROUTINE(expect_default_flush_config, &buf);
51 CX_TEST_ASSERT(buf.space == space);
52 CX_TEST_ASSERT((buf.flags & CX_BUFFER_AUTO_EXTEND) == 0);
53 CX_TEST_ASSERT((buf.flags & CX_BUFFER_FREE_CONTENTS) == 0);
54 CX_TEST_ASSERT(buf.pos == 0);
55 CX_TEST_ASSERT(buf.size == 0);
56 CX_TEST_ASSERT(buf.capacity == 16);
57 CX_TEST_ASSERT(buf.allocator == alloc);
58 cxBufferDestroy(&buf);
59 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
60 cxFree(alloc, space);
61 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
62 }
63 cx_testing_allocator_destroy(&talloc);
64 }
65
66 CX_TEST(test_buffer_init_wrap_space_auto_extend) {
67 CxTestingAllocator talloc;
68 cx_testing_allocator_init(&talloc);
69 CxAllocator *alloc = &talloc.base;
70 CX_TEST_DO {
71 CxBuffer buf;
72 void *space = cxMalloc(alloc, 16);
73 cxBufferInit(&buf, space, 16, alloc, CX_BUFFER_AUTO_EXTEND);
74 CX_TEST_CALL_SUBROUTINE(expect_default_flush_config, &buf);
75 CX_TEST_ASSERT(buf.space == space);
76 CX_TEST_ASSERT((buf.flags & CX_BUFFER_AUTO_EXTEND) == CX_BUFFER_AUTO_EXTEND);
77 CX_TEST_ASSERT((buf.flags & CX_BUFFER_FREE_CONTENTS) == 0);
78 CX_TEST_ASSERT(buf.pos == 0);
79 CX_TEST_ASSERT(buf.size == 0);
80 CX_TEST_ASSERT(buf.capacity == 16);
81 CX_TEST_ASSERT(buf.allocator == alloc);
82 cxBufferDestroy(&buf);
83 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
84 cxFree(alloc, space);
85 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
86 }
87 cx_testing_allocator_destroy(&talloc);
88 }
89
90 CX_TEST(test_buffer_init_wrap_space_auto_free) {
91 CxTestingAllocator talloc;
92 cx_testing_allocator_init(&talloc);
93 CxAllocator *alloc = &talloc.base;
94 CX_TEST_DO {
95 CxBuffer buf;
96 void *space = cxMalloc(alloc, 16);
97 cxBufferInit(&buf, space, 16, alloc, CX_BUFFER_FREE_CONTENTS);
98 CX_TEST_CALL_SUBROUTINE(expect_default_flush_config, &buf);
99 CX_TEST_ASSERT(buf.space == space);
100 CX_TEST_ASSERT((buf.flags & CX_BUFFER_AUTO_EXTEND) == 0);
101 CX_TEST_ASSERT((buf.flags & CX_BUFFER_FREE_CONTENTS) == CX_BUFFER_FREE_CONTENTS);
102 CX_TEST_ASSERT(buf.pos == 0);
103 CX_TEST_ASSERT(buf.size == 0);
104 CX_TEST_ASSERT(buf.capacity == 16);
105 CX_TEST_ASSERT(buf.allocator == alloc);
106 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
107 cxBufferDestroy(&buf);
108 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
109 }
110 cx_testing_allocator_destroy(&talloc);
111 }
112
113 CX_TEST(test_buffer_init_fresh_space) {
114 CxTestingAllocator talloc;
115 cx_testing_allocator_init(&talloc);
116 CxAllocator *alloc = &talloc.base;
117 CX_TEST_DO {
118 CxBuffer buf;
119 cxBufferInit(&buf, NULL, 8, alloc, CX_BUFFER_DEFAULT);
120 CX_TEST_CALL_SUBROUTINE(expect_default_flush_config, &buf);
121 CX_TEST_ASSERT(buf.space != NULL);
122 CX_TEST_ASSERT((buf.flags & CX_BUFFER_AUTO_EXTEND) == 0);
123 CX_TEST_ASSERT((buf.flags & CX_BUFFER_FREE_CONTENTS) == CX_BUFFER_FREE_CONTENTS);
124 CX_TEST_ASSERT(buf.pos == 0);
125 CX_TEST_ASSERT(buf.size == 0);
126 CX_TEST_ASSERT(buf.capacity == 8);
127 CX_TEST_ASSERT(buf.allocator == alloc);
128 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc)); // space is still allocated
129 cxBufferDestroy(&buf);
130 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
131 }
132 cx_testing_allocator_destroy(&talloc);
133 }
134
135 CX_TEST(test_buffer_init_on_heap) {
136 CxTestingAllocator talloc;
137 cx_testing_allocator_init(&talloc);
138 CxAllocator *alloc = &talloc.base;
139 CX_TEST_DO {
140 CxBuffer *buf;
141 void *space = cxMalloc(alloc, 16);
142 buf = cxBufferCreate(space, 16, alloc, CX_BUFFER_FREE_CONTENTS);
143 CX_TEST_ASSERT(buf != NULL);
144 CX_TEST_CALL_SUBROUTINE(expect_default_flush_config, buf);
145 CX_TEST_ASSERT(buf->space == space);
146 CX_TEST_ASSERT((buf->flags & CX_BUFFER_AUTO_EXTEND) == 0);
147 CX_TEST_ASSERT((buf->flags & CX_BUFFER_FREE_CONTENTS) == CX_BUFFER_FREE_CONTENTS);
148 CX_TEST_ASSERT(buf->pos == 0);
149 CX_TEST_ASSERT(buf->size == 0);
150 CX_TEST_ASSERT(buf->capacity == 16);
151 CX_TEST_ASSERT(buf->allocator == alloc);
152 cxBufferFree(buf);
153 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
154 }
155 cx_testing_allocator_destroy(&talloc);
156 }
157
158 CX_TEST(test_buffer_minimum_capacity_sufficient) {
159 CxTestingAllocator talloc;
160 cx_testing_allocator_init(&talloc);
161 CxAllocator *alloc = &talloc.base;
162 CX_TEST_DO {
163 void *space = cxMalloc(alloc, 8);
164 CxBuffer buf;
165 cxBufferInit(&buf, space, 8, alloc, CX_BUFFER_FREE_CONTENTS);
166 memcpy(space, "Testing", 8);
167 buf.size = 8;
168 cxBufferMinimumCapacity(&buf, 6);
169 CX_TEST_ASSERT(buf.capacity == 8);
170 CX_TEST_ASSERT(buf.size == 8);
171 CX_TEST_ASSERT(memcmp(buf.space, "Testing", 8) == 0);
172 cxBufferDestroy(&buf);
173 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
174 }
175 cx_testing_allocator_destroy(&talloc);
176 }
177
178 CX_TEST(test_buffer_minimum_capacity_extend) {
179 CxTestingAllocator talloc;
180 cx_testing_allocator_init(&talloc);
181 CxAllocator *alloc = &talloc.base;
182 CX_TEST_DO {
183 void *space = cxMalloc(alloc, 8);
184 CxBuffer buf;
185 cxBufferInit(&buf, space, 8, alloc, CX_BUFFER_FREE_CONTENTS); // NO auto extend!
186 memcpy(space, "Testing", 8);
187 buf.size = 8;
188 cxBufferMinimumCapacity(&buf, 16);
189 CX_TEST_ASSERT(buf.capacity == 16);
190 CX_TEST_ASSERT(buf.size == 8);
191 CX_TEST_ASSERT(memcmp(buf.space, "Testing", 8) == 0);
192 cxBufferDestroy(&buf);
193 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
194 }
195 cx_testing_allocator_destroy(&talloc);
196 }
197
198 CX_TEST(test_buffer_clear) {
199 char space[16];
200 strcpy(space, "clear test");
201 CxBuffer buf;
202 cxBufferInit(&buf, space, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
203 CX_TEST_DO {
204 CX_TEST_ASSERT(buf.size == 0);
205 // only clear the used part of the buffer
206 cxBufferClear(&buf);
207 CX_TEST_ASSERT(0 == memcmp(space, "clear test", 10));
208 buf.size = 5;
209 buf.pos = 3;
210 cxBufferClear(&buf);
211 CX_TEST_ASSERT(0 == memcmp(space, "\0\0\0\0\0 test", 10));
212 CX_TEST_ASSERT(buf.size == 0);
213 CX_TEST_ASSERT(buf.pos == 0);
214 }
215 cxBufferDestroy(&buf);
216 }
217
218 CX_TEST(test_buffer_reset) {
219 char space[16];
220 strcpy(space, "reset test");
221 CxBuffer buf;
222 cxBufferInit(&buf, space, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
223 CX_TEST_DO {
224 buf.size = 5;
225 buf.pos = 3;
226 cxBufferReset(&buf);
227 CX_TEST_ASSERT(0 == memcmp(space, "reset test", 10));
228 CX_TEST_ASSERT(buf.size == 0);
229 CX_TEST_ASSERT(buf.pos == 0);
230 }
231 cxBufferDestroy(&buf);
232 }
233
234 CX_TEST(test_buffer_seek_set_zero) {
235 CxBuffer buf;
236 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
237 buf.size = 6;
238 buf.pos = 3;
239 CX_TEST_DO {
240 int result = cxBufferSeek(&buf, 0, SEEK_SET);
241 CX_TEST_ASSERT(result == 0);
242 CX_TEST_ASSERT(buf.pos == 0);
243 }
244 cxBufferDestroy(&buf);
245 }
246
247 CX_TEST(test_buffer_seek_set_valid) {
248 CxBuffer buf;
249 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
250 buf.size = 6;
251 buf.pos = 3;
252 CX_TEST_DO {
253 int result = cxBufferSeek(&buf, 5, SEEK_SET);
254 CX_TEST_ASSERT(result == 0);
255 CX_TEST_ASSERT(buf.pos == 5);
256 }
257 cxBufferDestroy(&buf);
258 }
259
260 CX_TEST(test_buffer_seek_set_invalid) {
261 CxBuffer buf;
262 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
263 buf.size = 6;
264 buf.pos = 3;
265 CX_TEST_DO {
266 int result = cxBufferSeek(&buf, 6, SEEK_SET);
267 CX_TEST_ASSERT(result != 0);
268 CX_TEST_ASSERT(buf.pos == 3);
269 }
270 cxBufferDestroy(&buf);
271 }
272
273 CX_TEST(test_buffer_seek_cur_zero) {
274 CxBuffer buf;
275 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
276 buf.size = 6;
277 buf.pos = 3;
278 CX_TEST_DO {
279 int result = cxBufferSeek(&buf, 0, SEEK_CUR);
280 CX_TEST_ASSERT(result == 0);
281 CX_TEST_ASSERT(buf.pos == 3);
282 }
283 cxBufferDestroy(&buf);
284 }
285
286 CX_TEST(test_buffer_seek_cur_valid_positive) {
287 CxBuffer buf;
288 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
289 buf.size = 6;
290 buf.pos = 3;
291 CX_TEST_DO {
292 int result = cxBufferSeek(&buf, 2, SEEK_CUR);
293 CX_TEST_ASSERT(result == 0);
294 CX_TEST_ASSERT(buf.pos == 5);
295 }
296 cxBufferDestroy(&buf);
297 }
298
299 CX_TEST(test_buffer_seek_cur_valid_negative) {
300 CxBuffer buf;
301 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
302 buf.size = 6;
303 buf.pos = 3;
304 CX_TEST_DO {
305 int result = cxBufferSeek(&buf, -3, SEEK_CUR);
306 CX_TEST_ASSERT(result == 0);
307 CX_TEST_ASSERT(buf.pos == 0);
308 }
309 cxBufferDestroy(&buf);
310 }
311
312 CX_TEST(test_buffer_seek_cur_invalid_positive) {
313 CxBuffer buf;
314 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
315 buf.size = 6;
316 buf.pos = 3;
317 CX_TEST_DO {
318 int result = cxBufferSeek(&buf, 3, SEEK_CUR);
319 CX_TEST_ASSERT(result != 0);
320 CX_TEST_ASSERT(buf.pos == 3);
321 }
322 cxBufferDestroy(&buf);
323 }
324
325 CX_TEST(test_buffer_seek_cur_invalid_negative) {
326 CxBuffer buf;
327 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
328 buf.size = 6;
329 buf.pos = 3;
330 CX_TEST_DO {
331 int result = cxBufferSeek(&buf, -4, SEEK_CUR);
332 CX_TEST_ASSERT(result != 0);
333 CX_TEST_ASSERT(buf.pos == 3);
334 }
335 cxBufferDestroy(&buf);
336 }
337
338 CX_TEST(test_buffer_seek_end_zero) {
339 CxBuffer buf;
340 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
341 buf.size = 6;
342 buf.pos = 3;
343 CX_TEST_DO {
344 int result = cxBufferSeek(&buf, 0, SEEK_END);
345 // the (past-the-)end position is always invalid
346 CX_TEST_ASSERT(result != 0);
347 CX_TEST_ASSERT(buf.pos == 3);
348 }
349 cxBufferDestroy(&buf);
350 }
351
352 CX_TEST(test_buffer_seek_end_valid) {
353 CxBuffer buf;
354 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
355 buf.size = 6;
356 buf.pos = 3;
357 CX_TEST_DO {
358 int result = cxBufferSeek(&buf, -6, SEEK_END);
359 CX_TEST_ASSERT(result == 0);
360 CX_TEST_ASSERT(buf.pos == 0);
361 }
362 cxBufferDestroy(&buf);
363 }
364
365 CX_TEST(test_buffer_seek_end_invalid) {
366 CxBuffer buf;
367 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
368 buf.size = 6;
369 buf.pos = 3;
370 CX_TEST_DO {
371 int result = cxBufferSeek(&buf, 1, SEEK_END);
372 CX_TEST_ASSERT(result != 0);
373 CX_TEST_ASSERT(buf.pos == 3);
374 }
375 cxBufferDestroy(&buf);
376 }
377
378 CX_TEST(test_buffer_seek_whence_invalid) {
379 CxBuffer buf;
380 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
381 buf.size = 6;
382 buf.pos = 3;
383 CX_TEST_DO {
384 int result = cxBufferSeek(&buf, 2, 9000);
385 CX_TEST_ASSERT(result != 0);
386 CX_TEST_ASSERT(buf.size == 6);
387 CX_TEST_ASSERT(buf.pos == 3);
388 }
389 cxBufferDestroy(&buf);
390 }
391
392 CxTestSuite *cx_test_suite_buffer(void) {
393 CxTestSuite *suite = cx_test_suite_new("buffer");
394
395 cx_test_register(suite, test_buffer_init_wrap_space);
396 cx_test_register(suite, test_buffer_init_wrap_space_auto_extend);
397 cx_test_register(suite, test_buffer_init_wrap_space_auto_free);
398 cx_test_register(suite, test_buffer_init_fresh_space);
399 cx_test_register(suite, test_buffer_init_on_heap);
400 cx_test_register(suite, test_buffer_minimum_capacity_sufficient);
401 cx_test_register(suite, test_buffer_minimum_capacity_extend);
402 cx_test_register(suite, test_buffer_clear);
403 cx_test_register(suite, test_buffer_reset);
404 cx_test_register(suite, test_buffer_seek_set_zero);
405 cx_test_register(suite, test_buffer_seek_set_valid);
406 cx_test_register(suite, test_buffer_seek_set_invalid);
407 cx_test_register(suite, test_buffer_seek_cur_zero);
408 cx_test_register(suite, test_buffer_seek_cur_valid_positive);
409 cx_test_register(suite, test_buffer_seek_cur_valid_negative);
410 cx_test_register(suite, test_buffer_seek_cur_invalid_positive);
411 cx_test_register(suite, test_buffer_seek_cur_invalid_negative);
412 cx_test_register(suite, test_buffer_seek_end_zero);
413 cx_test_register(suite, test_buffer_seek_end_valid);
414 cx_test_register(suite, test_buffer_seek_end_invalid);
415 cx_test_register(suite, test_buffer_seek_whence_invalid);
416
417 return suite;
418 }

mercurial