1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #include <string.h> 6 #include <stdio.h> 7 #include <stdint.h> 8 #include <stdarg.h> 9 #include <stdlib.h> 10 #include <errno.h> 11 #include <termios.h> 12 #include <ctype.h> 13 #include <sys/queue.h> 14 15 #ifdef RTE_LIBRTE_CMDLINE 16 #include <cmdline_rdline.h> 17 #include <cmdline_parse.h> 18 #include <cmdline_socket.h> 19 #include <cmdline.h> 20 extern cmdline_parse_ctx_t main_ctx[]; 21 #endif 22 23 #include <rte_memory.h> 24 #include <rte_eal.h> 25 #include <rte_cycles.h> 26 #include <rte_log.h> 27 #include <rte_string_fns.h> 28 #ifdef RTE_LIBRTE_TIMER 29 #include <rte_timer.h> 30 #endif 31 32 #include "test.h" 33 #include "test_pdump.h" 34 35 #define RTE_LOGTYPE_APP RTE_LOGTYPE_USER1 36 37 const char *prgname; /* to be set to argv[0] */ 38 39 static const char *recursive_call; /* used in linuxapp for MP and other tests */ 40 41 static int 42 no_action(void){ return 0; } 43 44 static int 45 do_recursive_call(void) 46 { 47 unsigned i; 48 struct { 49 const char *env_var; 50 int (*action_fn)(void); 51 } actions[] = { 52 { "run_secondary_instances", test_mp_secondary }, 53 { "run_pdump_server_tests", test_pdump }, 54 { "test_missing_c_flag", no_action }, 55 { "test_master_lcore_flag", no_action }, 56 { "test_invalid_n_flag", no_action }, 57 { "test_no_hpet_flag", no_action }, 58 { "test_whitelist_flag", no_action }, 59 { "test_invalid_b_flag", no_action }, 60 { "test_invalid_vdev_flag", no_action }, 61 { "test_invalid_r_flag", no_action }, 62 { "test_misc_flags", no_action }, 63 { "test_memory_flags", no_action }, 64 { "test_file_prefix", no_action }, 65 { "test_no_huge_flag", no_action }, 66 }; 67 68 if (recursive_call == NULL) 69 return -1; 70 for (i = 0; i < sizeof(actions)/sizeof(actions[0]); i++) { 71 if (strcmp(actions[i].env_var, recursive_call) == 0) 72 return (actions[i].action_fn)(); 73 } 74 printf("ERROR - missing action to take for %s\n", recursive_call); 75 return -1; 76 } 77 78 int last_test_result; 79 80 #define MAX_EXTRA_ARGS 32 81 82 int 83 main(int argc, char **argv) 84 { 85 #ifdef RTE_LIBRTE_CMDLINE 86 struct cmdline *cl; 87 #endif 88 char *extra_args; 89 int ret; 90 91 extra_args = getenv("DPDK_TEST_PARAMS"); 92 if (extra_args != NULL && strlen(extra_args) > 0) { 93 char **all_argv; 94 char *eargv[MAX_EXTRA_ARGS]; 95 int all_argc; 96 int eargc; 97 int i; 98 99 RTE_LOG(INFO, APP, "Using additional DPDK_TEST_PARAMS: '%s'\n", 100 extra_args); 101 eargc = rte_strsplit(extra_args, strlen(extra_args), 102 eargv, MAX_EXTRA_ARGS, ' '); 103 104 /* merge argc/argv and the environment args */ 105 all_argc = argc + eargc; 106 all_argv = malloc(sizeof(*all_argv) * (all_argc + 1)); 107 if (all_argv == NULL) { 108 ret = -1; 109 goto out; 110 } 111 112 for (i = 0; i < argc; i++) 113 all_argv[i] = argv[i]; 114 for (i = 0; i < eargc; i++) 115 all_argv[argc + i] = eargv[i]; 116 all_argv[all_argc] = NULL; 117 118 /* call eal_init with combined args */ 119 ret = rte_eal_init(all_argc, all_argv); 120 free(all_argv); 121 } else 122 ret = rte_eal_init(argc, argv); 123 if (ret < 0) { 124 ret = -1; 125 goto out; 126 } 127 128 #ifdef RTE_LIBRTE_TIMER 129 rte_timer_subsystem_init(); 130 #endif 131 132 if (commands_init() < 0) { 133 ret = -1; 134 goto out; 135 } 136 137 argv += ret; 138 139 prgname = argv[0]; 140 141 recursive_call = getenv(RECURSIVE_ENV_VAR); 142 if (recursive_call != NULL) { 143 ret = do_recursive_call(); 144 goto out; 145 } 146 147 #ifdef RTE_LIBEAL_USE_HPET 148 if (rte_eal_hpet_init(1) < 0) 149 #endif 150 RTE_LOG(INFO, APP, 151 "HPET is not enabled, using TSC as default timer\n"); 152 153 154 #ifdef RTE_LIBRTE_CMDLINE 155 cl = cmdline_stdin_new(main_ctx, "RTE>>"); 156 if (cl == NULL) { 157 ret = -1; 158 goto out; 159 } 160 161 char *dpdk_test = getenv("DPDK_TEST"); 162 if (dpdk_test && strlen(dpdk_test)) { 163 char buf[1024]; 164 snprintf(buf, sizeof(buf), "%s\n", dpdk_test); 165 if (cmdline_in(cl, buf, strlen(buf)) < 0) { 166 printf("error on cmdline input\n"); 167 ret = -1; 168 goto out; 169 } 170 171 cmdline_stdin_exit(cl); 172 ret = last_test_result; 173 goto out; 174 } 175 /* if no DPDK_TEST env variable, go interactive */ 176 cmdline_interact(cl); 177 cmdline_stdin_exit(cl); 178 #endif 179 ret = 0; 180 181 out: 182 rte_eal_cleanup(); 183 return ret; 184 } 185 186 187 int 188 unit_test_suite_runner(struct unit_test_suite *suite) 189 { 190 int test_success; 191 unsigned int total = 0, executed = 0, skipped = 0; 192 unsigned int succeeded = 0, failed = 0, unsupported = 0; 193 const char *status; 194 195 if (suite->suite_name) { 196 printf(" + ------------------------------------------------------- +\n"); 197 printf(" + Test Suite : %s\n", suite->suite_name); 198 } 199 200 if (suite->setup) 201 if (suite->setup() != 0) { 202 /* 203 * setup failed, so count all enabled tests and mark 204 * them as failed 205 */ 206 while (suite->unit_test_cases[total].testcase) { 207 if (!suite->unit_test_cases[total].enabled) 208 skipped++; 209 else 210 failed++; 211 total++; 212 } 213 goto suite_summary; 214 } 215 216 printf(" + ------------------------------------------------------- +\n"); 217 218 while (suite->unit_test_cases[total].testcase) { 219 if (!suite->unit_test_cases[total].enabled) { 220 skipped++; 221 total++; 222 continue; 223 } else { 224 executed++; 225 } 226 227 /* run test case setup */ 228 if (suite->unit_test_cases[total].setup) 229 test_success = suite->unit_test_cases[total].setup(); 230 else 231 test_success = TEST_SUCCESS; 232 233 if (test_success == TEST_SUCCESS) { 234 /* run the test case */ 235 test_success = suite->unit_test_cases[total].testcase(); 236 if (test_success == TEST_SUCCESS) 237 succeeded++; 238 else if (test_success == -ENOTSUP) 239 unsupported++; 240 else 241 failed++; 242 } else if (test_success == -ENOTSUP) { 243 unsupported++; 244 } else { 245 failed++; 246 } 247 248 /* run the test case teardown */ 249 if (suite->unit_test_cases[total].teardown) 250 suite->unit_test_cases[total].teardown(); 251 252 if (test_success == TEST_SUCCESS) 253 status = "succeeded"; 254 else if (test_success == -ENOTSUP) 255 status = "unsupported"; 256 else 257 status = "failed"; 258 259 printf(" + TestCase [%2d] : %s %s\n", total, 260 suite->unit_test_cases[total].name, status); 261 262 total++; 263 } 264 265 /* Run test suite teardown */ 266 if (suite->teardown) 267 suite->teardown(); 268 269 goto suite_summary; 270 271 suite_summary: 272 printf(" + ------------------------------------------------------- +\n"); 273 printf(" + Test Suite Summary \n"); 274 printf(" + Tests Total : %2d\n", total); 275 printf(" + Tests Skipped : %2d\n", skipped); 276 printf(" + Tests Executed : %2d\n", executed); 277 printf(" + Tests Unsupported: %2d\n", unsupported); 278 printf(" + Tests Passed : %2d\n", succeeded); 279 printf(" + Tests Failed : %2d\n", failed); 280 printf(" + ------------------------------------------------------- +\n"); 281 282 last_test_result = failed; 283 284 if (failed) 285 return -1; 286 287 return 0; 288 } 289