1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2014 6WIND S.A.
3 */
4
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8
9 #include <rte_common.h>
10 #include <rte_kvargs.h>
11
12 #include "test.h"
13
14 /* incremented in handler, to check it is properly called once per
15 * key/value association */
16 static unsigned count;
17
18 /* this handler increment the "count" variable at each call and check
19 * that the key is "check" and the value is "value%d" */
check_handler(const char * key,const char * value,__rte_unused void * opaque)20 static int check_handler(const char *key, const char *value,
21 __rte_unused void *opaque)
22 {
23 char buf[16];
24
25 /* we check that the value is "check" */
26 if (strcmp(key, "check"))
27 return -1;
28
29 /* we check that the value is "value$(count)" */
30 snprintf(buf, sizeof(buf), "value%d", count);
31 if (strncmp(buf, value, sizeof(buf)))
32 return -1;
33
34 count ++;
35 return 0;
36 }
37
38 /* test parsing. */
test_kvargs_parsing(const char * args,unsigned int n)39 static int test_kvargs_parsing(const char *args, unsigned int n)
40 {
41 struct rte_kvargs *kvlist;
42
43 kvlist = rte_kvargs_parse(args, NULL);
44 if (kvlist == NULL) {
45 printf("rte_kvargs_parse() error: %s\n", args);
46 return -1;
47 }
48 if (kvlist->count != n) {
49 printf("invalid count value %d: %s\n", kvlist->count, args);
50 rte_kvargs_free(kvlist);
51 return -1;
52 }
53 rte_kvargs_free(kvlist);
54 return 0;
55 }
56
57 /* test a valid case */
test_valid_kvargs(void)58 static int test_valid_kvargs(void)
59 {
60 struct rte_kvargs *kvlist;
61 const char *args;
62 const char *valid_keys_list[] = { "foo", "check", NULL };
63 const char **valid_keys;
64 static const struct {
65 unsigned int expected;
66 const char *input;
67 } valid_inputs[] = {
68 { 2, "foo=1,foo=" },
69 { 2, "foo=1,foo=" },
70 { 2, "foo=1,foo" },
71 { 2, "foo=1,=2" },
72 { 1, "foo=[1,2" },
73 { 1, ",=" },
74 { 1, "foo=[" },
75 };
76 unsigned int i;
77
78 /* empty args is valid */
79 args = "";
80 valid_keys = NULL;
81 kvlist = rte_kvargs_parse(args, valid_keys);
82 if (kvlist == NULL) {
83 printf("rte_kvargs_parse() error");
84 goto fail;
85 }
86 rte_kvargs_free(kvlist);
87
88 /* first test without valid_keys */
89 args = "foo=1234,check=value0,check=value1";
90 valid_keys = NULL;
91 kvlist = rte_kvargs_parse(args, valid_keys);
92 if (kvlist == NULL) {
93 printf("rte_kvargs_parse() error");
94 goto fail;
95 }
96 /* call check_handler() for all entries with key="check" */
97 count = 0;
98 if (rte_kvargs_process(kvlist, "check", check_handler, NULL) < 0) {
99 printf("rte_kvargs_process() error\n");
100 rte_kvargs_free(kvlist);
101 goto fail;
102 }
103 if (count != 2) {
104 printf("invalid count value %d after rte_kvargs_process(check)\n",
105 count);
106 rte_kvargs_free(kvlist);
107 goto fail;
108 }
109 count = 0;
110 /* call check_handler() for all entries with key="nonexistent_key" */
111 if (rte_kvargs_process(kvlist, "nonexistent_key", check_handler, NULL) < 0) {
112 printf("rte_kvargs_process() error\n");
113 rte_kvargs_free(kvlist);
114 goto fail;
115 }
116 if (count != 0) {
117 printf("invalid count value %d after rte_kvargs_process(nonexistent_key)\n",
118 count);
119 rte_kvargs_free(kvlist);
120 goto fail;
121 }
122 /* count all entries with key="foo" */
123 count = rte_kvargs_count(kvlist, "foo");
124 if (count != 1) {
125 printf("invalid count value %d after rte_kvargs_count(foo)\n",
126 count);
127 rte_kvargs_free(kvlist);
128 goto fail;
129 }
130 /* count all entries */
131 count = rte_kvargs_count(kvlist, NULL);
132 if (count != 3) {
133 printf("invalid count value %d after rte_kvargs_count(NULL)\n",
134 count);
135 rte_kvargs_free(kvlist);
136 goto fail;
137 }
138 /* count all entries with key="nonexistent_key" */
139 count = rte_kvargs_count(kvlist, "nonexistent_key");
140 if (count != 0) {
141 printf("invalid count value %d after rte_kvargs_count(nonexistent_key)\n",
142 count);
143 rte_kvargs_free(kvlist);
144 goto fail;
145 }
146 rte_kvargs_free(kvlist);
147
148 /* second test using valid_keys */
149 args = "foo=droids,check=value0,check=value1,check=wrong_value";
150 valid_keys = valid_keys_list;
151 kvlist = rte_kvargs_parse(args, valid_keys);
152 if (kvlist == NULL) {
153 printf("rte_kvargs_parse() error");
154 goto fail;
155 }
156 /* call check_handler() on all entries with key="check", it
157 * should fail as the value is not recognized by the handler */
158 if (rte_kvargs_process(kvlist, "check", check_handler, NULL) == 0) {
159 printf("rte_kvargs_process() is success but should not\n");
160 rte_kvargs_free(kvlist);
161 goto fail;
162 }
163 count = rte_kvargs_count(kvlist, "check");
164 if (count != 3) {
165 printf("invalid count value %d after rte_kvargs_count(check)\n",
166 count);
167 rte_kvargs_free(kvlist);
168 goto fail;
169 }
170 rte_kvargs_free(kvlist);
171
172 /* third test using list as value */
173 args = "foo=[0,1],check=value2";
174 valid_keys = valid_keys_list;
175 kvlist = rte_kvargs_parse(args, valid_keys);
176 if (kvlist == NULL) {
177 printf("rte_kvargs_parse() error\n");
178 goto fail;
179 }
180 if (strcmp(kvlist->pairs[0].value, "[0,1]") != 0) {
181 printf("wrong value %s", kvlist->pairs[0].value);
182 goto fail;
183 }
184 count = kvlist->count;
185 if (count != 2) {
186 printf("invalid count value %d\n", count);
187 rte_kvargs_free(kvlist);
188 goto fail;
189 }
190 rte_kvargs_free(kvlist);
191
192 /* test using empty string (it is valid) */
193 args = "";
194 kvlist = rte_kvargs_parse(args, NULL);
195 if (kvlist == NULL) {
196 printf("rte_kvargs_parse() error\n");
197 goto fail;
198 }
199 if (rte_kvargs_count(kvlist, NULL) != 0) {
200 printf("invalid count value\n");
201 goto fail;
202 }
203 rte_kvargs_free(kvlist);
204
205 /* test using empty elements (it is valid) */
206 args = "foo=1,,check=value2,,";
207 kvlist = rte_kvargs_parse(args, NULL);
208 if (kvlist == NULL) {
209 printf("rte_kvargs_parse() error\n");
210 goto fail;
211 }
212 if (rte_kvargs_count(kvlist, NULL) != 2) {
213 printf("invalid count value\n");
214 goto fail;
215 }
216 if (rte_kvargs_count(kvlist, "foo") != 1) {
217 printf("invalid count value for 'foo'\n");
218 goto fail;
219 }
220 if (rte_kvargs_count(kvlist, "check") != 1) {
221 printf("invalid count value for 'check'\n");
222 goto fail;
223 }
224 rte_kvargs_free(kvlist);
225
226 valid_keys = NULL;
227
228 for (i = 0; i < RTE_DIM(valid_inputs); ++i) {
229 args = valid_inputs[i].input;
230 if (test_kvargs_parsing(args, valid_inputs[i].expected))
231 goto fail;
232 }
233
234 return 0;
235
236 fail:
237 printf("while processing <%s>", args);
238 if (valid_keys != NULL && *valid_keys != NULL) {
239 printf(" using valid_keys=<%s", *valid_keys);
240 while (*(++valid_keys) != NULL)
241 printf(",%s", *valid_keys);
242 printf(">");
243 }
244 printf("\n");
245 return -1;
246 }
247
248 /* test several error cases */
test_invalid_kvargs(void)249 static int test_invalid_kvargs(void)
250 {
251 struct rte_kvargs *kvlist;
252 /* list of argument that should fail */
253 const char *args_list[] = {
254 "wrong-key=x", /* key not in valid_keys_list */
255 NULL };
256 const char **args;
257 const char *valid_keys_list[] = { "foo", "check", NULL };
258 const char **valid_keys = valid_keys_list;
259
260 for (args = args_list; *args != NULL; args++) {
261
262 kvlist = rte_kvargs_parse(*args, valid_keys);
263 if (kvlist != NULL) {
264 printf("rte_kvargs_parse() returned 0 (but should not)\n");
265 rte_kvargs_free(kvlist);
266 goto fail;
267 }
268 }
269 return 0;
270
271 fail:
272 printf("while processing <%s>", *args);
273 if (valid_keys != NULL && *valid_keys != NULL) {
274 printf(" using valid_keys=<%s", *valid_keys);
275 while (*(++valid_keys) != NULL)
276 printf(",%s", *valid_keys);
277 printf(">");
278 }
279 printf("\n");
280 return -1;
281 }
282
283 static int
test_kvargs(void)284 test_kvargs(void)
285 {
286 printf("== test valid case ==\n");
287 if (test_valid_kvargs() < 0)
288 return -1;
289 printf("== test invalid case ==\n");
290 if (test_invalid_kvargs() < 0)
291 return -1;
292 return 0;
293 }
294
295 REGISTER_TEST_COMMAND(kvargs_autotest, test_kvargs);
296