Code

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