Code

40548c09340d444ed3d90064a2c4d82f84349858
[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 <check.h>
36 #include <stdlib.h>
38 /* Make SDB_INTERVAL_SECOND a constant initializer. */
39 #undef SDB_INTERVAL_SECOND
40 #define SDB_INTERVAL_SECOND 1000000000L
42 static sdb_memstore_t *store;
44 static void
45 populate(void)
46 {
47         sdb_data_t datum;
49         store = sdb_memstore_create();
50         ck_assert(store != NULL);
52         sdb_memstore_host(store, "h1", 1 * SDB_INTERVAL_SECOND);
53         sdb_memstore_host(store, "h2", 3 * SDB_INTERVAL_SECOND);
55         datum.type = SDB_TYPE_STRING;
56         datum.data.string = "v1";
57         sdb_memstore_attribute(store, "h1", "k1", &datum, 1 * SDB_INTERVAL_SECOND);
58         datum.data.string = "v2";
59         sdb_memstore_attribute(store, "h1", "k2", &datum, 2 * SDB_INTERVAL_SECOND);
60         datum.data.string = "v3";
61         sdb_memstore_attribute(store, "h1", "k3", &datum, 2 * SDB_INTERVAL_SECOND);
63         /* make sure that older updates don't overwrite existing values */
64         datum.data.string = "fail";
65         sdb_memstore_attribute(store, "h1", "k2", &datum, 1 * SDB_INTERVAL_SECOND);
66         sdb_memstore_attribute(store, "h1", "k3", &datum, 2 * SDB_INTERVAL_SECOND);
68         sdb_memstore_metric(store, "h1", "m1", /* store */ NULL, 2 * SDB_INTERVAL_SECOND);
69         sdb_memstore_metric(store, "h1", "m2", /* store */ NULL, 1 * SDB_INTERVAL_SECOND);
70         sdb_memstore_metric(store, "h2", "m1", /* store */ NULL, 1 * SDB_INTERVAL_SECOND);
72         sdb_memstore_service(store, "h2", "s1", 1 * SDB_INTERVAL_SECOND);
73         sdb_memstore_service(store, "h2", "s2", 2 * SDB_INTERVAL_SECOND);
75         datum.type = SDB_TYPE_INTEGER;
76         datum.data.integer = 42;
77         sdb_memstore_metric_attr(store, "h1", "m1", "k3",
78                         &datum, 2 * SDB_INTERVAL_SECOND);
80         datum.data.integer = 123;
81         sdb_memstore_service_attr(store, "h2", "s2", "k1",
82                         &datum, 2 * SDB_INTERVAL_SECOND);
83         datum.data.integer = 4711;
84         sdb_memstore_service_attr(store, "h2", "s2", "k2",
85                         &datum, 1 * SDB_INTERVAL_SECOND);
87         /* don't overwrite k1 */
88         datum.data.integer = 666;
89         sdb_memstore_service_attr(store, "h2", "s2", "k1",
90                         &datum, 2 * SDB_INTERVAL_SECOND);
91 } /* populate */
93 static void
94 turndown(void)
95 {
96         sdb_object_deref(SDB_OBJ(store));
97         store = NULL;
98 } /* turndown */
100 static int
101 scan_tojson(sdb_memstore_obj_t *obj,
102                 sdb_memstore_matcher_t __attribute__((unused)) *filter,
103                 void *user_data)
105         return sdb_memstore_emit(obj, &sdb_store_json_writer, user_data);
106 } /* scan_tojson */
108 static int
109 scan_tojson_full(sdb_memstore_obj_t *obj, sdb_memstore_matcher_t *filter,
110                 void *user_data)
112         return sdb_memstore_emit_full(obj, filter, &sdb_store_json_writer, user_data);
113 } /* scan_tojson_full */
115 static void
116 verify_json_output(sdb_strbuf_t *buf, const char *expected)
118         const char *got = sdb_strbuf_string(buf);
119         size_t len1 = strlen(got);
120         size_t len2 = strlen(expected);
122         size_t i;
123         int pos = -1;
125         if (len1 != len2)
126                 pos = (int)SDB_MIN(len1, len2);
128         for (i = 0; i < SDB_MIN(len1, len2); ++i) {
129                 if (got[i] != expected[i]) {
130                         pos = (int)i;
131                         break;
132                 }
133         }
135         fail_unless(pos == -1,
136                         "Serializing hosts to JSON returned unexpected result\n"
137                         "         got: %s\n              %*s\n    expected: %s",
138                         got, pos + 1, "^", expected);
139 } /* verify_json_output */
141 struct {
142         struct {
143                 sdb_memstore_matcher_t *(*m)(sdb_memstore_expr_t *, sdb_memstore_expr_t *);
144                 int field;
145                 sdb_data_t value;
146         } filter;
147         int type;
148         int (*f)(sdb_memstore_obj_t *, sdb_memstore_matcher_t *, void *);
149         const char *expected;
150 } store_tojson_data[] = {
151         { { NULL, 0, SDB_DATA_INIT },
152                 SDB_HOST, scan_tojson_full,
153                 "["
154                         "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", "
155                                 "\"update_interval\": \"0s\", \"backends\": [], "
156                                 "\"attributes\": ["
157                                         "{\"name\": \"k1\", \"value\": \"v1\", "
158                                                 "\"last_update\": \"1970-01-01 00:00:01 +0000\", "
159                                                 "\"update_interval\": \"0s\", \"backends\": []},"
160                                         "{\"name\": \"k2\", \"value\": \"v2\", "
161                                                 "\"last_update\": \"1970-01-01 00:00:02 +0000\", "
162                                                 "\"update_interval\": \"0s\", \"backends\": []},"
163                                         "{\"name\": \"k3\", \"value\": \"v3\", "
164                                                 "\"last_update\": \"1970-01-01 00:00:02 +0000\", "
165                                                 "\"update_interval\": \"0s\", \"backends\": []}"
166                                 "], "
167                                 "\"metrics\": ["
168                                         "{\"name\": \"m1\", "
169                                                 "\"timeseries\": false, "
170                                                 "\"last_update\": \"1970-01-01 00:00:02 +0000\", "
171                                                 "\"update_interval\": \"0s\", \"backends\": [], "
172                                                 "\"attributes\": ["
173                                                         "{\"name\": \"k3\", \"value\": 42, "
174                                                                 "\"last_update\": \"1970-01-01 00:00:02 +0000\", "
175                                                                 "\"update_interval\": \"0s\", \"backends\": []}"
176                                                 "]},"
177                                         "{\"name\": \"m2\", "
178                                                 "\"timeseries\": false, "
179                                                 "\"last_update\": \"1970-01-01 00:00:01 +0000\", "
180                                                 "\"update_interval\": \"0s\", \"backends\": []}"
181                                 "]},"
182                         "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", "
183                                 "\"update_interval\": \"0s\", \"backends\": [], "
184                                 "\"metrics\": ["
185                                         "{\"name\": \"m1\", "
186                                                 "\"timeseries\": false, "
187                                                 "\"last_update\": \"1970-01-01 00:00:01 +0000\", "
188                                                 "\"update_interval\": \"0s\", \"backends\": []}"
189                                 "], "
190                                 "\"services\": ["
191                                         "{\"name\": \"s1\", "
192                                                 "\"last_update\": \"1970-01-01 00:00:01 +0000\", "
193                                                 "\"update_interval\": \"0s\", \"backends\": []},"
194                                         "{\"name\": \"s2\", "
195                                                 "\"last_update\": \"1970-01-01 00:00:02 +0000\", "
196                                                 "\"update_interval\": \"0s\", \"backends\": [], "
197                                                 "\"attributes\": ["
198                                                         "{\"name\": \"k1\", \"value\": 123, "
199                                                                 "\"last_update\": \"1970-01-01 00:00:02 +0000\", "
200                                                                 "\"update_interval\": \"0s\", \"backends\": []},"
201                                                         "{\"name\": \"k2\", \"value\": 4711, "
202                                                                 "\"last_update\": \"1970-01-01 00:00:01 +0000\", "
203                                                                 "\"update_interval\": \"0s\", \"backends\": []}"
204                                                 "]}"
205                                 "]}"
206                 "]" },
207         { { NULL, 0, SDB_DATA_INIT },
208                 SDB_HOST, scan_tojson,
209                 "["
210                         "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", "
211                                 "\"update_interval\": \"0s\", \"backends\": []},"
212                         "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", "
213                                 "\"update_interval\": \"0s\", \"backends\": []}"
214                 "]" },
215         { { sdb_memstore_eq_matcher, SDB_FIELD_NAME,
216                         { SDB_TYPE_STRING, { .string = "h1" } } },
217                 SDB_HOST, scan_tojson_full,
218                 "["
219                         "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", "
220                                 "\"update_interval\": \"0s\", \"backends\": []}"
221                 "]" },
222         { { sdb_memstore_gt_matcher, SDB_FIELD_LAST_UPDATE,
223                         { SDB_TYPE_DATETIME, { .datetime = 1 * SDB_INTERVAL_SECOND } } },
224                 SDB_HOST, scan_tojson_full,
225                 "["
226                         "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", "
227                                 "\"update_interval\": \"0s\", \"backends\": [], "
228                                 "\"services\": ["
229                                         "{\"name\": \"s2\", "
230                                                 "\"last_update\": \"1970-01-01 00:00:02 +0000\", "
231                                                 "\"update_interval\": \"0s\", \"backends\": [], "
232                                                 "\"attributes\": ["
233                                                         "{\"name\": \"k1\", \"value\": 123, "
234                                                                 "\"last_update\": \"1970-01-01 00:00:02 +0000\", "
235                                                                 "\"update_interval\": \"0s\", \"backends\": []}"
236                                                 "]}"
237                                 "]}"
238                 "]" },
239         { { sdb_memstore_le_matcher, SDB_FIELD_LAST_UPDATE,
240                         { SDB_TYPE_DATETIME, { .datetime = 1 * SDB_INTERVAL_SECOND } } },
241                 SDB_HOST, scan_tojson_full,
242                 "["
243                         "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:01 +0000\", "
244                                 "\"update_interval\": \"0s\", \"backends\": [], "
245                                 "\"attributes\": ["
246                                         "{\"name\": \"k1\", \"value\": \"v1\", "
247                                                 "\"last_update\": \"1970-01-01 00:00:01 +0000\", "
248                                                 "\"update_interval\": \"0s\", \"backends\": []}"
249                                 "], "
250                                 "\"metrics\": ["
251                                         "{\"name\": \"m2\", "
252                                                 "\"timeseries\": false, "
253                                                 "\"last_update\": \"1970-01-01 00:00:01 +0000\", "
254                                                 "\"update_interval\": \"0s\", \"backends\": []}"
255                                 "]}"
256                 "]" },
257         { { sdb_memstore_ge_matcher, SDB_FIELD_LAST_UPDATE,
258                         { SDB_TYPE_DATETIME, { .datetime = 3 * SDB_INTERVAL_SECOND } } },
259                 SDB_HOST, scan_tojson_full,
260                 "["
261                         "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:03 +0000\", "
262                                 "\"update_interval\": \"0s\", \"backends\": []}"
263                 "]" },
264         { { sdb_memstore_lt_matcher, SDB_FIELD_LAST_UPDATE,
265                         { SDB_TYPE_DATETIME, { .datetime = 0 } } },
266                 SDB_HOST, scan_tojson_full,
267                 "[]" },
269         { { NULL, 0, SDB_DATA_INIT },
270                 SDB_SERVICE, scan_tojson_full,
271                 "["
272                         "{\"name\": \"s1\", "
273                                 "\"last_update\": \"1970-01-01 00:00:01 +0000\", "
274                                 "\"update_interval\": \"0s\", \"backends\": []},"
275                         "{\"name\": \"s2\", "
276                                 "\"last_update\": \"1970-01-01 00:00:02 +0000\", "
277                                 "\"update_interval\": \"0s\", \"backends\": [], "
278                                 "\"attributes\": ["
279                                         "{\"name\": \"k1\", \"value\": 123, "
280                                                 "\"last_update\": \"1970-01-01 00:00:02 +0000\", "
281                                                 "\"update_interval\": \"0s\", \"backends\": []},"
282                                         "{\"name\": \"k2\", \"value\": 4711, "
283                                                 "\"last_update\": \"1970-01-01 00:00:01 +0000\", "
284                                                 "\"update_interval\": \"0s\", \"backends\": []}"
285                                 "]}"
286                 "]" },
287         { { NULL, 0, SDB_DATA_INIT },
288                 SDB_SERVICE, scan_tojson,
289                 "["
290                         "{\"name\": \"s1\", "
291                                 "\"last_update\": \"1970-01-01 00:00:01 +0000\", "
292                                 "\"update_interval\": \"0s\", \"backends\": []},"
293                         "{\"name\": \"s2\", "
294                                 "\"last_update\": \"1970-01-01 00:00:02 +0000\", "
295                                 "\"update_interval\": \"0s\", \"backends\": []}"
296                 "]" },
297         { { sdb_memstore_gt_matcher, SDB_FIELD_LAST_UPDATE,
298                         { SDB_TYPE_DATETIME, { .datetime = 1 * SDB_INTERVAL_SECOND } } },
299                 SDB_SERVICE, scan_tojson_full,
300                 "["
301                         "{\"name\": \"s2\", "
302                                 "\"last_update\": \"1970-01-01 00:00:02 +0000\", "
303                                 "\"update_interval\": \"0s\", \"backends\": [], "
304                                 "\"attributes\": ["
305                                         "{\"name\": \"k1\", \"value\": 123, "
306                                                 "\"last_update\": \"1970-01-01 00:00:02 +0000\", "
307                                                 "\"update_interval\": \"0s\", \"backends\": []}"
308                                 "]}"
309                 "]" },
310         { { sdb_memstore_lt_matcher, SDB_FIELD_LAST_UPDATE,
311                         { SDB_TYPE_DATETIME, { .datetime = 0 } } },
312                 SDB_SERVICE, scan_tojson_full,
313                 "[]" },
314         { { NULL, 0, SDB_DATA_INIT },
315                 SDB_METRIC, scan_tojson_full,
316                 "["
317                         "{\"name\": \"m1\", "
318                                 "\"timeseries\": false, "
319                                 "\"last_update\": \"1970-01-01 00:00:02 +0000\", "
320                                 "\"update_interval\": \"0s\", \"backends\": [], "
321                                 "\"attributes\": ["
322                                         "{\"name\": \"k3\", \"value\": 42, "
323                                                 "\"last_update\": \"1970-01-01 00:00:02 +0000\", "
324                                                 "\"update_interval\": \"0s\", \"backends\": []}"
325                                 "]},"
326                         "{\"name\": \"m2\", "
327                                 "\"timeseries\": false, "
328                                 "\"last_update\": \"1970-01-01 00:00:01 +0000\", "
329                                 "\"update_interval\": \"0s\", \"backends\": []},"
330                         "{\"name\": \"m1\", "
331                                 "\"timeseries\": false, "
332                                 "\"last_update\": \"1970-01-01 00:00:01 +0000\", "
333                                 "\"update_interval\": \"0s\", \"backends\": []}"
334                 "]" },
335         { { NULL, 0, SDB_DATA_INIT },
336                 SDB_METRIC, scan_tojson,
337                 "["
338                         "{\"name\": \"m1\", "
339                                 "\"timeseries\": false, "
340                                 "\"last_update\": \"1970-01-01 00:00:02 +0000\", "
341                                 "\"update_interval\": \"0s\", \"backends\": []},"
342                         "{\"name\": \"m2\", "
343                                 "\"timeseries\": false, "
344                                 "\"last_update\": \"1970-01-01 00:00:01 +0000\", "
345                                 "\"update_interval\": \"0s\", \"backends\": []},"
346                         "{\"name\": \"m1\", "
347                                 "\"timeseries\": false, "
348                                 "\"last_update\": \"1970-01-01 00:00:01 +0000\", "
349                                 "\"update_interval\": \"0s\", \"backends\": []}"
350                 "]" },
351         { { sdb_memstore_le_matcher, SDB_FIELD_LAST_UPDATE,
352                         { SDB_TYPE_DATETIME, { .datetime = 1 * SDB_INTERVAL_SECOND } } },
353                 SDB_METRIC, scan_tojson_full,
354                 "["
355                         "{\"name\": \"m2\", "
356                                 "\"timeseries\": false, "
357                                 "\"last_update\": \"1970-01-01 00:00:01 +0000\", "
358                                 "\"update_interval\": \"0s\", \"backends\": []}"
359                 "]" },
360         { { sdb_memstore_lt_matcher, SDB_FIELD_LAST_UPDATE,
361                         { SDB_TYPE_DATETIME, { .datetime = 0 } } },
362                 SDB_METRIC, scan_tojson_full,
363                 "[]" },
364 };
366 START_TEST(test_store_tojson)
368         sdb_strbuf_t *buf = sdb_strbuf_create(0);
369         sdb_memstore_matcher_t *filter = NULL;
370         sdb_store_json_formatter_t *f;
371         int status;
373         if (store_tojson_data[_i].filter.m) {
374                 sdb_memstore_expr_t *field;
375                 sdb_memstore_expr_t *value;
377                 field = sdb_memstore_expr_fieldvalue(store_tojson_data[_i].filter.field);
378                 fail_unless(field != NULL,
379                                 "INTERNAL ERROR: sdb_memstore_expr_fieldvalue() = NULL");
380                 value = sdb_memstore_expr_constvalue(&store_tojson_data[_i].filter.value);
381                 fail_unless(value != NULL,
382                                 "INTERNAL ERROR: sdb_memstore_expr_constvalue() = NULL");
384                 filter = store_tojson_data[_i].filter.m(field, value);
385                 fail_unless(filter != NULL,
386                                 "INTERNAL ERROR: sdb_memstore_*_matcher() = NULL");
388                 sdb_object_deref(SDB_OBJ(field));
389                 sdb_object_deref(SDB_OBJ(value));
390         }
392         sdb_strbuf_clear(buf);
393         f = sdb_store_json_formatter(buf, store_tojson_data[_i].type, SDB_WANT_ARRAY);
394         ck_assert(f != NULL);
396         status = sdb_memstore_scan(store, store_tojson_data[_i].type,
397                         /* m = */ NULL, filter, store_tojson_data[_i].f, f);
398         fail_unless(status == 0,
399                         "sdb_memstore_scan(HOST, ..., tojson) = %d; expected: 0",
400                         status);
401         sdb_store_json_finish(f);
403         verify_json_output(buf, store_tojson_data[_i].expected);
405         sdb_object_deref(SDB_OBJ(filter));
406         sdb_object_deref(SDB_OBJ(f));
407         sdb_strbuf_destroy(buf);
409 END_TEST
411 TEST_MAIN("core::store_json")
413         TCase *tc = tcase_create("core");
414         tcase_add_unchecked_fixture(tc, populate, turndown);
415         TC_ADD_LOOP_TEST(tc, store_tojson);
416         ADD_TCASE(tc);
418 TEST_MAIN_END
420 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */