1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2018 Intel Corporation. All rights reserved. 3 * Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 */ 5 6 #include "spdk/stdinc.h" 7 8 #include "spdk_internal/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, 25 const struct spdk_rpc_opts *opts), 0); 26 DEFINE_STUB_V(spdk_rpc_set_allowlist, (const char **rpc_allowlist)); 27 DEFINE_STUB_V(spdk_rpc_finish, (void)); 28 DEFINE_STUB_V(spdk_subsystem_init_from_json_config, (const char *json_config_file, 29 const char *rpc_addr, 30 spdk_subsystem_init_fn cb_fn, void *cb_arg, bool stop_on_error)); 31 DEFINE_STUB_V(spdk_reactors_start, (void)); 32 DEFINE_STUB_V(spdk_reactors_stop, (void *arg1)); 33 DEFINE_STUB(spdk_reactors_init, int, (size_t msg_mempool_size), 0); 34 DEFINE_STUB_V(spdk_reactors_fini, (void)); 35 bool g_scheduling_in_progress; 36 37 static void 38 unittest_usage(void) 39 { 40 } 41 42 static int 43 unittest_parse_args(int ch, char *arg) 44 { 45 return 0; 46 } 47 48 static void 49 clean_opts(struct spdk_app_opts *opts) 50 { 51 free(opts->pci_allowed); 52 opts->pci_allowed = NULL; 53 free(opts->pci_blocked); 54 opts->pci_blocked = NULL; 55 memset(opts, 0, sizeof(struct spdk_app_opts)); 56 } 57 58 static void 59 test_spdk_app_parse_args(void) 60 { 61 spdk_app_parse_args_rvals_t rc; 62 struct spdk_app_opts opts = {}; 63 struct option my_options[2] = {}; 64 char *valid_argv[test_argc] = {"app_ut", 65 "--single-file-segments", 66 "-d", 67 "-p0", 68 "-B", 69 "0000:81:00.0" 70 }; 71 char *invalid_argv_BW[test_argc] = {"app_ut", 72 "-B", 73 "0000:81:00.0", 74 "-W", 75 "0000:82:00.0", 76 "-cspdk.conf" 77 }; 78 /* currently use -z as our new option */ 79 char *argv_added_short_opt[test_argc] = {"app_ut", 80 "-z", 81 "-d", 82 "--single-file-segments", 83 "-p0", 84 "-cspdk.conf" 85 }; 86 char *argv_added_long_opt[test_argc] = {"app_ut", 87 "-cspdk.conf", 88 "-d", 89 "-r/var/tmp/spdk.sock", 90 "--test-long-opt", 91 "--single-file-segments" 92 }; 93 char *invalid_argv_missing_option[test_argc] = {"app_ut", 94 "-d", 95 "-p", 96 "--single-file-segments", 97 "--silence-noticelog", 98 "-R" 99 }; 100 101 /* Test valid arguments. Expected result: PASS */ 102 rc = spdk_app_parse_args(test_argc, valid_argv, &opts, "", NULL, unittest_parse_args, NULL); 103 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_SUCCESS); 104 optind = 1; 105 clean_opts(&opts); 106 107 /* Test invalid short option Expected result: FAIL */ 108 rc = spdk_app_parse_args(test_argc, argv_added_short_opt, &opts, "", NULL, unittest_parse_args, 109 NULL); 110 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_FAIL); 111 optind = 1; 112 clean_opts(&opts); 113 114 /* Test valid global and local options. Expected result: PASS */ 115 rc = spdk_app_parse_args(test_argc, argv_added_short_opt, &opts, "z", NULL, unittest_parse_args, 116 unittest_usage); 117 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_SUCCESS); 118 optind = 1; 119 clean_opts(&opts); 120 121 /* Test invalid long option Expected result: FAIL */ 122 rc = spdk_app_parse_args(test_argc, argv_added_long_opt, &opts, "", NULL, unittest_parse_args, 123 NULL); 124 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_FAIL); 125 optind = 1; 126 clean_opts(&opts); 127 128 /* Test valid global and local options. Expected result: PASS */ 129 my_options[0].name = "test-long-opt"; 130 rc = spdk_app_parse_args(test_argc, argv_added_long_opt, &opts, "", my_options, unittest_parse_args, 131 unittest_usage); 132 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_SUCCESS); 133 optind = 1; 134 clean_opts(&opts); 135 136 /* Test overlapping global and local options. Expected result: FAIL */ 137 rc = spdk_app_parse_args(test_argc, valid_argv, &opts, SPDK_APP_GETOPT_STRING, NULL, 138 unittest_parse_args, NULL); 139 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_FAIL); 140 optind = 1; 141 clean_opts(&opts); 142 143 /* Specify -B and -W options at the same time. Expected result: FAIL */ 144 rc = spdk_app_parse_args(test_argc, invalid_argv_BW, &opts, "", NULL, unittest_parse_args, NULL); 145 SPDK_CU_ASSERT_FATAL(rc == SPDK_APP_PARSE_ARGS_FAIL); 146 optind = 1; 147 clean_opts(&opts); 148 149 /* Omit necessary argument to option */ 150 rc = spdk_app_parse_args(test_argc, invalid_argv_missing_option, &opts, "", NULL, 151 unittest_parse_args, NULL); 152 CU_ASSERT_EQUAL(rc, SPDK_APP_PARSE_ARGS_FAIL); 153 optind = 1; 154 clean_opts(&opts); 155 } 156 157 int 158 main(int argc, char **argv) 159 { 160 CU_pSuite suite = NULL; 161 unsigned int num_failures; 162 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 num_failures = spdk_ut_run_tests(argc, argv, NULL); 170 CU_cleanup_registry(); 171 172 return num_failures; 173 } 174