1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2018 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/stdinc.h" 7 8 #include "spdk_cunit.h" 9 #include "common/lib/test_env.c" 10 #include "event/app.c" 11 12 #define test_argc 6 13 14 DEFINE_STUB_V(spdk_event_call, (struct spdk_event *event)); 15 DEFINE_STUB(spdk_event_allocate, struct spdk_event *, (uint32_t core, spdk_event_fn fn, void *arg1, 16 void *arg2), NULL); 17 DEFINE_STUB_V(spdk_subsystem_init, (spdk_subsystem_init_fn cb_fn, void *cb_arg)); 18 DEFINE_STUB_V(spdk_subsystem_fini, (spdk_msg_fn cb_fn, void *cb_arg)); 19 DEFINE_STUB_V(spdk_rpc_register_method, (const char *method, spdk_rpc_method_handler func, 20 uint32_t state_mask)); 21 DEFINE_STUB_V(spdk_rpc_register_alias_deprecated, (const char *method, const char *alias)); 22 DEFINE_STUB_V(spdk_rpc_set_state, (uint32_t state)); 23 DEFINE_STUB(spdk_rpc_get_state, uint32_t, (void), SPDK_RPC_RUNTIME); 24 DEFINE_STUB(spdk_rpc_initialize, int, (const char *listen_addr), 0); 25 DEFINE_STUB_V(spdk_rpc_finish, (void)); 26 DEFINE_STUB_V(spdk_subsystem_init_from_json_config, (const char *json_config_file, 27 const char *rpc_addr, 28 spdk_subsystem_init_fn cb_fn, void *cb_arg, bool stop_on_error)); 29 DEFINE_STUB_V(spdk_reactors_start, (void)); 30 DEFINE_STUB_V(spdk_reactors_stop, (void *arg1)); 31 DEFINE_STUB(spdk_reactors_init, int, (size_t msg_mempool_size), 0); 32 DEFINE_STUB_V(spdk_reactors_fini, (void)); 33 DEFINE_STUB_V(_spdk_scheduler_set_period, (uint64_t period)); 34 bool g_scheduling_in_progress; 35 36 static void 37 unittest_usage(void) 38 { 39 } 40 41 static int 42 unittest_parse_args(int ch, char *arg) 43 { 44 return 0; 45 } 46 47 static void 48 clean_opts(struct spdk_app_opts *opts) 49 { 50 free(opts->pci_allowed); 51 opts->pci_allowed = NULL; 52 free(opts->pci_blocked); 53 opts->pci_blocked = NULL; 54 memset(opts, 0, sizeof(struct spdk_app_opts)); 55 } 56 57 static void 58 test_spdk_app_parse_args(void) 59 { 60 spdk_app_parse_args_rvals_t rc; 61 struct spdk_app_opts opts = {}; 62 struct option my_options[2] = {}; 63 char *valid_argv[test_argc] = {"app_ut", 64 "--single-file-segments", 65 "-d", 66 "-p0", 67 "-B", 68 "0000:81:00.0" 69 }; 70 char *invalid_argv_BW[test_argc] = {"app_ut", 71 "-B", 72 "0000:81:00.0", 73 "-W", 74 "0000:82:00.0", 75 "-cspdk.conf" 76 }; 77 /* currently use -z as our new option */ 78 char *argv_added_short_opt[test_argc] = {"app_ut", 79 "-z", 80 "-d", 81 "--single-file-segments", 82 "-p0", 83 "-cspdk.conf" 84 }; 85 char *argv_added_long_opt[test_argc] = {"app_ut", 86 "-cspdk.conf", 87 "-d", 88 "-r/var/tmp/spdk.sock", 89 "--test-long-opt", 90 "--single-file-segments" 91 }; 92 char *invalid_argv_missing_option[test_argc] = {"app_ut", 93 "-d", 94 "-p", 95 "--single-file-segments", 96 "--silence-noticelog", 97 "-R" 98 }; 99 100 /* Test valid arguments. Expected result: PASS */ 101 rc = spdk_app_parse_args(test_argc, valid_argv, &opts, "", NULL, unittest_parse_args, NULL); 102 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_SUCCESS); 103 optind = 1; 104 clean_opts(&opts); 105 106 /* Test invalid short option Expected result: FAIL */ 107 rc = spdk_app_parse_args(test_argc, argv_added_short_opt, &opts, "", NULL, unittest_parse_args, 108 NULL); 109 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_FAIL); 110 optind = 1; 111 clean_opts(&opts); 112 113 /* Test valid global and local options. Expected result: PASS */ 114 rc = spdk_app_parse_args(test_argc, argv_added_short_opt, &opts, "z", NULL, unittest_parse_args, 115 unittest_usage); 116 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_SUCCESS); 117 optind = 1; 118 clean_opts(&opts); 119 120 /* Test invalid long option Expected result: FAIL */ 121 rc = spdk_app_parse_args(test_argc, argv_added_long_opt, &opts, "", NULL, unittest_parse_args, 122 NULL); 123 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_FAIL); 124 optind = 1; 125 clean_opts(&opts); 126 127 /* Test valid global and local options. Expected result: PASS */ 128 my_options[0].name = "test-long-opt"; 129 rc = spdk_app_parse_args(test_argc, argv_added_long_opt, &opts, "", my_options, unittest_parse_args, 130 unittest_usage); 131 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_SUCCESS); 132 optind = 1; 133 clean_opts(&opts); 134 135 /* Test overlapping global and local options. Expected result: FAIL */ 136 rc = spdk_app_parse_args(test_argc, valid_argv, &opts, SPDK_APP_GETOPT_STRING, NULL, 137 unittest_parse_args, NULL); 138 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_FAIL); 139 optind = 1; 140 clean_opts(&opts); 141 142 /* Specify -B and -W options at the same time. Expected result: FAIL */ 143 rc = spdk_app_parse_args(test_argc, invalid_argv_BW, &opts, "", NULL, unittest_parse_args, NULL); 144 SPDK_CU_ASSERT_FATAL(rc == SPDK_APP_PARSE_ARGS_FAIL); 145 optind = 1; 146 clean_opts(&opts); 147 148 /* Omit necessary argument to option */ 149 rc = spdk_app_parse_args(test_argc, invalid_argv_missing_option, &opts, "", NULL, 150 unittest_parse_args, NULL); 151 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_FAIL); 152 optind = 1; 153 clean_opts(&opts); 154 } 155 156 int 157 main(int argc, char **argv) 158 { 159 CU_pSuite suite = NULL; 160 unsigned int num_failures; 161 162 CU_set_error_action(CUEA_ABORT); 163 CU_initialize_registry(); 164 165 suite = CU_add_suite("app_suite", NULL, NULL); 166 167 CU_ADD_TEST(suite, test_spdk_app_parse_args); 168 169 CU_basic_set_mode(CU_BRM_VERBOSE); 170 CU_basic_run_tests(); 171 num_failures = CU_get_number_of_failures(); 172 CU_cleanup_registry(); 173 174 return num_failures; 175 } 176