Code

data: Add basic support for a boolean type.
[sysdb.git] / t / unit / utils / proto_test.c
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 INT_TYPE "\0\0\0\2"
52 #define DECIMAL_TYPE "\0\0\0\3"
53 #define STRING_TYPE "\0\0\0\4"
54 #define DATETIME_TYPE "\0\0\0\5"
55 #define BINARY_TYPE "\0\0\0\6"
56 #define REGEX_TYPE "\0\0\0\7"
58 #define NULL_ARRAY "\0\0\1\0"
59 #define INT_ARRAY "\0\0\1\2"
60 #define DECIMAL_ARRAY "\0\0\1\3"
61 #define STRING_ARRAY "\0\0\1\4"
62 #define DATETIME_ARRAY "\0\0\1\5"
63 #define BINARY_ARRAY "\0\0\1\6"
64 #define REGEX_ARRAY "\0\0\1\7"
66         regex_t dummy_re;
67         int64_t int_values[] = { 47, 11, 23 };
68         double dec_values[] = { 47.11, .5 };
69         char *string_values[] = { "foo", "abcd" };
70         sdb_time_t datetime_values[] = { 4711, 1234567890123456789L };
71         struct {
72                 size_t length;
73                 unsigned char *datum;
74         } binary_values[] = {
75                 { 3, (unsigned char *)"\x1\x2\x3" },
76                 { 4, (unsigned char *)"\x42\x0\xa\x1b" },
77         };
78         struct {
79                 char *raw;
80                 regex_t regex;
81         } regex_values[] = {
82                 { "dummy regex", dummy_re },
83         };
85         struct {
86                 sdb_data_t datum;
87                 ssize_t expected_len;
88                 char *expected;
89         } golden_data[] = {
90                 {
91                         { SDB_TYPE_NULL, { .integer = 0 } },
92                         4, "\0\0\0\0",
93                 },
94                 {
95                         { SDB_TYPE_INTEGER, { .integer = 4711 } },
96                         12, INT_TYPE "\0\0\0\0\0\0\x12\x67",
97                 },
98                 {
99                         { SDB_TYPE_DECIMAL, { .decimal = 3.141592653e130 } },
100                         12, DECIMAL_TYPE "\x5b\x6\xa9\x40\x66\x1e\x10\x4",
101                 },
102                 {
103                         { SDB_TYPE_STRING, { .string = "some string" } },
104                         16, STRING_TYPE "some string\0",
105                 },
106                 {
107                         { SDB_TYPE_DATETIME, { .datetime = 1418923804000000 } },
108                         12, DATETIME_TYPE "\x0\x5\xa\x80\xf1\x4c\xff\x0",
109                 },
110                 {
111                         { SDB_TYPE_BINARY, { .binary = {
112                                 4, (unsigned char *)"\x42\x0\xa\x1b" } } },
113                         12, BINARY_TYPE "\0\0\0\x4" "\x42\x0\xa\x1b",
114                 },
115                 {
116                         { SDB_TYPE_REGEX, { .re = { "dummy", dummy_re } } },
117                         10, REGEX_TYPE "dummy\0",
118                 },
119                 {
120                         { SDB_TYPE_INTEGER | SDB_TYPE_ARRAY, { .array = {
121                                 3, int_values } } },
122                         32, INT_ARRAY "\0\0\0\x3" "\0\0\0\0\0\0\0\x2f"
123                                 "\0\0\0\0\0\0\0\xb" "\0\0\0\0\0\0\0\x17"
124                 },
125                 {
126                         { SDB_TYPE_DECIMAL | SDB_TYPE_ARRAY, { .array = {
127                                 2, dec_values } } },
128                         24, DECIMAL_ARRAY "\0\0\0\x2" "\x40\x47\x8e\x14\x7a\xe1\x47\xae"
129                                 "\x3f\xe0\0\0\0\0\0\0"
130                 },
131                 {
132                         { SDB_TYPE_STRING | SDB_TYPE_ARRAY, { .array = {
133                                 2, string_values } } },
134                         17, STRING_ARRAY "\0\0\0\x2" "foo\0" "abcd\0"
135                 },
136                 {
137                         { SDB_TYPE_DATETIME | SDB_TYPE_ARRAY, { .array = {
138                                 2, datetime_values } } },
139                         24, DATETIME_ARRAY "\0\0\0\x2" "\0\0\0\0\0\0\x12\x67"
140                                 "\x11\x22\x10\xf4\x7d\xe9\x81\x15"
141                 },
142                 {
143                         { SDB_TYPE_BINARY | SDB_TYPE_ARRAY, { .array = {
144                                 2, binary_values } } },
145                         23, BINARY_ARRAY "\0\0\0\x2" "\0\0\0\x3" "\x1\x2\x3"
146                                 "\0\0\0\4" "\x42\x0\xa\x1b"
147                 },
148                 {
149                         { SDB_TYPE_REGEX | SDB_TYPE_ARRAY, { .array = {
150                                 1, regex_values } } },
151                         20, REGEX_ARRAY "\0\0\0\1" "dummy regex\0"
152                 },
153         };
155         size_t i;
157         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
158                 ssize_t len = sdb_proto_marshal_data(NULL, 0, &golden_data[i].datum);
159                 char buf[len > 0 ? len : 1];
160                 char v1[sdb_data_strlen(&golden_data[i].datum)];
161                 char v2[sdb_data_strlen(&golden_data[i].datum)];
163                 sdb_data_t datum = SDB_DATA_INIT;
164                 ssize_t check;
166                 if (! sdb_data_format(&golden_data[i].datum, v1, sizeof(v1), 0))
167                         snprintf(v1, sizeof(v1), "<ERR>");
169                 fail_unless(len == golden_data[i].expected_len,
170                                 "<%zu> sdb_proto_marshal_data(NULL, 0, %s) = %zi; expected: %zi",
171                                 i, v1, len, golden_data[i].expected_len);
173                 if (len < 0)
174                         continue;
176                 len = sdb_proto_marshal_data(buf, sizeof(buf), &golden_data[i].datum);
177                 fail_unless(len == golden_data[i].expected_len,
178                                 "<%zu> sdb_proto_marshal_data(<buf>, %zu, %s) = %zi; expected: %zi",
179                                 i, sizeof(buf), v1, len, golden_data[i].expected_len);
180                 if (memcmp(buf, golden_data[i].expected, len) != 0) {
181                         size_t pos;
182                         for (pos = 0; pos < (size_t)len; ++pos)
183                                 if (buf[pos] != golden_data[i].expected[pos])
184                                         break;
185                         fail("<%zu> sdb_proto_marshal_data(%s) -> \"%s\"; expected: \"%s\" "
186                                         "(bytes %zu differ: '%x' != '%x')",
187                                         i, v1, buf, golden_data[i].expected,
188                                         pos, (int)buf[pos], (int)golden_data[i].expected[pos]);
189                 }
191                 check = sdb_proto_unmarshal_data(buf, len, &datum);
192                 if (! sdb_data_format(&datum, v2, sizeof(v2), 0))
193                         snprintf(v2, sizeof(v2), "<ERR>");
195                 if (sdb_data_isnull(&golden_data[i].datum))
196                         fail_unless(sdb_data_isnull(&datum),
197                                         "<%zu> sdb_proto_unmarshal_data(buf<%s>) -> \"%s\"", i, v1, v2);
198                 else
199                         fail_unless(sdb_data_cmp(&golden_data[i].datum, &datum) == 0,
200                                         "<%zu> sdb_proto_unmarshal_data(buf<%s>) -> \"%s\"", i, v1, v2);
201                 fail_unless(check == len,
202                                 "<%zu> sdb_proto_unmarshal_data(buf<%s>) = %zi; expected: %zi",
203                                 i, v1, check, len);
205                 sdb_data_free_datum(&datum);
206         }
208 END_TEST
210 #define HOST_TYPE "\0\0\0\1"
211 #define SVC_TYPE "\0\0\0\2"
212 #define METRIC_TYPE "\0\0\0\3"
213 #define HOST_ATTR_TYPE "\0\0\0\x11"
214 #define SVC_ATTR_TYPE "\0\0\0\x12"
215 #define METRIC_ATTR_TYPE "\0\0\0\x13"
217 START_TEST(test_marshal_host)
219         struct {
220                 sdb_proto_host_t host;
221                 ssize_t expected_len;
222                 char *expected;
223         } golden_data[] = {
224                 {
225                         { 4711, "hostA" },
226                         18, HOST_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0"
227                 },
228                 {
229                         { 0, "hostA" },
230                         18, HOST_TYPE "\0\0\0\0\0\0\0\0" "hostA\0"
231                 },
232                 { { 4711, NULL }, -1, NULL },
233         };
235         size_t i;
237         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
238                 ssize_t len = sdb_proto_marshal_host(NULL, 0, &golden_data[i].host);
239                 char buf[len > 0 ? len : 1];
241                 sdb_proto_host_t host;
242                 ssize_t check;
244                 fail_unless(len == golden_data[i].expected_len,
245                                 "<%zu> sdb_proto_marshal_host(NULL, 0, %s) = %zi; expected: %zi",
246                                 i, golden_data[i].host.name, len, golden_data[i].expected_len);
248                 if (len < 0)
249                         continue;
251                 len = sdb_proto_marshal_host(buf, sizeof(buf), &golden_data[i].host);
252                 fail_unless(len == golden_data[i].expected_len,
253                                 "<%zu> sdb_proto_marshal_host(<buf>, %zu, %s) = %zi; expected: %zi",
254                                 i, sizeof(buf), golden_data[i].host.name,
255                                 len, golden_data[i].expected_len);
256                 if (memcmp(buf, golden_data[i].expected, len) != 0) {
257                         size_t pos;
258                         for (pos = 0; pos < (size_t)len; ++pos)
259                                 if (buf[pos] != golden_data[i].expected[pos])
260                                         break;
261                         fail("<%zu> sdb_proto_marshal_host(%s) -> \"%s\"; expected: \"%s\" "
262                                         "(bytes %zu differ: '%x' != '%x')",
263                                         i, golden_data[i].host.name, buf, golden_data[i].expected,
264                                         pos, (int)buf[pos], (int)golden_data[i].expected[pos]);
265                 }
267                 check = sdb_proto_unmarshal_host(buf, len, &host);
268                 fail_unless(check == len,
269                                 "<%zu> sdb_proto_unmarshal_host(buf<%s>) = %zi; expected: %zi",
270                                 i, golden_data[i].host.name, check, len);
271                 fail_unless((host.last_update == golden_data[i].host.last_update)
272                                 && streq(host.name, golden_data[i].host.name),
273                                 "<%zu> sdb_proto_unmarshal_host(buf<%s>) = { %"PRIsdbTIME", %s }; "
274                                 "expected: { %"PRIsdbTIME", %s }", i, golden_data[i].host.name,
275                                 host.last_update, host.name, golden_data[i].host.last_update,
276                                 golden_data[i].host.name);
277         }
279 END_TEST
281 START_TEST(test_marshal_service)
283         struct {
284                 sdb_proto_service_t svc;
285                 ssize_t expected_len;
286                 char *expected;
287         } golden_data[] = {
288                 {
289                         { 4711, "hostA", "serviceX" },
290                         27, SVC_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0serviceX\0"
291                 },
292                 {
293                         { 0, "hostA", "serviceX" },
294                         27, SVC_TYPE "\0\0\0\0\0\0\0\0" "hostA\0serviceX\0"
295                 },
296                 { { 4711, "hostA", NULL }, -1, NULL },
297                 { { 4711, NULL, "serviceX" }, -1, NULL },
298                 { { 4711, NULL, NULL }, -1, NULL },
299         };
301         size_t i;
303         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
304                 ssize_t len = sdb_proto_marshal_service(NULL, 0, &golden_data[i].svc);
305                 char buf[len > 0 ? len : 1];
307                 sdb_proto_service_t svc;
308                 ssize_t check;
310                 fail_unless(len == golden_data[i].expected_len,
311                                 "<%zu> sdb_proto_marshal_service(NULL, 0, %s) = %zi; expected: %zi",
312                                 i, golden_data[i].svc.name, len, golden_data[i].expected_len);
314                 if (len < 0)
315                         continue;
317                 len = sdb_proto_marshal_service(buf, sizeof(buf), &golden_data[i].svc);
318                 fail_unless(len == golden_data[i].expected_len,
319                                 "<%zu> sdb_proto_marshal_service(<buf>, %zu, %s) = %zi; expected: %zi",
320                                 i, sizeof(buf), golden_data[i].svc.name,
321                                 len, golden_data[i].expected_len);
322                 if (memcmp(buf, golden_data[i].expected, len) != 0) {
323                         size_t pos;
324                         for (pos = 0; pos < (size_t)len; ++pos)
325                                 if (buf[pos] != golden_data[i].expected[pos])
326                                         break;
327                         fail("<%zu> sdb_proto_marshal_service(%s) -> \"%s\"; expected: \"%s\" "
328                                         "(bytes %zu differ: '%x' != '%x')",
329                                         i, golden_data[i].svc.name, buf, golden_data[i].expected,
330                                         pos, (int)buf[pos], (int)golden_data[i].expected[pos]);
331                 }
333                 check = sdb_proto_unmarshal_service(buf, len, &svc);
334                 fail_unless(check == len,
335                                 "<%zu> sdb_proto_unmarshal_service(buf<%s>) = %zi; expected: %zi",
336                                 i, golden_data[i].svc.name, check, len);
337                 fail_unless((svc.last_update == golden_data[i].svc.last_update)
338                                 && streq(svc.hostname, golden_data[i].svc.hostname)
339                                 && streq(svc.name, golden_data[i].svc.name),
340                                 "<%zu> sdb_proto_unmarshal_service(buf<%s>) = { %"PRIsdbTIME", %s, %s }; "
341                                 "expected: { %"PRIsdbTIME", %s, %s }", i, golden_data[i].svc.name,
342                                 svc.last_update, svc.hostname, svc.name, golden_data[i].svc.last_update,
343                                 golden_data[i].svc.hostname, golden_data[i].svc.name);
344         }
346 END_TEST
348 START_TEST(test_marshal_metric)
350         struct {
351                 sdb_proto_metric_t metric;
352                 ssize_t expected_len;
353                 char *expected;
354         } golden_data[] = {
355                 {
356                         { 4711, "hostA", "metricX", NULL, NULL },
357                         26, METRIC_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0metricX\0"
358                 },
359                 {
360                         { 0, "hostA", "metricX", NULL, NULL },
361                         26, METRIC_TYPE "\0\0\0\0\0\0\0\0" "hostA\0metricX\0"
362                 },
363                 {
364                         { 0, "hostA", "metricX", "type", NULL },
365                         26, METRIC_TYPE "\0\0\0\0\0\0\0\0" "hostA\0metricX\0"
366                 },
367                 {
368                         { 0, "hostA", "metricX", NULL, "id" },
369                         26, METRIC_TYPE "\0\0\0\0\0\0\0\0" "hostA\0metricX\0"
370                 },
371                 {
372                         { 4711, "hostA", "metricX", "type", "id" },
373                         34, METRIC_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0metricX\0type\0id\0"
374                 },
375                 { { 4711, "hostA", NULL, NULL, NULL }, -1, NULL },
376                 { { 4711, NULL, "metricX", NULL, NULL }, -1, NULL },
377                 { { 4711, NULL, NULL, NULL, NULL }, -1, NULL },
378         };
380         size_t i;
382         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
383                 ssize_t len = sdb_proto_marshal_metric(NULL, 0, &golden_data[i].metric);
384                 char buf[len > 0 ? len : 1];
386                 sdb_proto_metric_t metric;
387                 ssize_t check;
389                 fail_unless(len == golden_data[i].expected_len,
390                                 "<%zu> sdb_proto_marshal_metric(NULL, 0, %s) = %zi; expected: %zi",
391                                 i, golden_data[i].metric.name, len, golden_data[i].expected_len);
393                 if (len < 0)
394                         continue;
396                 len = sdb_proto_marshal_metric(buf, sizeof(buf), &golden_data[i].metric);
397                 fail_unless(len == golden_data[i].expected_len,
398                                 "<%zu> sdb_proto_marshal_metric(<buf>, %zu, %s) = %zi; expected: %zi",
399                                 i, sizeof(buf), golden_data[i].metric.name,
400                                 len, golden_data[i].expected_len);
401                 if (memcmp(buf, golden_data[i].expected, len) != 0) {
402                         size_t pos;
403                         for (pos = 0; pos < (size_t)len; ++pos)
404                                 if (buf[pos] != golden_data[i].expected[pos])
405                                         break;
406                         fail("<%zu> sdb_proto_marshal_metric(%s) -> \"%s\"; expected: \"%s\" "
407                                         "(bytes %zu differ: '%x' != '%x')",
408                                         i, golden_data[i].metric.name, buf, golden_data[i].expected,
409                                         pos, (int)buf[pos], (int)golden_data[i].expected[pos]);
410                 }
412                 if ((! golden_data[i].metric.store_type)
413                                 || (! golden_data[i].metric.store_id)) {
414                         /* if any of these is NULL, we expect both to be NULL */
415                         golden_data[i].metric.store_type = NULL;
416                         golden_data[i].metric.store_id = NULL;
417                 }
419                 check = sdb_proto_unmarshal_metric(buf, len, &metric);
420                 fail_unless(check == len,
421                                 "<%zu> sdb_proto_unmarshal_metric(buf<%s>) = %zi; expected: %zi",
422                                 i, golden_data[i].metric.name, check, len);
423                 fail_unless((metric.last_update == golden_data[i].metric.last_update)
424                                 && streq(metric.hostname, golden_data[i].metric.hostname)
425                                 && streq(metric.name, golden_data[i].metric.name)
426                                 && streq(metric.store_type, golden_data[i].metric.store_type)
427                                 && streq(metric.store_id, golden_data[i].metric.store_id),
428                                 "<%zu> sdb_proto_unmarshal_metric(buf<%s>) = "
429                                 "{ %"PRIsdbTIME", %s, %s, %s, %s }; expected: "
430                                 "{ %"PRIsdbTIME", %s, %s, %s, %s }", i, golden_data[i].metric.name,
431                                 metric.last_update, metric.hostname, metric.name,
432                                 metric.store_type, metric.store_id,
433                                 golden_data[i].metric.last_update,
434                                 golden_data[i].metric.hostname, golden_data[i].metric.name,
435                                 golden_data[i].metric.store_type, golden_data[i].metric.store_id);
436         }
438 END_TEST
440 START_TEST(test_marshal_attribute)
442         sdb_data_t v = { SDB_TYPE_INTEGER, { .integer = 4711 } };
443 #define VAL "\0\0\0\2" "\0\0\0\0\0\0\x12\x67"
444         struct {
445                 sdb_proto_attribute_t attr;
446                 ssize_t expected_len;
447                 char *expected;
448         } golden_data[] = {
449                 {
450                         { 4711, SDB_HOST, NULL, "hostA", "k1", v },
451                         33, HOST_ATTR_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0" "k1\0" VAL
452                 },
453                 {
454                         { 4711, SDB_SERVICE, "hostA", "svc1", "k1", v },
455                         38, SVC_ATTR_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0" "svc1\0" "k1\0" VAL
456                 },
457                 {
458                         { 4711, SDB_METRIC, "hostA", "m1", "k1", v },
459                         36, METRIC_ATTR_TYPE "\0\0\0\0\0\0\x12\x67" "hostA\0" "m1\0" "k1\0" VAL
460                 },
461                 { { 4711, SDB_HOST, NULL, NULL, "k1", v }, -1, NULL },
462                 { { 4711, SDB_HOST, NULL, "hostA", NULL, v }, -1, NULL },
463                 { { 4711, SDB_SERVICE, NULL, "svc1", "k1", v }, -1, NULL },
464                 { { 4711, SDB_METRIC, NULL, "m1", "k1", v }, -1, NULL },
465                 { { 4711, 0, "hostA", "svc1", "k1", v }, -1, NULL },
466         };
468         size_t i;
470         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
471                 ssize_t len = sdb_proto_marshal_attribute(NULL, 0, &golden_data[i].attr);
472                 char buf[len > 0 ? len : 1];
474                 sdb_proto_attribute_t attr;
475                 ssize_t check;
476                 char v1[sdb_data_strlen(&golden_data[i].attr.value) + 1];
477                 char v2[sdb_data_strlen(&golden_data[i].attr.value) + 1];
479                 fail_unless(len == golden_data[i].expected_len,
480                                 "<%zu> sdb_proto_marshal_attribute(NULL, 0, %s) = %zi; expected: %zi",
481                                 i, golden_data[i].attr.key, len, golden_data[i].expected_len);
483                 if (len < 0)
484                         continue;
486                 len = sdb_proto_marshal_attribute(buf, sizeof(buf), &golden_data[i].attr);
487                 fail_unless(len == golden_data[i].expected_len,
488                                 "<%zu> sdb_proto_marshal_attribute(<buf>, %zu, %s) = %zi; expected: %zi",
489                                 i, sizeof(buf), golden_data[i].attr.key,
490                                 len, golden_data[i].expected_len);
491                 if (memcmp(buf, golden_data[i].expected, len) != 0) {
492                         size_t pos;
493                         for (pos = 0; pos < (size_t)len; ++pos)
494                                 if (buf[pos] != golden_data[i].expected[pos])
495                                         break;
496                         fail("<%zu> sdb_proto_marshal_attribute(%s) -> \"%s\"; expected: \"%s\" "
497                                         "(bytes %zu differ: '%x' != '%x')",
498                                         i, golden_data[i].attr.key, buf, golden_data[i].expected,
499                                         pos, (int)buf[pos], (int)golden_data[i].expected[pos]);
500                 }
502                 if (! sdb_data_format(&golden_data[i].attr.value, v1, sizeof(v1), 0))
503                         snprintf(v1, sizeof(v1), "<ERR>");
505                 check = sdb_proto_unmarshal_attribute(buf, len, &attr);
506                 fail_unless(check == len,
507                                 "<%zu> sdb_proto_unmarshal_attribute(buf<%s>) = %zi; expected: %zi",
508                                 i, golden_data[i].attr.key, check, len);
510                 if (! sdb_data_format(&attr.value, v2, sizeof(v2), 0))
511                         snprintf(v2, sizeof(v2), "<ERR>");
512                 fail_unless((attr.last_update == golden_data[i].attr.last_update)
513                                 && (attr.parent_type == golden_data[i].attr.parent_type)
514                                 && streq(attr.hostname, golden_data[i].attr.hostname)
515                                 && streq(attr.parent, golden_data[i].attr.parent)
516                                 && streq(attr.key, golden_data[i].attr.key)
517                                 && (sdb_data_cmp(&attr.value, &golden_data[i].attr.value) == 0),
518                                 "<%zu> sdb_proto_unmarshal_attribute(buf<%s>) = "
519                                 "{ %"PRIsdbTIME", %s, %s, %s, %s, %s }; expected: "
520                                 "{ %"PRIsdbTIME", %s, %s, %s, %s, %s }", i, golden_data[i].attr.key,
521                                 attr.last_update, SDB_STORE_TYPE_TO_NAME(attr.parent_type),
522                                 attr.hostname, attr.parent, attr.key, v1,
523                                 golden_data[i].attr.last_update,
524                                 SDB_STORE_TYPE_TO_NAME(golden_data[i].attr.parent_type),
525                                 golden_data[i].attr.hostname, golden_data[i].attr.parent,
526                                 golden_data[i].attr.key, v2);
527         }
529 END_TEST
531 TEST_MAIN("utils::proto")
533         TCase *tc = tcase_create("core");
534         tcase_add_test(tc, test_marshal_data);
535         tcase_add_test(tc, test_marshal_host);
536         tcase_add_test(tc, test_marshal_service);
537         tcase_add_test(tc, test_marshal_metric);
538         tcase_add_test(tc, test_marshal_attribute);
539         ADD_TCASE(tc);
541 TEST_MAIN_END
543 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */