1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 36 #include "spdk_cunit.h" 37 #include "common/lib/test_env.c" 38 #include "event/app.c" 39 40 #define test_argc 6 41 42 DEFINE_STUB_V(spdk_event_call, (struct spdk_event *event)); 43 DEFINE_STUB(spdk_event_allocate, struct spdk_event *, (uint32_t core, spdk_event_fn fn, void *arg1, 44 void *arg2), NULL); 45 DEFINE_STUB_V(spdk_subsystem_init, (spdk_subsystem_init_fn cb_fn, void *cb_arg)); 46 DEFINE_STUB_V(spdk_subsystem_fini, (spdk_msg_fn cb_fn, void *cb_arg)); 47 DEFINE_STUB_V(spdk_rpc_register_method, (const char *method, spdk_rpc_method_handler func, 48 uint32_t state_mask)); 49 DEFINE_STUB_V(spdk_rpc_register_alias_deprecated, (const char *method, const char *alias)); 50 DEFINE_STUB_V(spdk_rpc_set_state, (uint32_t state)); 51 DEFINE_STUB(spdk_rpc_get_state, uint32_t, (void), SPDK_RPC_RUNTIME); 52 DEFINE_STUB(spdk_rpc_initialize, int, (const char *listen_addr), 0); 53 DEFINE_STUB_V(spdk_rpc_finish, (void)); 54 DEFINE_STUB_V(spdk_subsystem_init_from_json_config, (const char *json_config_file, 55 const char *rpc_addr, 56 spdk_subsystem_init_fn cb_fn, void *cb_arg, bool stop_on_error)); 57 DEFINE_STUB_V(spdk_reactors_start, (void)); 58 DEFINE_STUB_V(spdk_reactors_stop, (void *arg1)); 59 DEFINE_STUB(spdk_reactors_init, int, (void), 0); 60 DEFINE_STUB_V(spdk_reactors_fini, (void)); 61 DEFINE_STUB_V(_spdk_scheduler_set_period, (uint64_t period)); 62 bool g_scheduling_in_progress; 63 64 static void 65 unittest_usage(void) 66 { 67 } 68 69 static int 70 unittest_parse_args(int ch, char *arg) 71 { 72 return 0; 73 } 74 75 static void 76 clean_opts(struct spdk_app_opts *opts) 77 { 78 free(opts->pci_allowed); 79 opts->pci_allowed = NULL; 80 free(opts->pci_blocked); 81 opts->pci_blocked = NULL; 82 memset(opts, 0, sizeof(struct spdk_app_opts)); 83 } 84 85 static void 86 test_spdk_app_parse_args(void) 87 { 88 spdk_app_parse_args_rvals_t rc; 89 struct spdk_app_opts opts = {}; 90 struct option my_options[2] = {}; 91 char *valid_argv[test_argc] = {"app_ut", 92 "--single-file-segments", 93 "-d", 94 "-p0", 95 "-B", 96 "0000:81:00.0" 97 }; 98 char *invalid_argv_BW[test_argc] = {"app_ut", 99 "-B", 100 "0000:81:00.0", 101 "-W", 102 "0000:82:00.0", 103 "-cspdk.conf" 104 }; 105 /* currently use -z as our new option */ 106 char *argv_added_short_opt[test_argc] = {"app_ut", 107 "-z", 108 "-d", 109 "--single-file-segments", 110 "-p0", 111 "-cspdk.conf" 112 }; 113 char *argv_added_long_opt[test_argc] = {"app_ut", 114 "-cspdk.conf", 115 "-d", 116 "-r/var/tmp/spdk.sock", 117 "--test-long-opt", 118 "--single-file-segments" 119 }; 120 char *invalid_argv_missing_option[test_argc] = {"app_ut", 121 "-d", 122 "-p", 123 "--single-file-segments", 124 "--silence-noticelog", 125 "-R" 126 }; 127 128 /* Test valid arguments. Expected result: PASS */ 129 rc = spdk_app_parse_args(test_argc, valid_argv, &opts, "", NULL, unittest_parse_args, NULL); 130 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_SUCCESS); 131 optind = 1; 132 clean_opts(&opts); 133 134 /* Test invalid short option Expected result: FAIL */ 135 rc = spdk_app_parse_args(test_argc, argv_added_short_opt, &opts, "", NULL, unittest_parse_args, 136 NULL); 137 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_FAIL); 138 optind = 1; 139 clean_opts(&opts); 140 141 /* Test valid global and local options. Expected result: PASS */ 142 rc = spdk_app_parse_args(test_argc, argv_added_short_opt, &opts, "z", NULL, unittest_parse_args, 143 unittest_usage); 144 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_SUCCESS); 145 optind = 1; 146 clean_opts(&opts); 147 148 /* Test invalid long option Expected result: FAIL */ 149 rc = spdk_app_parse_args(test_argc, argv_added_long_opt, &opts, "", NULL, unittest_parse_args, 150 NULL); 151 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_FAIL); 152 optind = 1; 153 clean_opts(&opts); 154 155 /* Test valid global and local options. Expected result: PASS */ 156 my_options[0].name = "test-long-opt"; 157 rc = spdk_app_parse_args(test_argc, argv_added_long_opt, &opts, "", my_options, unittest_parse_args, 158 unittest_usage); 159 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_SUCCESS); 160 optind = 1; 161 clean_opts(&opts); 162 163 /* Test overlapping global and local options. Expected result: FAIL */ 164 rc = spdk_app_parse_args(test_argc, valid_argv, &opts, SPDK_APP_GETOPT_STRING, NULL, 165 unittest_parse_args, NULL); 166 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_FAIL); 167 optind = 1; 168 clean_opts(&opts); 169 170 /* Specify -B and -W options at the same time. Expected result: FAIL */ 171 rc = spdk_app_parse_args(test_argc, invalid_argv_BW, &opts, "", NULL, unittest_parse_args, NULL); 172 SPDK_CU_ASSERT_FATAL(rc == SPDK_APP_PARSE_ARGS_FAIL); 173 optind = 1; 174 clean_opts(&opts); 175 176 /* Omit necessary argument to option */ 177 rc = spdk_app_parse_args(test_argc, invalid_argv_missing_option, &opts, "", NULL, 178 unittest_parse_args, NULL); 179 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_FAIL); 180 optind = 1; 181 clean_opts(&opts); 182 } 183 184 int 185 main(int argc, char **argv) 186 { 187 CU_pSuite suite = NULL; 188 unsigned int num_failures; 189 190 CU_set_error_action(CUEA_ABORT); 191 CU_initialize_registry(); 192 193 suite = CU_add_suite("app_suite", NULL, NULL); 194 195 CU_ADD_TEST(suite, test_spdk_app_parse_args); 196 197 CU_basic_set_mode(CU_BRM_VERBOSE); 198 CU_basic_run_tests(); 199 num_failures = CU_get_number_of_failures(); 200 CU_cleanup_registry(); 201 202 return num_failures; 203 } 204