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