Code

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