snmp plugin: Use array instead of cycle in res->errstat check
[collectd.git] / src / utils_vl_lookup_test.c
1 /**
2  * collectd - src/tests/test_utils_vl_lookup.c
3  * Copyright (C) 2012       Florian Forster
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  *   Florian Forster <octo at collectd.org>
25  **/
26
27 #include "collectd.h"
28
29 #include "testing.h"
30 #include "utils_vl_lookup.h"
31
32 static _Bool expect_new_obj = 0;
33 static _Bool have_new_obj = 0;
34
35 static lookup_identifier_t last_class_ident;
36 static lookup_identifier_t last_obj_ident;
37
38 static data_source_t dsrc_test = {"value", DS_TYPE_DERIVE, 0.0, NAN};
39 static data_set_t const ds_test = {"test", 1, &dsrc_test};
40
41 static data_source_t dsrc_unknown = {"value", DS_TYPE_DERIVE, 0.0, NAN};
42 static data_set_t const ds_unknown = {"unknown", 1, &dsrc_unknown};
43
44 static int lookup_obj_callback(data_set_t const *ds, value_list_t const *vl,
45                                void *user_class, void *user_obj) {
46   lookup_identifier_t *class = user_class;
47   lookup_identifier_t *obj = user_obj;
48
49   OK1(expect_new_obj == have_new_obj,
50       (expect_new_obj ? "New obj is created." : "Updating existing obj."));
51
52   memcpy(&last_class_ident, class, sizeof(last_class_ident));
53   memcpy(&last_obj_ident, obj, sizeof(last_obj_ident));
54
55   if (strcmp(obj->plugin_instance, "failure") == 0)
56     return -1;
57
58   return 0;
59 }
60
61 static void *lookup_class_callback(data_set_t const *ds, value_list_t const *vl,
62                                    void *user_class) {
63   lookup_identifier_t *class = user_class;
64   lookup_identifier_t *obj;
65
66   assert(expect_new_obj);
67
68   memcpy(&last_class_ident, class, sizeof(last_class_ident));
69
70   obj = malloc(sizeof(*obj));
71   strncpy(obj->host, vl->host, sizeof(obj->host));
72   strncpy(obj->plugin, vl->plugin, sizeof(obj->plugin));
73   strncpy(obj->plugin_instance, vl->plugin_instance,
74           sizeof(obj->plugin_instance));
75   strncpy(obj->type, vl->type, sizeof(obj->type));
76   strncpy(obj->type_instance, vl->type_instance, sizeof(obj->type_instance));
77
78   have_new_obj = 1;
79
80   return (void *)obj;
81 }
82
83 static int checked_lookup_add(lookup_t *obj, /* {{{ */
84                               char const *host, char const *plugin,
85                               char const *plugin_instance, char const *type,
86                               char const *type_instance,
87                               unsigned int group_by) {
88   lookup_identifier_t ident;
89   void *user_class;
90
91   strncpy(ident.host, host, sizeof(ident.host));
92   strncpy(ident.plugin, plugin, sizeof(ident.plugin));
93   strncpy(ident.plugin_instance, plugin_instance,
94           sizeof(ident.plugin_instance));
95   strncpy(ident.type, type, sizeof(ident.type));
96   strncpy(ident.type_instance, type_instance, sizeof(ident.type_instance));
97
98   user_class = malloc(sizeof(ident));
99   memmove(user_class, &ident, sizeof(ident));
100
101   OK(lookup_add(obj, &ident, group_by, user_class) == 0);
102   return 0;
103 } /* }}} int checked_lookup_add */
104
105 static int checked_lookup_search(lookup_t *obj, char const *host,
106                                  char const *plugin,
107                                  char const *plugin_instance, char const *type,
108                                  char const *type_instance, _Bool expect_new) {
109   int status;
110   value_list_t vl = VALUE_LIST_INIT;
111   data_set_t const *ds = &ds_unknown;
112
113   strncpy(vl.host, host, sizeof(vl.host));
114   strncpy(vl.plugin, plugin, sizeof(vl.plugin));
115   strncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance));
116   strncpy(vl.type, type, sizeof(vl.type));
117   strncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
118
119   if (strcmp(vl.type, "test") == 0)
120     ds = &ds_test;
121
122   expect_new_obj = expect_new;
123   have_new_obj = 0;
124
125   status = lookup_search(obj, ds, &vl);
126   return status;
127 }
128
129 DEF_TEST(group_by_specific_host) {
130   lookup_t *obj;
131   CHECK_NOT_NULL(obj = lookup_create(lookup_class_callback, lookup_obj_callback,
132                                      (void *)free, (void *)free));
133
134   checked_lookup_add(obj, "/.*/", "test", "", "test", "/.*/", LU_GROUP_BY_HOST);
135   checked_lookup_search(obj, "host0", "test", "", "test", "0",
136                         /* expect new = */ 1);
137   checked_lookup_search(obj, "host0", "test", "", "test", "1",
138                         /* expect new = */ 0);
139   checked_lookup_search(obj, "host1", "test", "", "test", "0",
140                         /* expect new = */ 1);
141   checked_lookup_search(obj, "host1", "test", "", "test", "1",
142                         /* expect new = */ 0);
143
144   lookup_destroy(obj);
145   return 0;
146 }
147
148 DEF_TEST(group_by_any_host) {
149   lookup_t *obj;
150   CHECK_NOT_NULL(obj = lookup_create(lookup_class_callback, lookup_obj_callback,
151                                      (void *)free, (void *)free));
152
153   checked_lookup_add(obj, "/.*/", "/.*/", "/.*/", "test", "/.*/",
154                      LU_GROUP_BY_HOST);
155   checked_lookup_search(obj, "host0", "plugin0", "", "test", "0",
156                         /* expect new = */ 1);
157   checked_lookup_search(obj, "host0", "plugin0", "", "test", "1",
158                         /* expect new = */ 0);
159   checked_lookup_search(obj, "host0", "plugin1", "", "test", "0",
160                         /* expect new = */ 0);
161   checked_lookup_search(obj, "host0", "plugin1", "", "test", "1",
162                         /* expect new = */ 0);
163   checked_lookup_search(obj, "host1", "plugin0", "", "test", "0",
164                         /* expect new = */ 1);
165   checked_lookup_search(obj, "host1", "plugin0", "", "test", "1",
166                         /* expect new = */ 0);
167   checked_lookup_search(obj, "host1", "plugin1", "", "test", "0",
168                         /* expect new = */ 0);
169   checked_lookup_search(obj, "host1", "plugin1", "", "test", "1",
170                         /* expect new = */ 0);
171
172   lookup_destroy(obj);
173   return 0;
174 }
175
176 DEF_TEST(multiple_lookups) {
177   lookup_t *obj;
178   int status;
179
180   CHECK_NOT_NULL(obj = lookup_create(lookup_class_callback, lookup_obj_callback,
181                                      (void *)free, (void *)free));
182
183   checked_lookup_add(obj, "/.*/", "plugin0", "", "test", "/.*/",
184                      LU_GROUP_BY_HOST);
185   checked_lookup_add(obj, "/.*/", "/.*/", "", "test", "ti0", LU_GROUP_BY_HOST);
186
187   status = checked_lookup_search(obj, "host0", "plugin1", "", "test", "",
188                                  /* expect new = */ 0);
189   assert(status == 0);
190   status = checked_lookup_search(obj, "host0", "plugin0", "", "test", "",
191                                  /* expect new = */ 1);
192   assert(status == 1);
193   status = checked_lookup_search(obj, "host0", "plugin1", "", "test", "ti0",
194                                  /* expect new = */ 1);
195   assert(status == 1);
196   status = checked_lookup_search(obj, "host0", "plugin0", "", "test", "ti0",
197                                  /* expect new = */ 0);
198   assert(status == 2);
199
200   lookup_destroy(obj);
201   return 0;
202 }
203
204 DEF_TEST(regex) {
205   lookup_t *obj;
206   CHECK_NOT_NULL(obj = lookup_create(lookup_class_callback, lookup_obj_callback,
207                                      (void *)free, (void *)free));
208
209   checked_lookup_add(obj, "/^db[0-9]\\./", "cpu", "/.*/", "cpu", "/.*/",
210                      LU_GROUP_BY_TYPE_INSTANCE);
211   checked_lookup_search(obj, "db0.example.com", "cpu", "0", "cpu", "user",
212                         /* expect new = */ 1);
213   checked_lookup_search(obj, "db0.example.com", "cpu", "0", "cpu", "idle",
214                         /* expect new = */ 1);
215   checked_lookup_search(obj, "db0.example.com", "cpu", "1", "cpu", "user",
216                         /* expect new = */ 0);
217   checked_lookup_search(obj, "db0.example.com", "cpu", "1", "cpu", "idle",
218                         /* expect new = */ 0);
219   checked_lookup_search(obj, "app0.example.com", "cpu", "0", "cpu", "user",
220                         /* expect new = */ 0);
221   checked_lookup_search(obj, "app0.example.com", "cpu", "0", "cpu", "idle",
222                         /* expect new = */ 0);
223   checked_lookup_search(obj, "db1.example.com", "cpu", "0", "cpu", "user",
224                         /* expect new = */ 0);
225   checked_lookup_search(obj, "db1.example.com", "cpu", "0", "cpu", "idle",
226                         /* expect new = */ 0);
227   checked_lookup_search(obj, "db1.example.com", "cpu", "0", "cpu", "system",
228                         /* expect new = */ 1);
229
230   lookup_destroy(obj);
231   return 0;
232 }
233
234 int main(int argc, char **argv) /* {{{ */
235 {
236   RUN_TEST(group_by_specific_host);
237   RUN_TEST(group_by_any_host);
238   RUN_TEST(multiple_lookups);
239   RUN_TEST(regex);
240
241   END_TEST;
242 } /* }}} int main */