4a939b64f430ef8dd43d479fdc57ed0789188805
1 /*
2 * SysDB - t/core/store_test.c
3 * Copyright (C) 2013 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 <check.h>
32 #include <string.h>
34 START_TEST(test_store_host)
35 {
36 struct {
37 const char *name;
38 sdb_time_t last_update;
39 int expected;
40 } golden_data[] = {
41 { "a", 2, 0 },
42 { "a", 3, 0 },
43 { "a", 1, 1 },
44 { "b", 2, 0 },
45 { "b", 1, 1 },
46 { "A", 1, 1 }, /* case-insensitive */
47 { "A", 4, 0 },
48 };
50 struct {
51 const char *name;
52 _Bool has;
53 } golden_hosts[] = {
54 { "a", 1 == 1 },
55 { "b", 1 == 1 },
56 { "c", 0 == 1 },
57 { "A", 1 == 1 },
58 };
60 size_t i;
62 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
63 int status;
65 status = sdb_store_host(golden_data[i].name,
66 golden_data[i].last_update);
67 fail_unless(status == golden_data[i].expected,
68 "sdb_store_host(%s, %d) = %d; expected: %d",
69 golden_data[i].name, (int)golden_data[i].last_update,
70 status, golden_data[i].expected);
71 }
73 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_hosts); ++i) {
74 _Bool has;
76 has = sdb_store_has_host(golden_hosts[i].name);
77 fail_unless(has == golden_hosts[i].has,
78 "sdb_store_has_host(%s) = %d; expected: %d",
79 golden_hosts[i].name, has, golden_hosts[i].has);
80 }
81 }
82 END_TEST
84 START_TEST(test_store_attr)
85 {
86 struct {
87 const char *host;
88 const char *key;
89 const char *value;
90 sdb_time_t last_update;
91 int expected;
92 } golden_data[] = {
93 { "k", "k", "v", 1, -1 },
94 { "k", "k", "v", 1, -1 }, /* retry to ensure the host is not created */
95 { "l", "k1", "v1", 1, 0 },
96 { "l", "k1", "v2", 2, 0 },
97 { "l", "k1", "v3", 1, 1 },
98 { "l", "k2", "v1", 1, 0 },
99 { "m", "k", "v1", 2, 0 },
100 { "m", "k", "v2", 1, 1 },
101 };
103 size_t i;
105 sdb_store_host("l", 1);
106 sdb_store_host("m", 1);
107 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
108 int status;
110 status = sdb_store_attribute(golden_data[i].host,
111 golden_data[i].key, golden_data[i].value,
112 golden_data[i].last_update);
113 fail_unless(status == golden_data[i].expected,
114 "sdb_store_attribute(%s, %s, %s, %d) = %d; expected: %d",
115 golden_data[i].host, golden_data[i].key, golden_data[i].value,
116 golden_data[i].last_update, status, golden_data[i].expected);
117 }
118 }
119 END_TEST
121 START_TEST(test_store_service)
122 {
123 struct {
124 const char *host;
125 const char *svc;
126 sdb_time_t last_update;
127 int expected;
128 } golden_data[] = {
129 { "k", "s", 1, -1 },
130 { "k", "s", 1, -1 }, /* retry to ensure the host is not created */
131 { "l", "s1", 1, 0 },
132 { "l", "s1", 2, 0 },
133 { "l", "s1", 1, 1 },
134 { "l", "s2", 1, 0 },
135 { "m", "s", 2, 0 },
136 { "m", "s", 1, 1 },
137 };
139 size_t i;
141 sdb_store_host("m", 1);
142 sdb_store_host("l", 1);
143 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
144 int status;
146 status = sdb_store_service(golden_data[i].host,
147 golden_data[i].svc, golden_data[i].last_update);
148 fail_unless(status == golden_data[i].expected,
149 "sdb_store_attribute(%s, %s, %d) = %d; expected: %d",
150 golden_data[i].host, golden_data[i].svc,
151 golden_data[i].last_update, status, golden_data[i].expected);
152 }
153 }
154 END_TEST
156 static void
157 verify_json_output(sdb_strbuf_t *buf, const char *expected, int flags)
158 {
159 int pos;
160 size_t len1, len2;
161 size_t i;
163 len1 = strlen(sdb_strbuf_string(buf));
164 len2 = strlen(expected);
166 pos = -1;
167 if (len1 != len2)
168 pos = (int)(len1 <= len2 ? len1 : len2);
170 for (i = 0; i < (len1 <= len2 ? len1 : len2); ++i) {
171 if (sdb_strbuf_string(buf)[i] != expected[i]) {
172 pos = (int)i;
173 break;
174 }
175 }
177 fail_unless(pos == -1,
178 "sdb_store_tojson(%x) returned unexpected result\n"
179 " got: %s\n %*s\n expected: %s",
180 flags, sdb_strbuf_string(buf), pos + 1, "^", expected);
181 } /* verify_json_output */
183 START_TEST(test_store_tojson)
184 {
185 sdb_strbuf_t *buf;
186 size_t i;
188 struct {
189 int flags;
190 const char *expected;
191 } golden_data[] = {
192 { 0, "{\"hosts\":["
193 "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
194 "\"attributes\": ["
195 "{\"name\": \"k1\", \"value\": \"v1\", \"last_update\": \"1970-01-01 00:00:00 +0000\"},"
196 "{\"name\": \"k2\", \"value\": \"v2\", \"last_update\": \"1970-01-01 00:00:00 +0000\"},"
197 "{\"name\": \"k3\", \"value\": \"v3\", \"last_update\": \"1970-01-01 00:00:00 +0000\"}"
198 "], "
199 "\"services\": []},"
200 "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
201 "\"attributes\": [], "
202 "\"services\": ["
203 "{\"name\": \"s1\", \"last_update\": \"1970-01-01 00:00:00 +0000\"},"
204 "{\"name\": \"s2\", \"last_update\": \"1970-01-01 00:00:00 +0000\"}"
205 "]}"
206 "]}" },
207 { SDB_SKIP_SERVICES,
208 "{\"hosts\":["
209 "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
210 "\"attributes\": ["
211 "{\"name\": \"k1\", \"value\": \"v1\", \"last_update\": \"1970-01-01 00:00:00 +0000\"},"
212 "{\"name\": \"k2\", \"value\": \"v2\", \"last_update\": \"1970-01-01 00:00:00 +0000\"},"
213 "{\"name\": \"k3\", \"value\": \"v3\", \"last_update\": \"1970-01-01 00:00:00 +0000\"}"
214 "]},"
215 "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
216 "\"attributes\": []}"
217 "]}" },
218 { SDB_SKIP_ATTRIBUTES,
219 "{\"hosts\":["
220 "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
221 "\"services\": []},"
222 "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\", "
223 "\"services\": ["
224 "{\"name\": \"s1\", \"last_update\": \"1970-01-01 00:00:00 +0000\"},"
225 "{\"name\": \"s2\", \"last_update\": \"1970-01-01 00:00:00 +0000\"}"
226 "]}"
227 "]}" },
228 { SDB_SKIP_SERVICES | SDB_SKIP_ATTRIBUTES,
229 "{\"hosts\":["
230 "{\"name\": \"h1\", \"last_update\": \"1970-01-01 00:00:00 +0000\"},"
231 "{\"name\": \"h2\", \"last_update\": \"1970-01-01 00:00:00 +0000\"}"
232 "]}" },
233 };
235 sdb_store_host("h1", 1);
236 sdb_store_host("h2", 1);
238 sdb_store_attribute("h1", "k1", "v1", 1);
239 sdb_store_attribute("h1", "k2", "v2", 1);
240 sdb_store_attribute("h1", "k3", "v3", 1);
242 sdb_store_service("h2", "s1", 1);
243 sdb_store_service("h2", "s2", 1);
245 buf = sdb_strbuf_create(0);
247 for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
248 int status;
250 sdb_strbuf_clear(buf);
252 status = sdb_store_tojson(buf, golden_data[i].flags);
253 fail_unless(status == 0,
254 "sdb_store_tojson(%x) = %d; expected: 0",
255 golden_data[i].flags, status);
257 verify_json_output(buf, golden_data[i].expected, golden_data[i].flags);
258 }
259 sdb_strbuf_destroy(buf);
260 }
261 END_TEST
263 Suite *
264 core_store_suite(void)
265 {
266 Suite *s = suite_create("core::store");
267 TCase *tc;
269 tc = tcase_create("core");
270 /* test this first to ensure the store is empty
271 * even when using CK_NOFORK */
272 tcase_add_test(tc, test_store_tojson);
273 tcase_add_test(tc, test_store_host);
274 tcase_add_test(tc, test_store_attr);
275 tcase_add_test(tc, test_store_service);
276 suite_add_tcase(s, tc);
278 return s;
279 } /* core_store_suite */
281 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */