Code

plugin: Record all loaded plugins and use that for improved error messages.
[sysdb.git] / t / utils / strbuf_test.c
1 /*
2  * SysDB - t/utils/strbuf_test.c
3  * Copyright (C) 2013 Sebastian 'tokkee' Harl <sh@tokkee.org>
4  * 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
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
28 #include "utils/strbuf.h"
29 #include "libsysdb_test.h"
31 #include <check.h>
33 /*
34  * private data types
35  */
37 static sdb_strbuf_t *buf;
39 static void
40 setup(void)
41 {
42         buf = sdb_strbuf_create(0);
43         fail_unless(buf != NULL,
44                         "sdb_strbuf_create() = NULL; expected strbuf object");
45 } /* setup */
47 static void
48 teardown(void)
49 {
50         sdb_strbuf_destroy(buf);
51         buf = NULL;
52 } /* teardown */
54 /*
55  * tests
56  */
58 START_TEST(test_empty)
59 {
60         sdb_strbuf_t *b = NULL;
61         va_list ap;
63         /* check that methods don't crash */
64         sdb_strbuf_destroy(b);
65         sdb_strbuf_skip(b, 0, 0);
66         sdb_strbuf_skip(b, 0, 10);
67         sdb_strbuf_skip(b, 10, 10);
69         /* check that methods return an error */
70         fail_unless(sdb_strbuf_vappend(b, "test", ap) < 0,
71                         "sdb_strbuf_vappend(NULL) didn't report failure");
72         fail_unless(sdb_strbuf_append(b, "test") < 0,
73                         "sdb_strbuf_append(NULL) didn't report failure");
74         fail_unless(sdb_strbuf_vsprintf(b, "test", ap) < 0,
75                         "sdb_strbuf_vsprintf(NULL) didn't report failure");
76         fail_unless(sdb_strbuf_sprintf(b, "test") < 0,
77                         "sdb_strbuf_sprintf(NULL) didn't report failure");
78         fail_unless(sdb_strbuf_memcpy(b, "test", 4) < 0,
79                         "sdb_strbuf_memcpy(NULL) didn't report failure");
80         fail_unless(sdb_strbuf_memappend(b, "test", 4) < 0,
81                         "sdb_strbuf_memappend(NULL) didn't report failure");
82         fail_unless(sdb_strbuf_read(b, 0, 32) < 0,
83                         "sdb_strbuf_read(NULL) didn't report failure");
84         fail_unless(sdb_strbuf_chomp(b) < 0,
85                         "sdb_strbuf_chomp(NULL) didn't report failure");
86 }
87 END_TEST
89 START_TEST(test_sdb_strbuf_create)
90 {
91         sdb_strbuf_t *s;
92         size_t len;
94         s = sdb_strbuf_create(0);
95         fail_unless(s != NULL,
96                         "sdb_strbuf_create() = NULL; expected strbuf object");
97         len = sdb_strbuf_len(s);
98         fail_unless(len == 0,
99                         "sdb_strbuf_create() created buffer with len = %zu; "
100                         "expected: 0", len);
101         sdb_strbuf_destroy(s);
103         s = sdb_strbuf_create(128);
104         fail_unless(s != NULL,
105                         "sdb_strbuf_create() = NULL; expected strbuf object");
106         len = sdb_strbuf_len(s);
107         /* len still has to be 0 -- there's no content */
108         fail_unless(len == 0,
109                         "sdb_strbuf_create() created buffer with len = %zu; "
110                         "expected: 0", len);
111         sdb_strbuf_destroy(s);
113 END_TEST
115 START_TEST(test_sdb_strbuf_append)
117         ssize_t n, expected;
118         size_t len;
119         const char *test;
121         n = sdb_strbuf_append(buf, "1234567890");
122         fail_unless(n == 10,
123                         "sdb_strbuf_append() appended %zi bytes; expected: 10", n);
124         len = sdb_strbuf_len(buf);
125         fail_unless(len == 10,
126                         "sdb_strbuf_append() left behind buffer with len = %zu; "
127                         "expected: 10", len);
129         n = sdb_strbuf_append(buf, "ABCDE");
130         fail_unless(n == 5,
131                         "sdb_strbuf_append() appended %zi bytes; expected: 5", n);
132         len = sdb_strbuf_len(buf);
133         fail_unless(len == 15,
134                         "sdb_strbuf_append() left behind buffer with len = %zu; "
135                         "expected: 15", len);
137         test = sdb_strbuf_string(buf);
138         fail_unless(test[len] == '\0',
139                         "sdb_strbuf_append() did not nil-terminate the string");
140         fail_unless(!strcmp(test, "1234567890ABCDE"),
141                         "sdb_strbuf_append() did not correctly concatenate two string; "
142                         "got: %s; expected: 1234567890ABCDE", test);
144         n = sdb_strbuf_append(buf, "%zu; %5.4f", len, (double)len / 10.0);
145         expected = /* len */ 2 + /* "; " */ 2 + /* decimal len/10 */ 6;
146         fail_unless(n == expected,
147                         "sdb_strbuf_append() appended %zi bytes; expected: %zi",
148                         n, expected);
149         len = sdb_strbuf_len(buf);
150         fail_unless(len == 15 + (size_t)expected,
151                         "sdb_strbuf_append() left behind buffer with len = %zu; "
152                         "expected: %zu", len, 15 + (size_t)expected);
154         test = sdb_strbuf_string(buf);
155         fail_unless(test[len] == '\0',
156                         "sdb_strbuf_append() did not nil-terminate the string");
157         fail_unless(!strcmp(test, "1234567890ABCDE15; 1.5000"),
158                         "sdb_strbuf_append() did not correctly concatenate two string; "
159                         "got: %s; expected: 1234567890ABCDE15; 1.5000", test);
161 END_TEST
163 START_TEST(test_sdb_strbuf_sprintf)
165         ssize_t n, expected;
166         size_t len;
167         const char *test;
169         n = sdb_strbuf_sprintf(buf, "1234567890");
170         fail_unless(n == 10,
171                         "sdb_strbuf_sprintf() wrote %zi bytes; expected: 10", n);
172         len = sdb_strbuf_len(buf);
173         fail_unless(len == 10,
174                         "sdb_strbuf_sprintf() left behind buffer with len = %zu; "
175                         "expected: 10", len);
177         n = sdb_strbuf_sprintf(buf, "ABCDE");
178         fail_unless(n == 5,
179                         "sdb_strbuf_sprintf() wrote %zi bytes; expected: 5", n);
180         len = sdb_strbuf_len(buf);
181         fail_unless(len == 5,
182                         "sdb_strbuf_sprintf() left behind buffer with len = %zu; "
183                         "expected: 5", len);
185         test = sdb_strbuf_string(buf);
186         fail_unless(test[len] == '\0',
187                         "sdb_strbuf_sprintf() did not nil-terminate the string");
188         fail_unless(!strcmp(test, "ABCDE"),
189                         "sdb_strbuf_sprintf() did not format string correctly; "
190                         "got: %s; expected: ABCDE", test);
192         n = sdb_strbuf_sprintf(buf, "%zu; %5.4f", len, (double)len / 10.0);
193         expected = /* len */ 1 + /* "; " */ 2 + /* decimal len/10 */ 6;
194         fail_unless(n == expected,
195                         "sdb_strbuf_sprintf() wrote %zi bytes; expected: %zi",
196                         n, expected);
197         len = sdb_strbuf_len(buf);
198         fail_unless(len == (size_t)expected,
199                         "sdb_strbuf_sprintf() left behind buffer with len = %zu; "
200                         "expected: %zu", len, (size_t)expected);
202         test = sdb_strbuf_string(buf);
203         fail_unless(test[len] == '\0',
204                         "sdb_strbuf_sprintf() did not nil-terminate the string");
205         fail_unless(!strcmp(test, "5; 0.5000"),
206                         "sdb_strbuf_sprintf() did not format string correctly; "
207                         "got: %s; expected: 5; 0.5000", test);
209 END_TEST
211 START_TEST(test_incremental)
213         ssize_t n;
214         size_t i;
216         sdb_strbuf_destroy(buf);
217         buf = sdb_strbuf_create(1024);
219         /* fill buffer one by one; leave room for nul-byte */
220         for (i = 0; i < 1023; ++i) {
221                 n = sdb_strbuf_append(buf, ".");
222                 fail_unless(n == 1, "sdb_strbuf_append() = %zi; expected: 1", n);
223         }
225         /* write another byte; this has to trigger a resize */
226         n = sdb_strbuf_append(buf, ".");
227         fail_unless(n == 1, "sdb_strbuf_append() = %zi; expected: 1", n);
229         /* write more bytes; this should trigger at least one more resize but
230          * that's an implementation detail */
231         for (i = 0; i < 1024; ++i) {
232                 n = sdb_strbuf_append(buf, ".");
233                 fail_unless(n == 1, "sdb_strbuf_append() = %zi; expected: 1", n);
234         }
236         n = (ssize_t)sdb_strbuf_len(buf);
237         fail_unless(n == 2048, "sdb_strbuf_len() = %zi; expectd: 2048", n);
239 END_TEST
241 static struct {
242         const char *input;
243         size_t size;
244 } mem_golden_data[] = {
245         { "abc\0\x10\x42", 6 },
246         { "\0\1\2\3\4", 5 },
247         { "\n\n\0\n\n", 5 },
248         { "", 0 },
249 };
251 START_TEST(test_sdb_strbuf_memcpy)
253         size_t i;
255         for (i = 0; i < SDB_STATIC_ARRAY_LEN(mem_golden_data); ++i) {
256                 ssize_t n;
257                 const char *check;
259                 n = sdb_strbuf_memcpy(buf, mem_golden_data[i].input,
260                                 mem_golden_data[i].size);
261                 fail_unless(n >= 0,
262                                 "sdb_strbuf_memcpy() = %zi; expected: >=0", n);
263                 fail_unless((size_t)n == mem_golden_data[i].size,
264                                 "sdb_strbuf_memcpy() = %zi; expected: %zu",
265                                 n, mem_golden_data[i].size);
267                 n = (ssize_t)sdb_strbuf_len(buf);
268                 fail_unless((size_t)n == mem_golden_data[i].size,
269                                 "sdb_strbuf_len() = %zu (after memcpy); expected: %zu",
270                                 n, mem_golden_data[i].size);
272                 check = sdb_strbuf_string(buf);
273                 fail_unless(check != NULL,
274                                 "sdb_strbuf_string() = NULL (after memcpy); expected: data");
275                 fail_unless(check[mem_golden_data[i].size] == '\0',
276                                 "sdb_strbuf_memcpy() did not nil-terminate the data");
277                 fail_unless(!memcmp(check, mem_golden_data[i].input,
278                                         mem_golden_data[i].size),
279                                 "sdb_strbuf_memcpy() did not set the buffer correctly");
280         }
282 END_TEST
284 START_TEST(test_sdb_strbuf_memappend)
286         size_t i;
288         for (i = 0; i < SDB_STATIC_ARRAY_LEN(mem_golden_data); ++i) {
289                 ssize_t n;
290                 const char *check;
292                 size_t total, j;
294                 n = sdb_strbuf_memappend(buf, mem_golden_data[i].input,
295                                 mem_golden_data[i].size);
296                 fail_unless(n >= 0,
297                                 "sdb_strbuf_memappend() = %zi; expected: >=0", n);
298                 fail_unless((size_t)n == mem_golden_data[i].size,
299                                 "sdb_strbuf_memappend() = %zi; expected: %zu",
300                                 n, mem_golden_data[i].size);
302                 check = sdb_strbuf_string(buf);
303                 fail_unless(check != NULL,
304                                 "sdb_strbuf_string() = NULL (after memappend); "
305                                 "expected: data");
307                 n = (ssize_t)sdb_strbuf_len(buf);
308                 total = 0;
309                 for (j = 0; j <= i; ++j) {
310                         fail_unless(total + mem_golden_data[j].size <= (size_t)n,
311                                         "sdb_strbuf_len() = %zu (after memappend); "
312                                         "expected: >=%zu", n, total + mem_golden_data[j].size);
314                         fail_unless(!memcmp(check + total, mem_golden_data[j].input,
315                                                 mem_golden_data[j].size),
316                                         "sdb_strbuf_memappend() did not "
317                                         "set the buffer correctly");
318                         total += mem_golden_data[j].size;
319                 }
320                 fail_unless((size_t)n == total,
321                                 "sdb_strbuf_len() = %zu (after memappend); expected: %zu",
322                                 n, total);
324                 fail_unless(check[total] == '\0',
325                                 "sdb_strbuf_memappend() did not nil-terminate the data");
326         }
328 END_TEST
330 static struct {
331         const char *input;
332         ssize_t expected;
333         const char *expected_string;
334 } chomp_golden_data[] = {
335         { NULL, 0, "" },
336         { "\n", 1, "" },
337         { "\n\n", 2, "" },
338         { "12345\n\n\n", 3, "12345" },
339         { "abcd", 0, "abcd" },
340 };
342 START_TEST(test_sdb_strbuf_chomp)
344         size_t i;
346         for (i = 0; i < SDB_STATIC_ARRAY_LEN(chomp_golden_data); ++i) {
347                 ssize_t n;
348                 const char *check;
350                 if (chomp_golden_data[i].input)
351                         sdb_strbuf_sprintf(buf, chomp_golden_data[i].input);
353                 /* empty buffer */
354                 n = sdb_strbuf_chomp(buf);
355                 fail_unless(n == chomp_golden_data[i].expected,
356                                 "sdb_strbuf_chomp() = %zi; expected: %zi", n,
357                                 chomp_golden_data[i].expected);
359                 check = sdb_strbuf_string(buf);
360                 fail_unless(!strcmp(check, chomp_golden_data[i].expected_string),
361                                 "sdb_strbuf_chomp() did not correctly remove newlines; "
362                                 "got string '%s'; expected: '%s'", check,
363                                 chomp_golden_data[i].expected_string);
364         }
366 END_TEST
368 /* input is "1234567890" */
369 static struct {
370         size_t offset;
371         size_t n;
372         const char *expected;
373         size_t expected_len;
374 } skip_golden_data[] = {
375         { 0, 0, "1234567890", 10 },
376         { 0, 1, "234567890", 9 },
377         { 0, 2, "34567890", 8 },
378         { 0, 9, "0", 1 },
379         { 0, 10, "", 0 },
380         { 0, 11, "", 0 },
381         { 0, 100, "", 0 },
382         { 1, 0, "1234567890", 10 },
383         { 1, 1, "134567890", 9 },
384         { 1, 2, "14567890", 8 },
385         { 8, 1, "123456780", 9 },
386         { 8, 2, "12345678", 8 },
387         { 8, 3, "12345678", 8 },
388         { 9, 1, "123456789", 9 },
389         { 9, 2, "123456789", 9 },
390         { 10, 1, "1234567890", 10 },
391         { 10, 2, "1234567890", 10 },
392 };
394 START_TEST(test_sdb_strbuf_skip)
396         const char *input = "1234567890";
397         size_t i;
399         for (i = 0; i < SDB_STATIC_ARRAY_LEN(skip_golden_data); ++i) {
400                 const char *check;
401                 size_t n;
403                 sdb_strbuf_sprintf(buf, input);
404                 sdb_strbuf_skip(buf, skip_golden_data[i].offset,
405                                 skip_golden_data[i].n);
407                 n = sdb_strbuf_len(buf);
408                 fail_unless(n == skip_golden_data[i].expected_len,
409                                 "sdb_strbuf_len() = %zu (after skip); expected: %zu",
410                                 n, skip_golden_data[i].expected_len);
412                 check = sdb_strbuf_string(buf);
413                 fail_unless(!!check,
414                                 "sdb_strbuf_string() = NULL (after skip); expected: string");
416                 fail_unless(check[n] == '\0',
417                                 "sdb_strbuf_skip() did not nil-terminate the string");
419                 fail_unless(! strcmp(skip_golden_data[i].expected, check),
420                                 "sdb_strbuf_skip('%s', %zu) did not skip correctly; "
421                                 "got string '%s'; expected: '%s'", input,
422                                 skip_golden_data[i].n, check, skip_golden_data[i].expected);
423         }
425 END_TEST
427 static struct {
428         const char *input;
429         const char *expected;
430 } string_golden_data[] = {
431         { NULL, "" },
432         { "a", "a" },
433         { "abcdef", "abcdef" },
434 };
436 START_TEST(test_sdb_strbuf_string)
438         size_t i;
440         for (i = 0; i < SDB_STATIC_ARRAY_LEN(string_golden_data); ++i) {
441                 const char *check;
443                 if (string_golden_data[i].input)
444                         sdb_strbuf_sprintf(buf, string_golden_data[i].input);
445                 check = sdb_strbuf_string(buf);
446                 fail_unless(!strcmp(check, string_golden_data[i].expected),
447                                 "sdb_strbuf_string() = '%s'; expected: '%s'",
448                                 check, string_golden_data[i].expected);
449         }
451 END_TEST
453 static struct {
454         const char *input;
455         size_t expected;
456 } len_golden_data[] = {
457         { NULL, 0 },
458         { "a", 1 },
459         { "12345", 5 },
460 };
462 START_TEST(test_sdb_strbuf_len)
464         size_t i;
466         for (i = 0; i < SDB_STATIC_ARRAY_LEN(len_golden_data); ++i) {
467                 size_t check;
469                 if (len_golden_data[i].input)
470                         sdb_strbuf_sprintf(buf, len_golden_data[i].input);
471                 check = sdb_strbuf_len(buf);
472                 fail_unless(check == len_golden_data[i].expected,
473                                 "sdb_strbuf_len() = %zu; expected: %zu",
474                                 check, len_golden_data[i].expected);
475         }
477 END_TEST
479 Suite *
480 util_strbuf_suite(void)
482         Suite *s = suite_create("utils::strbuf");
483         TCase *tc;
485         tc = tcase_create("empty");
486         tcase_add_test(tc, test_empty);
487         suite_add_tcase(s, tc);
489         tc = tcase_create("core");
490         tcase_add_checked_fixture(tc, setup, teardown);
491         tcase_add_test(tc, test_sdb_strbuf_create);
492         tcase_add_test(tc, test_sdb_strbuf_append);
493         tcase_add_test(tc, test_sdb_strbuf_sprintf);
494         tcase_add_test(tc, test_incremental);
495         tcase_add_test(tc, test_sdb_strbuf_memcpy);
496         tcase_add_test(tc, test_sdb_strbuf_memappend);
497         tcase_add_test(tc, test_sdb_strbuf_chomp);
498         tcase_add_test(tc, test_sdb_strbuf_skip);
499         tcase_add_test(tc, test_sdb_strbuf_string);
500         tcase_add_test(tc, test_sdb_strbuf_len);
501         suite_add_tcase(s, tc);
503         return s;
504 } /* util_strbuf_suite */
506 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */