1 /*
2 * SysDB - t/unit/core/data_test.c
3 * Copyright (C) 2014 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 "core/data.h"
29 #include "libsysdb_test.h"
31 #include <assert.h>
32 #include <check.h>
34 static regex_t empty_re;
36 START_TEST(test_data)
37 {
38 sdb_data_t d1, d2;
39 int check;
41 int int_values[] = { 47, 11, 23 };
42 char *string_values[] = { "foo", "bar", "qux" "baz" };
43 size_t i;
45 d2.type = SDB_TYPE_INTEGER;
46 d2.data.integer = 4711;
47 memset(&d1, 0, sizeof(d1));
48 check = sdb_data_copy(&d1, &d2);
49 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
50 fail_unless(d1.type == d2.type,
51 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
52 d1.type, d2.type);
53 fail_unless(d1.data.integer == d2.data.integer,
54 "sdb_data_copy() didn't copy integer data: got: %d; expected: %d",
55 d1.data.integer, d2.data.integer);
57 d2.type = SDB_TYPE_DECIMAL;
58 d2.data.decimal = 47.11;
59 check = sdb_data_copy(&d1, &d2);
60 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
61 fail_unless(d1.type == d2.type,
62 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
63 d1.type, d2.type);
64 fail_unless(d1.data.decimal == d2.data.decimal,
65 "sdb_data_copy() didn't copy decimal data: got: %f; expected: %f",
66 d1.data.decimal, d2.data.decimal);
68 d2.type = SDB_TYPE_STRING;
69 d2.data.string = "some string";
70 check = sdb_data_copy(&d1, &d2);
71 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
72 fail_unless(d1.type == d2.type,
73 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
74 d1.type, d2.type);
75 fail_unless(!strcmp(d1.data.string, d2.data.string),
76 "sdb_data_copy() didn't copy string data: got: %s; expected: %s",
77 d1.data.string, d2.data.string);
79 sdb_data_free_datum(&d1);
80 fail_unless(d1.data.string == NULL,
81 "sdb_data_free_datum() didn't free string data");
83 d1.type = 0;
84 d2.type = SDB_TYPE_STRING;
85 d2.data.string = NULL;
86 check = sdb_data_copy(&d1, &d2);
87 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
88 fail_unless(d1.type == d2.type,
89 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
90 d1.type, d2.type);
91 fail_unless(d1.data.string == d2.data.string,
92 "sdb_data_copy() didn't copy string data: got: %s; expected: %s",
93 d1.data.string, d2.data.string);
95 sdb_data_free_datum(&d1);
96 fail_unless(d1.data.string == NULL,
97 "sdb_data_free_datum() didn't free string data");
99 d2.type = SDB_TYPE_DATETIME;
100 d2.data.datetime = 4711;
101 check = sdb_data_copy(&d1, &d2);
102 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
103 fail_unless(d1.type == d2.type,
104 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
105 d1.type, d2.type);
106 fail_unless(d1.data.datetime == d2.data.datetime,
107 "sdb_data_copy() didn't copy datetime data: got: %d; expected: %d",
108 d1.data.datetime, d2.data.datetime);
110 d2.type = SDB_TYPE_BINARY;
111 d2.data.binary.datum = (unsigned char *)"some string";
112 d2.data.binary.length = strlen((const char *)d2.data.binary.datum);
113 check = sdb_data_copy(&d1, &d2);
114 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
115 fail_unless(d1.type == d2.type,
116 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
117 d1.type, d2.type);
118 fail_unless(d1.data.binary.length == d2.data.binary.length,
119 "sdb_data_copy() didn't copy length; got: %d; expected: 5d",
120 d1.data.binary.length, d2.data.binary.length);
121 fail_unless(!memcmp(d1.data.binary.datum, d2.data.binary.datum,
122 d2.data.binary.length),
123 "sdb_data_copy() didn't copy binary data: got: %s; expected: %s",
124 d1.data.binary.datum, d2.data.binary.datum);
126 sdb_data_free_datum(&d1);
127 fail_unless(d1.data.binary.length == 0,
128 "sdb_data_free_datum() didn't reset binary datum length");
129 fail_unless(d1.data.binary.datum == NULL,
130 "sdb_data_free_datum() didn't free binary datum");
132 d1.type = 0;
133 d2.type = SDB_TYPE_BINARY;
134 d2.data.binary.datum = NULL;
135 d2.data.binary.length = 0;
136 check = sdb_data_copy(&d1, &d2);
137 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
138 fail_unless(d1.type == d2.type,
139 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
140 d1.type, d2.type);
141 fail_unless(d1.data.binary.length == d2.data.binary.length,
142 "sdb_data_copy() didn't copy length; got: %d; expected: 5d",
143 d1.data.binary.length, d2.data.binary.length);
144 fail_unless(d1.data.binary.datum == d2.data.binary.datum,
145 "sdb_data_copy() didn't copy binary data: got: %s; expected: %s",
146 d1.data.binary.datum, d2.data.binary.datum);
148 sdb_data_free_datum(&d1);
149 fail_unless(d1.data.binary.length == 0,
150 "sdb_data_free_datum() didn't reset binary datum length");
151 fail_unless(d1.data.binary.datum == NULL,
152 "sdb_data_free_datum() didn't free binary datum");
154 check = sdb_data_parse(".", SDB_TYPE_REGEX, &d2);
155 fail_unless(check == 0,
156 "INTERNAL ERROR: Failed to parse regex '.'");
157 assert(d2.type == SDB_TYPE_REGEX);
158 check = sdb_data_copy(&d1, &d2);
159 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
160 fail_unless(d1.type == d2.type,
161 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
162 d1.type, d2.type);
163 fail_unless(d1.data.re.raw != d2.data.re.raw,
164 "sdb_data_copy() copy string pointer");
165 fail_unless(!strcmp(d1.data.re.raw, d2.data.re.raw),
166 "sdb_data_copy() didn't copy raw regex: got: %s; expected: %s",
167 d1.data.re.raw, d2.data.re.raw);
168 sdb_data_free_datum(&d2);
170 sdb_data_free_datum(&d1);
171 fail_unless(d1.data.re.raw == NULL,
172 "sdb_data_free_datum() didn't reset raw regex");
174 d2.type = SDB_TYPE_REGEX;
175 d2.data.re.raw = NULL;
176 check = sdb_data_copy(&d1, &d2);
177 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
178 fail_unless(d1.type == d2.type,
179 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
180 d1.type, d2.type);
182 d2.type = SDB_TYPE_ARRAY | SDB_TYPE_INTEGER;
183 d2.data.array.length = SDB_STATIC_ARRAY_LEN(int_values);
184 d2.data.array.values = int_values;
185 check = sdb_data_copy(&d1, &d2);
186 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
187 fail_unless(d1.type == d2.type,
188 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
189 d1.type, d2.type);
190 fail_unless(d1.data.array.values != d2.data.array.values,
191 "sdb_data_copy() didn't copy values: got: %p; expected: %p",
192 d1.data.array.values, d2.data.array.values);
193 for (i = 0; i < SDB_STATIC_ARRAY_LEN(int_values); ++i) {
194 int *i1 = d1.data.array.values;
195 int *i2 = d2.data.array.values;
196 fail_unless(i1[i] == i2[i],
197 "sdb_data_copy() modified integer value %d: "
198 "got: %d; expected: %d", i, i1[i], i2[i]);
199 }
200 sdb_data_free_datum(&d1);
202 d2.type = SDB_TYPE_ARRAY | SDB_TYPE_STRING;
203 d2.data.array.length = SDB_STATIC_ARRAY_LEN(string_values);
204 d2.data.array.values = string_values;
205 check = sdb_data_copy(&d1, &d2);
206 fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
207 fail_unless(d1.type == d2.type,
208 "sdb_data_copy() didn't copy type; got: %i; expected: %i",
209 d1.type, d2.type);
210 fail_unless(d1.data.array.values != d2.data.array.values,
211 "sdb_data_copy() didn't copy values: got: %p; expected: %p",
212 d1.data.array.values, d2.data.array.values);
213 for (i = 0; i < SDB_STATIC_ARRAY_LEN(string_values); ++i) {
214 char **s1 = d1.data.array.values;
215 char **s2 = d2.data.array.values;
216 fail_unless(s1[i] != s2[i],
217 "sdb_data_copy() didn't copy string value %d", i);
218 fail_unless(!strcmp(s1[i], s2[i]),
219 "sdb_data_copy() modified string value %d: "
220 "got: %s; expected: %s", i, s1[i], s2[i]);
221 }
222 sdb_data_free_datum(&d1);
223 }
224 END_TEST
226 START_TEST(test_cmp)
227 {
228 struct {
229 sdb_data_t d1;
230 sdb_data_t d2;
231 int expected;
232 } golden_data[] = {
233 {
234 { SDB_TYPE_INTEGER, { .integer = 47 } },
235 { SDB_TYPE_INTEGER, { .integer = 4711 } },
236 -1,
237 },
238 {
239 { SDB_TYPE_INTEGER, { .integer = 4711 } },
240 { SDB_TYPE_INTEGER, { .integer = 4711 } },
241 0,
242 },
243 {
244 { SDB_TYPE_INTEGER, { .integer = 4711 } },
245 { SDB_TYPE_INTEGER, { .integer = 47 } },
246 1,
247 },
248 {
249 { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
250 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
251 -1,
252 },
253 {
254 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
255 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
256 0,
257 },
258 {
259 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
260 { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
261 1,
262 },
263 {
264 { SDB_TYPE_STRING, { .string = NULL } },
265 { SDB_TYPE_STRING, { .string = "" } },
266 -1,
267 },
268 {
269 { SDB_TYPE_STRING, { .string = NULL } },
270 { SDB_TYPE_STRING, { .string = NULL } },
271 0,
272 },
273 {
274 { SDB_TYPE_STRING, { .string = "" } },
275 { SDB_TYPE_STRING, { .string = NULL } },
276 1,
277 },
278 {
279 { SDB_TYPE_STRING, { .string = "a" } },
280 { SDB_TYPE_STRING, { .string = "b" } },
281 -1,
282 },
283 {
284 { SDB_TYPE_STRING, { .string = "a" } },
285 { SDB_TYPE_STRING, { .string = "ab" } },
286 -1,
287 },
288 {
289 { SDB_TYPE_STRING, { .string = "a" } },
290 { SDB_TYPE_STRING, { .string = "a" } },
291 0,
292 },
293 {
294 { SDB_TYPE_STRING, { .string = "b" } },
295 { SDB_TYPE_STRING, { .string = "a" } },
296 1,
297 },
298 {
299 { SDB_TYPE_STRING, { .string = "ab" } },
300 { SDB_TYPE_STRING, { .string = "a" } },
301 1,
302 },
303 {
304 { SDB_TYPE_DATETIME, { .datetime = 471147114711471000 } },
305 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
306 -1,
307 },
308 {
309 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
310 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
311 0,
312 },
313 {
314 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
315 { SDB_TYPE_DATETIME, { .datetime = 471147114711471000 } },
316 1,
317 },
318 {
319 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
320 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
321 -1,
322 },
323 {
324 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
325 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
326 0,
327 },
328 {
329 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
330 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
331 1,
332 },
333 {
334 {
335 SDB_TYPE_BINARY,
336 { .binary = { 3, (unsigned char *)"a\0a" } },
337 },
338 {
339 SDB_TYPE_BINARY,
340 { .binary = { 3, (unsigned char *)"a\0b" } },
341 },
342 -1,
343 },
344 {
345 {
346 SDB_TYPE_BINARY,
347 { .binary = { 1, (unsigned char *)"a" } },
348 },
349 {
350 SDB_TYPE_BINARY,
351 { .binary = { 3, (unsigned char *)"a\0\0" } },
352 },
353 -1,
354 },
355 {
356 {
357 SDB_TYPE_BINARY,
358 { .binary = { 3, (unsigned char *)"a\0a" } },
359 },
360 {
361 SDB_TYPE_BINARY,
362 { .binary = { 3, (unsigned char *)"a\0a" } },
363 },
364 0,
365 },
366 {
367 {
368 SDB_TYPE_BINARY,
369 { .binary = { 3, (unsigned char *)"a\0b" } },
370 },
371 {
372 SDB_TYPE_BINARY,
373 { .binary = { 3, (unsigned char *)"a\0a" } },
374 },
375 1,
376 },
377 {
378 {
379 SDB_TYPE_BINARY,
380 { .binary = { 3, (unsigned char *)"a\0\0" } },
381 },
382 {
383 SDB_TYPE_BINARY,
384 { .binary = { 1, (unsigned char *)"a" } },
385 },
386 1,
387 },
388 {
389 { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
390 { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
391 0,
392 },
393 {
394 { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
395 { SDB_TYPE_REGEX, { .re = { "b", empty_re } } },
396 -1,
397 },
398 {
399 { SDB_TYPE_REGEX, { .re = { "b", empty_re } } },
400 { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
401 1,
402 },
403 };
405 size_t i;
407 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
408 int check = sdb_data_cmp(&golden_data[i].d1, &golden_data[i].d2);
409 check = check < 0 ? -1 : check > 0 ? 1 : 0;
410 if (check != golden_data[i].expected) {
411 char d1_str[64] = "", d2_str[64] = "";
412 sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
413 SDB_DOUBLE_QUOTED);
414 sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
415 SDB_DOUBLE_QUOTED);
416 fail("sdb_data_cmp(%s, %s) = %d; expected: %d",
417 d1_str, d2_str, check, golden_data[i].expected);
418 }
419 }
420 }
421 END_TEST
423 START_TEST(test_strcmp)
424 {
425 struct {
426 sdb_data_t d1;
427 sdb_data_t d2;
428 int expected;
429 } golden_data[] = {
430 /* same data as for the sdb_data_cmp test; in case the types match,
431 * both functions should behave the same (except for some loss in
432 * precision, e.g. when formatting datetime values) */
433 {
434 { SDB_TYPE_INTEGER, { .integer = 47 } },
435 { SDB_TYPE_INTEGER, { .integer = 4711 } },
436 -1,
437 },
438 {
439 { SDB_TYPE_INTEGER, { .integer = 4711 } },
440 { SDB_TYPE_INTEGER, { .integer = 4711 } },
441 0,
442 },
443 {
444 { SDB_TYPE_INTEGER, { .integer = 4711 } },
445 { SDB_TYPE_INTEGER, { .integer = 47 } },
446 1,
447 },
448 {
449 { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
450 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
451 -1,
452 },
453 {
454 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
455 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
456 0,
457 },
458 {
459 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
460 { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
461 1,
462 },
463 {
464 { SDB_TYPE_STRING, { .string = NULL } },
465 { SDB_TYPE_STRING, { .string = "" } },
466 -1,
467 },
468 {
469 { SDB_TYPE_STRING, { .string = NULL } },
470 { SDB_TYPE_STRING, { .string = NULL } },
471 0,
472 },
473 {
474 { SDB_TYPE_STRING, { .string = "" } },
475 { SDB_TYPE_STRING, { .string = NULL } },
476 1,
477 },
478 {
479 { SDB_TYPE_STRING, { .string = "a" } },
480 { SDB_TYPE_STRING, { .string = "b" } },
481 -1,
482 },
483 {
484 { SDB_TYPE_STRING, { .string = "a" } },
485 { SDB_TYPE_STRING, { .string = "ab" } },
486 -1,
487 },
488 {
489 { SDB_TYPE_STRING, { .string = "a" } },
490 { SDB_TYPE_STRING, { .string = "a" } },
491 0,
492 },
493 {
494 { SDB_TYPE_STRING, { .string = "b" } },
495 { SDB_TYPE_STRING, { .string = "a" } },
496 1,
497 },
498 {
499 { SDB_TYPE_STRING, { .string = "ab" } },
500 { SDB_TYPE_STRING, { .string = "a" } },
501 1,
502 },
503 {
504 { SDB_TYPE_DATETIME, { .datetime = 471047114711471100 } },
505 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
506 -1,
507 },
508 {
509 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
510 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
511 0,
512 },
513 {
514 { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
515 { SDB_TYPE_DATETIME, { .datetime = 471047114711471100 } },
516 1,
517 },
518 {
519 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
520 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
521 -1,
522 },
523 {
524 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
525 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
526 0,
527 },
528 {
529 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
530 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
531 1,
532 },
533 {
534 {
535 SDB_TYPE_BINARY,
536 { .binary = { 3, (unsigned char *)"a\0a" } },
537 },
538 {
539 SDB_TYPE_BINARY,
540 { .binary = { 3, (unsigned char *)"a\0b" } },
541 },
542 -1,
543 },
544 {
545 {
546 SDB_TYPE_BINARY,
547 { .binary = { 1, (unsigned char *)"a" } },
548 },
549 {
550 SDB_TYPE_BINARY,
551 { .binary = { 3, (unsigned char *)"a\0\0" } },
552 },
553 -1,
554 },
555 {
556 {
557 SDB_TYPE_BINARY,
558 { .binary = { 3, (unsigned char *)"a\0a" } },
559 },
560 {
561 SDB_TYPE_BINARY,
562 { .binary = { 3, (unsigned char *)"a\0a" } },
563 },
564 0,
565 },
566 {
567 {
568 SDB_TYPE_BINARY,
569 { .binary = { 3, (unsigned char *)"a\0b" } },
570 },
571 {
572 SDB_TYPE_BINARY,
573 { .binary = { 3, (unsigned char *)"a\0a" } },
574 },
575 1,
576 },
577 {
578 {
579 SDB_TYPE_BINARY,
580 { .binary = { 3, (unsigned char *)"a\0\0" } },
581 },
582 {
583 SDB_TYPE_BINARY,
584 { .binary = { 1, (unsigned char *)"a" } },
585 },
586 1,
587 },
588 {
589 { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
590 { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
591 0,
592 },
593 {
594 { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
595 { SDB_TYPE_REGEX, { .re = { "b", empty_re } } },
596 -1,
597 },
598 {
599 { SDB_TYPE_REGEX, { .re = { "b", empty_re } } },
600 { SDB_TYPE_REGEX, { .re = { "a", empty_re } } },
601 1,
602 },
603 /* type mismatches */
604 {
605 { SDB_TYPE_INTEGER, { .integer = 123 } },
606 { SDB_TYPE_STRING, { .string = "123" } },
607 0,
608 },
609 {
610 { SDB_TYPE_INTEGER, { .integer = 120 } },
611 { SDB_TYPE_STRING, { .string = "123" } },
612 -1,
613 },
614 {
615 { SDB_TYPE_STRING, { .string = "123" } },
616 { SDB_TYPE_INTEGER, { .integer = 120 } },
617 1,
618 },
619 {
620 { SDB_TYPE_STRING, { .string = "12.3" } },
621 { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
622 0,
623 },
624 {
625 { SDB_TYPE_STRING, { .string = "12.0" } },
626 { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
627 -1,
628 },
629 {
630 { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
631 { SDB_TYPE_STRING, { .string = "12.0" } },
632 1,
633 },
634 {
635 { SDB_TYPE_REGEX, { .re = { "regex", empty_re } } },
636 { SDB_TYPE_STRING, { .string = "/regex/" } },
637 0,
638 },
639 };
641 size_t i;
643 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
644 int check = sdb_data_strcmp(&golden_data[i].d1, &golden_data[i].d2);
645 check = check < 0 ? -1 : check > 0 ? 1 : 0;
646 if (check != golden_data[i].expected) {
647 char d1_str[64] = "", d2_str[64] = "";
648 sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
649 SDB_DOUBLE_QUOTED);
650 sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
651 SDB_DOUBLE_QUOTED);
652 fail("sdb_data_strcmp(%s, %s) = %d; expected: %d",
653 d1_str, d2_str, check, golden_data[i].expected);
654 }
655 }
656 }
657 END_TEST
659 START_TEST(test_parse_op)
660 {
661 struct {
662 const char *op;
663 int id;
664 } golden_data[] = {
665 { "+", SDB_DATA_ADD },
666 { "-", SDB_DATA_SUB },
667 { "*", SDB_DATA_MUL },
668 { "/", SDB_DATA_DIV },
669 { "%", SDB_DATA_MOD },
670 { "||", SDB_DATA_CONCAT },
671 { "&&", -1 },
672 };
674 size_t i;
676 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
677 const char *op;
678 int id;
680 id = sdb_data_parse_op(golden_data[i].op);
681 fail_unless(id == golden_data[i].id,
682 "sdb_data_parse_op(%s) = %d; expected: %d",
683 golden_data[i].op, id, golden_data[i].id);
685 if (id <= 0)
686 continue;
688 op = SDB_DATA_OP_TO_STRING(id);
689 fail_unless(!strcmp(op, golden_data[i].op),
690 "SDB_DATA_OP_TO_STRING(%d) = '%s'; expected: '%s'",
691 id, op, golden_data[i].op);
692 }
693 }
694 END_TEST
696 START_TEST(test_expr_eval)
697 {
698 sdb_data_t err = { -1, { .integer = 0 } };
700 struct {
701 sdb_data_t d1;
702 sdb_data_t d2;
703 sdb_data_t expected_add;
704 sdb_data_t expected_sub;
705 sdb_data_t expected_mul;
706 sdb_data_t expected_div;
707 sdb_data_t expected_mod;
708 sdb_data_t expected_concat;
709 } golden_data[] = {
710 {
711 { SDB_TYPE_INTEGER, { .integer = 4711 } },
712 { SDB_TYPE_INTEGER, { .integer = 47 } },
713 { SDB_TYPE_INTEGER, { .integer = 4758 } },
714 { SDB_TYPE_INTEGER, { .integer = 4664 } },
715 { SDB_TYPE_INTEGER, { .integer = 221417 } },
716 { SDB_TYPE_INTEGER, { .integer = 100 } },
717 { SDB_TYPE_INTEGER, { .integer = 11 } },
718 err,
719 },
720 {
721 { SDB_TYPE_DECIMAL, { .decimal = 35.0 } },
722 { SDB_TYPE_DECIMAL, { .decimal = 17.5 } },
723 { SDB_TYPE_DECIMAL, { .decimal = 52.5 } },
724 { SDB_TYPE_DECIMAL, { .decimal = 17.5 } },
725 { SDB_TYPE_DECIMAL, { .decimal = 612.5 } },
726 { SDB_TYPE_DECIMAL, { .decimal = 2.0 } },
727 { SDB_TYPE_DECIMAL, { .decimal = 0.0 } },
728 err,
729 },
730 {
731 { SDB_TYPE_STRING, { .string = NULL } },
732 { SDB_TYPE_STRING, { .string = "" } },
733 SDB_DATA_NULL,
734 SDB_DATA_NULL,
735 SDB_DATA_NULL,
736 SDB_DATA_NULL,
737 SDB_DATA_NULL,
738 SDB_DATA_NULL,
739 },
740 {
741 { SDB_TYPE_STRING, { .string = NULL } },
742 { SDB_TYPE_STRING, { .string = NULL } },
743 SDB_DATA_NULL,
744 SDB_DATA_NULL,
745 SDB_DATA_NULL,
746 SDB_DATA_NULL,
747 SDB_DATA_NULL,
748 SDB_DATA_NULL,
749 },
750 {
751 { SDB_TYPE_STRING, { .string = "" } },
752 { SDB_TYPE_STRING, { .string = NULL } },
753 SDB_DATA_NULL,
754 SDB_DATA_NULL,
755 SDB_DATA_NULL,
756 SDB_DATA_NULL,
757 SDB_DATA_NULL,
758 SDB_DATA_NULL,
759 },
760 {
761 { SDB_TYPE_STRING, { .string = "a" } },
762 { SDB_TYPE_STRING, { .string = "b" } },
763 err,
764 err,
765 err,
766 err,
767 err,
768 { SDB_TYPE_STRING, { .string = "ab" } },
769 },
770 {
771 { SDB_TYPE_DATETIME, { .datetime = 47114711 } },
772 { SDB_TYPE_DATETIME, { .datetime = 4711 } },
773 { SDB_TYPE_DATETIME, { .datetime = 47119422 } },
774 { SDB_TYPE_DATETIME, { .datetime = 47110000 } },
775 { SDB_TYPE_DATETIME, { .datetime = 221957403521 } },
776 { SDB_TYPE_DATETIME, { .datetime = 10001 } },
777 { SDB_TYPE_DATETIME, { .datetime = 0 } },
778 err,
779 },
780 {
781 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
782 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
783 SDB_DATA_NULL,
784 SDB_DATA_NULL,
785 SDB_DATA_NULL,
786 SDB_DATA_NULL,
787 SDB_DATA_NULL,
788 SDB_DATA_NULL,
789 },
790 {
791 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
792 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
793 SDB_DATA_NULL,
794 SDB_DATA_NULL,
795 SDB_DATA_NULL,
796 SDB_DATA_NULL,
797 SDB_DATA_NULL,
798 SDB_DATA_NULL,
799 },
800 {
801 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
802 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
803 SDB_DATA_NULL,
804 SDB_DATA_NULL,
805 SDB_DATA_NULL,
806 SDB_DATA_NULL,
807 SDB_DATA_NULL,
808 SDB_DATA_NULL,
809 },
810 {
811 {
812 SDB_TYPE_BINARY,
813 { .binary = { 3, (unsigned char *)"a\0a" } },
814 },
815 {
816 SDB_TYPE_BINARY,
817 { .binary = { 3, (unsigned char *)"b\0b" } },
818 },
819 err,
820 err,
821 err,
822 err,
823 err,
824 {
825 SDB_TYPE_BINARY,
826 { .binary = { 6, (unsigned char *)"a\0ab\0b" } },
827 },
828 },
829 {
830 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
831 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
832 err,
833 err,
834 err,
835 err,
836 err,
837 err,
838 },
839 {
840 { SDB_TYPE_NULL, { .integer = 0 } },
841 { SDB_TYPE_NULL, { .integer = 0 } },
842 SDB_DATA_NULL,
843 SDB_DATA_NULL,
844 SDB_DATA_NULL,
845 SDB_DATA_NULL,
846 SDB_DATA_NULL,
847 SDB_DATA_NULL,
848 },
849 {
850 { SDB_TYPE_NULL, { .integer = 0 } },
851 { SDB_TYPE_INTEGER, { .integer = 42 } },
852 SDB_DATA_NULL,
853 SDB_DATA_NULL,
854 SDB_DATA_NULL,
855 SDB_DATA_NULL,
856 SDB_DATA_NULL,
857 SDB_DATA_NULL,
858 },
859 {
860 { SDB_TYPE_INTEGER, { .integer = 42 } },
861 { SDB_TYPE_NULL, { .integer = 0 } },
862 SDB_DATA_NULL,
863 SDB_DATA_NULL,
864 SDB_DATA_NULL,
865 SDB_DATA_NULL,
866 SDB_DATA_NULL,
867 SDB_DATA_NULL,
868 },
869 {
870 { SDB_TYPE_NULL, { .integer = 0 } },
871 { SDB_TYPE_DECIMAL, { .decimal = 47.11 } },
872 SDB_DATA_NULL,
873 SDB_DATA_NULL,
874 SDB_DATA_NULL,
875 SDB_DATA_NULL,
876 SDB_DATA_NULL,
877 SDB_DATA_NULL,
878 },
879 {
880 { SDB_TYPE_DECIMAL, { .decimal = 47.11 } },
881 { SDB_TYPE_NULL, { .integer = 0 } },
882 SDB_DATA_NULL,
883 SDB_DATA_NULL,
884 SDB_DATA_NULL,
885 SDB_DATA_NULL,
886 SDB_DATA_NULL,
887 SDB_DATA_NULL,
888 },
889 {
890 { SDB_TYPE_NULL, { .integer = 0 } },
891 { SDB_TYPE_STRING, { .string = "47.11" } },
892 SDB_DATA_NULL,
893 SDB_DATA_NULL,
894 SDB_DATA_NULL,
895 SDB_DATA_NULL,
896 SDB_DATA_NULL,
897 SDB_DATA_NULL,
898 },
899 {
900 { SDB_TYPE_STRING, { .string = "47.11" } },
901 { SDB_TYPE_NULL, { .integer = 0 } },
902 SDB_DATA_NULL,
903 SDB_DATA_NULL,
904 SDB_DATA_NULL,
905 SDB_DATA_NULL,
906 SDB_DATA_NULL,
907 SDB_DATA_NULL,
908 },
909 {
910 { SDB_TYPE_NULL, { .integer = 0 } },
911 { SDB_TYPE_DATETIME, { .datetime = 4711 } },
912 SDB_DATA_NULL,
913 SDB_DATA_NULL,
914 SDB_DATA_NULL,
915 SDB_DATA_NULL,
916 SDB_DATA_NULL,
917 SDB_DATA_NULL,
918 },
919 {
920 { SDB_TYPE_DATETIME, { .datetime = 4711 } },
921 { SDB_TYPE_NULL, { .integer = 0 } },
922 SDB_DATA_NULL,
923 SDB_DATA_NULL,
924 SDB_DATA_NULL,
925 SDB_DATA_NULL,
926 SDB_DATA_NULL,
927 SDB_DATA_NULL,
928 },
929 {
930 { SDB_TYPE_NULL, { .integer = 0 } },
931 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
932 SDB_DATA_NULL,
933 SDB_DATA_NULL,
934 SDB_DATA_NULL,
935 SDB_DATA_NULL,
936 SDB_DATA_NULL,
937 SDB_DATA_NULL,
938 },
939 {
940 { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
941 { SDB_TYPE_NULL, { .integer = 0 } },
942 SDB_DATA_NULL,
943 SDB_DATA_NULL,
944 SDB_DATA_NULL,
945 SDB_DATA_NULL,
946 SDB_DATA_NULL,
947 SDB_DATA_NULL,
948 },
949 {
950 { SDB_TYPE_NULL, { .integer = 0 } },
951 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
952 SDB_DATA_NULL,
953 SDB_DATA_NULL,
954 SDB_DATA_NULL,
955 SDB_DATA_NULL,
956 SDB_DATA_NULL,
957 SDB_DATA_NULL,
958 },
959 {
960 { SDB_TYPE_REGEX, { .re = { ".", empty_re } } },
961 { SDB_TYPE_NULL, { .integer = 0 } },
962 SDB_DATA_NULL,
963 SDB_DATA_NULL,
964 SDB_DATA_NULL,
965 SDB_DATA_NULL,
966 SDB_DATA_NULL,
967 SDB_DATA_NULL,
968 },
969 /* supported type-mismatches */
970 {
971 /* int * datetime */
972 { SDB_TYPE_INTEGER, { .integer = 20 } },
973 { SDB_TYPE_DATETIME, { .datetime = 2 } },
974 err,
975 err,
976 { SDB_TYPE_DATETIME, { .datetime = 40 } },
977 err,
978 err,
979 err,
980 },
981 {
982 /* datetime * int, datetime / int, datetime % int */
983 { SDB_TYPE_DATETIME, { .datetime = 20 } },
984 { SDB_TYPE_INTEGER, { .integer = 2 } },
985 err,
986 err,
987 { SDB_TYPE_DATETIME, { .datetime = 40 } },
988 { SDB_TYPE_DATETIME, { .datetime = 10 } },
989 { SDB_TYPE_DATETIME, { .datetime = 0 } },
990 err,
991 },
992 {
993 /* float * datetime */
994 { SDB_TYPE_DECIMAL, { .decimal = 20.0 } },
995 { SDB_TYPE_DATETIME, { .datetime = 2 } },
996 err,
997 err,
998 { SDB_TYPE_DATETIME, { .datetime = 40 } },
999 err,
1000 err,
1001 err,
1002 },
1003 {
1004 /* datetime * float, datetime / float, datetime % float */
1005 { SDB_TYPE_DATETIME, { .datetime = 20 } },
1006 { SDB_TYPE_DECIMAL, { .decimal = 2.0 } },
1007 err,
1008 err,
1009 { SDB_TYPE_DATETIME, { .datetime = 40 } },
1010 { SDB_TYPE_DATETIME, { .datetime = 10 } },
1011 { SDB_TYPE_DATETIME, { .datetime = 0 } },
1012 err,
1013 },
1014 };
1016 size_t i;
1018 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
1019 struct {
1020 int op;
1021 sdb_data_t expected;
1022 } tests[] = {
1023 { SDB_DATA_ADD, golden_data[i].expected_add },
1024 { SDB_DATA_SUB, golden_data[i].expected_sub },
1025 { SDB_DATA_MUL, golden_data[i].expected_mul },
1026 { SDB_DATA_DIV, golden_data[i].expected_div },
1027 { SDB_DATA_MOD, golden_data[i].expected_mod },
1028 { SDB_DATA_CONCAT, golden_data[i].expected_concat },
1029 };
1031 size_t j;
1032 for (j = 0; j < SDB_STATIC_ARRAY_LEN(tests); ++j) {
1033 sdb_data_t res;
1034 int check;
1036 char d1_str[64] = "", d2_str[64] = "";
1037 sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
1038 SDB_DOUBLE_QUOTED);
1039 sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
1040 SDB_DOUBLE_QUOTED);
1042 check = sdb_data_expr_eval(tests[j].op,
1043 &golden_data[i].d1, &golden_data[i].d2, &res);
1044 fail_unless((check == 0) == (tests[j].expected.type != -1),
1045 "sdb_data_expr_eval(%s, %s, %s) = %d; expected: %d",
1046 SDB_DATA_OP_TO_STRING(tests[j].op), d1_str, d2_str, check,
1047 tests[j].expected.type == -1 ? -1 : 0);
1048 if (tests[j].expected.type == -1)
1049 continue;
1051 if (tests[j].expected.type == SDB_TYPE_NULL) {
1052 fail_unless(res.type == SDB_TYPE_NULL,
1053 "sdb_data_expr_eval(%s, %s, %s) evaluated to "
1054 "type %d; expected: SDB_TYPE_NULL",
1055 SDB_DATA_OP_TO_STRING(tests[j].op),
1056 d1_str, d2_str, res.type);
1057 continue;
1058 }
1060 check = sdb_data_cmp(&res, &tests[j].expected);
1061 if (check != 0) {
1062 char res_str[64] = "", expected_str[64] = "";
1063 sdb_data_format(&res, res_str, sizeof(res_str),
1064 SDB_DOUBLE_QUOTED);
1065 sdb_data_format(&tests[j].expected, expected_str,
1066 sizeof(expected_str), SDB_DOUBLE_QUOTED);
1067 fail("sdb_data_expr_eval(%s, %s, %s) evaluated to %s "
1068 "(type %d); expected: %s (type %d)",
1069 SDB_DATA_OP_TO_STRING(tests[j].op),
1070 d1_str, d2_str, res_str, res.type,
1071 expected_str, tests[j].expected.type);
1072 }
1074 sdb_data_free_datum(&res);
1075 }
1076 }
1077 }
1078 END_TEST
1080 START_TEST(test_format)
1081 {
1082 struct {
1083 sdb_data_t datum;
1084 const char *expected;
1085 } golden_data[] = {
1086 {
1087 { SDB_TYPE_INTEGER, { .integer = 4711 } },
1088 "4711",
1089 },
1090 {
1091 { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
1092 "65536",
1093 },
1094 {
1095 { SDB_TYPE_DECIMAL, { .decimal = 12.3 } },
1096 "12.3",
1097 },
1098 {
1099 { SDB_TYPE_STRING, { .string = NULL } },
1100 "\"<NULL>\"",
1101 },
1102 {
1103 { SDB_TYPE_STRING, { .string = "this is a test" } },
1104 "\"this is a test\"",
1105 },
1106 {
1107 { SDB_TYPE_STRING, { .string = "special \\ \" characters" } },
1108 "\"special \\\\ \\\" characters\"",
1109 },
1110 {
1111 { SDB_TYPE_DATETIME, { .datetime= 471147114711471100 } },
1112 "\"1984-12-06 02:11:54 +0000\"",
1113 },
1114 {
1115 { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
1116 "\"<NULL>\"",
1117 },
1118 {
1119 {
1120 SDB_TYPE_BINARY,
1121 { .binary = { 12, (unsigned char *)"binary\0crap\x42" } },
1122 },
1123 "\"\\x62\\x69\\x6e\\x61\\x72\\x79\\x0\\x63\\x72\\x61\\x70\\x42\"",
1124 },
1125 {
1126 { SDB_TYPE_REGEX, { .re = { "some regex", empty_re } } },
1127 "\"/some regex/\"",
1128 },
1129 };
1131 size_t i;
1133 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
1134 sdb_data_t *datum = &golden_data[i].datum;
1135 char buf[sdb_data_strlen(datum) + 2];
1136 int check;
1138 memset(buf, (int)'A', sizeof(buf));
1140 check = sdb_data_format(datum, buf, sizeof(buf) - 1,
1141 SDB_DOUBLE_QUOTED);
1142 fail_unless(check > 0,
1143 "sdb_data_format(type=%s) = %d; expected: >0",
1144 SDB_TYPE_TO_STRING(datum->type), check);
1145 fail_unless(! strcmp(buf, golden_data[i].expected),
1146 "sdb_data_format(type=%s) used wrong format: %s; expected: %s",
1147 SDB_TYPE_TO_STRING(datum->type), buf, golden_data[i].expected);
1149 fail_unless((size_t)check <= sizeof(buf) - 2,
1150 "sdb_data_format(type=%s) wrote %d bytes; "
1151 "expected <= %zu based on sdb_data_strlen()",
1152 SDB_TYPE_TO_STRING(datum->type), check, sizeof(buf) - 2);
1154 fail_unless(buf[sizeof(buf) - 2] == '\0',
1155 "sdb_data_format(type=%s) did not nul-terminate the buffer",
1156 SDB_TYPE_TO_STRING(datum->type));
1157 fail_unless(buf[sizeof(buf) - 1] == 'A',
1158 "sdb_data_format(type=%s) wrote past the end of the buffer",
1159 SDB_TYPE_TO_STRING(datum->type));
1160 }
1161 }
1162 END_TEST
1164 START_TEST(test_parse)
1165 {
1166 struct {
1167 char *input;
1168 sdb_data_t result;
1169 int expected;
1170 } golden_data[] = {
1171 { "4711", { SDB_TYPE_INTEGER, { .integer = 4711 } }, 0 },
1172 { "0x10", { SDB_TYPE_INTEGER, { .integer = 16 } }, 0 },
1173 { "010", { SDB_TYPE_INTEGER, { .integer = 8 } }, 0 },
1174 { "abc", { SDB_TYPE_INTEGER, { .integer = 0 } }, -1 },
1175 { "1.2", { SDB_TYPE_DECIMAL, { .decimal = 1.2 } }, 0 },
1176 { "0x1p+16", { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } }, 0 },
1177 { "abc", { SDB_TYPE_DECIMAL, { .decimal = 0.0 } }, -1 },
1178 { "abc", { SDB_TYPE_STRING, { .string = "abc" } }, 0 },
1179 { ".4", { SDB_TYPE_DATETIME, { .datetime = 400000000 } }, 0 },
1180 { "abc", { SDB_TYPE_DATETIME, { .datetime = 0 } }, -1 },
1181 { "abc", { SDB_TYPE_BINARY,
1182 { .binary = { 3, (unsigned char *)"abc" } } }, 0 },
1183 { "abc", { SDB_TYPE_REGEX, { .re = { "abc", empty_re } } }, 0 },
1184 { "(|", { SDB_TYPE_REGEX, { .re = { "", empty_re } } }, -1 },
1185 };
1187 size_t i;
1189 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
1190 sdb_data_t result;
1191 int type, check;
1193 memset(&result, 0, sizeof(result));
1194 type = golden_data[i].result.type;
1195 check = sdb_data_parse(golden_data[i].input, type, &result);
1196 fail_unless(check == golden_data[i].expected,
1197 "sdb_data_parse(%s, %d, <d>) = %d; expected: %d",
1198 golden_data[i].input, type, check, golden_data[i].expected);
1200 if (check)
1201 continue;
1203 fail_unless(sdb_data_cmp(&result, &golden_data[i].result) == 0,
1204 "sdb_data_parse(%s, %d, <d>) did not create expected result",
1205 golden_data[i].input, type);
1207 if (type == SDB_TYPE_STRING)
1208 fail_unless(golden_data[i].input == result.data.string,
1209 "sdb_data_parse(%s, %d, <d>) modified input string",
1210 golden_data[i].input, type);
1211 if (type == SDB_TYPE_BINARY)
1212 fail_unless(golden_data[i].input == (char *)result.data.binary.datum,
1213 "sdb_data_parse(%s, %d, <d>) modified input string",
1214 golden_data[i].input, type);
1215 if (type == SDB_TYPE_REGEX) {
1216 fail_unless(golden_data[i].input != result.data.re.raw,
1217 "sdb_data_parse(%s, %d, <d>) copied input string",
1218 golden_data[i].input, type);
1219 sdb_data_free_datum(&result);
1220 }
1221 }
1222 }
1223 END_TEST
1225 Suite *
1226 core_data_suite(void)
1227 {
1228 Suite *s = suite_create("core::data");
1229 TCase *tc;
1231 tc = tcase_create("core");
1232 tcase_add_test(tc, test_data);
1233 tcase_add_test(tc, test_cmp);
1234 tcase_add_test(tc, test_strcmp);
1235 tcase_add_test(tc, test_parse_op);
1236 tcase_add_test(tc, test_expr_eval);
1237 tcase_add_test(tc, test_format);
1238 tcase_add_test(tc, test_parse);
1239 suite_add_tcase(s, tc);
1241 return s;
1242 } /* core_data_suite */
1244 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */