New upstream version 18.02
[deb_dpdk.git] / test / test / commands.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation.
3  * Copyright(c) 2014 6WIND S.A.
4  */
5
6 #include <stdio.h>
7 #include <stdarg.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <stdlib.h>
11 #include <netinet/in.h>
12 #include <termios.h>
13 #ifndef __linux__
14 #ifndef __FreeBSD__
15 #include <net/socket.h>
16 #endif
17 #endif
18 #include <inttypes.h>
19 #include <errno.h>
20 #include <sys/queue.h>
21
22 #include <rte_common.h>
23 #include <rte_log.h>
24 #include <rte_debug.h>
25 #include <rte_memory.h>
26 #include <rte_memcpy.h>
27 #include <rte_memzone.h>
28 #include <rte_launch.h>
29 #include <rte_cycles.h>
30 #include <rte_eal.h>
31 #include <rte_per_lcore.h>
32 #include <rte_lcore.h>
33 #include <rte_atomic.h>
34 #include <rte_branch_prediction.h>
35 #include <rte_ring.h>
36 #include <rte_malloc.h>
37 #include <rte_mempool.h>
38 #include <rte_mbuf.h>
39 #include <rte_devargs.h>
40
41 #include <cmdline_rdline.h>
42 #include <cmdline_parse.h>
43 #include <cmdline_parse_ipaddr.h>
44 #include <cmdline_parse_num.h>
45 #include <cmdline_parse_string.h>
46 #include <cmdline.h>
47
48 #include "test.h"
49
50 /****************/
51
52 static struct test_commands_list commands_list =
53         TAILQ_HEAD_INITIALIZER(commands_list);
54
55 void
56 add_test_command(struct test_command *t)
57 {
58         TAILQ_INSERT_TAIL(&commands_list, t, next);
59 }
60
61 struct cmd_autotest_result {
62         cmdline_fixed_string_t autotest;
63 };
64
65 static void cmd_autotest_parsed(void *parsed_result,
66                                 __attribute__((unused)) struct cmdline *cl,
67                                 __attribute__((unused)) void *data)
68 {
69         struct test_command *t;
70         struct cmd_autotest_result *res = parsed_result;
71         int ret = 0;
72
73         TAILQ_FOREACH(t, &commands_list, next) {
74                 if (!strcmp(res->autotest, t->command))
75                         ret = t->callback();
76         }
77
78         last_test_result = ret;
79         if (ret == 0)
80                 printf("Test OK\n");
81         else if (ret == TEST_SKIPPED)
82                 printf("Test Skipped\n");
83         else
84                 printf("Test Failed\n");
85         fflush(stdout);
86 }
87
88 cmdline_parse_token_string_t cmd_autotest_autotest =
89         TOKEN_STRING_INITIALIZER(struct cmd_autotest_result, autotest,
90                                  "");
91
92 cmdline_parse_inst_t cmd_autotest = {
93         .f = cmd_autotest_parsed,  /* function to call */
94         .data = NULL,      /* 2nd arg of func */
95         .help_str = "launch autotest",
96         .tokens = {        /* token list, NULL terminated */
97                 (void *)&cmd_autotest_autotest,
98                 NULL,
99         },
100 };
101
102 /****************/
103
104 struct cmd_dump_result {
105         cmdline_fixed_string_t dump;
106 };
107
108 static void
109 dump_struct_sizes(void)
110 {
111 #define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned)sizeof(t));
112         DUMP_SIZE(struct rte_mbuf);
113         DUMP_SIZE(struct rte_mempool);
114         DUMP_SIZE(struct rte_ring);
115 #undef DUMP_SIZE
116 }
117
118 static void cmd_dump_parsed(void *parsed_result,
119                             __attribute__((unused)) struct cmdline *cl,
120                             __attribute__((unused)) void *data)
121 {
122         struct cmd_dump_result *res = parsed_result;
123
124         if (!strcmp(res->dump, "dump_physmem"))
125                 rte_dump_physmem_layout(stdout);
126         else if (!strcmp(res->dump, "dump_memzone"))
127                 rte_memzone_dump(stdout);
128         else if (!strcmp(res->dump, "dump_struct_sizes"))
129                 dump_struct_sizes();
130         else if (!strcmp(res->dump, "dump_ring"))
131                 rte_ring_list_dump(stdout);
132         else if (!strcmp(res->dump, "dump_mempool"))
133                 rte_mempool_list_dump(stdout);
134         else if (!strcmp(res->dump, "dump_devargs"))
135                 rte_eal_devargs_dump(stdout);
136         else if (!strcmp(res->dump, "dump_log_types"))
137                 rte_log_dump(stdout);
138         else if (!strcmp(res->dump, "dump_malloc_stats"))
139                 rte_malloc_dump_stats(stdout, NULL);
140 }
141
142 cmdline_parse_token_string_t cmd_dump_dump =
143         TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
144                                  "dump_physmem#"
145                                  "dump_memzone#"
146                                  "dump_struct_sizes#"
147                                  "dump_ring#"
148                                  "dump_mempool#"
149                                  "dump_malloc_stats#"
150                                  "dump_devargs#"
151                                  "dump_log_types");
152
153 cmdline_parse_inst_t cmd_dump = {
154         .f = cmd_dump_parsed,  /* function to call */
155         .data = NULL,      /* 2nd arg of func */
156         .help_str = "dump status",
157         .tokens = {        /* token list, NULL terminated */
158                 (void *)&cmd_dump_dump,
159                 NULL,
160         },
161 };
162
163 /****************/
164
165 struct cmd_dump_one_result {
166         cmdline_fixed_string_t dump;
167         cmdline_fixed_string_t name;
168 };
169
170 static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl,
171                                 __attribute__((unused)) void *data)
172 {
173         struct cmd_dump_one_result *res = parsed_result;
174
175         if (!strcmp(res->dump, "dump_ring")) {
176                 struct rte_ring *r;
177                 r = rte_ring_lookup(res->name);
178                 if (r == NULL) {
179                         cmdline_printf(cl, "Cannot find ring\n");
180                         return;
181                 }
182                 rte_ring_dump(stdout, r);
183         }
184         else if (!strcmp(res->dump, "dump_mempool")) {
185                 struct rte_mempool *mp;
186                 mp = rte_mempool_lookup(res->name);
187                 if (mp == NULL) {
188                         cmdline_printf(cl, "Cannot find mempool\n");
189                         return;
190                 }
191                 rte_mempool_dump(stdout, mp);
192         }
193 }
194
195 cmdline_parse_token_string_t cmd_dump_one_dump =
196         TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump,
197                                  "dump_ring#dump_mempool");
198
199 cmdline_parse_token_string_t cmd_dump_one_name =
200         TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL);
201
202 cmdline_parse_inst_t cmd_dump_one = {
203         .f = cmd_dump_one_parsed,  /* function to call */
204         .data = NULL,      /* 2nd arg of func */
205         .help_str = "dump one ring/mempool: dump_ring|dump_mempool <name>",
206         .tokens = {        /* token list, NULL terminated */
207                 (void *)&cmd_dump_one_dump,
208                 (void *)&cmd_dump_one_name,
209                 NULL,
210         },
211 };
212
213 /****************/
214
215 struct cmd_quit_result {
216         cmdline_fixed_string_t quit;
217 };
218
219 static void
220 cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
221                 struct cmdline *cl,
222                 __attribute__((unused)) void *data)
223 {
224         cmdline_quit(cl);
225 }
226
227 cmdline_parse_token_string_t cmd_quit_quit =
228         TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit,
229                                  "quit");
230
231 cmdline_parse_inst_t cmd_quit = {
232         .f = cmd_quit_parsed,  /* function to call */
233         .data = NULL,      /* 2nd arg of func */
234         .help_str = "exit application",
235         .tokens = {        /* token list, NULL terminated */
236                 (void *)&cmd_quit_quit,
237                 NULL,
238         },
239 };
240
241 /****************/
242
243 struct cmd_set_rxtx_result {
244         cmdline_fixed_string_t set;
245         cmdline_fixed_string_t mode;
246 };
247
248 static void cmd_set_rxtx_parsed(void *parsed_result, struct cmdline *cl,
249                                 __attribute__((unused)) void *data)
250 {
251         struct cmd_set_rxtx_result *res = parsed_result;
252         if (test_set_rxtx_conf(res->mode) < 0)
253                 cmdline_printf(cl, "Cannot find such mode\n");
254 }
255
256 cmdline_parse_token_string_t cmd_set_rxtx_set =
257         TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, set,
258                                  "set_rxtx_mode");
259
260 cmdline_parse_token_string_t cmd_set_rxtx_mode =
261         TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_result, mode, NULL);
262
263 cmdline_parse_inst_t cmd_set_rxtx = {
264         .f = cmd_set_rxtx_parsed,  /* function to call */
265         .data = NULL,      /* 2nd arg of func */
266         .help_str = "set rxtx routine: "
267                         "set_rxtx <mode>",
268         .tokens = {        /* token list, NULL terminated */
269                 (void *)&cmd_set_rxtx_set,
270                 (void *)&cmd_set_rxtx_mode,
271                 NULL,
272         },
273 };
274
275 /****************/
276
277 struct cmd_set_rxtx_anchor {
278         cmdline_fixed_string_t set;
279         cmdline_fixed_string_t type;
280 };
281
282 static void
283 cmd_set_rxtx_anchor_parsed(void *parsed_result,
284                            struct cmdline *cl,
285                            __attribute__((unused)) void *data)
286 {
287         struct cmd_set_rxtx_anchor *res = parsed_result;
288         if (test_set_rxtx_anchor(res->type) < 0)
289                 cmdline_printf(cl, "Cannot find such anchor\n");
290 }
291
292 cmdline_parse_token_string_t cmd_set_rxtx_anchor_set =
293         TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_anchor, set,
294                                  "set_rxtx_anchor");
295
296 cmdline_parse_token_string_t cmd_set_rxtx_anchor_type =
297         TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_anchor, type, NULL);
298
299 cmdline_parse_inst_t cmd_set_rxtx_anchor = {
300         .f = cmd_set_rxtx_anchor_parsed,  /* function to call */
301         .data = NULL,      /* 2nd arg of func */
302         .help_str = "set rxtx anchor: "
303                         "set_rxtx_anchor <type>",
304         .tokens = {        /* token list, NULL terminated */
305                 (void *)&cmd_set_rxtx_anchor_set,
306                 (void *)&cmd_set_rxtx_anchor_type,
307                 NULL,
308         },
309 };
310
311 /****************/
312
313 /* for stream control */
314 struct cmd_set_rxtx_sc {
315         cmdline_fixed_string_t set;
316         cmdline_fixed_string_t type;
317 };
318
319 static void
320 cmd_set_rxtx_sc_parsed(void *parsed_result,
321                            struct cmdline *cl,
322                            __attribute__((unused)) void *data)
323 {
324         struct cmd_set_rxtx_sc *res = parsed_result;
325         if (test_set_rxtx_sc(res->type) < 0)
326                 cmdline_printf(cl, "Cannot find such stream control\n");
327 }
328
329 cmdline_parse_token_string_t cmd_set_rxtx_sc_set =
330         TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, set,
331                                  "set_rxtx_sc");
332
333 cmdline_parse_token_string_t cmd_set_rxtx_sc_type =
334         TOKEN_STRING_INITIALIZER(struct cmd_set_rxtx_sc, type, NULL);
335
336 cmdline_parse_inst_t cmd_set_rxtx_sc = {
337         .f = cmd_set_rxtx_sc_parsed,  /* function to call */
338         .data = NULL,      /* 2nd arg of func */
339         .help_str = "set rxtx stream control: "
340                         "set_rxtx_sc <type>",
341         .tokens = {        /* token list, NULL terminated */
342                 (void *)&cmd_set_rxtx_sc_set,
343                 (void *)&cmd_set_rxtx_sc_type,
344                 NULL,
345         },
346 };
347
348 /****************/
349
350
351 cmdline_parse_ctx_t main_ctx[] = {
352         (cmdline_parse_inst_t *)&cmd_autotest,
353         (cmdline_parse_inst_t *)&cmd_dump,
354         (cmdline_parse_inst_t *)&cmd_dump_one,
355         (cmdline_parse_inst_t *)&cmd_quit,
356         (cmdline_parse_inst_t *)&cmd_set_rxtx,
357         (cmdline_parse_inst_t *)&cmd_set_rxtx_anchor,
358         (cmdline_parse_inst_t *)&cmd_set_rxtx_sc,
359         NULL,
360 };
361
362 int commands_init(void)
363 {
364         struct test_command *t;
365         char *commands, *ptr;
366         int commands_len = 0;
367
368         TAILQ_FOREACH(t, &commands_list, next) {
369                 commands_len += strlen(t->command) + 1;
370         }
371
372         commands = malloc(commands_len + 1);
373         if (!commands)
374                 return -1;
375
376         ptr = commands;
377         TAILQ_FOREACH(t, &commands_list, next) {
378                 ptr += sprintf(ptr, "%s#", t->command);
379         }
380         ptr--;
381         ptr[0] = '\0';
382
383         cmd_autotest_autotest.string_data.str = commands;
384         return 0;
385 }