Code

store_lookup: Made logical operators public.
[sysdb.git] / t / core / store_lookup_test.c
1 /*
2  * SysDB - t/core/store_lookup_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 <check.h>
32 #include <string.h>
34 static void
35 populate(void)
36 {
37         const char *hosts[] = { "a", "b", "c" };
39         struct {
40                 const char *host;
41                 const char *service;
42         } services[] = {
43                 { "a", "s1" },
44                 { "a", "s2" },
45                 { "b", "s1" },
46                 { "b", "s3" },
47         };
49         struct {
50                 const char *host;
51                 const char *name;
52                 sdb_data_t  value;
53         } attrs[] = {
54                 { "a", "k1", { SDB_TYPE_STRING, { .string = "v1" } } },
55         };
57         size_t i;
59         for (i = 0; i < SDB_STATIC_ARRAY_LEN(hosts); ++i) {
60                 int status = sdb_store_host(hosts[i], 1);
61                 fail_unless(status == 0,
62                                 "sdb_store_host(%s, 1) = %d; expected: 0",
63                                 hosts[i], status);
64         }
66         for (i = 0; i < SDB_STATIC_ARRAY_LEN(services); ++i) {
67                 int status = sdb_store_service(services[i].host,
68                                 services[i].service, 1);
69                 fail_unless(status == 0,
70                                 "sdb_store_service(%s, %s, 1) = %d; expected: 0",
71                                 services[i].host, services[i].service, status);
72         }
74         for (i = 0; i < SDB_STATIC_ARRAY_LEN(attrs); ++i) {
75                 int status = sdb_store_attribute(attrs[i].host,
76                                 attrs[i].name, &attrs[i].value, 1);
77                 fail_unless(status == 0,
78                                 "sdb_store_attribute(%s, %s, <val>, 1) = %d; expected: 0",
79                                 attrs[i].host, attrs[i].name, status);
80         }
81 } /* populate */
83 START_TEST(test_store_match)
84 {
85         sdb_store_base_t *obj;
87         struct {
88                 const char *hostname;
89                 const char *hostname_re;
91                 const char *service_name;
92                 const char *service_name_re;
94                 const char *attr_name;
95                 const char *attr_name_re;
96                 const char *attr_value;
97                 const char *attr_value_re;
99                 int expected;
100         } golden_data[] = {
101                 {
102                         /* host */ NULL, NULL,
103                         /* svc  */ NULL, NULL,
104                         /* attr */ NULL, NULL, NULL, NULL, 0
105                 },
106                 {
107                         /* host */ "a", NULL,
108                         /* svc  */ NULL, NULL,
109                         /* attr */ NULL, NULL, NULL, NULL, 0
110                 },
111                 {
112                         /* host */ "b", NULL,
113                         /* svc  */ NULL, NULL,
114                         /* attr */ NULL, NULL, NULL, NULL, -1
115                 },
116                 {
117                         /* host */ NULL, "^a$",
118                         /* svc  */ NULL, NULL,
119                         /* attr */ NULL, NULL, NULL, NULL, 0
120                 },
121                 {
122                         /* host */ NULL, "^b$",
123                         /* svc  */ NULL, NULL,
124                         /* attr */ NULL, NULL, NULL, NULL, -1
125                 },
126                 {
127                         /* host */ "a", "^a$",
128                         /* svc  */ NULL, NULL,
129                         /* attr */ NULL, NULL, NULL, NULL, 0
130                 },
131                 {
132                         /* host */ "a", "^b$",
133                         /* svc  */ NULL, NULL,
134                         /* attr */ NULL, NULL, NULL, NULL, -1
135                 },
136                 {
137                         /* host */ "b", "^a$",
138                         /* svc  */ NULL, NULL,
139                         /* attr */ NULL, NULL, NULL, NULL, -1
140                 },
141                 {
142                         /* host */ "a", "^a$",
143                         /* svc  */ "s1", NULL,
144                         /* attr */ NULL, NULL, NULL, NULL, 0
145                 },
146                 {
147                         /* host */ "a", "^a$",
148                         /* svc  */ NULL, "^s1$",
149                         /* attr */ NULL, NULL, NULL, NULL, 0
150                 },
151                 {
152                         /* host */ "a", "^a$",
153                         /* svc  */ "s1", "^s1$",
154                         /* attr */ NULL, NULL, NULL, NULL, 0
155                 },
156                 {
157                         /* host */ "a", "^a$",
158                         /* svc  */ "x1", NULL,
159                         /* attr */ NULL, NULL, NULL, NULL, -1
160                 },
161                 {
162                         /* host */ "a", "^a$",
163                         /* svc  */ NULL, "x",
164                         /* attr */ NULL, NULL, NULL, NULL, -1
165                 },
166                 {
167                         /* host */ "a", "^a$",
168                         /* svc  */ "x1", "x",
169                         /* attr */ NULL, NULL, NULL, NULL, -1
170                 },
171                 {
172                         /* host */ "a", "^a$",
173                         /* svc  */ "s1", "x",
174                         /* attr */ NULL, NULL, NULL, NULL, -1
175                 },
176                 {
177                         /* host */ "a", "^a$",
178                         /* svc  */ "x1", "s",
179                         /* attr */ NULL, NULL, NULL, NULL, -1
180                 },
181                 {
182                         /* host */ "a", "^a$",
183                         /* svc  */ "s1", "^s1$",
184                         /* attr */ "k1", NULL, NULL, NULL, 0
185                 },
186                 {
187                         /* host */ "a", "^a$",
188                         /* svc  */ "s1", "^s1$",
189                         /* attr */ NULL, "^k", NULL, NULL, 0
190                 },
191                 {
192                         /* host */ "a", "^a$",
193                         /* svc  */ "s1", "^s1$",
194                         /* attr */ NULL, NULL, "v1", NULL, 0
195                 },
196                 {
197                         /* host */ "a", "^a$",
198                         /* svc  */ "s1", "^s1$",
199                         /* attr */ NULL, NULL, NULL, "^v1$", 0
200                 },
201                 {
202                         /* host */ "a", "^a$",
203                         /* svc  */ "s1", "^s1$",
204                         /* attr */ "k1", "1", "v1", "1", 0
205                 },
206         };
208         size_t i;
210         obj = sdb_store_get_host("a");
211         fail_unless(obj != NULL,
212                         "sdb_store_get_host(a) = NULL; expected: <host>");
214         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
215                 sdb_store_matcher_t *h, *s, *a;
216                 int status;
218                 s = sdb_store_service_matcher(golden_data[i].service_name,
219                                 golden_data[i].service_name_re, NULL);
220                 fail_unless(s != NULL,
221                                 "sdb_store_service_matcher() = NULL; expected: <matcher>");
223                 a = sdb_store_attr_matcher(golden_data[i].attr_name,
224                                 golden_data[i].attr_name_re, golden_data[i].attr_value,
225                                 golden_data[i].attr_value_re);
226                 fail_unless(a != NULL,
227                                 "sdb_store_attr_matcher() = NULL; expected: <matcher>");
229                 h = sdb_store_host_matcher(golden_data[i].hostname,
230                                 golden_data[i].hostname_re, s, a);
231                 fail_unless(h != NULL,
232                                 "sdb_store_host_matcher() = NULL: expected: <matcher>");
233                 /* pass ownership to the host matcher */
234                 sdb_object_deref(SDB_OBJ(s));
235                 sdb_object_deref(SDB_OBJ(a));
237                 status = sdb_store_matcher_matches(h, obj);
238                 fail_unless(status == golden_data[i].expected,
239                                 "sdb_store_matcher_matches({{%s, %s},{%s, %s},"
240                                 "{%s, %s, %s, %s}}, <host a>) = %d; expected: %d",
241                                 golden_data[i].hostname, golden_data[i].hostname_re,
242                                 golden_data[i].service_name, golden_data[i].service_name_re,
243                                 golden_data[i].attr_name, golden_data[i].attr_name_re,
244                                 golden_data[i].attr_value, golden_data[i].attr_value_re,
245                                 status, golden_data[i].expected);
247                 sdb_object_deref(SDB_OBJ(h));
248         }
250 END_TEST
252 START_TEST(test_store_match_op)
254         sdb_store_base_t *obj;
256         sdb_store_matcher_t *always = sdb_store_host_matcher(NULL, NULL, NULL, NULL);
257         sdb_store_matcher_t *never = sdb_store_host_matcher("a", "b", NULL, NULL);
259         struct {
260                 const char *op;
261                 sdb_store_matcher_t *left;
262                 sdb_store_matcher_t *right;
263                 int expected;
264         } golden_data[] = {
265                 { "OR",  always, always,  0 },
266                 { "OR",  always, never,   0 },
267                 { "OR",  never,  always,  0 },
268                 { "OR",  never,  never,  -1 },
269                 { "AND", always, always,  0 },
270                 { "AND", always, never,  -1 },
271                 { "AND", never,  always, -1 },
272                 { "AND", never,  never,  -1 },
273         };
275         int status;
276         size_t i;
278         obj = sdb_store_get_host("a");
280         status = sdb_store_matcher_matches(always, obj);
281         fail_unless(status == 0,
282                         "INTERNAL ERROR: 'always' did not match host");
283         status = sdb_store_matcher_matches(never, obj);
284         fail_unless(status < 0,
285                         "INTERNAL ERROR: 'never' matches host");
287         for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
288                 sdb_store_matcher_t *m;
290                 if (! strcmp(golden_data[i].op, "OR"))
291                         m = sdb_store_dis_matcher(golden_data[i].left,
292                                         golden_data[i].right);
293                 else if (! strcmp(golden_data[i].op, "AND"))
294                         m = sdb_store_con_matcher(golden_data[i].left,
295                                         golden_data[i].right);
296                 else
297                         fail("INTERNAL ERROR: unexpected operator %s", golden_data[i].op);
299 #define TO_NAME(v) (((v) == always) ? "always" \
300                 : ((v) == never) ? "never" : "<unknown>")
302                 status = sdb_store_matcher_matches(m, obj);
303                 fail_unless(status == golden_data[i].expected,
304                                 "%s(%s, %s) = %d; expected: %d", golden_data[i].op,
305                                 TO_NAME(golden_data[i].left), TO_NAME(golden_data[i].right),
306                                 status, golden_data[i].expected);
308 #undef TO_NAME
310                 sdb_object_deref(SDB_OBJ(m));
311         }
313         sdb_object_deref(SDB_OBJ(always));
314         sdb_object_deref(SDB_OBJ(never));
316 END_TEST
318 Suite *
319 core_store_lookup_suite(void)
321         Suite *s = suite_create("core::store_lookup");
322         TCase *tc;
324         tc = tcase_create("core");
325         tcase_add_checked_fixture(tc, populate, sdb_store_clear);
326         tcase_add_test(tc, test_store_match);
327         tcase_add_test(tc, test_store_match_op);
328         suite_add_tcase(s, tc);
330         return s;
331 } /* core_store_lookup_suite */
333 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */