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