net/virtio: fix incorrect cast of void *
[dpdk.git] / test / test / test_cmdline_string.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <inttypes.h>
37
38 #include <rte_common.h>
39 #include <rte_string_fns.h>
40
41 #include <cmdline_parse.h>
42 #include <cmdline_parse_string.h>
43
44 #include "test_cmdline.h"
45
46 /* structures needed to run tests */
47
48 struct string_elt_str {
49         const char * str;       /* parsed string */
50         const char * result;    /* expected string */
51         int idx;        /* position at which result is expected to be */
52 };
53
54 struct string_elt_str string_elt_strs[] = {
55                 {"one#two#three", "three", 2},
56                 {"one#two with spaces#three", "three", 2},
57                 {"one#two\twith\ttabs#three", "three", 2},
58                 {"one#two\rwith\rreturns#three", "three", 2},
59                 {"one#two\nwith\nnewlines#three", "three", 2},
60                 {"one#two#three", "one", 0},
61                 {"one#two#three", "two", 1},
62                 {"one#two\0three", "two", 1},
63                 {"one#two with spaces#three", "two with spaces", 1},
64                 {"one#two\twith\ttabs#three", "two\twith\ttabs", 1},
65                 {"one#two\rwith\rreturns#three", "two\rwith\rreturns", 1},
66                 {"one#two\nwith\nnewlines#three", "two\nwith\nnewlines", 1},
67 };
68
69 #if (CMDLINE_TEST_BUFSIZE < STR_TOKEN_SIZE) \
70 || (CMDLINE_TEST_BUFSIZE < STR_MULTI_TOKEN_SIZE)
71 #undef CMDLINE_TEST_BUFSIZE
72 #define CMDLINE_TEST_BUFSIZE RTE_MAX(STR_TOKEN_SIZE, STR_MULTI_TOKEN_SIZE)
73 #endif
74
75 struct string_nb_str {
76         const char * str;       /* parsed string */
77         int nb_strs;    /* expected number of strings in str */
78 };
79
80 struct string_nb_str string_nb_strs[] = {
81                 {"one#two#three", 3},
82                 {"one", 1},
83                 {"one# \t two \r # three \n #four", 4},
84 };
85
86
87
88 struct string_parse_str {
89         const char * str;       /* parsed string */
90         const char * fixed_str; /* parsing mode (any, fixed or multi) */
91         const char * result;    /* expected result */
92 };
93
94 struct string_parse_str string_parse_strs[] = {
95                 {"one", NULL, "one"},   /* any string */
96                 {"two", "one#two#three", "two"},        /* multiple choice string */
97                 {"three", "three", "three"},    /* fixed string */
98                 {"three", "one#two with\rgarbage\tcharacters\n#three", "three"},
99                 {"two with\rgarbage\tcharacters\n",
100                                 "one#two with\rgarbage\tcharacters\n#three",
101                                 "two with\rgarbage\tcharacters\n"},
102                 {"one two", "one", "one"}, /* fixed string */
103                 {"one two", TOKEN_STRING_MULTI, "one two"}, /* multi string */
104                 {"one two", NULL, "one"}, /* any string */
105                 {"one two #three", TOKEN_STRING_MULTI, "one two "},
106                 /* multi string with comment */
107 };
108
109
110
111 struct string_invalid_str {
112         const char * str;       /* parsed string */
113         const char * fixed_str; /* parsing mode (any, fixed or multi) */
114 };
115
116 struct string_invalid_str string_invalid_strs[] = {
117                 {"invalid", "one"},     /* fixed string */
118                 {"invalid", "one#two#three"},   /* multiple choice string */
119                 {"invalid", "invalidone"},      /* string that starts the same */
120                 {"invalidone", "invalid"},      /* string that starts the same */
121                 {"toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
122                  "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
123                  "toolong!!!", NULL },
124                 {"toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
125                  "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
126                  "toolong!!!", "fixed" },
127                 {"toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
128                  "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
129                  "toolong!!!", "multi#choice#string" },
130                 {"invalid",
131                  "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
132                  "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
133                  "toolong!!!" },
134                  {"", "invalid"}
135 };
136
137
138
139 const char * string_help_strs[] = {
140                 NULL,
141                 "fixed_str",
142                 "multi#str",
143 };
144
145
146
147 #define STRING_PARSE_STRS_SIZE \
148         (sizeof(string_parse_strs) / sizeof(string_parse_strs[0]))
149 #define STRING_HELP_STRS_SIZE \
150         (sizeof(string_help_strs) / sizeof(string_help_strs[0]))
151 #define STRING_ELT_STRS_SIZE \
152         (sizeof(string_elt_strs) / sizeof(string_elt_strs[0]))
153 #define STRING_NB_STRS_SIZE \
154         (sizeof(string_nb_strs) / sizeof(string_nb_strs[0]))
155 #define STRING_INVALID_STRS_SIZE \
156         (sizeof(string_invalid_strs) / sizeof(string_invalid_strs[0]))
157
158 #define SMALL_BUF 8
159
160 /* test invalid parameters */
161 int
162 test_parse_string_invalid_param(void)
163 {
164         cmdline_parse_token_string_t token;
165         int result;
166         char buf[CMDLINE_TEST_BUFSIZE];
167
168         memset(&token, 0, sizeof(token));
169
170         snprintf(buf, sizeof(buf), "buffer");
171
172         /* test null token */
173         if (cmdline_get_help_string(
174                 NULL, buf, 0) != -1) {
175                 printf("Error: function accepted null token!\n");
176                 return -1;
177         }
178         if (cmdline_complete_get_elt_string(
179                         NULL, 0, buf, 0) != -1) {
180                 printf("Error: function accepted null token!\n");
181                 return -1;
182         }
183         if (cmdline_complete_get_nb_string(NULL) != -1) {
184                 printf("Error: function accepted null token!\n");
185                 return -1;
186         }
187         if (cmdline_parse_string(NULL, buf, NULL, 0) != -1) {
188                 printf("Error: function accepted null token!\n");
189                 return -1;
190         }
191         /* test null buffer */
192         if (cmdline_complete_get_elt_string(
193                         (cmdline_parse_token_hdr_t*)&token, 0, NULL, 0) != -1) {
194                 printf("Error: function accepted null buffer!\n");
195                 return -1;
196         }
197         if (cmdline_parse_string(
198                         (cmdline_parse_token_hdr_t*)&token, NULL,
199                         (void*)&result, sizeof(result)) != -1) {
200                 printf("Error: function accepted null buffer!\n");
201                 return -1;
202         }
203         if (cmdline_get_help_string(
204                         (cmdline_parse_token_hdr_t*)&token, NULL, 0) != -1) {
205                 printf("Error: function accepted null buffer!\n");
206                 return -1;
207         }
208         /* test null result */
209         if (cmdline_parse_string(
210                         (cmdline_parse_token_hdr_t*)&token, buf, NULL, 0) == -1) {
211                 printf("Error: function rejected null result!\n");
212                 return -1;
213         }
214         /* test negative index */
215         if (cmdline_complete_get_elt_string(
216                         (cmdline_parse_token_hdr_t*)&token, -1, buf, 0) != -1) {
217                 printf("Error: function accepted negative index!\n");
218                 return -1;
219         }
220         return 0;
221 }
222
223 /* test valid parameters but invalid data */
224 int
225 test_parse_string_invalid_data(void)
226 {
227         cmdline_parse_token_string_t token;
228         cmdline_parse_token_string_t help_token;
229         char buf[CMDLINE_TEST_BUFSIZE];
230         char help_str[CMDLINE_TEST_BUFSIZE];
231         char small_buf[SMALL_BUF];
232         unsigned i;
233
234         /* test parsing invalid strings */
235         for (i = 0; i < STRING_INVALID_STRS_SIZE; i++) {
236                 memset(&token, 0, sizeof(token));
237                 memset(buf, 0, sizeof(buf));
238
239                 /* prepare test token data */
240                 token.string_data.str = string_invalid_strs[i].fixed_str;
241
242                 if (cmdline_parse_string((cmdline_parse_token_hdr_t*)&token,
243                                 string_invalid_strs[i].str, (void*)buf,
244                                 sizeof(buf)) != -1) {
245                         memset(help_str, 0, sizeof(help_str));
246                         memset(&help_token, 0, sizeof(help_token));
247
248                         help_token.string_data.str = string_invalid_strs[i].fixed_str;
249
250                         /* get parse type so we can give a good error message */
251                         cmdline_get_help_string((cmdline_parse_token_hdr_t*)&token, help_str,
252                                         sizeof(help_str));
253
254                         printf("Error: parsing %s as %s succeeded!\n",
255                                         string_invalid_strs[i].str, help_str);
256                         return -1;
257                 }
258         }
259
260         /* misc tests (big comments signify test cases) */
261         memset(&token, 0, sizeof(token));
262         memset(small_buf, 0, sizeof(small_buf));
263
264         /*
265          * try to get element from a null token
266          */
267         token.string_data.str = NULL;
268         if (cmdline_complete_get_elt_string(
269                         (cmdline_parse_token_hdr_t*)&token, 1,
270                         buf, sizeof(buf)) != -1) {
271                 printf("Error: getting token from null token string!\n");
272                 return -1;
273         }
274
275         /*
276          * try to get element into a buffer that is too small
277          */
278         token.string_data.str = "too_small_buffer";
279         if (cmdline_complete_get_elt_string(
280                         (cmdline_parse_token_hdr_t*)&token, 0,
281                         small_buf, sizeof(small_buf)) != -1) {
282                 printf("Error: writing token into too small a buffer succeeded!\n");
283                 return -1;
284         }
285
286         /*
287          * get help string written into a buffer smaller than help string
288          * truncation should occur
289          */
290         token.string_data.str = NULL;
291         if (cmdline_get_help_string(
292                         (cmdline_parse_token_hdr_t*)&token,
293                         small_buf, sizeof(small_buf)) == -1) {
294                 printf("Error: writing help string into too small a buffer failed!\n");
295                 return -1;
296         }
297         /* get help string for "any string" so we can compare it with small_buf */
298         cmdline_get_help_string((cmdline_parse_token_hdr_t*)&token, help_str,
299                         sizeof(help_str));
300         if (strncmp(small_buf, help_str, sizeof(small_buf) - 1)) {
301                 printf("Error: help string mismatch!\n");
302                 return -1;
303         }
304         /* check null terminator */
305         if (small_buf[sizeof(small_buf) - 1] != '\0') {
306                 printf("Error: small buffer doesn't have a null terminator!\n");
307                 return -1;
308         }
309
310         /*
311          * try to count tokens in a null token
312          */
313         token.string_data.str = NULL;
314         if (cmdline_complete_get_nb_string(
315                         (cmdline_parse_token_hdr_t*)&token) != 0) {
316                 printf("Error: getting token count from null token succeeded!\n");
317                 return -1;
318         }
319
320         return 0;
321 }
322
323 /* test valid parameters and data */
324 int
325 test_parse_string_valid(void)
326 {
327         cmdline_parse_token_string_t token;
328         cmdline_parse_token_string_t help_token;
329         char buf[CMDLINE_TEST_BUFSIZE];
330         char help_str[CMDLINE_TEST_BUFSIZE];
331         unsigned i;
332
333         /* test parsing strings */
334         for (i = 0; i < STRING_PARSE_STRS_SIZE; i++) {
335                 memset(&token, 0, sizeof(token));
336                 memset(buf, 0, sizeof(buf));
337
338                 token.string_data.str = string_parse_strs[i].fixed_str;
339
340                 if (cmdline_parse_string((cmdline_parse_token_hdr_t*)&token,
341                                 string_parse_strs[i].str, (void*)buf,
342                                 sizeof(buf)) < 0) {
343
344                         /* clean help data */
345                         memset(&help_token, 0, sizeof(help_token));
346                         memset(help_str, 0, sizeof(help_str));
347
348                         /* prepare help token */
349                         help_token.string_data.str = string_parse_strs[i].fixed_str;
350
351                         /* get help string so that we get an informative error message */
352                         cmdline_get_help_string((cmdline_parse_token_hdr_t*)&token, help_str,
353                                         sizeof(help_str));
354
355                         printf("Error: parsing %s as %s failed!\n",
356                                         string_parse_strs[i].str, help_str);
357                         return -1;
358                 }
359                 if (strcmp(buf, string_parse_strs[i].result) != 0) {
360                         printf("Error: result mismatch!\n");
361                         return -1;
362                 }
363         }
364
365         /* get number of string tokens and verify it's correct */
366         for (i = 0; i < STRING_NB_STRS_SIZE; i++) {
367                 memset(&token, 0, sizeof(token));
368
369                 token.string_data.str = string_nb_strs[i].str;
370
371                 if (cmdline_complete_get_nb_string(
372                                 (cmdline_parse_token_hdr_t*)&token) <
373                                 string_nb_strs[i].nb_strs) {
374                         printf("Error: strings count mismatch!\n");
375                         return -1;
376                 }
377         }
378
379         /* get token at specified position and verify it's correct */
380         for (i = 0; i < STRING_ELT_STRS_SIZE; i++) {
381                 memset(&token, 0, sizeof(token));
382                 memset(buf, 0, sizeof(buf));
383
384                 token.string_data.str = string_elt_strs[i].str;
385
386                 if (cmdline_complete_get_elt_string(
387                                 (cmdline_parse_token_hdr_t*)&token, string_elt_strs[i].idx,
388                                 buf, sizeof(buf)) < 0) {
389                         printf("Error: getting string element failed!\n");
390                         return -1;
391                 }
392                 if (strncmp(buf, string_elt_strs[i].result,
393                                 sizeof(buf)) != 0) {
394                         printf("Error: result mismatch!\n");
395                         return -1;
396                 }
397         }
398
399         /* cover all cases with help strings */
400         for (i = 0; i < STRING_HELP_STRS_SIZE; i++) {
401                 memset(&help_token, 0, sizeof(help_token));
402                 memset(help_str, 0, sizeof(help_str));
403                 help_token.string_data.str = string_help_strs[i];
404                 if (cmdline_get_help_string((cmdline_parse_token_hdr_t*)&help_token,
405                                 help_str, sizeof(help_str)) < 0) {
406                         printf("Error: help operation failed!\n");
407                         return -1;
408                 }
409         }
410
411         return 0;
412 }