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