Code

9dc157068183b49c2e2c4e1e74276bcccee9c064
[sysdb.git] / t / unit / core / store_json_test.c
1 /*
2  * SysDB - t/unit/core/store_json_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/store.h"
29 #include "libsysdb_test.h"
31 #include <assert.h>
33 #include <check.h>
34 #include <stdlib.h>
36 static void
37 populate(void)
38 {
39         sdb_data_t datum;
41         sdb_store_host("h1", 1);
42         sdb_store_host("h2", 3);
44         datum.type = SDB_TYPE_STRING;
45         datum.data.string = "v1";
46         sdb_store_attribute("h1", "k1", &datum, 1);
47         datum.data.string = "v2";
48         sdb_store_attribute("h1", "k2", &datum, 2);
49         datum.data.string = "v3";
50         sdb_store_attribute("h1", "k3", &datum, 2);
52         /* make sure that older updates don't overwrite existing values */
53         datum.data.string = "fail";
54         sdb_store_attribute("h1", "k2", &datum, 1);
55         sdb_store_attribute("h1", "k3", &datum, 2);
57         sdb_store_metric("h1", "m1", /* store */ NULL, 2);
58         sdb_store_metric("h1", "m2", /* store */ NULL, 1);
59         sdb_store_metric("h2", "m1", /* store */ NULL, 1);
61         sdb_store_service("h2", "s1", 1);
62         sdb_store_service("h2", "s2", 2);
64         datum.type = SDB_TYPE_INTEGER;
65         datum.data.integer = 42;
66         sdb_store_metric_attr("h1", "m1", "k3", &datum, 2);
68         datum.data.integer = 123;
69         sdb_store_service_attr("h2", "s2", "k1", &datum, 2);
70         datum.data.integer = 4711;
71         sdb_store_service_attr("h2", "s2", "k2", &datum, 1);
73         /* don't overwrite k1 */
74         datum.data.integer = 666;
75         sdb_store_service_attr("h2", "s2", "k1", &datum, 2);
76 } /* populate */
78 static int
79 scan_tojson(sdb_store_obj_t *obj,
80                 sdb_store_matcher_t __attribute__((unused)) *filter,
81                 void *user_data)
82 {
83         sdb_store_json_formatter_t *f = user_data;
84         return sdb_store_json_emit(f, obj);
85 } /* scan_tojson */
87 static int
88 scan_tojson_full(sdb_store_obj_t *obj, sdb_store_matcher_t *filter,
89                 void *user_data)
90 {
91         sdb_store_json_formatter_t *f = user_data;
92         return sdb_store_json_emit_full(f, obj, filter);
93 } /* scan_tojson_full */
95 static void
96 verify_json_output(sdb_strbuf_t *buf, const char *expected)
97 {
98         const char *got = sdb_strbuf_string(buf);
99         size_t len1 = strlen(got);
100         size_t len2 = strlen(expected);
102         size_t i;
103         int pos = -1;
105         if (len1 != len2)
106                 pos = (int)SDB_MIN(len1, len2);
108         for (i = 0; i < SDB_MIN(len1, len2); ++i) {
109                 if (got[i] != expected[i]) {
110                         pos = (int)i;
111                         break;
112                 }
113         }
115         fail_unless(pos == -1,
116                         "Serializing hosts to JSON returned unexpected result\n"
117                         "         got: %s\n              %*s\n    expected: %s",
118                         got, pos + 1, "^", expected);
119 } /* verify_json_output */
121 struct {
122         struct {
123                 sdb_store_matcher_t *(*m)(sdb_store_expr_t *,
124                                 sdb_store_expr_t *);
125                 int field;
126                 sdb_data_t value;
127         } filter;
128         int type;
129         int (*f)(sdb_store_obj_t *, sdb_store_matcher_t *, void *);
130         const char *expected;
131 } store_tojson_data[] = {
132         { { NULL, 0, SDB_DATA_INIT },
133                 SDB_HOST, scan_tojson_full,
134                 "["
135                         "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
136                                 "\"update_interval\": \"0s\", \"backends\": [], "
137                                 "\"attributes\": ["
138                                         "{\"name\": \"k1\", \"value\": \"v1\", "
139                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
140                                                 "\"update_interval\": \"0s\", \"backends\": []},"
141                                         "{\"name\": \"k2\", \"value\": \"v2\", "
142                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
143                                                 "\"update_interval\": \"0s\", \"backends\": []},"
144                                         "{\"name\": \"k3\", \"value\": \"v3\", "
145                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
146                                                 "\"update_interval\": \"0s\", \"backends\": []}"
147                                 "], "
148                                 "\"metrics\": ["
149                                         "{\"name\": \"m1\", "
150                                                 "\"timeseries\": false, "
151                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
152                                                 "\"update_interval\": \"0s\", \"backends\": [], "
153                                                 "\"attributes\": ["
154                                                         "{\"name\": \"k3\", \"value\": 42, "
155                                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
156                                                                 "\"update_interval\": \"0s\", \"backends\": []}"
157                                                 "]},"
158                                         "{\"name\": \"m2\", "
159                                                 "\"timeseries\": false, "
160                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
161                                                 "\"update_interval\": \"0s\", \"backends\": []}"
162                                 "]},"
163                         "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
164                                 "\"update_interval\": \"0s\", \"backends\": [], "
165                                 "\"metrics\": ["
166                                         "{\"name\": \"m1\", "
167                                                 "\"timeseries\": false, "
168                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
169                                                 "\"update_interval\": \"0s\", \"backends\": []}"
170                                 "], "
171                                 "\"services\": ["
172                                         "{\"name\": \"s1\", "
173                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
174                                                 "\"update_interval\": \"0s\", \"backends\": []},"
175                                         "{\"name\": \"s2\", "
176                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
177                                                 "\"update_interval\": \"0s\", \"backends\": [], "
178                                                 "\"attributes\": ["
179                                                         "{\"name\": \"k1\", \"value\": 123, "
180                                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
181                                                                 "\"update_interval\": \"0s\", \"backends\": []},"
182                                                         "{\"name\": \"k2\", \"value\": 4711, "
183                                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
184                                                                 "\"update_interval\": \"0s\", \"backends\": []}"
185                                                 "]}"
186                                 "]}"
187                 "]" },
188         { { NULL, 0, SDB_DATA_INIT },
189                 SDB_HOST, scan_tojson,
190                 "["
191                         "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
192                                 "\"update_interval\": \"0s\", \"backends\": []},"
193                         "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
194                                 "\"update_interval\": \"0s\", \"backends\": []}"
195                 "]" },
196         { { sdb_store_eq_matcher, SDB_FIELD_NAME,
197                         { SDB_TYPE_STRING, { .string = "h1" } } },
198                 SDB_HOST, scan_tojson_full,
199                 "["
200                         "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
201                                 "\"update_interval\": \"0s\", \"backends\": []}"
202                 "]" },
203         { { sdb_store_gt_matcher, SDB_FIELD_LAST_UPDATE,
204                         { SDB_TYPE_DATETIME, { .datetime = 1 } } },
205                 SDB_HOST, scan_tojson_full,
206                 "["
207                         "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
208                                 "\"update_interval\": \"0s\", \"backends\": [], "
209                                 "\"services\": ["
210                                         "{\"name\": \"s2\", "
211                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
212                                                 "\"update_interval\": \"0s\", \"backends\": [], "
213                                                 "\"attributes\": ["
214                                                         "{\"name\": \"k1\", \"value\": 123, "
215                                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
216                                                                 "\"update_interval\": \"0s\", \"backends\": []}"
217                                                 "]}"
218                                 "]}"
219                 "]" },
220         { { sdb_store_le_matcher, SDB_FIELD_LAST_UPDATE,
221                         { SDB_TYPE_DATETIME, { .datetime = 1 } } },
222                 SDB_HOST, scan_tojson_full,
223                 "["
224                         "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
225                                 "\"update_interval\": \"0s\", \"backends\": [], "
226                                 "\"attributes\": ["
227                                         "{\"name\": \"k1\", \"value\": \"v1\", "
228                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
229                                                 "\"update_interval\": \"0s\", \"backends\": []}"
230                                 "], "
231                                 "\"metrics\": ["
232                                         "{\"name\": \"m2\", "
233                                                 "\"timeseries\": false, "
234                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
235                                                 "\"update_interval\": \"0s\", \"backends\": []}"
236                                 "]}"
237                 "]" },
238         { { sdb_store_ge_matcher, SDB_FIELD_LAST_UPDATE,
239                         { SDB_TYPE_DATETIME, { .datetime = 3 } } },
240                 SDB_HOST, scan_tojson_full,
241                 "["
242                         "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
243                                 "\"update_interval\": \"0s\", \"backends\": []}"
244                 "]" },
245         { { sdb_store_lt_matcher, SDB_FIELD_LAST_UPDATE,
246                         { SDB_TYPE_DATETIME, { .datetime = 0 } } },
247                 SDB_HOST, scan_tojson_full,
248                 "[]" },
250         { { NULL, 0, SDB_DATA_INIT },
251                 SDB_SERVICE, scan_tojson_full,
252                 "["
253                         "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
254                                 "\"update_interval\": \"0s\", \"backends\": [], "
255                                 "\"services\": ["
256                                         "{\"name\": \"s1\", "
257                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
258                                                 "\"update_interval\": \"0s\", \"backends\": []},"
259                                         "{\"name\": \"s2\", "
260                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
261                                                 "\"update_interval\": \"0s\", \"backends\": [], "
262                                                 "\"attributes\": ["
263                                                         "{\"name\": \"k1\", \"value\": 123, "
264                                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
265                                                                 "\"update_interval\": \"0s\", \"backends\": []},"
266                                                         "{\"name\": \"k2\", \"value\": 4711, "
267                                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
268                                                                 "\"update_interval\": \"0s\", \"backends\": []}"
269                                                 "]}"
270                                 "]}"
271                 "]" },
272         { { NULL, 0, SDB_DATA_INIT },
273                 SDB_SERVICE, scan_tojson,
274                 "["
275                         "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
276                                 "\"update_interval\": \"0s\", \"backends\": [], "
277                                 "\"services\": ["
278                                         "{\"name\": \"s1\", "
279                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
280                                                 "\"update_interval\": \"0s\", \"backends\": []},"
281                                         "{\"name\": \"s2\", "
282                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
283                                                 "\"update_interval\": \"0s\", \"backends\": []}"
284                                 "]}"
285                 "]" },
286         { { sdb_store_gt_matcher, SDB_FIELD_LAST_UPDATE,
287                         { SDB_TYPE_DATETIME, { .datetime = 1 } } },
288                 SDB_SERVICE, scan_tojson_full,
289                 "["
290                         "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
291                                 "\"update_interval\": \"0s\", \"backends\": [], "
292                                 "\"services\": ["
293                                         "{\"name\": \"s2\", "
294                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
295                                                 "\"update_interval\": \"0s\", \"backends\": [], "
296                                                 "\"attributes\": ["
297                                                         "{\"name\": \"k1\", \"value\": 123, "
298                                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
299                                                                 "\"update_interval\": \"0s\", \"backends\": []}"
300                                                 "]}"
301                                 "]}"
302                 "]" },
303         { { sdb_store_lt_matcher, SDB_FIELD_LAST_UPDATE,
304                         { SDB_TYPE_DATETIME, { .datetime = 0 } } },
305                 SDB_SERVICE, scan_tojson_full,
306                 "[]" },
307         { { NULL, 0, SDB_DATA_INIT },
308                 SDB_METRIC, scan_tojson_full,
309                 "["
310                         "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
311                                 "\"update_interval\": \"0s\", \"backends\": [], "
312                                 "\"metrics\": ["
313                                         "{\"name\": \"m1\", "
314                                                 "\"timeseries\": false, "
315                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
316                                                 "\"update_interval\": \"0s\", \"backends\": [], "
317                                                 "\"attributes\": ["
318                                                         "{\"name\": \"k3\", \"value\": 42, "
319                                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
320                                                                 "\"update_interval\": \"0s\", \"backends\": []}"
321                                                 "]},"
322                                         "{\"name\": \"m2\", "
323                                                 "\"timeseries\": false, "
324                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
325                                                 "\"update_interval\": \"0s\", \"backends\": []}"
326                                 "]},"
327                         "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
328                                 "\"update_interval\": \"0s\", \"backends\": [], "
329                                 "\"metrics\": ["
330                                         "{\"name\": \"m1\", "
331                                                 "\"timeseries\": false, "
332                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
333                                                 "\"update_interval\": \"0s\", \"backends\": []}"
334                                 "]}"
335                 "]" },
336         { { NULL, 0, SDB_DATA_INIT },
337                 SDB_METRIC, scan_tojson,
338                 "["
339                         "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
340                                 "\"update_interval\": \"0s\", \"backends\": [], "
341                                 "\"metrics\": ["
342                                         "{\"name\": \"m1\", "
343                                                 "\"timeseries\": false, "
344                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
345                                                 "\"update_interval\": \"0s\", \"backends\": []},"
346                                         "{\"name\": \"m2\", "
347                                                 "\"timeseries\": false, "
348                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
349                                                 "\"update_interval\": \"0s\", \"backends\": []}"
350                                 "]},"
351                         "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
352                                 "\"update_interval\": \"0s\", \"backends\": [], "
353                                 "\"metrics\": ["
354                                         "{\"name\": \"m1\", "
355                                                 "\"timeseries\": false, "
356                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
357                                                 "\"update_interval\": \"0s\", \"backends\": []}"
358                                 "]}"
359                 "]" },
360         { { sdb_store_le_matcher, SDB_FIELD_LAST_UPDATE,
361                         { SDB_TYPE_DATETIME, { .datetime = 1 } } },
362                 SDB_METRIC, scan_tojson_full,
363                 "["
364                         "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
365                                 "\"update_interval\": \"0s\", \"backends\": [], "
366                                 "\"metrics\": ["
367                                         "{\"name\": \"m2\", "
368                                                 "\"timeseries\": false, "
369                                                 "\"last_update\": \"1970-01-01 00:00:00 +0000\", "
370                                                 "\"update_interval\": \"0s\", \"backends\": []}"
371                                 "]}"
372                 "]" },
373         { { sdb_store_lt_matcher, SDB_FIELD_LAST_UPDATE,
374                         { SDB_TYPE_DATETIME, { .datetime = 0 } } },
375                 SDB_METRIC, scan_tojson_full,
376                 "[]" },
377 };
379 START_TEST(test_store_tojson)
381         sdb_strbuf_t *buf = sdb_strbuf_create(0);
382         sdb_store_matcher_t *filter = NULL;
383         sdb_store_json_formatter_t *f;
384         int status;
386         if (store_tojson_data[_i].filter.m) {
387                 sdb_store_expr_t *field;
388                 sdb_store_expr_t *value;
390                 field = sdb_store_expr_fieldvalue(store_tojson_data[_i].filter.field);
391                 fail_unless(field != NULL,
392                                 "INTERNAL ERROR: sdb_store_expr_fieldvalue() = NULL");
393                 value = sdb_store_expr_constvalue(&store_tojson_data[_i].filter.value);
394                 fail_unless(value != NULL,
395                                 "INTERNAL ERROR: sdb_store_expr_constvalue() = NULL");
397                 filter = store_tojson_data[_i].filter.m(field, value);
398                 fail_unless(filter != NULL,
399                                 "INTERNAL ERROR: sdb_store_*_matcher() = NULL");
401                 sdb_object_deref(SDB_OBJ(field));
402                 sdb_object_deref(SDB_OBJ(value));
403         }
405         sdb_strbuf_clear(buf);
406         f = sdb_store_json_formatter(buf,
407                         store_tojson_data[_i].type, SDB_WANT_ARRAY);
408         assert(f);
410         status = sdb_store_scan(store_tojson_data[_i].type,
411                         /* m = */ NULL, filter, store_tojson_data[_i].f, f);
412         fail_unless(status == 0,
413                         "sdb_store_scan(HOST, ..., tojson) = %d; expected: 0",
414                         status);
415         sdb_store_json_finish(f);
417         verify_json_output(buf, store_tojson_data[_i].expected);
419         free(f);
420         sdb_object_deref(SDB_OBJ(filter));
421         sdb_strbuf_destroy(buf);
423 END_TEST
425 Suite *
426 core_store_json_suite(void)
428         Suite *s = suite_create("core::store_json");
429         TCase *tc;
431         tc = tcase_create("core");
432         TC_ADD_LOOP_TEST(tc, store_tojson);
433         tcase_add_unchecked_fixture(tc, populate, sdb_store_clear);
434         suite_add_tcase(s, tc);
436         return s;
437 } /* core_store_json_suite */
439 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */