6470b8160e69a93d95f7cb07d5256e217e8f0d58
[collectd.git] / src / utils / cmds / cmds_test.c
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  **/
26
27 // clang-format off
28 /*
29  * Explicit order is required or _FILE_OFFSET_BITS will have definition mismatches on Solaris
30  * See Github Issue #3193 for details
31  */
32 #include "utils/common/common.h"
33 #include "testing.h"
34 #include "utils/cmds/cmds.h"
35 // clang-format on
36
37 static void error_cb(void *ud, cmd_status_t status, const char *format,
38                      va_list ap) {
39   if (status == CMD_OK)
40     return;
41
42   printf("ERROR[%d]: ", status);
43   vprintf(format, ap);
44   printf("\n");
45   fflush(stdout);
46 } /* void error_cb */
47
48 static cmd_options_t default_host_opts = {
49     /* identifier_default_host = */ "dummy-host",
50 };
51
52 static struct {
53   char *input;
54   cmd_options_t *opts;
55   cmd_status_t expected_status;
56   cmd_type_t expected_type;
57 } parse_data[] = {
58     /* Valid FLUSH commands. */
59     {
60         "FLUSH", NULL, CMD_OK, CMD_FLUSH,
61     },
62     {
63         "FLUSH identifier=myhost/magic/MAGIC", NULL, CMD_OK, CMD_FLUSH,
64     },
65     {
66         "FLUSH identifier=magic/MAGIC", &default_host_opts, CMD_OK, CMD_FLUSH,
67     },
68     {
69         "FLUSH timeout=123 plugin=\"A\"", NULL, CMD_OK, CMD_FLUSH,
70     },
71     /* Invalid FLUSH commands. */
72     {
73         /* Missing hostname; no default. */
74         "FLUSH identifier=magic/MAGIC", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
75     },
76     {
77         /* Missing 'identifier' key. */
78         "FLUSH myhost/magic/MAGIC", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
79     },
80     {
81         /* Invalid timeout. */
82         "FLUSH timeout=A", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
83     },
84     {
85         /* Invalid identifier. */
86         "FLUSH identifier=invalid", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
87     },
88     {
89         /* Invalid option. */
90         "FLUSH invalid=option", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
91     },
92
93     /* Valid GETVAL commands. */
94     {
95         "GETVAL myhost/magic/MAGIC", NULL, CMD_OK, CMD_GETVAL,
96     },
97     {
98         "GETVAL magic/MAGIC", &default_host_opts, CMD_OK, CMD_GETVAL,
99     },
100
101     /* Invalid GETVAL commands. */
102     {
103         "GETVAL magic/MAGIC", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
104     },
105     {
106         "GETVAL", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
107     },
108     {
109         "GETVAL invalid", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
110     },
111
112     /* Valid LISTVAL commands. */
113     {
114         "LISTVAL", NULL, CMD_OK, CMD_LISTVAL,
115     },
116
117     /* Invalid LISTVAL commands. */
118     {
119         "LISTVAL invalid", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
120     },
121
122     /* Valid PUTVAL commands. */
123     {
124         "PUTVAL magic/MAGIC N:42", &default_host_opts, CMD_OK, CMD_PUTVAL,
125     },
126     {
127         "PUTVAL myhost/magic/MAGIC N:42", NULL, CMD_OK, CMD_PUTVAL,
128     },
129     {
130         "PUTVAL myhost/magic/MAGIC 1234:42", NULL, CMD_OK, CMD_PUTVAL,
131     },
132     {
133         "PUTVAL myhost/magic/MAGIC 1234:42 2345:23", NULL, CMD_OK, CMD_PUTVAL,
134     },
135     {
136         "PUTVAL myhost/magic/MAGIC interval=2 1234:42", NULL, CMD_OK,
137         CMD_PUTVAL,
138     },
139     {
140         "PUTVAL myhost/magic/MAGIC interval=2 1234:42 interval=5 2345:23", NULL,
141         CMD_OK, CMD_PUTVAL,
142     },
143
144     /* Invalid PUTVAL commands. */
145     {
146         "PUTVAL magic/MAGIC N:42", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
147     },
148     {
149         "PUTVAL", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
150     },
151     {
152         "PUTVAL invalid N:42", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
153     },
154     {
155         "PUTVAL myhost/magic/MAGIC A:42", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
156     },
157     {
158         "PUTVAL myhost/magic/MAGIC 1234:A", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
159     },
160     {
161         "PUTVAL myhost/magic/MAGIC", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
162     },
163     {
164         "PUTVAL 1234:A", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
165     },
166     {
167         "PUTVAL myhost/magic/UNKNOWN 1234:42", NULL, CMD_PARSE_ERROR,
168         CMD_UNKNOWN,
169     },
170     /*
171      * As of collectd 5.x, PUTVAL accepts invalid options.
172     {
173             "PUTVAL myhost/magic/MAGIC invalid=2 1234:42",
174             NULL,
175             CMD_PARSE_ERROR,
176             CMD_UNKNOWN,
177     },
178     */
179
180     /* Invalid commands. */
181     {
182         "INVALID", NULL, CMD_UNKNOWN_COMMAND, CMD_UNKNOWN,
183     },
184     {
185         "INVALID interval=2", NULL, CMD_UNKNOWN_COMMAND, CMD_UNKNOWN,
186     },
187 };
188
189 DEF_TEST(parse) {
190   cmd_error_handler_t err = {error_cb, NULL};
191   int test_result = 0;
192
193   for (size_t i = 0; i < STATIC_ARRAY_SIZE(parse_data); i++) {
194     char *input = strdup(parse_data[i].input);
195
196     char description[1024];
197     cmd_status_t status;
198     cmd_t cmd;
199
200     bool result;
201
202     memset(&cmd, 0, sizeof(cmd));
203
204     status = cmd_parse(input, &cmd, parse_data[i].opts, &err);
205     ssnprintf(description, sizeof(description), "cmd_parse (\"%s\", opts=%p) = "
206                                                 "%d (type=%d [%s]); want %d "
207                                                 "(type=%d [%s])",
208               parse_data[i].input, parse_data[i].opts, status, cmd.type,
209               CMD_TO_STRING(cmd.type), parse_data[i].expected_status,
210               parse_data[i].expected_type,
211               CMD_TO_STRING(parse_data[i].expected_type));
212     result = (status == parse_data[i].expected_status) &&
213              (cmd.type == parse_data[i].expected_type);
214     LOG(result, description);
215
216     /* Run all tests before failing. */
217     if (!result)
218       test_result = -1;
219
220     cmd_destroy(&cmd);
221     free(input);
222   }
223
224   return test_result;
225 }
226
227 int main(int argc, char **argv) {
228   RUN_TEST(parse);
229   END_TEST;
230 }