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");
107 }
108 END_TEST
110 START_TEST(test_cmp)
111 {
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 }
289 }
290 END_TEST
292 START_TEST(test_format)
293 {
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 }
365 }
366 END_TEST
368 Suite *
369 core_data_suite(void)
370 {
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 : */