1 /**
2 * collectd - src/tests/utils_cmds_test.c
3 * Copyright (C) 2016 Sebastian 'tokkee' Harl
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 * Sebastian 'tokkee' Harl <sh at tokkee.org>
25 **/
27 #include "common.h"
28 #include "testing.h"
29 #include "utils_cmds.h"
31 static void error_cb (void *ud, cmd_status_t status,
32 const char *format, va_list ap)
33 {
34 if (status == CMD_OK)
35 return;
37 printf ("ERROR[%d]: ", status);
38 vprintf (format, ap);
39 printf ("\n");
40 fflush (stdout);
41 } /* void error_cb */
43 static cmd_options_t default_host_opts = {
44 /* identifier_default_host = */ "dummy-host",
45 };
47 static struct {
48 char *input;
49 cmd_options_t *opts;
50 cmd_status_t expected_status;
51 cmd_type_t expected_type;
52 } parse_data[] = {
53 /* Valid FLUSH commands. */
54 {
55 "FLUSH",
56 NULL,
57 CMD_OK,
58 CMD_FLUSH,
59 },
60 {
61 "FLUSH identifier=myhost/magic/MAGIC",
62 NULL,
63 CMD_OK,
64 CMD_FLUSH,
65 },
66 {
67 "FLUSH identifier=magic/MAGIC",
68 &default_host_opts,
69 CMD_OK,
70 CMD_FLUSH,
71 },
72 {
73 "FLUSH timeout=123 plugin=\"A\"",
74 NULL,
75 CMD_OK,
76 CMD_FLUSH,
77 },
78 /* Invalid FLUSH commands. */
79 {
80 /* Missing hostname; no default. */
81 "FLUSH identifier=magic/MAGIC",
82 NULL,
83 CMD_PARSE_ERROR,
84 CMD_UNKNOWN,
85 },
86 {
87 /* Missing 'identifier' key. */
88 "FLUSH myhost/magic/MAGIC",
89 NULL,
90 CMD_PARSE_ERROR,
91 CMD_UNKNOWN,
92 },
93 {
94 /* Invalid timeout. */
95 "FLUSH timeout=A",
96 NULL,
97 CMD_PARSE_ERROR,
98 CMD_UNKNOWN,
99 },
100 {
101 /* Invalid identifier. */
102 "FLUSH identifier=invalid",
103 NULL,
104 CMD_PARSE_ERROR,
105 CMD_UNKNOWN,
106 },
107 {
108 /* Invalid option. */
109 "FLUSH invalid=option",
110 NULL,
111 CMD_PARSE_ERROR,
112 CMD_UNKNOWN,
113 },
115 /* Valid GETVAL commands. */
116 {
117 "GETVAL myhost/magic/MAGIC",
118 NULL,
119 CMD_OK,
120 CMD_GETVAL,
121 },
122 {
123 "GETVAL magic/MAGIC",
124 &default_host_opts,
125 CMD_OK,
126 CMD_GETVAL,
127 },
129 /* Invalid GETVAL commands. */
130 {
131 "GETVAL magic/MAGIC",
132 NULL,
133 CMD_PARSE_ERROR,
134 CMD_UNKNOWN,
135 },
136 {
137 "GETVAL",
138 NULL,
139 CMD_PARSE_ERROR,
140 CMD_UNKNOWN,
141 },
142 {
143 "GETVAL invalid",
144 NULL,
145 CMD_PARSE_ERROR,
146 CMD_UNKNOWN,
147 },
149 /* Valid LISTVAL commands. */
150 {
151 "LISTVAL",
152 NULL,
153 CMD_OK,
154 CMD_LISTVAL,
155 },
157 /* Invalid LISTVAL commands. */
158 {
159 "LISTVAL invalid",
160 NULL,
161 CMD_PARSE_ERROR,
162 CMD_UNKNOWN,
163 },
165 /* Valid PUTVAL commands. */
166 {
167 "PUTVAL magic/MAGIC N:42",
168 &default_host_opts,
169 CMD_OK,
170 CMD_PUTVAL,
171 },
172 {
173 "PUTVAL myhost/magic/MAGIC N:42",
174 NULL,
175 CMD_OK,
176 CMD_PUTVAL,
177 },
178 {
179 "PUTVAL myhost/magic/MAGIC 1234:42",
180 NULL,
181 CMD_OK,
182 CMD_PUTVAL,
183 },
184 {
185 "PUTVAL myhost/magic/MAGIC 1234:42 2345:23",
186 NULL,
187 CMD_OK,
188 CMD_PUTVAL,
189 },
190 {
191 "PUTVAL myhost/magic/MAGIC interval=2 1234:42",
192 NULL,
193 CMD_OK,
194 CMD_PUTVAL,
195 },
196 {
197 "PUTVAL myhost/magic/MAGIC interval=2 1234:42 interval=5 2345:23",
198 NULL,
199 CMD_OK,
200 CMD_PUTVAL,
201 },
203 /* Invalid PUTVAL commands. */
204 {
205 "PUTVAL magic/MAGIC N:42",
206 NULL,
207 CMD_PARSE_ERROR,
208 CMD_UNKNOWN,
209 },
210 {
211 "PUTVAL",
212 NULL,
213 CMD_PARSE_ERROR,
214 CMD_UNKNOWN,
215 },
216 {
217 "PUTVAL invalid N:42",
218 NULL,
219 CMD_PARSE_ERROR,
220 CMD_UNKNOWN,
221 },
222 {
223 "PUTVAL myhost/magic/MAGIC A:42",
224 NULL,
225 CMD_PARSE_ERROR,
226 CMD_UNKNOWN,
227 },
228 {
229 "PUTVAL myhost/magic/MAGIC 1234:A",
230 NULL,
231 CMD_PARSE_ERROR,
232 CMD_UNKNOWN,
233 },
234 {
235 "PUTVAL myhost/magic/MAGIC",
236 NULL,
237 CMD_PARSE_ERROR,
238 CMD_UNKNOWN,
239 },
240 {
241 "PUTVAL 1234:A",
242 NULL,
243 CMD_PARSE_ERROR,
244 CMD_UNKNOWN,
245 },
246 {
247 "PUTVAL myhost/magic/UNKNOWN 1234:42",
248 NULL,
249 CMD_PARSE_ERROR,
250 CMD_UNKNOWN,
251 },
252 /*
253 * As of collectd 5.x, PUTVAL accepts invalid options.
254 {
255 "PUTVAL myhost/magic/MAGIC invalid=2 1234:42",
256 NULL,
257 CMD_PARSE_ERROR,
258 CMD_UNKNOWN,
259 },
260 */
262 /* Invalid commands. */
263 {
264 "INVALID",
265 NULL,
266 CMD_UNKNOWN_COMMAND,
267 CMD_UNKNOWN,
268 },
269 {
270 "INVALID interval=2",
271 NULL,
272 CMD_UNKNOWN_COMMAND,
273 CMD_UNKNOWN,
274 },
275 };
277 DEF_TEST(parse)
278 {
279 cmd_error_handler_t err = { error_cb, NULL };
280 int test_result = 0;
282 for (size_t i = 0; i < STATIC_ARRAY_SIZE (parse_data); i++) {
283 char *input = strdup (parse_data[i].input);
285 char description[1024];
286 cmd_status_t status;
287 cmd_t cmd;
289 _Bool result;
291 memset (&cmd, 0, sizeof (cmd));
293 status = cmd_parse (input, &cmd, parse_data[i].opts, &err);
294 snprintf (description, sizeof (description),
295 "cmd_parse (\"%s\", opts=%p) = %d (type=%d [%s]); want %d (type=%d [%s])",
296 parse_data[i].input, parse_data[i].opts, status,
297 cmd.type, CMD_TO_STRING (cmd.type),
298 parse_data[i].expected_status,
299 parse_data[i].expected_type,
300 CMD_TO_STRING (parse_data[i].expected_type));
301 result = (status == parse_data[i].expected_status)
302 && (cmd.type == parse_data[i].expected_type);
303 LOG (result, description);
305 /* Run all tests before failing. */
306 if (! result)
307 test_result = -1;
309 cmd_destroy (&cmd);
310 free (input);
311 }
313 return (test_result);
314 }
316 int main (int argc, char **argv)
317 {
318 RUN_TEST(parse);
319 END_TEST;
320 }