New upstream version 18.02
[deb_dpdk.git] / test / test / test_cmdline_string.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #include <stdio.h>
6 #include <string.h>
7 #include <inttypes.h>
8
9 #include <rte_common.h>
10 #include <rte_string_fns.h>
11
12 #include <cmdline_parse.h>
13 #include <cmdline_parse_string.h>
14
15 #include "test_cmdline.h"
16
17 /* structures needed to run tests */
18
19 struct string_elt_str {
20         const char * str;       /* parsed string */
21         const char * result;    /* expected string */
22         int idx;        /* position at which result is expected to be */
23 };
24
25 struct string_elt_str string_elt_strs[] = {
26                 {"one#two#three", "three", 2},
27                 {"one#two with spaces#three", "three", 2},
28                 {"one#two\twith\ttabs#three", "three", 2},
29                 {"one#two\rwith\rreturns#three", "three", 2},
30                 {"one#two\nwith\nnewlines#three", "three", 2},
31                 {"one#two#three", "one", 0},
32                 {"one#two#three", "two", 1},
33                 {"one#two\0three", "two", 1},
34                 {"one#two with spaces#three", "two with spaces", 1},
35                 {"one#two\twith\ttabs#three", "two\twith\ttabs", 1},
36                 {"one#two\rwith\rreturns#three", "two\rwith\rreturns", 1},
37                 {"one#two\nwith\nnewlines#three", "two\nwith\nnewlines", 1},
38 };
39
40 #if (CMDLINE_TEST_BUFSIZE < STR_TOKEN_SIZE) \
41 || (CMDLINE_TEST_BUFSIZE < STR_MULTI_TOKEN_SIZE)
42 #undef CMDLINE_TEST_BUFSIZE
43 #define CMDLINE_TEST_BUFSIZE RTE_MAX(STR_TOKEN_SIZE, STR_MULTI_TOKEN_SIZE)
44 #endif
45
46 struct string_nb_str {
47         const char * str;       /* parsed string */
48         int nb_strs;    /* expected number of strings in str */
49 };
50
51 struct string_nb_str string_nb_strs[] = {
52                 {"one#two#three", 3},
53                 {"one", 1},
54                 {"one# \t two \r # three \n #four", 4},
55 };
56
57
58
59 struct string_parse_str {
60         const char * str;       /* parsed string */
61         const char * fixed_str; /* parsing mode (any, fixed or multi) */
62         const char * result;    /* expected result */
63 };
64
65 struct string_parse_str string_parse_strs[] = {
66                 {"one", NULL, "one"},   /* any string */
67                 {"two", "one#two#three", "two"},        /* multiple choice string */
68                 {"three", "three", "three"},    /* fixed string */
69                 {"three", "one#two with\rgarbage\tcharacters\n#three", "three"},
70                 {"two with\rgarbage\tcharacters\n",
71                                 "one#two with\rgarbage\tcharacters\n#three",
72                                 "two with\rgarbage\tcharacters\n"},
73                 {"one two", "one", "one"}, /* fixed string */
74                 {"one two", TOKEN_STRING_MULTI, "one two"}, /* multi string */
75                 {"one two", NULL, "one"}, /* any string */
76                 {"one two #three", TOKEN_STRING_MULTI, "one two "},
77                 /* multi string with comment */
78 };
79
80
81
82 struct string_invalid_str {
83         const char * str;       /* parsed string */
84         const char * fixed_str; /* parsing mode (any, fixed or multi) */
85 };
86
87 struct string_invalid_str string_invalid_strs[] = {
88                 {"invalid", "one"},     /* fixed string */
89                 {"invalid", "one#two#three"},   /* multiple choice string */
90                 {"invalid", "invalidone"},      /* string that starts the same */
91                 {"invalidone", "invalid"},      /* string that starts the same */
92                 {"toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
93                  "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
94                  "toolong!!!", NULL },
95                 {"toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
96                  "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
97                  "toolong!!!", "fixed" },
98                 {"toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
99                  "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
100                  "toolong!!!", "multi#choice#string" },
101                 {"invalid",
102                  "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
103                  "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
104                  "toolong!!!" },
105                  {"", "invalid"}
106 };
107
108
109
110 const char * string_help_strs[] = {
111                 NULL,
112                 "fixed_str",
113                 "multi#str",
114 };
115
116
117
118 #define STRING_PARSE_STRS_SIZE \
119         (sizeof(string_parse_strs) / sizeof(string_parse_strs[0]))
120 #define STRING_HELP_STRS_SIZE \
121         (sizeof(string_help_strs) / sizeof(string_help_strs[0]))
122 #define STRING_ELT_STRS_SIZE \
123         (sizeof(string_elt_strs) / sizeof(string_elt_strs[0]))
124 #define STRING_NB_STRS_SIZE \
125         (sizeof(string_nb_strs) / sizeof(string_nb_strs[0]))
126 #define STRING_INVALID_STRS_SIZE \
127         (sizeof(string_invalid_strs) / sizeof(string_invalid_strs[0]))
128
129 #define SMALL_BUF 8
130
131 /* test invalid parameters */
132 int
133 test_parse_string_invalid_param(void)
134 {
135         cmdline_parse_token_string_t token;
136         int result;
137         char buf[CMDLINE_TEST_BUFSIZE];
138
139         memset(&token, 0, sizeof(token));
140
141         snprintf(buf, sizeof(buf), "buffer");
142
143         /* test null token */
144         if (cmdline_get_help_string(
145                 NULL, buf, 0) != -1) {
146                 printf("Error: function accepted null token!\n");
147                 return -1;
148         }
149         if (cmdline_complete_get_elt_string(
150                         NULL, 0, buf, 0) != -1) {
151                 printf("Error: function accepted null token!\n");
152                 return -1;
153         }
154         if (cmdline_complete_get_nb_string(NULL) != -1) {
155                 printf("Error: function accepted null token!\n");
156                 return -1;
157         }
158         if (cmdline_parse_string(NULL, buf, NULL, 0) != -1) {
159                 printf("Error: function accepted null token!\n");
160                 return -1;
161         }
162         /* test null buffer */
163         if (cmdline_complete_get_elt_string(
164                         (cmdline_parse_token_hdr_t*)&token, 0, NULL, 0) != -1) {
165                 printf("Error: function accepted null buffer!\n");
166                 return -1;
167         }
168         if (cmdline_parse_string(
169                         (cmdline_parse_token_hdr_t*)&token, NULL,
170                         (void*)&result, sizeof(result)) != -1) {
171                 printf("Error: function accepted null buffer!\n");
172                 return -1;
173         }
174         if (cmdline_get_help_string(
175                         (cmdline_parse_token_hdr_t*)&token, NULL, 0) != -1) {
176                 printf("Error: function accepted null buffer!\n");
177                 return -1;
178         }
179         /* test null result */
180         if (cmdline_parse_string(
181                         (cmdline_parse_token_hdr_t*)&token, buf, NULL, 0) == -1) {
182                 printf("Error: function rejected null result!\n");
183                 return -1;
184         }
185         /* test negative index */
186         if (cmdline_complete_get_elt_string(
187                         (cmdline_parse_token_hdr_t*)&token, -1, buf, 0) != -1) {
188                 printf("Error: function accepted negative index!\n");
189                 return -1;
190         }
191         return 0;
192 }
193
194 /* test valid parameters but invalid data */
195 int
196 test_parse_string_invalid_data(void)
197 {
198         cmdline_parse_token_string_t token;
199         cmdline_parse_token_string_t help_token;
200         char buf[CMDLINE_TEST_BUFSIZE];
201         char help_str[CMDLINE_TEST_BUFSIZE];
202         char small_buf[SMALL_BUF];
203         unsigned i;
204
205         /* test parsing invalid strings */
206         for (i = 0; i < STRING_INVALID_STRS_SIZE; i++) {
207                 memset(&token, 0, sizeof(token));
208                 memset(buf, 0, sizeof(buf));
209
210                 /* prepare test token data */
211                 token.string_data.str = string_invalid_strs[i].fixed_str;
212
213                 if (cmdline_parse_string((cmdline_parse_token_hdr_t*)&token,
214                                 string_invalid_strs[i].str, (void*)buf,
215                                 sizeof(buf)) != -1) {
216                         memset(help_str, 0, sizeof(help_str));
217                         memset(&help_token, 0, sizeof(help_token));
218
219                         help_token.string_data.str = string_invalid_strs[i].fixed_str;
220
221                         /* get parse type so we can give a good error message */
222                         cmdline_get_help_string((cmdline_parse_token_hdr_t*)&token, help_str,
223                                         sizeof(help_str));
224
225                         printf("Error: parsing %s as %s succeeded!\n",
226                                         string_invalid_strs[i].str, help_str);
227                         return -1;
228                 }
229         }
230
231         /* misc tests (big comments signify test cases) */
232         memset(&token, 0, sizeof(token));
233         memset(small_buf, 0, sizeof(small_buf));
234
235         /*
236          * try to get element from a null token
237          */
238         token.string_data.str = NULL;
239         if (cmdline_complete_get_elt_string(
240                         (cmdline_parse_token_hdr_t*)&token, 1,
241                         buf, sizeof(buf)) != -1) {
242                 printf("Error: getting token from null token string!\n");
243                 return -1;
244         }
245
246         /*
247          * try to get element into a buffer that is too small
248          */
249         token.string_data.str = "too_small_buffer";
250         if (cmdline_complete_get_elt_string(
251                         (cmdline_parse_token_hdr_t*)&token, 0,
252                         small_buf, sizeof(small_buf)) != -1) {
253                 printf("Error: writing token into too small a buffer succeeded!\n");
254                 return -1;
255         }
256
257         /*
258          * get help string written into a buffer smaller than help string
259          * truncation should occur
260          */
261         token.string_data.str = NULL;
262         if (cmdline_get_help_string(
263                         (cmdline_parse_token_hdr_t*)&token,
264                         small_buf, sizeof(small_buf)) == -1) {
265                 printf("Error: writing help string into too small a buffer failed!\n");
266                 return -1;
267         }
268         /* get help string for "any string" so we can compare it with small_buf */
269         cmdline_get_help_string((cmdline_parse_token_hdr_t*)&token, help_str,
270                         sizeof(help_str));
271         if (strncmp(small_buf, help_str, sizeof(small_buf) - 1)) {
272                 printf("Error: help string mismatch!\n");
273                 return -1;
274         }
275         /* check null terminator */
276         if (small_buf[sizeof(small_buf) - 1] != '\0') {
277                 printf("Error: small buffer doesn't have a null terminator!\n");
278                 return -1;
279         }
280
281         /*
282          * try to count tokens in a null token
283          */
284         token.string_data.str = NULL;
285         if (cmdline_complete_get_nb_string(
286                         (cmdline_parse_token_hdr_t*)&token) != 0) {
287                 printf("Error: getting token count from null token succeeded!\n");
288                 return -1;
289         }
290
291         return 0;
292 }
293
294 /* test valid parameters and data */
295 int
296 test_parse_string_valid(void)
297 {
298         cmdline_parse_token_string_t token;
299         cmdline_parse_token_string_t help_token;
300         char buf[CMDLINE_TEST_BUFSIZE];
301         char help_str[CMDLINE_TEST_BUFSIZE];
302         unsigned i;
303
304         /* test parsing strings */
305         for (i = 0; i < STRING_PARSE_STRS_SIZE; i++) {
306                 memset(&token, 0, sizeof(token));
307                 memset(buf, 0, sizeof(buf));
308
309                 token.string_data.str = string_parse_strs[i].fixed_str;
310
311                 if (cmdline_parse_string((cmdline_parse_token_hdr_t*)&token,
312                                 string_parse_strs[i].str, (void*)buf,
313                                 sizeof(buf)) < 0) {
314
315                         /* clean help data */
316                         memset(&help_token, 0, sizeof(help_token));
317                         memset(help_str, 0, sizeof(help_str));
318
319                         /* prepare help token */
320                         help_token.string_data.str = string_parse_strs[i].fixed_str;
321
322                         /* get help string so that we get an informative error message */
323                         cmdline_get_help_string((cmdline_parse_token_hdr_t*)&token, help_str,
324                                         sizeof(help_str));
325
326                         printf("Error: parsing %s as %s failed!\n",
327                                         string_parse_strs[i].str, help_str);
328                         return -1;
329                 }
330                 if (strcmp(buf, string_parse_strs[i].result) != 0) {
331                         printf("Error: result mismatch!\n");
332                         return -1;
333                 }
334         }
335
336         /* get number of string tokens and verify it's correct */
337         for (i = 0; i < STRING_NB_STRS_SIZE; i++) {
338                 memset(&token, 0, sizeof(token));
339
340                 token.string_data.str = string_nb_strs[i].str;
341
342                 if (cmdline_complete_get_nb_string(
343                                 (cmdline_parse_token_hdr_t*)&token) <
344                                 string_nb_strs[i].nb_strs) {
345                         printf("Error: strings count mismatch!\n");
346                         return -1;
347                 }
348         }
349
350         /* get token at specified position and verify it's correct */
351         for (i = 0; i < STRING_ELT_STRS_SIZE; i++) {
352                 memset(&token, 0, sizeof(token));
353                 memset(buf, 0, sizeof(buf));
354
355                 token.string_data.str = string_elt_strs[i].str;
356
357                 if (cmdline_complete_get_elt_string(
358                                 (cmdline_parse_token_hdr_t*)&token, string_elt_strs[i].idx,
359                                 buf, sizeof(buf)) < 0) {
360                         printf("Error: getting string element failed!\n");
361                         return -1;
362                 }
363                 if (strncmp(buf, string_elt_strs[i].result,
364                                 sizeof(buf)) != 0) {
365                         printf("Error: result mismatch!\n");
366                         return -1;
367                 }
368         }
369
370         /* cover all cases with help strings */
371         for (i = 0; i < STRING_HELP_STRS_SIZE; i++) {
372                 memset(&help_token, 0, sizeof(help_token));
373                 memset(help_str, 0, sizeof(help_str));
374                 help_token.string_data.str = string_help_strs[i];
375                 if (cmdline_get_help_string((cmdline_parse_token_hdr_t*)&help_token,
376                                 help_str, sizeof(help_str)) < 0) {
377                         printf("Error: help operation failed!\n");
378                         return -1;
379                 }
380         }
381
382         return 0;
383 }