Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2021 Intel Corporation. All rights reserved.
3 : : */
4 : :
5 : : #include "spdk/stdinc.h"
6 : : #include "spdk_internal/cunit.h"
7 : : #include "common/lib/test_env.c"
8 : : #include "common/lib/test_iobuf.c"
9 : : #include "nvmf/transport.c"
10 : : #include "nvmf/rdma.c"
11 : : #include "common/lib/test_rdma.c"
12 : :
13 : 3 : SPDK_LOG_REGISTER_COMPONENT(nvmf)
14 : :
15 : : #define RDMA_UT_UNITS_IN_MAX_IO 16
16 : : #define SPDK_NVMF_DEFAULT_BUFFER_CACHE_SIZE 32
17 : :
18 : : struct spdk_nvmf_transport_opts g_rdma_ut_transport_opts = {
19 : : .max_queue_depth = SPDK_NVMF_RDMA_DEFAULT_MAX_QUEUE_DEPTH,
20 : : .max_qpairs_per_ctrlr = SPDK_NVMF_RDMA_DEFAULT_MAX_QPAIRS_PER_CTRLR,
21 : : .in_capsule_data_size = SPDK_NVMF_RDMA_DEFAULT_IN_CAPSULE_DATA_SIZE,
22 : : .max_io_size = (SPDK_NVMF_RDMA_MIN_IO_BUFFER_SIZE * RDMA_UT_UNITS_IN_MAX_IO),
23 : : .io_unit_size = SPDK_NVMF_RDMA_MIN_IO_BUFFER_SIZE,
24 : : .max_aq_depth = SPDK_NVMF_RDMA_DEFAULT_AQ_DEPTH,
25 : : .num_shared_buffers = SPDK_NVMF_RDMA_DEFAULT_NUM_SHARED_BUFFERS,
26 : : .opts_size = sizeof(g_rdma_ut_transport_opts)
27 : : };
28 : :
29 : 18 : DEFINE_STUB(spdk_nvme_transport_id_compare, int, (const struct spdk_nvme_transport_id *trid1,
30 : : const struct spdk_nvme_transport_id *trid2), 0);
31 : 0 : DEFINE_STUB_V(spdk_nvmf_tgt_new_qpair, (struct spdk_nvmf_tgt *tgt, struct spdk_nvmf_qpair *qpair));
32 [ # # ]: 0 : DEFINE_STUB(spdk_nvmf_request_get_dif_ctx, bool, (struct spdk_nvmf_request *req,
33 : : struct spdk_dif_ctx *dif_ctx), false);
34 : 0 : DEFINE_STUB(spdk_nvmf_qpair_disconnect, int, (struct spdk_nvmf_qpair *qpair,
35 : : nvmf_qpair_disconnect_cb cb_fn, void *ctx), 0);
36 : 0 : DEFINE_STUB_V(spdk_nvmf_request_exec, (struct spdk_nvmf_request *req));
37 : 0 : DEFINE_STUB_V(spdk_nvme_trid_populate_transport, (struct spdk_nvme_transport_id *trid,
38 : : enum spdk_nvme_transport_type trtype));
39 : 0 : DEFINE_STUB(nvmf_ctrlr_abort_request, int, (struct spdk_nvmf_request *req), 0);
40 : 0 : DEFINE_STUB(spdk_nvmf_request_complete, int, (struct spdk_nvmf_request *req), 0);
41 : 9 : DEFINE_STUB(ut_transport_destroy, int, (struct spdk_nvmf_transport *transport,
42 : : spdk_nvmf_transport_destroy_done_cb cb_fn, void *cb_arg), 0);
43 : 0 : DEFINE_STUB(ibv_get_device_name, const char *, (struct ibv_device *device), NULL);
44 : 0 : DEFINE_STUB(ibv_query_qp, int, (struct ibv_qp *qp, struct ibv_qp_attr *attr,
45 : : int attr_mask,
46 : : struct ibv_qp_init_attr *init_attr), 0);
47 : 0 : DEFINE_STUB(rdma_create_id, int, (struct rdma_event_channel *channel,
48 : : struct rdma_cm_id **id, void *context,
49 : : enum rdma_port_space ps), 0);
50 : 0 : DEFINE_STUB(rdma_bind_addr, int, (struct rdma_cm_id *id, struct sockaddr *addr), 0);
51 : 0 : DEFINE_STUB(rdma_listen, int, (struct rdma_cm_id *id, int backlog), 0);
52 : 0 : DEFINE_STUB(rdma_destroy_id, int, (struct rdma_cm_id *id), 0);
53 : 0 : DEFINE_STUB(ibv_dereg_mr, int, (struct ibv_mr *mr), 0);
54 : 0 : DEFINE_STUB(rdma_reject, int, (struct rdma_cm_id *id,
55 : : const void *private_data, uint8_t private_data_len), 0);
56 : 0 : DEFINE_STUB(ibv_resize_cq, int, (struct ibv_cq *cq, int cqe), 0);
57 : 0 : DEFINE_STUB_V(rdma_destroy_qp, (struct rdma_cm_id *id));
58 : 0 : DEFINE_STUB_V(rdma_destroy_event_channel, (struct rdma_event_channel *channel));
59 : 0 : DEFINE_STUB(ibv_dealloc_pd, int, (struct ibv_pd *pd), 0);
60 : 0 : DEFINE_STUB(rdma_create_event_channel, struct rdma_event_channel *, (void), NULL);
61 : 0 : DEFINE_STUB(rdma_get_devices, struct ibv_context **, (int *num_devices), NULL);
62 : 0 : DEFINE_STUB(ibv_query_device, int, (struct ibv_context *context,
63 : : struct ibv_device_attr *device_attr), 0);
64 : 0 : DEFINE_STUB(ibv_alloc_pd, struct ibv_pd *, (struct ibv_context *context), NULL);
65 : 0 : DEFINE_STUB_V(rdma_free_devices, (struct ibv_context **list));
66 : 0 : DEFINE_STUB(ibv_get_async_event, int, (struct ibv_context *context, struct ibv_async_event *event),
67 : : 0);
68 : 0 : DEFINE_STUB(ibv_event_type_str, const char *, (enum ibv_event_type event_type), NULL);
69 : 0 : DEFINE_STUB_V(ibv_ack_async_event, (struct ibv_async_event *event));
70 : 0 : DEFINE_STUB(rdma_get_cm_event, int, (struct rdma_event_channel *channel,
71 : : struct rdma_cm_event **event), 0);
72 : 0 : DEFINE_STUB(rdma_ack_cm_event, int, (struct rdma_cm_event *event), 0);
73 : 0 : DEFINE_STUB(ibv_destroy_cq, int, (struct ibv_cq *cq), 0);
74 : 0 : DEFINE_STUB(ibv_create_cq, struct ibv_cq *, (struct ibv_context *context, int cqe,
75 : : void *cq_context,
76 : : struct ibv_comp_channel *channel,
77 : : int comp_vector), NULL);
78 : 0 : DEFINE_STUB(ibv_wc_status_str, const char *, (enum ibv_wc_status status), NULL);
79 : 0 : DEFINE_STUB(rdma_get_dst_port, __be16, (struct rdma_cm_id *id), 0);
80 : 0 : DEFINE_STUB(rdma_get_src_port, __be16, (struct rdma_cm_id *id), 0);
81 : 0 : DEFINE_STUB(spdk_nvmf_qpair_get_listen_trid, int, (struct spdk_nvmf_qpair *qpair,
82 : : struct spdk_nvme_transport_id *trid), 0);
83 : 0 : DEFINE_STUB(spdk_nvme_transport_id_adrfam_str, const char *, (enum spdk_nvmf_adrfam adrfam), NULL);
84 : 3 : DEFINE_STUB_V(ut_opts_init, (struct spdk_nvmf_transport_opts *opts));
85 : 6 : DEFINE_STUB(ut_transport_listen, int, (struct spdk_nvmf_transport *transport,
86 : : const struct spdk_nvme_transport_id *trid, struct spdk_nvmf_listen_opts *opts), 0);
87 : 3 : DEFINE_STUB_V(ut_transport_stop_listen, (struct spdk_nvmf_transport *transport,
88 : : const struct spdk_nvme_transport_id *trid));
89 : 0 : DEFINE_STUB(spdk_mempool_lookup, struct spdk_mempool *, (const char *name), NULL);
90 : :
91 : : /* ibv_reg_mr can be a macro, need to undefine it */
92 : : #ifdef ibv_reg_mr
93 : : #undef ibv_reg_mr
94 : : #endif
95 : :
96 : : DEFINE_RETURN_MOCK(ibv_reg_mr, struct ibv_mr *);
97 : : struct ibv_mr *
98 : : ibv_reg_mr(struct ibv_pd *pd, void *addr, size_t length, int access)
99 : : {
100 [ # # # # ]: 0 : HANDLE_RETURN_MOCK(ibv_reg_mr);
101 [ # # ]: 0 : if (length > 0) {
102 : 0 : return &g_rdma_mr;
103 : : } else {
104 : 0 : return NULL;
105 : : }
106 : : }
107 : :
108 : : struct spdk_nvmf_transport ut_transport = {};
109 : :
110 : : static int
111 : 9 : ut_transport_create(struct spdk_nvmf_transport_opts *opts, spdk_nvmf_transport_create_done_cb cb_fn,
112 : : void *cb_arg)
113 : : {
114 : 9 : cb_fn(cb_arg, &ut_transport);
115 : 9 : return 0;
116 : : }
117 : :
118 : : static void
119 : 9 : test_nvmf_create_transport_done(void *cb_arg, struct spdk_nvmf_transport *transport)
120 : : {
121 : 9 : struct spdk_nvmf_transport **ctx = cb_arg;
122 : :
123 : 9 : *ctx = transport;
124 : 9 : }
125 : :
126 : : static void
127 : 3 : test_spdk_nvmf_transport_create(void)
128 : : {
129 : : int rc;
130 : 3 : struct spdk_nvmf_transport *transport = NULL;
131 : : struct nvmf_transport_ops_list_element *ops_element;
132 : 3 : struct spdk_iobuf_opts opts_iobuf = {};
133 : 3 : struct spdk_nvmf_transport_ops ops = {
134 : : .name = "new_ops",
135 : : .type = (enum spdk_nvme_transport_type)SPDK_NVMF_TRTYPE_RDMA,
136 : : .create_async = ut_transport_create,
137 : : .destroy = ut_transport_destroy
138 : : };
139 : :
140 : 3 : opts_iobuf.large_bufsize = 0x10000;
141 : 3 : opts_iobuf.large_pool_count = 4096;
142 : 3 : opts_iobuf.small_bufsize = 0x1000;
143 : 3 : opts_iobuf.small_pool_count = 4096;
144 : :
145 : 3 : rc = spdk_iobuf_set_opts(&opts_iobuf);
146 : 3 : CU_ASSERT(rc == 0);
147 : :
148 : : /* No available ops element */
149 : 3 : rc = spdk_nvmf_transport_create_async("new_ops", &g_rdma_ut_transport_opts,
150 : : test_nvmf_create_transport_done, &transport);
151 : 3 : CU_ASSERT(rc != 0);
152 : 3 : CU_ASSERT(transport == NULL);
153 : :
154 : 3 : spdk_nvmf_transport_register(&ops);
155 : :
156 : : /* Ensure io_unit_size cannot be set to 0 */
157 : 3 : g_rdma_ut_transport_opts.io_unit_size = 0;
158 : 3 : rc = spdk_nvmf_transport_create_async("new_ops", &g_rdma_ut_transport_opts,
159 : : test_nvmf_create_transport_done, &transport);
160 : 3 : CU_ASSERT(rc != 0);
161 : 3 : CU_ASSERT(transport == NULL);
162 : :
163 : : /* Ensure io_unit_size cannot be larger than large_bufsize */
164 : 3 : g_rdma_ut_transport_opts.io_unit_size = opts_iobuf.large_bufsize * 2;
165 : 3 : rc = spdk_nvmf_transport_create_async("new_ops", &g_rdma_ut_transport_opts,
166 : : test_nvmf_create_transport_done, &transport);
167 : 3 : CU_ASSERT(rc != 0);
168 : 3 : CU_ASSERT(transport == NULL);
169 : :
170 : 3 : g_rdma_ut_transport_opts.io_unit_size = SPDK_NVMF_RDMA_MIN_IO_BUFFER_SIZE;
171 : :
172 : : /* Create transport successfully */
173 : 3 : rc = spdk_nvmf_transport_create_async("new_ops", &g_rdma_ut_transport_opts,
174 : : test_nvmf_create_transport_done, &transport);
175 : 3 : CU_ASSERT(rc == 0);
176 : 3 : CU_ASSERT(transport == &ut_transport);
177 [ - + ]: 3 : CU_ASSERT(!memcmp(&transport->opts, &g_rdma_ut_transport_opts, sizeof(g_rdma_ut_transport_opts)));
178 [ - + ]: 3 : CU_ASSERT(!memcmp(transport->ops, &ops, sizeof(ops)));
179 : :
180 : 3 : rc = spdk_nvmf_transport_destroy(transport, NULL, NULL);
181 : 3 : CU_ASSERT(rc == 0);
182 : :
183 : : /* transport_opts parameter invalid */
184 : 3 : transport = NULL;
185 : 3 : g_rdma_ut_transport_opts.max_io_size = 4096;
186 : :
187 : 3 : rc = spdk_nvmf_transport_create_async("new_ops", &g_rdma_ut_transport_opts,
188 : : test_nvmf_create_transport_done, &transport);
189 : 3 : CU_ASSERT(rc != 0);
190 : 3 : CU_ASSERT(transport == NULL);
191 : 3 : g_rdma_ut_transport_opts.max_io_size = (SPDK_NVMF_RDMA_MIN_IO_BUFFER_SIZE *
192 : : RDMA_UT_UNITS_IN_MAX_IO);
193 : :
194 : 3 : ops_element = TAILQ_LAST(&g_spdk_nvmf_transport_ops, nvmf_transport_ops_list);
195 [ - + ]: 3 : TAILQ_REMOVE(&g_spdk_nvmf_transport_ops, ops_element, link);
196 : 3 : free(ops_element);
197 : 3 : }
198 : :
199 : : static struct spdk_nvmf_transport_poll_group *
200 : 6 : ut_poll_group_create(struct spdk_nvmf_transport *transport,
201 : : struct spdk_nvmf_poll_group *group)
202 : : {
203 : : struct spdk_nvmf_transport_poll_group *tgroup;
204 : :
205 : 6 : tgroup = calloc(1, sizeof(*tgroup));
206 [ - + ]: 6 : SPDK_CU_ASSERT_FATAL(tgroup != NULL);
207 : 6 : return tgroup;
208 : : }
209 : :
210 : : static void
211 : 6 : ut_poll_group_destroy(struct spdk_nvmf_transport_poll_group *group)
212 : : {
213 : 6 : free(group);
214 : 6 : }
215 : :
216 : : static void
217 : 3 : test_nvmf_transport_poll_group_create(void)
218 : : {
219 : 3 : struct spdk_nvmf_transport_poll_group *poll_group = NULL;
220 : 3 : struct spdk_nvmf_transport transport = {};
221 : 3 : struct spdk_nvmf_transport_ops ops = {};
222 : :
223 : 3 : ops.poll_group_create = ut_poll_group_create;
224 : 3 : ops.poll_group_destroy = ut_poll_group_destroy;
225 : 3 : transport.ops = &ops;
226 : 3 : transport.opts.buf_cache_size = SPDK_NVMF_DEFAULT_BUFFER_CACHE_SIZE;
227 : :
228 : 3 : poll_group = nvmf_transport_poll_group_create(&transport, NULL);
229 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(poll_group != NULL);
230 : 3 : CU_ASSERT(poll_group->transport == &transport);
231 : :
232 : 3 : nvmf_transport_poll_group_destroy(poll_group);
233 : :
234 : 3 : poll_group = nvmf_transport_poll_group_create(&transport, NULL);
235 [ - + ]: 3 : SPDK_CU_ASSERT_FATAL(poll_group != NULL);
236 : 3 : CU_ASSERT(poll_group->transport == &transport);
237 : :
238 : 3 : nvmf_transport_poll_group_destroy(poll_group);
239 : 3 : }
240 : :
241 : : static void
242 : 3 : test_spdk_nvmf_transport_opts_init(void)
243 : : {
244 : : int rc;
245 : : bool rcbool;
246 : : size_t opts_size;
247 : 3 : struct spdk_nvmf_transport *transport = NULL;
248 : 3 : struct spdk_nvmf_transport_opts opts = {};
249 : : const struct spdk_nvmf_transport_ops *tops;
250 : 3 : struct spdk_nvmf_transport_ops ops = {
251 : : .name = "ut_ops",
252 : : .type = (enum spdk_nvme_transport_type)SPDK_NVMF_TRTYPE_RDMA,
253 : : .create_async = ut_transport_create,
254 : : .destroy = ut_transport_destroy,
255 : : .opts_init = ut_opts_init
256 : : };
257 : :
258 : 3 : spdk_nvmf_transport_register(&ops);
259 : 3 : rc = spdk_nvmf_transport_create_async("ut_ops", &g_rdma_ut_transport_opts,
260 : : test_nvmf_create_transport_done, &transport);
261 : 3 : CU_ASSERT(rc == 0);
262 : 3 : CU_ASSERT(transport == &ut_transport);
263 : :
264 : 3 : tops = nvmf_get_transport_ops(ops.name);
265 [ - + ]: 3 : CU_ASSERT(memcmp(tops, &ops, sizeof(struct spdk_nvmf_transport_ops)) == 0);
266 : :
267 : : /* Test1: Invalid parameter: unavailable transport type */
268 : 3 : opts_size = sizeof(struct spdk_nvmf_transport_opts);
269 : :
270 : 3 : rcbool = spdk_nvmf_transport_opts_init("invalid_ops", &opts, opts_size);
271 : 3 : CU_ASSERT(rcbool == false);
272 : :
273 : : /* Test2: Invalid parameter: NULL pointer */
274 : 3 : rcbool = true;
275 : :
276 : 3 : rcbool = spdk_nvmf_transport_opts_init(ops.name, NULL, opts_size);
277 : 3 : CU_ASSERT(rcbool == false);
278 : :
279 : : /* Test3: Invalid parameter: opts_size inside opts be zero value */
280 : 3 : rcbool = true;
281 : 3 : opts_size = 0;
282 : :
283 : 3 : rcbool = spdk_nvmf_transport_opts_init(ops.name, &opts, opts_size);
284 : 3 : CU_ASSERT(rcbool == false);
285 : :
286 : : /* Test4: success */
287 : 3 : opts.opts_size = 0;
288 : 3 : opts_size = sizeof(struct spdk_nvmf_transport_opts);
289 : :
290 : 3 : rcbool = spdk_nvmf_transport_opts_init(ops.name, &opts, opts_size);
291 : 3 : CU_ASSERT(rcbool == true);
292 : 3 : CU_ASSERT(opts.opts_size == opts_size);
293 : :
294 : 3 : rc = spdk_nvmf_transport_destroy(transport, NULL, NULL);
295 : 3 : CU_ASSERT(rc == 0);
296 : 3 : }
297 : :
298 : : static void
299 : 3 : test_spdk_nvmf_transport_listen_ext(void)
300 : : {
301 : : int rc;
302 : 3 : struct spdk_nvmf_transport *transport = NULL;
303 : 3 : struct spdk_nvme_transport_id trid1 = {};
304 : 3 : struct spdk_nvme_transport_id trid2 = {};
305 : 3 : struct spdk_nvmf_listen_opts lopts = {};
306 : : struct spdk_nvmf_listener *tlistener;
307 : 3 : struct spdk_nvmf_transport_ops ops = {
308 : : .name = "ut_ops1",
309 : : .type = (enum spdk_nvme_transport_type)SPDK_NVMF_TRTYPE_RDMA,
310 : : .create_async = ut_transport_create,
311 : : .destroy = ut_transport_destroy,
312 : : .opts_init = ut_opts_init,
313 : : .listen = ut_transport_listen,
314 : : .stop_listen = ut_transport_stop_listen
315 : : };
316 : :
317 : 3 : trid1.trtype = (enum spdk_nvme_transport_type)SPDK_NVMF_TRTYPE_RDMA;
318 : 3 : trid1.adrfam = (enum spdk_nvmf_adrfam)SPDK_NVMF_ADRFAM_IPV4;
319 : 3 : trid1.priority = 4;
320 : 3 : memcpy(trid1.traddr, "192.168.100.72", sizeof("192.168.100.72"));
321 : 3 : memcpy(trid1.trsvcid, "4420", sizeof("4420"));
322 : :
323 : 3 : spdk_nvmf_transport_register(&ops);
324 : 3 : rc = spdk_nvmf_transport_create_async("ut_ops1", &g_rdma_ut_transport_opts,
325 : : test_nvmf_create_transport_done, &transport);
326 : 3 : CU_ASSERT(rc == 0);
327 : 3 : CU_ASSERT(transport == &ut_transport);
328 : :
329 : : /* Test1: Execute listen failed */
330 : 3 : MOCK_SET(ut_transport_listen, -1);
331 : :
332 : 3 : rc = spdk_nvmf_transport_listen(transport, &trid1, &lopts);
333 : 3 : tlistener = nvmf_transport_find_listener(transport, &trid1);
334 : 3 : CU_ASSERT(rc == -1);
335 : 3 : CU_ASSERT(tlistener == NULL);
336 : :
337 : : /* Test2: Execute listen success */
338 : 3 : MOCK_SET(ut_transport_listen, 0);
339 : :
340 : 3 : rc = spdk_nvmf_transport_listen(transport, &trid1, &lopts);
341 : 3 : tlistener = nvmf_transport_find_listener(transport, &trid1);
342 : 3 : CU_ASSERT(rc == 0);
343 : 3 : CU_ASSERT(tlistener != NULL);
344 : 3 : CU_ASSERT(tlistener->ref == 1);
345 [ - + ]: 3 : CU_ASSERT(memcmp(&tlistener->trid, &trid1, sizeof(trid1)) == 0);
346 : :
347 : : /* Test3: Listen for an identifier repeatedly */
348 : 3 : tlistener = NULL;
349 : :
350 : 3 : rc = spdk_nvmf_transport_listen(transport, &trid1, &lopts);
351 : 3 : tlistener = nvmf_transport_find_listener(transport, &trid1);
352 : 3 : CU_ASSERT(rc == 0);
353 : 3 : CU_ASSERT(tlistener != NULL);
354 : 3 : CU_ASSERT(tlistener->ref == 2);
355 [ - + ]: 3 : CU_ASSERT(memcmp(&tlistener->trid, &trid1, sizeof(trid1)) == 0);
356 : :
357 : : /* Test4: Stop listen when ref >1, Listen will not be released */
358 : 3 : tlistener = NULL;
359 : :
360 : 3 : rc = spdk_nvmf_transport_stop_listen(transport, &trid1);
361 : 3 : tlistener = nvmf_transport_find_listener(transport, &trid1);
362 : 3 : CU_ASSERT(rc == 0);
363 : 3 : CU_ASSERT(tlistener != NULL);
364 : 3 : CU_ASSERT(tlistener->ref == 1);
365 [ - + ]: 3 : CU_ASSERT(memcmp(&tlistener->trid, &trid1, sizeof(trid1)) == 0);
366 : :
367 : : /* Test5: Stop listen when ref == 1, Listen will be released */
368 : :
369 : 3 : rc = spdk_nvmf_transport_stop_listen(transport, &trid1);
370 : 3 : tlistener = nvmf_transport_find_listener(transport, &trid1);
371 : 3 : CU_ASSERT(rc == 0);
372 : 3 : CU_ASSERT(tlistener == NULL);
373 : :
374 : : /* Test6: Release unrecognized listener */
375 : 3 : rc = spdk_nvmf_transport_stop_listen(transport, &trid2);
376 : :
377 : 3 : CU_ASSERT(rc == -ENOENT);
378 : :
379 : 3 : rc = spdk_nvmf_transport_destroy(transport, NULL, NULL);
380 : 3 : CU_ASSERT(rc == 0);
381 : 3 : }
382 : :
383 : : int
384 : 3 : main(int argc, char **argv)
385 : : {
386 : 3 : CU_pSuite suite = NULL;
387 : : unsigned int num_failures;
388 : :
389 : 3 : CU_initialize_registry();
390 : :
391 : 3 : suite = CU_add_suite("nvmf", NULL, NULL);
392 : :
393 : 3 : CU_ADD_TEST(suite, test_spdk_nvmf_transport_create);
394 : 3 : CU_ADD_TEST(suite, test_nvmf_transport_poll_group_create);
395 : 3 : CU_ADD_TEST(suite, test_spdk_nvmf_transport_opts_init);
396 : 3 : CU_ADD_TEST(suite, test_spdk_nvmf_transport_listen_ext);
397 : :
398 : 3 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
399 : 3 : CU_cleanup_registry();
400 : 3 : return num_failures;
401 : : }
|