1 /*
2 * SysDB - t/unit/utils/proto_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 #if HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include "core/store.h"
33 #include "utils/proto.h"
34 #include "testutils.h"
36 #include <check.h>
37 #include <stdbool.h>
38 #include <stdio.h>
39 #include <string.h>
41 static bool
42 streq(const char *s1, const char *s2)
43 {
44 if ((! s1) || (! s2))
45 return (s1 == NULL) == (s2 == NULL);
46 return strcmp(s1, s2) == 0;
47 } /* streq */
49 START_TEST(test_marshal_data)
50 {
51 #define BOOL_TYPE "\0\0\0\1"
52 #define INT_TYPE "\0\0\0\2"
53 #define DECIMAL_TYPE "\0\0\0\3"
54 #define STRING_TYPE "\0\0\0\4"
55 #define DATETIME_TYPE "\0\0\0\5"
56 #define BINARY_TYPE "\0\0\0\6"
57 #define REGEX_TYPE "\0\0\0\7"
59 #define BOOL_ARRAY "\0\0\1\1"
60 #define NULL_ARRAY "\0\0\1\0"
61 #define INT_ARRAY "\0\0\1\2"
62 #define DECIMAL_ARRAY "\0\0\1\3"
63 #define STRING_ARRAY "\0\0\1\4"
64 #define DATETIME_ARRAY "\0\0\1\5"
65 #define BINARY_ARRAY "\0\0\1\6"
66 #define REGEX_ARRAY "\0\0\1\7"
68 regex_t dummy_re;
69 bool bool_values[] = { true, false };
70 int64_t int_values[] = { 47, 11, 23 };
71 double dec_values[] = { 47.11, .5 };
72 char *string_values[] = { "foo", "abcd" };
73 sdb_time_t datetime_values[] = { 4711, 1234567890123456789L };
74 struct {
75 size_t length;
76 unsigned char *datum;
77 } binary_values[] = {
78 { 3, (unsigned char *)"\x1\x2\x3" },
79 { 4, (unsigned char *)"\x42\x0\xa\x1b" },
80 };
81 struct {
82 char *raw;
83 regex_t regex;
84 } regex_values[] = {
85 { "dummy regex", dummy_re },
86 };
88 struct {
89 sdb_data_t datum;
90 ssize_t expected_len;
91 char *expected;
92 } golden_data[] = {
93 {
94 { SDB_TYPE_NULL, { .integer = 0 } },
95 4, "\0\0\0\0",
96 },
97 {
98 { SDB_TYPE_BOOLEAN, { .boolean = true } },
99 5, BOOL_TYPE "\1",
100 },
101 {
102 { SDB_TYPE_BOOLEAN, { .boolean = false } },
103 5, BOOL_TYPE "\0",
104 },
105 {
106 { SDB_TYPE_INTEGER, { .integer = 4711 } },
107 12, INT_TYPE "\0\0\0\0\0\0\x12\x67",
108 },
109 {
110 { SDB_TYPE_DECIMAL, { .decimal = 3.141592653e130 } },
111 12, DECIMAL_TYPE "\x5b\x6\xa9\x40\x66\x1e\x10\x4",
112 },
113 {
114 { SDB_TYPE_STRING, { .string = "some string" } },
115 16, STRING_TYPE "some string\0",
116 },
117 {
118 { SDB_TYPE_DATETIME, { .datetime = 1418923804000000 } },
119 12, DATETIME_TYPE "\x0\x5\xa\x80\xf1\x4c\xff\x0",
120 },
121 {
122 { SDB_TYPE_BINARY, { .binary = {
123 4, (unsigned char *)"\x42\x0\xa\x1b" } } },
124 12, BINARY_TYPE "\0\0\0\x4" "\x42\x0\xa\x1b",
125 },
126 {
127 { SDB_TYPE_REGEX, { .re = { "dummy", dummy_re } } },
128 10, REGEX_TYPE "dummy\0",
129 },
130 {
131 { SDB_TYPE_BOOLEAN | SDB_TYPE_ARRAY, { .array = {
132 SDB_STATIC_ARRAY_LEN(bool_values), bool_values,
133 } } },
134 10, BOOL_ARRAY "\0\0\0\x2" "\1\0"
135 },
136 {
137 { SDB_TYPE_INTEGER | SDB_TYPE_ARRAY, { .array = {
138 SDB_STATIC_ARRAY_LEN(int_values), int_values,
139 } } },
140 32, INT_ARRAY "\0\0\0\x3" "\0\0\0\0\0\0\0\x2f"
141 "\0\0\0\0\0\0\0\xb" "\0\0\0\0\0\0\0\x17"
142 },
143 {
144 { SDB_TYPE_DECIMAL | SDB_TYPE_ARRAY, { .array = {
145 SDB_STATIC_ARRAY_LEN(dec_values), dec_values,
146 } } },
147 24, DECIMAL_ARRAY "\0\0\0\x2" "\x40\x47\x8e\x14\x7a\xe1\x47\xae"
148 "\x3f\xe0\0\0\0\0\0\0"
149 },
150 {
151 { SDB_TYPE_STRING | SDB_TYPE_ARRAY, { .array = {
152 SDB_STATIC_ARRAY_LEN(string_values), string_values,
153 } } },
154 17, STRING_ARRAY "\0\0\0\x2" "foo\0" "abcd\0"
155 },
156 {
157 { SDB_TYPE_DATETIME | SDB_TYPE_ARRAY, { .array = {
158 SDB_STATIC_ARRAY_LEN(datetime_values), datetime_values,
159 } } },
160 24, DATETIME_ARRAY "\0\0\0\x2" "\0\0\0\0\0\0\x12\x67"
161 "\x11\x22\x10\xf4\x7d\xe9\x81\x15"
162 },
163 {
164 { SDB_TYPE_BINARY | SDB_TYPE_ARRAY, { .array = {
165 SDB_STATIC_ARRAY_LEN(binary_values), binary_values,
166 } } },
167 23, BINARY_ARRAY "\0\0\0\x2" "\0\0\0\x3" "\x1\x2\x3"
168 "\0\0\0\4" "\x42\x0\xa\x1b"
169 },
170 {
171 { SDB_TYPE_REGEX | SDB_TYPE_ARRAY, { .array = {
172 SDB_STATIC_ARRAY_LEN(regex_values), regex_values,
173 } } },
174 20, REGEX_ARRAY "\0\0\0\1" "dummy regex\0"
175 },
176 };
178 size_t i;
180 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
181 ssize_t len = sdb_proto_marshal_data(NULL, 0, &golden_data[i].datum);
182 char buf[len > 0 ? len : 1];
183 char v1[sdb_data_strlen(&golden_data[i].datum)];
184 char v2[sdb_data_strlen(&golden_data[i].datum)];
186 sdb_data_t datum = SDB_DATA_INIT;
187 ssize_t check;
189 if (! sdb_data_format(&golden_data[i].datum, v1, sizeof(v1), 0))
190 snprintf(v1, sizeof(v1), "<ERR>");
192 fail_unless(len == golden_data[i].expected_len,
193 "<%zu> sdb_proto_marshal_data(NULL, 0, %s) = %zi; expected: %zi",
194 i, v1, len, golden_data[i].expected_len);
196 if (len < 0)
197 continue;
199 len = sdb_proto_marshal_data(buf, sizeof(buf), &golden_data[i].datum);
200 fail_unless(len == golden_data[i].expected_len,
201 "<%zu> sdb_proto_marshal_data(<buf>, %zu, %s) = %zi; expected: %zi",
202 i, sizeof(buf), v1, len, golden_data[i].expected_len);
203 if (memcmp(buf, golden_data[i].expected, len) != 0) {
204 size_t pos;
205 for (pos = 0; pos < (size_t)len; ++pos)
206 if (buf[pos] != golden_data[i].expected[pos])
207 break;
208 fail("<%zu> sdb_proto_marshal_data(%s) -> \"%s\"; expected: \"%s\" "
209 "(bytes %zu differ: '%x' != '%x')",
210 i, v1, buf, golden_data[i].expected,
211 pos, (int)buf[pos], (int)golden_data[i].expected[pos]);
212 }
214 check = sdb_proto_unmarshal_data(buf, len, &datum);
215 if (! sdb_data_format(&datum, v2, sizeof(v2), 0))
216 snprintf(v2, sizeof(v2), "<ERR>");
218 if (sdb_data_isnull(&golden_data[i].datum))
219 fail_unless(sdb_data_isnull(&datum),
220 "<%zu> sdb_proto_unmarshal_data(buf<%s>) -> \"%s\"", i, v1, v2);
221 else
222 fail_unless(sdb_data_cmp(&golden_data[i].datum, &datum) == 0,
223 "<%zu> sdb_proto_unmarshal_data(buf<%s>) -> \"%s\"", i, v1, v2);
224 fail_unless(check == len,
225 "<%zu> sdb_proto_unmarshal_data(buf<%s>) = %zi; expected: %zi",
226 i, v1, check, len);
228 sdb_data_free_datum(&datum);
229 }
230 }
231 END_TEST
233 #define HOST_TYPE "\0\0\0\1"
234 #define SVC_TYPE "\0\0\0\2"
235 #define METRIC_TYPE "\0\0\0\3"
236 #define HOST_ATTR_TYPE "\0\0\0\x11"
237 #define SVC_ATTR_TYPE "\0\0\0\x12"
238 #define METRIC_ATTR_TYPE "\0\0\0\x13"
240 START_TEST(test_marshal_host)
241 {
242 struct {
243 sdb_proto_host_t host;
244 ssize_t expected_len;
245 char *expected;
246 } golden_data[] = {
247 {
248 { 4711, "hostA" },
249 18, HOST_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0"
250 },
251 {
252 { 0, "hostA" },
253 18, HOST_TYPE "\0\0\0\0\0\0\0\0" "hostA\0"
254 },
255 { { 4711, NULL }, -1, NULL },
256 };
258 size_t i;
260 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
261 ssize_t len = sdb_proto_marshal_host(NULL, 0, &golden_data[i].host);
262 char buf[len > 0 ? len : 1];
264 sdb_proto_host_t host;
265 ssize_t check;
267 fail_unless(len == golden_data[i].expected_len,
268 "<%zu> sdb_proto_marshal_host(NULL, 0, %s) = %zi; expected: %zi",
269 i, golden_data[i].host.name, len, golden_data[i].expected_len);
271 if (len < 0)
272 continue;
274 len = sdb_proto_marshal_host(buf, sizeof(buf), &golden_data[i].host);
275 fail_unless(len == golden_data[i].expected_len,
276 "<%zu> sdb_proto_marshal_host(<buf>, %zu, %s) = %zi; expected: %zi",
277 i, sizeof(buf), golden_data[i].host.name,
278 len, golden_data[i].expected_len);
279 if (memcmp(buf, golden_data[i].expected, len) != 0) {
280 size_t pos;
281 for (pos = 0; pos < (size_t)len; ++pos)
282 if (buf[pos] != golden_data[i].expected[pos])
283 break;
284 fail("<%zu> sdb_proto_marshal_host(%s) -> \"%s\"; expected: \"%s\" "
285 "(bytes %zu differ: '%x' != '%x')",
286 i, golden_data[i].host.name, buf, golden_data[i].expected,
287 pos, (int)buf[pos], (int)golden_data[i].expected[pos]);
288 }
290 check = sdb_proto_unmarshal_host(buf, len, &host);
291 fail_unless(check == len,
292 "<%zu> sdb_proto_unmarshal_host(buf<%s>) = %zi; expected: %zi",
293 i, golden_data[i].host.name, check, len);
294 fail_unless((host.last_update == golden_data[i].host.last_update)
295 && streq(host.name, golden_data[i].host.name),
296 "<%zu> sdb_proto_unmarshal_host(buf<%s>) = { %"PRIsdbTIME", %s }; "
297 "expected: { %"PRIsdbTIME", %s }", i, golden_data[i].host.name,
298 host.last_update, host.name, golden_data[i].host.last_update,
299 golden_data[i].host.name);
300 }
301 }
302 END_TEST
304 START_TEST(test_marshal_service)
305 {
306 struct {
307 sdb_proto_service_t svc;
308 ssize_t expected_len;
309 char *expected;
310 } golden_data[] = {
311 {
312 { 4711, "hostA", "serviceX" },
313 27, SVC_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0serviceX\0"
314 },
315 {
316 { 0, "hostA", "serviceX" },
317 27, SVC_TYPE "\0\0\0\0\0\0\0\0" "hostA\0serviceX\0"
318 },
319 { { 4711, "hostA", NULL }, -1, NULL },
320 { { 4711, NULL, "serviceX" }, -1, NULL },
321 { { 4711, NULL, NULL }, -1, NULL },
322 };
324 size_t i;
326 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
327 ssize_t len = sdb_proto_marshal_service(NULL, 0, &golden_data[i].svc);
328 char buf[len > 0 ? len : 1];
330 sdb_proto_service_t svc;
331 ssize_t check;
333 fail_unless(len == golden_data[i].expected_len,
334 "<%zu> sdb_proto_marshal_service(NULL, 0, %s) = %zi; expected: %zi",
335 i, golden_data[i].svc.name, len, golden_data[i].expected_len);
337 if (len < 0)
338 continue;
340 len = sdb_proto_marshal_service(buf, sizeof(buf), &golden_data[i].svc);
341 fail_unless(len == golden_data[i].expected_len,
342 "<%zu> sdb_proto_marshal_service(<buf>, %zu, %s) = %zi; expected: %zi",
343 i, sizeof(buf), golden_data[i].svc.name,
344 len, golden_data[i].expected_len);
345 if (memcmp(buf, golden_data[i].expected, len) != 0) {
346 size_t pos;
347 for (pos = 0; pos < (size_t)len; ++pos)
348 if (buf[pos] != golden_data[i].expected[pos])
349 break;
350 fail("<%zu> sdb_proto_marshal_service(%s) -> \"%s\"; expected: \"%s\" "
351 "(bytes %zu differ: '%x' != '%x')",
352 i, golden_data[i].svc.name, buf, golden_data[i].expected,
353 pos, (int)buf[pos], (int)golden_data[i].expected[pos]);
354 }
356 check = sdb_proto_unmarshal_service(buf, len, &svc);
357 fail_unless(check == len,
358 "<%zu> sdb_proto_unmarshal_service(buf<%s>) = %zi; expected: %zi",
359 i, golden_data[i].svc.name, check, len);
360 fail_unless((svc.last_update == golden_data[i].svc.last_update)
361 && streq(svc.hostname, golden_data[i].svc.hostname)
362 && streq(svc.name, golden_data[i].svc.name),
363 "<%zu> sdb_proto_unmarshal_service(buf<%s>) = { %"PRIsdbTIME", %s, %s }; "
364 "expected: { %"PRIsdbTIME", %s, %s }", i, golden_data[i].svc.name,
365 svc.last_update, svc.hostname, svc.name, golden_data[i].svc.last_update,
366 golden_data[i].svc.hostname, golden_data[i].svc.name);
367 }
368 }
369 END_TEST
371 START_TEST(test_marshal_metric)
372 {
373 struct {
374 sdb_proto_metric_t metric;
375 ssize_t expected_len;
376 char *expected;
377 } golden_data[] = {
378 {
379 { 4711, "hostA", "metricX", NULL, NULL, 0 },
380 26, METRIC_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0metricX\0"
381 },
382 {
383 { 0, "hostA", "metricX", NULL, NULL, 0 },
384 26, METRIC_TYPE "\0\0\0\0\0\0\0\0" "hostA\0metricX\0"
385 },
386 {
387 { 0, "hostA", "metricX", "type", NULL, 0 },
388 26, METRIC_TYPE "\0\0\0\0\0\0\0\0" "hostA\0metricX\0"
389 },
390 {
391 { 0, "hostA", "metricX", NULL, "id", 0 },
392 26, METRIC_TYPE "\0\0\0\0\0\0\0\0" "hostA\0metricX\0"
393 },
394 {
395 { 0, "hostA", "metricX", NULL, NULL, 4711 },
396 26, METRIC_TYPE "\0\0\0\0\0\0\0\0" "hostA\0metricX\0"
397 },
398 {
399 { 4711, "hostA", "metricX", "type", "id", 0 },
400 34, METRIC_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0metricX\0type\0id\0"
401 },
402 {
403 { 4711, "hostA", "metricX", "type", "id", 4711 },
404 42, METRIC_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0metricX\0type\0id\0" "\0\0\0\0\0\0\x12\x67"
405 },
406 { { 4711, "hostA", NULL, NULL, NULL, 0 }, -1, NULL },
407 { { 4711, NULL, "metricX", NULL, NULL, 0 }, -1, NULL },
408 { { 4711, NULL, NULL, NULL, NULL, 0 }, -1, NULL },
409 };
411 size_t i;
413 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
414 ssize_t len = sdb_proto_marshal_metric(NULL, 0, &golden_data[i].metric);
415 char buf[len > 0 ? len : 1];
417 sdb_proto_metric_t metric;
418 ssize_t check;
420 fail_unless(len == golden_data[i].expected_len,
421 "<%zu> sdb_proto_marshal_metric(NULL, 0, %s) = %zi; expected: %zi",
422 i, golden_data[i].metric.name, len, golden_data[i].expected_len);
424 if (len < 0)
425 continue;
427 len = sdb_proto_marshal_metric(buf, sizeof(buf), &golden_data[i].metric);
428 fail_unless(len == golden_data[i].expected_len,
429 "<%zu> sdb_proto_marshal_metric(<buf>, %zu, %s) = %zi; expected: %zi",
430 i, sizeof(buf), golden_data[i].metric.name,
431 len, golden_data[i].expected_len);
432 if (memcmp(buf, golden_data[i].expected, len) != 0) {
433 size_t pos;
434 for (pos = 0; pos < (size_t)len; ++pos)
435 if (buf[pos] != golden_data[i].expected[pos])
436 break;
437 fail("<%zu> sdb_proto_marshal_metric(%s) -> \"%s\"; expected: \"%s\" "
438 "(bytes %zu differ: '%x' != '%x')",
439 i, golden_data[i].metric.name, buf, golden_data[i].expected,
440 pos, (int)buf[pos], (int)golden_data[i].expected[pos]);
441 }
443 if ((! golden_data[i].metric.store_type)
444 || (! golden_data[i].metric.store_id)) {
445 /* if any of these is NULL, we expect all to be NULL */
446 golden_data[i].metric.store_type = NULL;
447 golden_data[i].metric.store_id = NULL;
448 golden_data[i].metric.store_last_update = 0;
449 }
451 check = sdb_proto_unmarshal_metric(buf, len, &metric);
452 fail_unless(check == len,
453 "<%zu> sdb_proto_unmarshal_metric(buf<%s>) = %zi; expected: %zi",
454 i, golden_data[i].metric.name, check, len);
455 fail_unless((metric.last_update == golden_data[i].metric.last_update)
456 && streq(metric.hostname, golden_data[i].metric.hostname)
457 && streq(metric.name, golden_data[i].metric.name)
458 && streq(metric.store_type, golden_data[i].metric.store_type)
459 && streq(metric.store_id, golden_data[i].metric.store_id)
460 && metric.store_last_update == golden_data[i].metric.store_last_update,
461 "<%zu> sdb_proto_unmarshal_metric(buf<%s>) = "
462 "{ %"PRIsdbTIME", %s, %s, %s, %s, %"PRIsdbTIME" }; expected: "
463 "{ %"PRIsdbTIME", %s, %s, %s, %s, %"PRIsdbTIME" }",
464 i, golden_data[i].metric.name,
465 metric.last_update, metric.hostname, metric.name,
466 metric.store_type, metric.store_id, metric.store_last_update,
467 golden_data[i].metric.last_update,
468 golden_data[i].metric.hostname, golden_data[i].metric.name,
469 golden_data[i].metric.store_type, golden_data[i].metric.store_id,
470 golden_data[i].metric.store_last_update);
471 }
472 }
473 END_TEST
475 START_TEST(test_marshal_attribute)
476 {
477 sdb_data_t v = { SDB_TYPE_INTEGER, { .integer = 4711 } };
478 #define VAL "\0\0\0\2" "\0\0\0\0\0\0\x12\x67"
479 struct {
480 sdb_proto_attribute_t attr;
481 ssize_t expected_len;
482 char *expected;
483 } golden_data[] = {
484 {
485 { 4711, SDB_HOST, NULL, "hostA", "k1", v },
486 33, HOST_ATTR_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0" "k1\0" VAL
487 },
488 {
489 { 4711, SDB_SERVICE, "hostA", "svc1", "k1", v },
490 38, SVC_ATTR_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0" "svc1\0" "k1\0" VAL
491 },
492 {
493 { 4711, SDB_METRIC, "hostA", "m1", "k1", v },
494 36, METRIC_ATTR_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0" "m1\0" "k1\0" VAL
495 },
496 { { 4711, SDB_HOST, NULL, NULL, "k1", v }, -1, NULL },
497 { { 4711, SDB_HOST, NULL, "hostA", NULL, v }, -1, NULL },
498 { { 4711, SDB_SERVICE, NULL, "svc1", "k1", v }, -1, NULL },
499 { { 4711, SDB_METRIC, NULL, "m1", "k1", v }, -1, NULL },
500 { { 4711, 0, "hostA", "svc1", "k1", v }, -1, NULL },
501 };
503 size_t i;
505 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
506 ssize_t len = sdb_proto_marshal_attribute(NULL, 0, &golden_data[i].attr);
507 char buf[len > 0 ? len : 1];
509 sdb_proto_attribute_t attr;
510 ssize_t check;
511 char v1[sdb_data_strlen(&golden_data[i].attr.value) + 1];
512 char v2[sdb_data_strlen(&golden_data[i].attr.value) + 1];
514 fail_unless(len == golden_data[i].expected_len,
515 "<%zu> sdb_proto_marshal_attribute(NULL, 0, %s) = %zi; expected: %zi",
516 i, golden_data[i].attr.key, len, golden_data[i].expected_len);
518 if (len < 0)
519 continue;
521 len = sdb_proto_marshal_attribute(buf, sizeof(buf), &golden_data[i].attr);
522 fail_unless(len == golden_data[i].expected_len,
523 "<%zu> sdb_proto_marshal_attribute(<buf>, %zu, %s) = %zi; expected: %zi",
524 i, sizeof(buf), golden_data[i].attr.key,
525 len, golden_data[i].expected_len);
526 if (memcmp(buf, golden_data[i].expected, len) != 0) {
527 size_t pos;
528 for (pos = 0; pos < (size_t)len; ++pos)
529 if (buf[pos] != golden_data[i].expected[pos])
530 break;
531 fail("<%zu> sdb_proto_marshal_attribute(%s) -> \"%s\"; expected: \"%s\" "
532 "(bytes %zu differ: '%x' != '%x')",
533 i, golden_data[i].attr.key, buf, golden_data[i].expected,
534 pos, (int)buf[pos], (int)golden_data[i].expected[pos]);
535 }
537 if (! sdb_data_format(&golden_data[i].attr.value, v1, sizeof(v1), 0))
538 snprintf(v1, sizeof(v1), "<ERR>");
540 check = sdb_proto_unmarshal_attribute(buf, len, &attr);
541 fail_unless(check == len,
542 "<%zu> sdb_proto_unmarshal_attribute(buf<%s>) = %zi; expected: %zi",
543 i, golden_data[i].attr.key, check, len);
545 if (! sdb_data_format(&attr.value, v2, sizeof(v2), 0))
546 snprintf(v2, sizeof(v2), "<ERR>");
547 fail_unless((attr.last_update == golden_data[i].attr.last_update)
548 && (attr.parent_type == golden_data[i].attr.parent_type)
549 && streq(attr.hostname, golden_data[i].attr.hostname)
550 && streq(attr.parent, golden_data[i].attr.parent)
551 && streq(attr.key, golden_data[i].attr.key)
552 && (sdb_data_cmp(&attr.value, &golden_data[i].attr.value) == 0),
553 "<%zu> sdb_proto_unmarshal_attribute(buf<%s>) = "
554 "{ %"PRIsdbTIME", %s, %s, %s, %s, %s }; expected: "
555 "{ %"PRIsdbTIME", %s, %s, %s, %s, %s }", i, golden_data[i].attr.key,
556 attr.last_update, SDB_STORE_TYPE_TO_NAME(attr.parent_type),
557 attr.hostname, attr.parent, attr.key, v1,
558 golden_data[i].attr.last_update,
559 SDB_STORE_TYPE_TO_NAME(golden_data[i].attr.parent_type),
560 golden_data[i].attr.hostname, golden_data[i].attr.parent,
561 golden_data[i].attr.key, v2);
562 }
563 }
564 END_TEST
566 TEST_MAIN("utils::proto")
567 {
568 TCase *tc = tcase_create("core");
569 tcase_add_test(tc, test_marshal_data);
570 tcase_add_test(tc, test_marshal_host);
571 tcase_add_test(tc, test_marshal_service);
572 tcase_add_test(tc, test_marshal_metric);
573 tcase_add_test(tc, test_marshal_attribute);
574 ADD_TCASE(tc);
575 }
576 TEST_MAIN_END
578 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */