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 },
380 26, METRIC_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0metricX\0"
381 },
382 {
383 { 0, "hostA", "metricX", NULL, NULL },
384 26, METRIC_TYPE "\0\0\0\0\0\0\0\0" "hostA\0metricX\0"
385 },
386 {
387 { 0, "hostA", "metricX", "type", NULL },
388 26, METRIC_TYPE "\0\0\0\0\0\0\0\0" "hostA\0metricX\0"
389 },
390 {
391 { 0, "hostA", "metricX", NULL, "id" },
392 26, METRIC_TYPE "\0\0\0\0\0\0\0\0" "hostA\0metricX\0"
393 },
394 {
395 { 4711, "hostA", "metricX", "type", "id" },
396 34, METRIC_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0metricX\0type\0id\0"
397 },
398 { { 4711, "hostA", NULL, NULL, NULL }, -1, NULL },
399 { { 4711, NULL, "metricX", NULL, NULL }, -1, NULL },
400 { { 4711, NULL, NULL, NULL, NULL }, -1, NULL },
401 };
403 size_t i;
405 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
406 ssize_t len = sdb_proto_marshal_metric(NULL, 0, &golden_data[i].metric);
407 char buf[len > 0 ? len : 1];
409 sdb_proto_metric_t metric;
410 ssize_t check;
412 fail_unless(len == golden_data[i].expected_len,
413 "<%zu> sdb_proto_marshal_metric(NULL, 0, %s) = %zi; expected: %zi",
414 i, golden_data[i].metric.name, len, golden_data[i].expected_len);
416 if (len < 0)
417 continue;
419 len = sdb_proto_marshal_metric(buf, sizeof(buf), &golden_data[i].metric);
420 fail_unless(len == golden_data[i].expected_len,
421 "<%zu> sdb_proto_marshal_metric(<buf>, %zu, %s) = %zi; expected: %zi",
422 i, sizeof(buf), golden_data[i].metric.name,
423 len, golden_data[i].expected_len);
424 if (memcmp(buf, golden_data[i].expected, len) != 0) {
425 size_t pos;
426 for (pos = 0; pos < (size_t)len; ++pos)
427 if (buf[pos] != golden_data[i].expected[pos])
428 break;
429 fail("<%zu> sdb_proto_marshal_metric(%s) -> \"%s\"; expected: \"%s\" "
430 "(bytes %zu differ: '%x' != '%x')",
431 i, golden_data[i].metric.name, buf, golden_data[i].expected,
432 pos, (int)buf[pos], (int)golden_data[i].expected[pos]);
433 }
435 if ((! golden_data[i].metric.store_type)
436 || (! golden_data[i].metric.store_id)) {
437 /* if any of these is NULL, we expect both to be NULL */
438 golden_data[i].metric.store_type = NULL;
439 golden_data[i].metric.store_id = NULL;
440 }
442 check = sdb_proto_unmarshal_metric(buf, len, &metric);
443 fail_unless(check == len,
444 "<%zu> sdb_proto_unmarshal_metric(buf<%s>) = %zi; expected: %zi",
445 i, golden_data[i].metric.name, check, len);
446 fail_unless((metric.last_update == golden_data[i].metric.last_update)
447 && streq(metric.hostname, golden_data[i].metric.hostname)
448 && streq(metric.name, golden_data[i].metric.name)
449 && streq(metric.store_type, golden_data[i].metric.store_type)
450 && streq(metric.store_id, golden_data[i].metric.store_id),
451 "<%zu> sdb_proto_unmarshal_metric(buf<%s>) = "
452 "{ %"PRIsdbTIME", %s, %s, %s, %s }; expected: "
453 "{ %"PRIsdbTIME", %s, %s, %s, %s }", i, golden_data[i].metric.name,
454 metric.last_update, metric.hostname, metric.name,
455 metric.store_type, metric.store_id,
456 golden_data[i].metric.last_update,
457 golden_data[i].metric.hostname, golden_data[i].metric.name,
458 golden_data[i].metric.store_type, golden_data[i].metric.store_id);
459 }
460 }
461 END_TEST
463 START_TEST(test_marshal_attribute)
464 {
465 sdb_data_t v = { SDB_TYPE_INTEGER, { .integer = 4711 } };
466 #define VAL "\0\0\0\2" "\0\0\0\0\0\0\x12\x67"
467 struct {
468 sdb_proto_attribute_t attr;
469 ssize_t expected_len;
470 char *expected;
471 } golden_data[] = {
472 {
473 { 4711, SDB_HOST, NULL, "hostA", "k1", v },
474 33, HOST_ATTR_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0" "k1\0" VAL
475 },
476 {
477 { 4711, SDB_SERVICE, "hostA", "svc1", "k1", v },
478 38, SVC_ATTR_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0" "svc1\0" "k1\0" VAL
479 },
480 {
481 { 4711, SDB_METRIC, "hostA", "m1", "k1", v },
482 36, METRIC_ATTR_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0" "m1\0" "k1\0" VAL
483 },
484 { { 4711, SDB_HOST, NULL, NULL, "k1", v }, -1, NULL },
485 { { 4711, SDB_HOST, NULL, "hostA", NULL, v }, -1, NULL },
486 { { 4711, SDB_SERVICE, NULL, "svc1", "k1", v }, -1, NULL },
487 { { 4711, SDB_METRIC, NULL, "m1", "k1", v }, -1, NULL },
488 { { 4711, 0, "hostA", "svc1", "k1", v }, -1, NULL },
489 };
491 size_t i;
493 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
494 ssize_t len = sdb_proto_marshal_attribute(NULL, 0, &golden_data[i].attr);
495 char buf[len > 0 ? len : 1];
497 sdb_proto_attribute_t attr;
498 ssize_t check;
499 char v1[sdb_data_strlen(&golden_data[i].attr.value) + 1];
500 char v2[sdb_data_strlen(&golden_data[i].attr.value) + 1];
502 fail_unless(len == golden_data[i].expected_len,
503 "<%zu> sdb_proto_marshal_attribute(NULL, 0, %s) = %zi; expected: %zi",
504 i, golden_data[i].attr.key, len, golden_data[i].expected_len);
506 if (len < 0)
507 continue;
509 len = sdb_proto_marshal_attribute(buf, sizeof(buf), &golden_data[i].attr);
510 fail_unless(len == golden_data[i].expected_len,
511 "<%zu> sdb_proto_marshal_attribute(<buf>, %zu, %s) = %zi; expected: %zi",
512 i, sizeof(buf), golden_data[i].attr.key,
513 len, golden_data[i].expected_len);
514 if (memcmp(buf, golden_data[i].expected, len) != 0) {
515 size_t pos;
516 for (pos = 0; pos < (size_t)len; ++pos)
517 if (buf[pos] != golden_data[i].expected[pos])
518 break;
519 fail("<%zu> sdb_proto_marshal_attribute(%s) -> \"%s\"; expected: \"%s\" "
520 "(bytes %zu differ: '%x' != '%x')",
521 i, golden_data[i].attr.key, buf, golden_data[i].expected,
522 pos, (int)buf[pos], (int)golden_data[i].expected[pos]);
523 }
525 if (! sdb_data_format(&golden_data[i].attr.value, v1, sizeof(v1), 0))
526 snprintf(v1, sizeof(v1), "<ERR>");
528 check = sdb_proto_unmarshal_attribute(buf, len, &attr);
529 fail_unless(check == len,
530 "<%zu> sdb_proto_unmarshal_attribute(buf<%s>) = %zi; expected: %zi",
531 i, golden_data[i].attr.key, check, len);
533 if (! sdb_data_format(&attr.value, v2, sizeof(v2), 0))
534 snprintf(v2, sizeof(v2), "<ERR>");
535 fail_unless((attr.last_update == golden_data[i].attr.last_update)
536 && (attr.parent_type == golden_data[i].attr.parent_type)
537 && streq(attr.hostname, golden_data[i].attr.hostname)
538 && streq(attr.parent, golden_data[i].attr.parent)
539 && streq(attr.key, golden_data[i].attr.key)
540 && (sdb_data_cmp(&attr.value, &golden_data[i].attr.value) == 0),
541 "<%zu> sdb_proto_unmarshal_attribute(buf<%s>) = "
542 "{ %"PRIsdbTIME", %s, %s, %s, %s, %s }; expected: "
543 "{ %"PRIsdbTIME", %s, %s, %s, %s, %s }", i, golden_data[i].attr.key,
544 attr.last_update, SDB_STORE_TYPE_TO_NAME(attr.parent_type),
545 attr.hostname, attr.parent, attr.key, v1,
546 golden_data[i].attr.last_update,
547 SDB_STORE_TYPE_TO_NAME(golden_data[i].attr.parent_type),
548 golden_data[i].attr.hostname, golden_data[i].attr.parent,
549 golden_data[i].attr.key, v2);
550 }
551 }
552 END_TEST
554 TEST_MAIN("utils::proto")
555 {
556 TCase *tc = tcase_create("core");
557 tcase_add_test(tc, test_marshal_data);
558 tcase_add_test(tc, test_marshal_host);
559 tcase_add_test(tc, test_marshal_service);
560 tcase_add_test(tc, test_marshal_metric);
561 tcase_add_test(tc, test_marshal_attribute);
562 ADD_TCASE(tc);
563 }
564 TEST_MAIN_END
566 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */