Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2021 Intel Corporation.
3 : : * All rights reserved.
4 : : * Copyright (c) 2021, 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5 : : */
6 : :
7 : : #include "spdk/stdinc.h"
8 : : #include "spdk_internal/cunit.h"
9 : : #include "nvme/nvme_transport.c"
10 : : #include "common/lib/test_env.c"
11 : :
12 : 4 : SPDK_LOG_REGISTER_COMPONENT(nvme)
13 : :
14 : 0 : DEFINE_STUB(nvme_poll_group_connect_qpair, int, (struct spdk_nvme_qpair *qpair), 0);
15 : 0 : DEFINE_STUB_V(nvme_qpair_abort_all_queued_reqs, (struct spdk_nvme_qpair *qpair));
16 : 0 : DEFINE_STUB(nvme_poll_group_disconnect_qpair, int, (struct spdk_nvme_qpair *qpair), 0);
17 : 0 : DEFINE_STUB(spdk_nvme_ctrlr_free_io_qpair, int, (struct spdk_nvme_qpair *qpair), 0);
18 : 0 : DEFINE_STUB(spdk_nvme_transport_id_trtype_str, const char *,
19 : : (enum spdk_nvme_transport_type trtype), NULL);
20 : 0 : DEFINE_STUB(spdk_nvme_qpair_process_completions, int32_t, (struct spdk_nvme_qpair *qpair,
21 : : uint32_t max_completions), 0);
22 : 0 : DEFINE_STUB(spdk_nvme_poll_group_process_completions, int64_t, (struct spdk_nvme_poll_group *group,
23 : : uint32_t completions_per_qpair,
24 : : spdk_nvme_disconnected_qpair_cb disconnected_qpair_cb), 0);
25 : 0 : DEFINE_STUB(nvme_ctrlr_get_current_process, struct spdk_nvme_ctrlr_process *,
26 : : (struct spdk_nvme_ctrlr *ctrlr), NULL);
27 [ # # ]: 0 : DEFINE_STUB(spdk_nvme_ctrlr_is_fabrics, bool, (struct spdk_nvme_ctrlr *ctrlr), false);
28 : :
29 : : static void
30 : 8 : ut_construct_transport(struct spdk_nvme_transport *transport, const char name[])
31 : : {
32 [ - + - + : 8 : memcpy(transport->ops.name, name, strlen(name));
- + ]
33 : 8 : TAILQ_INSERT_TAIL(&g_spdk_nvme_transports, transport, link);
34 : 8 : }
35 : :
36 : : static void
37 : 4 : test_nvme_get_transport(void)
38 : : {
39 : 4 : const struct spdk_nvme_transport *nvme_transport = NULL;
40 : 4 : struct spdk_nvme_transport new_transport = {};
41 : :
42 : 4 : ut_construct_transport(&new_transport, "new_transport");
43 : :
44 : 4 : nvme_transport = nvme_get_transport("new_transport");
45 : 4 : CU_ASSERT(nvme_transport == &new_transport);
46 [ - + ]: 4 : TAILQ_REMOVE(&g_spdk_nvme_transports, nvme_transport, link);
47 : 4 : CU_ASSERT(TAILQ_EMPTY(&g_spdk_nvme_transports));
48 : :
49 : : /* Unavailable transport entry */
50 : 4 : nvme_transport = nvme_get_transport("new_transport");
51 [ - + ]: 4 : SPDK_CU_ASSERT_FATAL(nvme_transport == NULL);
52 : 4 : }
53 : :
54 : : static int
55 : 4 : ut_poll_group_connect_qpair(struct spdk_nvme_qpair *qpair)
56 : : {
57 : 4 : return 0;
58 : : }
59 : :
60 : : static void
61 : 4 : test_nvme_transport_poll_group_connect_qpair(void)
62 : : {
63 : : int rc;
64 : 4 : struct spdk_nvme_qpair qpair = {};
65 : 4 : struct spdk_nvme_transport_poll_group tgroup = {};
66 : 4 : struct spdk_nvme_transport transport = {};
67 : :
68 : 4 : qpair.poll_group = &tgroup;
69 : 4 : tgroup.transport = &transport;
70 : 4 : transport.ops.poll_group_connect_qpair = ut_poll_group_connect_qpair;
71 : 4 : STAILQ_INIT(&tgroup.connected_qpairs);
72 : 4 : STAILQ_INIT(&tgroup.disconnected_qpairs);
73 : :
74 : : /* Connected qpairs */
75 : 4 : qpair.poll_group_tailq_head = &tgroup.connected_qpairs;
76 : :
77 : 4 : rc = nvme_transport_poll_group_connect_qpair(&qpair);
78 : 4 : CU_ASSERT(rc == 0);
79 : :
80 : : /* Disconnected qpairs */
81 : :
82 : 4 : qpair.poll_group_tailq_head = &tgroup.disconnected_qpairs;
83 : 4 : STAILQ_INSERT_TAIL(&tgroup.disconnected_qpairs, &qpair, poll_group_stailq);
84 : :
85 : 4 : rc = nvme_transport_poll_group_connect_qpair(&qpair);
86 : 4 : CU_ASSERT(rc == 0);
87 : 4 : CU_ASSERT(STAILQ_EMPTY(&tgroup.disconnected_qpairs));
88 : 4 : CU_ASSERT(!STAILQ_EMPTY(&tgroup.connected_qpairs));
89 [ + - + - : 4 : STAILQ_REMOVE(&tgroup.connected_qpairs, &qpair, spdk_nvme_qpair, poll_group_stailq);
- - - - ]
90 : 4 : CU_ASSERT(STAILQ_EMPTY(&tgroup.connected_qpairs));
91 : :
92 : : /* None qpairs */
93 : 4 : qpair.poll_group_tailq_head = NULL;
94 : :
95 : 4 : rc = nvme_transport_poll_group_connect_qpair(&qpair);
96 [ - + ]: 4 : SPDK_CU_ASSERT_FATAL(rc == -EINVAL);
97 : 4 : }
98 : :
99 : : static int
100 : 4 : ut_poll_group_disconnect_qpair(struct spdk_nvme_qpair *qpair)
101 : : {
102 : 4 : return 0;
103 : : }
104 : :
105 : : static void
106 : 4 : test_nvme_transport_poll_group_disconnect_qpair(void)
107 : : {
108 : : int rc;
109 : 4 : struct spdk_nvme_qpair qpair = {};
110 : 4 : struct spdk_nvme_transport_poll_group tgroup = {};
111 : 4 : struct spdk_nvme_transport transport = {};
112 : :
113 : 4 : qpair.poll_group = &tgroup;
114 : 4 : tgroup.transport = &transport;
115 : 4 : transport.ops.poll_group_disconnect_qpair = ut_poll_group_disconnect_qpair;
116 : 4 : STAILQ_INIT(&tgroup.connected_qpairs);
117 : 4 : STAILQ_INIT(&tgroup.disconnected_qpairs);
118 : :
119 : : /* Disconnected qpairs */
120 : 4 : qpair.poll_group_tailq_head = &tgroup.disconnected_qpairs;
121 : :
122 : 4 : rc = nvme_transport_poll_group_disconnect_qpair(&qpair);
123 : 4 : CU_ASSERT(rc == 0);
124 : :
125 : : /* Connected qpairs */
126 : 4 : qpair.poll_group_tailq_head = &tgroup.connected_qpairs;
127 : 4 : STAILQ_INSERT_TAIL(&tgroup.connected_qpairs, &qpair, poll_group_stailq);
128 : 4 : tgroup.num_connected_qpairs++;
129 : :
130 : 4 : rc = nvme_transport_poll_group_disconnect_qpair(&qpair);
131 : 4 : CU_ASSERT(rc == 0);
132 : 4 : CU_ASSERT(STAILQ_EMPTY(&tgroup.connected_qpairs));
133 : 4 : CU_ASSERT(tgroup.num_connected_qpairs == 0);
134 : 4 : CU_ASSERT(!STAILQ_EMPTY(&tgroup.disconnected_qpairs));
135 [ + - + - : 4 : STAILQ_REMOVE(&tgroup.disconnected_qpairs, &qpair, spdk_nvme_qpair, poll_group_stailq);
- - - - ]
136 : 4 : CU_ASSERT(STAILQ_EMPTY(&tgroup.disconnected_qpairs));
137 : :
138 : : /* None qpairs */
139 : 4 : qpair.poll_group_tailq_head = NULL;
140 : :
141 : 4 : rc = nvme_transport_poll_group_disconnect_qpair(&qpair);
142 [ - + ]: 4 : SPDK_CU_ASSERT_FATAL(rc == -EINVAL);
143 : 4 : }
144 : :
145 : : static int
146 : 8 : ut_poll_group_add_remove(struct spdk_nvme_transport_poll_group *tgroup,
147 : : struct spdk_nvme_qpair *qpair)
148 : : {
149 : 8 : return 0;
150 : : }
151 : :
152 : : static void
153 : 4 : test_nvme_transport_poll_group_add_remove(void)
154 : : {
155 : : int rc;
156 : 4 : struct spdk_nvme_transport_poll_group tgroup = {};
157 : 4 : struct spdk_nvme_qpair qpair = {};
158 : 4 : const struct spdk_nvme_transport transport = {
159 : : .ops.poll_group_add = ut_poll_group_add_remove,
160 : : .ops.poll_group_remove = ut_poll_group_add_remove
161 : : };
162 : :
163 : 4 : tgroup.transport = &transport;
164 : 4 : qpair.poll_group = &tgroup;
165 : 4 : qpair.state = NVME_QPAIR_DISCONNECTED;
166 : 4 : STAILQ_INIT(&tgroup.connected_qpairs);
167 : 4 : STAILQ_INIT(&tgroup.disconnected_qpairs);
168 : :
169 : : /* Add qpair */
170 : 4 : rc = nvme_transport_poll_group_add(&tgroup, &qpair);
171 : 4 : CU_ASSERT(rc == 0);
172 : 4 : CU_ASSERT(qpair.poll_group_tailq_head == &tgroup.disconnected_qpairs);
173 : 4 : CU_ASSERT(STAILQ_FIRST(&tgroup.disconnected_qpairs) == &qpair);
174 : :
175 : : /* Remove disconnected_qpairs */
176 [ - + ]: 4 : SPDK_CU_ASSERT_FATAL(!STAILQ_EMPTY(&tgroup.disconnected_qpairs));
177 : :
178 : 4 : rc = nvme_transport_poll_group_remove(&tgroup, &qpair);
179 : 4 : CU_ASSERT(rc == 0);
180 : 4 : CU_ASSERT(STAILQ_EMPTY(&tgroup.disconnected_qpairs));
181 : 4 : CU_ASSERT(qpair.poll_group == NULL);
182 : 4 : CU_ASSERT(qpair.poll_group_tailq_head == NULL);
183 : :
184 : : /* Remove connected_qpairs */
185 : 4 : qpair.poll_group_tailq_head = &tgroup.connected_qpairs;
186 : 4 : STAILQ_INSERT_TAIL(&tgroup.connected_qpairs, &qpair, poll_group_stailq);
187 : :
188 : 4 : rc = nvme_transport_poll_group_remove(&tgroup, &qpair);
189 : 4 : CU_ASSERT(rc == -EINVAL);
190 : :
191 [ + - + - : 4 : STAILQ_REMOVE(&tgroup.connected_qpairs, &qpair, spdk_nvme_qpair, poll_group_stailq);
- - - - ]
192 : :
193 : : /* Invalid qpair */
194 : 4 : qpair.poll_group_tailq_head = NULL;
195 : :
196 : 4 : rc = nvme_transport_poll_group_remove(&tgroup, &qpair);
197 : 4 : CU_ASSERT(rc == -ENOENT);
198 : 4 : }
199 : :
200 : : static int
201 : 4 : g_ut_ctrlr_get_memory_domains(const struct spdk_nvme_ctrlr *ctrlr,
202 : : struct spdk_memory_domain **domains, int array_size)
203 : : {
204 : 4 : return 1;
205 : : }
206 : :
207 : : static void
208 : 4 : test_ctrlr_get_memory_domains(void)
209 : : {
210 : 4 : struct spdk_nvme_ctrlr ctrlr = {
211 : : .trid = {
212 : : .trstring = "new_transport"
213 : : }
214 : : };
215 : 4 : struct spdk_nvme_transport new_transport = {
216 : : .ops = { .ctrlr_get_memory_domains = g_ut_ctrlr_get_memory_domains }
217 : : };
218 : :
219 : 4 : ut_construct_transport(&new_transport, "new_transport");
220 : :
221 : : /* transport contains necessary op */
222 : 4 : CU_ASSERT(nvme_transport_ctrlr_get_memory_domains(&ctrlr, NULL, 0) == 1);
223 : :
224 : : /* transport doesn't contain necessary op */
225 : 4 : new_transport.ops.ctrlr_get_memory_domains = NULL;
226 : 4 : CU_ASSERT(nvme_transport_ctrlr_get_memory_domains(&ctrlr, NULL, 0) == 0);
227 : :
228 [ - + ]: 4 : TAILQ_REMOVE(&g_spdk_nvme_transports, &new_transport, link);
229 : 4 : }
230 : :
231 : : int
232 : 4 : main(int argc, char **argv)
233 : : {
234 : 4 : CU_pSuite suite = NULL;
235 : : unsigned int num_failures;
236 : :
237 : 4 : CU_initialize_registry();
238 : :
239 : 4 : suite = CU_add_suite("nvme_transport", NULL, NULL);
240 : 4 : CU_ADD_TEST(suite, test_nvme_get_transport);
241 : 4 : CU_ADD_TEST(suite, test_nvme_transport_poll_group_connect_qpair);
242 : 4 : CU_ADD_TEST(suite, test_nvme_transport_poll_group_disconnect_qpair);
243 : 4 : CU_ADD_TEST(suite, test_nvme_transport_poll_group_add_remove);
244 : 4 : CU_ADD_TEST(suite, test_ctrlr_get_memory_domains);
245 : :
246 : 4 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
247 : 4 : CU_cleanup_registry();
248 : 4 : return num_failures;
249 : : }
|