1 /* 2 * Copyright 2014 6WIND S.A. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * - Neither the name of 6WIND S.A. nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 31 * OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <stdlib.h> 35 #include <stdio.h> 36 #include <string.h> 37 38 #include <rte_common.h> 39 #include <rte_kvargs.h> 40 41 #include "test.h" 42 43 /* incrementd in handler, to check it is properly called once per 44 * key/value association */ 45 static unsigned count; 46 47 /* this handler increment the "count" variable at each call and check 48 * that the key is "check" and the value is "value%d" */ 49 static int check_handler(const char *key, const char *value, 50 __rte_unused void *opaque) 51 { 52 char buf[16]; 53 54 /* we check that the value is "check" */ 55 if (strcmp(key, "check")) 56 return -1; 57 58 /* we check that the value is "value$(count)" */ 59 snprintf(buf, sizeof(buf), "value%d", count); 60 if (strncmp(buf, value, sizeof(buf))) 61 return -1; 62 63 count ++; 64 return 0; 65 } 66 67 /* test a valid case */ 68 static int test_valid_kvargs(void) 69 { 70 struct rte_kvargs *kvlist; 71 const char *args; 72 const char *valid_keys_list[] = { "foo", "check", NULL }; 73 const char **valid_keys; 74 75 /* empty args is valid */ 76 args = ""; 77 valid_keys = NULL; 78 kvlist = rte_kvargs_parse(args, valid_keys); 79 if (kvlist == NULL) { 80 printf("rte_kvargs_parse() error"); 81 goto fail; 82 } 83 rte_kvargs_free(kvlist); 84 85 /* first test without valid_keys */ 86 args = "foo=1234,check=value0,check=value1"; 87 valid_keys = NULL; 88 kvlist = rte_kvargs_parse(args, valid_keys); 89 if (kvlist == NULL) { 90 printf("rte_kvargs_parse() error"); 91 goto fail; 92 } 93 /* call check_handler() for all entries with key="check" */ 94 count = 0; 95 if (rte_kvargs_process(kvlist, "check", check_handler, NULL) < 0) { 96 printf("rte_kvargs_process() error\n"); 97 rte_kvargs_free(kvlist); 98 goto fail; 99 } 100 if (count != 2) { 101 printf("invalid count value %d after rte_kvargs_process(check)\n", 102 count); 103 rte_kvargs_free(kvlist); 104 goto fail; 105 } 106 count = 0; 107 /* call check_handler() for all entries with key="unexistant_key" */ 108 if (rte_kvargs_process(kvlist, "unexistant_key", check_handler, NULL) < 0) { 109 printf("rte_kvargs_process() error\n"); 110 rte_kvargs_free(kvlist); 111 goto fail; 112 } 113 if (count != 0) { 114 printf("invalid count value %d after rte_kvargs_process(unexistant_key)\n", 115 count); 116 rte_kvargs_free(kvlist); 117 goto fail; 118 } 119 /* count all entries with key="foo" */ 120 count = rte_kvargs_count(kvlist, "foo"); 121 if (count != 1) { 122 printf("invalid count value %d after rte_kvargs_count(foo)\n", 123 count); 124 rte_kvargs_free(kvlist); 125 goto fail; 126 } 127 /* count all entries */ 128 count = rte_kvargs_count(kvlist, NULL); 129 if (count != 3) { 130 printf("invalid count value %d after rte_kvargs_count(NULL)\n", 131 count); 132 rte_kvargs_free(kvlist); 133 goto fail; 134 } 135 /* count all entries with key="unexistant_key" */ 136 count = rte_kvargs_count(kvlist, "unexistant_key"); 137 if (count != 0) { 138 printf("invalid count value %d after rte_kvargs_count(unexistant_key)\n", 139 count); 140 rte_kvargs_free(kvlist); 141 goto fail; 142 } 143 rte_kvargs_free(kvlist); 144 145 /* second test using valid_keys */ 146 args = "foo=droids,check=value0,check=value1,check=wrong_value"; 147 valid_keys = valid_keys_list; 148 kvlist = rte_kvargs_parse(args, valid_keys); 149 if (kvlist == NULL) { 150 printf("rte_kvargs_parse() error"); 151 goto fail; 152 } 153 /* call check_handler() on all entries with key="check", it 154 * should fail as the value is not recognized by the handler */ 155 if (rte_kvargs_process(kvlist, "check", check_handler, NULL) == 0) { 156 printf("rte_kvargs_process() is success bu should not\n"); 157 rte_kvargs_free(kvlist); 158 goto fail; 159 } 160 count = rte_kvargs_count(kvlist, "check"); 161 if (count != 3) { 162 printf("invalid count value %d after rte_kvargs_count(check)\n", 163 count); 164 rte_kvargs_free(kvlist); 165 goto fail; 166 } 167 rte_kvargs_free(kvlist); 168 169 return 0; 170 171 fail: 172 printf("while processing <%s>", args); 173 if (valid_keys != NULL && *valid_keys != NULL) { 174 printf(" using valid_keys=<%s", *valid_keys); 175 while (*(++valid_keys) != NULL) 176 printf(",%s", *valid_keys); 177 printf(">"); 178 } 179 printf("\n"); 180 return -1; 181 } 182 183 /* test several error cases */ 184 static int test_invalid_kvargs(void) 185 { 186 struct rte_kvargs *kvlist; 187 /* list of argument that should fail */ 188 const char *args_list[] = { 189 "wrong-key=x", /* key not in valid_keys_list */ 190 "foo=1,foo=", /* empty value */ 191 "foo=1,,foo=2", /* empty key/value */ 192 "foo=1,foo", /* no value */ 193 "foo=1,=2", /* no key */ 194 ",=", /* also test with a smiley */ 195 NULL }; 196 const char **args; 197 const char *valid_keys_list[] = { "foo", "check", NULL }; 198 const char **valid_keys = valid_keys_list; 199 200 for (args = args_list; *args != NULL; args++) { 201 202 kvlist = rte_kvargs_parse(*args, valid_keys); 203 if (kvlist != NULL) { 204 printf("rte_kvargs_parse() returned 0 (but should not)\n"); 205 rte_kvargs_free(kvlist); 206 goto fail; 207 } 208 return 0; 209 } 210 211 fail: 212 printf("while processing <%s>", *args); 213 if (valid_keys != NULL && *valid_keys != NULL) { 214 printf(" using valid_keys=<%s", *valid_keys); 215 while (*(++valid_keys) != NULL) 216 printf(",%s", *valid_keys); 217 printf(">"); 218 } 219 printf("\n"); 220 return -1; 221 } 222 223 static int 224 test_kvargs(void) 225 { 226 printf("== test valid case ==\n"); 227 if (test_valid_kvargs() < 0) 228 return -1; 229 printf("== test invalid case ==\n"); 230 if (test_invalid_kvargs() < 0) 231 return -1; 232 return 0; 233 } 234 235 REGISTER_TEST_COMMAND(kvargs_autotest, test_kvargs); 236