Code

e0ff3a88cb9c5d684bcb66345dd3df7977b12e71
[sysdb.git] / t / unit / core / data_test.c
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 <check.h>
33 START_TEST(test_data)
34 {
35         sdb_data_t d1, d2;
36         int check;
38         d2.type = SDB_TYPE_INTEGER;
39         d2.data.integer = 4711;
40         check = sdb_data_copy(&d1, &d2);
41         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
42         fail_unless(d1.type == d2.type,
43                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
44                         d1.type, d2.type);
45         fail_unless(d1.data.integer == d2.data.integer,
46                         "sdb_data_copy() didn't copy integer data: got: %d; expected: %d",
47                         d1.data.integer, d2.data.integer);
49         d2.type = SDB_TYPE_DECIMAL;
50         d2.data.decimal = 47.11;
51         check = sdb_data_copy(&d1, &d2);
52         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
53         fail_unless(d1.type == d2.type,
54                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
55                         d1.type, d2.type);
56         fail_unless(d1.data.decimal == d2.data.decimal,
57                         "sdb_data_copy() didn't copy decimal data: got: %f; expected: %f",
58                         d1.data.decimal, d2.data.decimal);
60         d2.type = SDB_TYPE_STRING;
61         d2.data.string = "some string";
62         check = sdb_data_copy(&d1, &d2);
63         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
64         fail_unless(d1.type == d2.type,
65                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
66                         d1.type, d2.type);
67         fail_unless(!strcmp(d1.data.string, d2.data.string),
68                         "sdb_data_copy() didn't copy string data: got: %s; expected: %s",
69                         d1.data.string, d2.data.string);
71         sdb_data_free_datum(&d1);
72         fail_unless(d1.data.string == NULL,
73                         "sdb_data_free_datum() didn't free string data");
75         d2.type = SDB_TYPE_DATETIME;
76         d2.data.datetime = 4711;
77         check = sdb_data_copy(&d1, &d2);
78         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
79         fail_unless(d1.type == d2.type,
80                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
81                         d1.type, d2.type);
82         fail_unless(d1.data.datetime == d2.data.datetime,
83                         "sdb_data_copy() didn't copy datetime data: got: %d; expected: %d",
84                         d1.data.datetime, d2.data.datetime);
86         d2.type = SDB_TYPE_BINARY;
87         d2.data.binary.datum = (unsigned char *)"some string";
88         d2.data.binary.length = strlen((const char *)d2.data.binary.datum);
89         check = sdb_data_copy(&d1, &d2);
90         fail_unless(!check, "sdb_data_copy() = %i; expected: 0", check);
91         fail_unless(d1.type == d2.type,
92                         "sdb_data_copy() didn't copy type; got: %i; expected: %i",
93                         d1.type, d2.type);
94         fail_unless(d1.data.binary.length == d2.data.binary.length,
95                         "sdb_data_copy() didn't copy length; got: %d; expected: 5d",
96                         d1.data.binary.length, d2.data.binary.length);
97         fail_unless(!memcmp(d1.data.binary.datum, d2.data.binary.datum,
98                                 d2.data.binary.length),
99                         "sdb_data_copy() didn't copy binary data: got: %s; expected: %s",
100                         d1.data.string, d2.data.string);
102         sdb_data_free_datum(&d1);
103         fail_unless(d1.data.binary.length == 0,
104                         "sdb_data_free_datum() didn't reset binary datum length");
105         fail_unless(d1.data.binary.datum == NULL,
106                         "sdb_data_free_datum() didn't free binary datum");
108 END_TEST
110 START_TEST(test_cmp)
112         struct {
113                 sdb_data_t d1;
114                 sdb_data_t d2;
115                 int expected;
116         } golden_data[] = {
117                 {
118                         { SDB_TYPE_INTEGER, { .integer = 47 } },
119                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
120                         -1,
121                 },
122                 {
123                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
124                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
125                         0,
126                 },
127                 {
128                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
129                         { SDB_TYPE_INTEGER, { .integer = 47 } },
130                         1,
131                 },
132                 {
133                         { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
134                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
135                         -1,
136                 },
137                 {
138                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
139                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
140                         0,
141                 },
142                 {
143                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
144                         { SDB_TYPE_DECIMAL, { .decimal = 65535.9 } },
145                         1,
146                 },
147                 {
148                         { SDB_TYPE_STRING, { .string = NULL } },
149                         { SDB_TYPE_STRING, { .string = "" } },
150                         -1,
151                 },
152                 {
153                         { SDB_TYPE_STRING, { .string = NULL } },
154                         { SDB_TYPE_STRING, { .string = NULL } },
155                         0,
156                 },
157                 {
158                         { SDB_TYPE_STRING, { .string = "" } },
159                         { SDB_TYPE_STRING, { .string = NULL } },
160                         1,
161                 },
162                 {
163                         { SDB_TYPE_STRING, { .string = "a" } },
164                         { SDB_TYPE_STRING, { .string = "b" } },
165                         -1,
166                 },
167                 {
168                         { SDB_TYPE_STRING, { .string = "a" } },
169                         { SDB_TYPE_STRING, { .string = "ab" } },
170                         -1,
171                 },
172                 {
173                         { SDB_TYPE_STRING, { .string = "a" } },
174                         { SDB_TYPE_STRING, { .string = "a" } },
175                         0,
176                 },
177                 {
178                         { SDB_TYPE_STRING, { .string = "b" } },
179                         { SDB_TYPE_STRING, { .string = "a" } },
180                         1,
181                 },
182                 {
183                         { SDB_TYPE_STRING, { .string = "ab" } },
184                         { SDB_TYPE_STRING, { .string = "a" } },
185                         1,
186                 },
187                 {
188                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471000 } },
189                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
190                         -1,
191                 },
192                 {
193                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
194                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
195                         0,
196                 },
197                 {
198                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471100 } },
199                         { SDB_TYPE_DATETIME, { .datetime = 471147114711471000 } },
200                         1,
201                 },
202                 {
203                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
204                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
205                         -1,
206                 },
207                 {
208                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
209                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
210                         0,
211                 },
212                 {
213                         { SDB_TYPE_BINARY, { .binary = { 1, (unsigned char *)"a" } } },
214                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
215                         1,
216                 },
217                 {
218                         {
219                                 SDB_TYPE_BINARY,
220                                 { .binary = { 3, (unsigned char *)"a\0a" } },
221                         },
222                         {
223                                 SDB_TYPE_BINARY,
224                                 { .binary = { 3, (unsigned char *)"a\0b" } },
225                         },
226                         -1,
227                 },
228                 {
229                         {
230                                 SDB_TYPE_BINARY,
231                                 { .binary = { 1, (unsigned char *)"a" } },
232                         },
233                         {
234                                 SDB_TYPE_BINARY,
235                                 { .binary = { 3, (unsigned char *)"a\0\0" } },
236                         },
237                         -1,
238                 },
239                 {
240                         {
241                                 SDB_TYPE_BINARY,
242                                 { .binary = { 3, (unsigned char *)"a\0a" } },
243                         },
244                         {
245                                 SDB_TYPE_BINARY,
246                                 { .binary = { 3, (unsigned char *)"a\0a" } },
247                         },
248                         0,
249                 },
250                 {
251                         {
252                                 SDB_TYPE_BINARY,
253                                 { .binary = { 3, (unsigned char *)"a\0b" } },
254                         },
255                         {
256                                 SDB_TYPE_BINARY,
257                                 { .binary = { 3, (unsigned char *)"a\0a" } },
258                         },
259                         1,
260                 },
261                 {
262                         {
263                                 SDB_TYPE_BINARY,
264                                 { .binary = { 3, (unsigned char *)"a\0\0" } },
265                         },
266                         {
267                                 SDB_TYPE_BINARY,
268                                 { .binary = { 1, (unsigned char *)"a" } },
269                         },
270                         1,
271                 },
272         };
274         size_t i;
276         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
277                 int check = sdb_data_cmp(&golden_data[i].d1, &golden_data[i].d2);
278                 check = check < 0 ? -1 : check > 0 ? 1 : 0;
279                 if (check != golden_data[i].expected) {
280                         char d1_str[64] = "", d2_str[64] = "";
281                         sdb_data_format(&golden_data[i].d1, d1_str, sizeof(d1_str),
282                                         SDB_DOUBLE_QUOTED);
283                         sdb_data_format(&golden_data[i].d2, d2_str, sizeof(d2_str),
284                                         SDB_DOUBLE_QUOTED);
285                         fail("sdb_data_cmp(%s, %s) = %d; expected: %d",
286                                         d1_str, d2_str, check, golden_data[i].expected);
287                 }
288         }
290 END_TEST
292 START_TEST(test_format)
294         struct {
295                 sdb_data_t datum;
296                 const char *expected;
297         } golden_data[] = {
298                 {
299                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
300                         "4711",
301                 },
302                 {
303                         { SDB_TYPE_DECIMAL, { .decimal = 65536.0 } },
304                         "0x1p+16",
305                 },
306                 {
307                         { SDB_TYPE_STRING, { .string = NULL } },
308                         "\"NULL\"",
309                 },
310                 {
311                         { SDB_TYPE_STRING, { .string = "this is a test" } },
312                         "\"this is a test\"",
313                 },
314                 {
315                         { SDB_TYPE_STRING, { .string = "special \\ \" characters" } },
316                         "\"special \\\\ \\\" characters\"",
317                 },
318                 {
319                         { SDB_TYPE_DATETIME, { .datetime= 471147114711471100 } },
320                         "\"1984-12-06 02:11:54 +0000\"",
321                 },
322                 {
323                         { SDB_TYPE_BINARY, { .binary = { 0, NULL } } },
324                         "\"\"",
325                 },
326                 {
327                         {
328                                 SDB_TYPE_BINARY,
329                                 { .binary = { 12, (unsigned char *)"binary\0crap\x42" } },
330                         },
331                         "\"\\x62\\x69\\x6e\\x61\\x72\\x79\\x0\\x63\\x72\\x61\\x70\\x42\"",
332                 },
333         };
335         size_t i;
337         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
338                 sdb_data_t *datum = &golden_data[i].datum;
339                 char buf[sdb_data_strlen(datum) + 2];
340                 int check;
342                 memset(buf, (int)'A', sizeof(buf));
344                 check = sdb_data_format(datum, buf, sizeof(buf) - 1,
345                                 SDB_DOUBLE_QUOTED);
346                 fail_unless(check > 0,
347                                 "sdb_data_format(type=%s) = %d; expected: >0",
348                                 SDB_TYPE_TO_STRING(datum->type), check);
349                 fail_unless(! strcmp(buf, golden_data[i].expected),
350                                 "sdb_data_format(type=%s) used wrong format: %s; expected: %s",
351                                 SDB_TYPE_TO_STRING(datum->type), buf, golden_data[i].expected);
353                 fail_unless((size_t)check <= sizeof(buf) - 2,
354                                 "sdb_data_format(type=%s) wrote %d bytes; "
355                                 "expected <= %zu based on sdb_data_strlen()",
356                                 SDB_TYPE_TO_STRING(datum->type), check, sizeof(buf) - 2);
358                 fail_unless(buf[sizeof(buf) - 2] == '\0',
359                                 "sdb_data_format(type=%s) did not nul-terminate the buffer",
360                                 SDB_TYPE_TO_STRING(datum->type));
361                 fail_unless(buf[sizeof(buf) - 1] == 'A',
362                                 "sdb_data_format(type=%s) wrote past the end of the buffer",
363                                 SDB_TYPE_TO_STRING(datum->type));
364         }
366 END_TEST
368 Suite *
369 core_data_suite(void)
371         Suite *s = suite_create("core::data");
372         TCase *tc;
374         tc = tcase_create("core");
375         tcase_add_test(tc, test_data);
376         tcase_add_test(tc, test_cmp);
377         tcase_add_test(tc, test_format);
378         suite_add_tcase(s, tc);
380         return s;
381 } /* core_data_suite */
383 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */