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 /* incrementd 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" */ 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. */ 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 */ 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="unexistant_key" */ 111 if (rte_kvargs_process(kvlist, "unexistant_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(unexistant_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="unexistant_key" */ 139 count = rte_kvargs_count(kvlist, "unexistant_key"); 140 if (count != 0) { 141 printf("invalid count value %d after rte_kvargs_count(unexistant_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 bu 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 */ 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 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