Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2018 Intel Corporation.
3 : : * All rights reserved.
4 : : * Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5 : : */
6 : :
7 : : #include "spdk_internal/cunit.h"
8 : : /* We have our own mock for this */
9 : : #define UNIT_TEST_NO_VTOPHYS
10 : : #include "common/lib/test_env.c"
11 : : #include "spdk_internal/mock.h"
12 : : #include "thread/thread_internal.h"
13 : : #include "unit/lib/json_mock.c"
14 : :
15 : : #include <rte_compressdev.h>
16 : :
17 : : /* There will be one if the data perfectly matches the chunk size,
18 : : * or there could be an offset into the data and a remainder after
19 : : * the data or both for a max of 3.
20 : : */
21 : : #define UT_MBUFS_PER_OP 3
22 : : /* For testing the crossing of a huge page boundary on address translation,
23 : : * we'll have an extra one but we only test on the source side.
24 : : */
25 : : #define UT_MBUFS_PER_OP_BOUND_TEST 4
26 : :
27 : : struct spdk_io_channel *g_io_ch;
28 : : struct rte_comp_op g_comp_op[2];
29 : : struct comp_device_qp g_device_qp;
30 : : struct compress_dev g_device;
31 : : struct rte_compressdev_capabilities g_cdev_cap;
32 : : static struct rte_mbuf *g_src_mbufs[UT_MBUFS_PER_OP_BOUND_TEST];
33 : : static struct rte_mbuf *g_dst_mbufs[UT_MBUFS_PER_OP];
34 : : static struct rte_mbuf g_expected_src_mbufs[UT_MBUFS_PER_OP_BOUND_TEST];
35 : : static struct rte_mbuf g_expected_dst_mbufs[UT_MBUFS_PER_OP];
36 : : struct compress_io_channel *g_comp_ch;
37 : :
38 : : /* Those functions are defined as static inline in DPDK, so we can't
39 : : * mock them straight away. We use defines to redirect them into
40 : : * our custom functions.
41 : : */
42 : :
43 : : static int ut_total_rte_pktmbuf_attach_extbuf = 0;
44 : : static void mock_rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr, rte_iova_t buf_iova,
45 : : uint16_t buf_len, struct rte_mbuf_ext_shared_info *shinfo);
46 : : #define rte_pktmbuf_attach_extbuf mock_rte_pktmbuf_attach_extbuf
47 : : static void
48 : 213 : mock_rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr, rte_iova_t buf_iova,
49 : : uint16_t buf_len, struct rte_mbuf_ext_shared_info *shinfo)
50 : : {
51 [ + + # # ]: 213 : assert(m != NULL);
52 [ + - + - ]: 213 : m->buf_addr = buf_addr;
53 [ + - + - ]: 213 : m->buf_iova = buf_iova;
54 [ + - + - ]: 213 : m->buf_len = buf_len;
55 [ + - + - : 213 : m->data_len = m->pkt_len = 0;
+ - + - ]
56 [ + - ]: 213 : ut_total_rte_pktmbuf_attach_extbuf++;
57 : 213 : }
58 : :
59 : : static char *mock_rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len);
60 : : #define rte_pktmbuf_append mock_rte_pktmbuf_append
61 : : static char *
62 : 213 : mock_rte_pktmbuf_append(struct rte_mbuf *m, uint16_t len)
63 : : {
64 [ + - + - : 213 : m->pkt_len = m->pkt_len + len;
+ - + - ]
65 : 213 : return NULL;
66 : : }
67 : :
68 : : static inline int mock_rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail);
69 : : #define rte_pktmbuf_chain mock_rte_pktmbuf_chain
70 : : static inline int
71 : 144 : mock_rte_pktmbuf_chain(struct rte_mbuf *head, struct rte_mbuf *tail)
72 : : {
73 : 48 : struct rte_mbuf *cur_tail;
74 : :
75 : 144 : cur_tail = rte_pktmbuf_lastseg(head);
76 [ + - + - ]: 144 : cur_tail->next = tail;
77 : :
78 : 144 : return 0;
79 : 48 : }
80 : :
81 : : uint16_t ut_max_nb_queue_pairs = 0;
82 : : void __rte_experimental mock_rte_compressdev_info_get(uint8_t dev_id,
83 : : struct rte_compressdev_info *dev_info);
84 : : #define rte_compressdev_info_get mock_rte_compressdev_info_get
85 : : void __rte_experimental
86 : 18 : mock_rte_compressdev_info_get(uint8_t dev_id, struct rte_compressdev_info *dev_info)
87 : : {
88 [ + - + - ]: 18 : dev_info->max_nb_queue_pairs = ut_max_nb_queue_pairs;
89 [ + - + - ]: 18 : dev_info->capabilities = &g_cdev_cap;
90 [ + - + - ]: 18 : dev_info->driver_name = "compressdev";
91 : 18 : }
92 : :
93 : : int ut_rte_compressdev_configure = 0;
94 : : int __rte_experimental mock_rte_compressdev_configure(uint8_t dev_id,
95 : : struct rte_compressdev_config *config);
96 : : #define rte_compressdev_configure mock_rte_compressdev_configure
97 : : int __rte_experimental
98 : 18 : mock_rte_compressdev_configure(uint8_t dev_id, struct rte_compressdev_config *config)
99 : : {
100 : 18 : return ut_rte_compressdev_configure;
101 : : }
102 : :
103 : : int ut_rte_compressdev_queue_pair_setup = 0;
104 : : int __rte_experimental mock_rte_compressdev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
105 : : uint32_t max_inflight_ops, int socket_id);
106 : : #define rte_compressdev_queue_pair_setup mock_rte_compressdev_queue_pair_setup
107 : : int __rte_experimental
108 : 435 : mock_rte_compressdev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id,
109 : : uint32_t max_inflight_ops, int socket_id)
110 : : {
111 : 435 : return ut_rte_compressdev_queue_pair_setup;
112 : : }
113 : :
114 : : int ut_rte_compressdev_start = 0;
115 : : int __rte_experimental mock_rte_compressdev_start(uint8_t dev_id);
116 : : #define rte_compressdev_start mock_rte_compressdev_start
117 : : int __rte_experimental
118 : 9 : mock_rte_compressdev_start(uint8_t dev_id)
119 : : {
120 : 9 : return ut_rte_compressdev_start;
121 : : }
122 : :
123 : : int ut_rte_compressdev_private_xform_create = 0;
124 : : int __rte_experimental mock_rte_compressdev_private_xform_create(uint8_t dev_id,
125 : : const struct rte_comp_xform *xform, void **private_xform);
126 : : #define rte_compressdev_private_xform_create mock_rte_compressdev_private_xform_create
127 : : int __rte_experimental
128 : 9 : mock_rte_compressdev_private_xform_create(uint8_t dev_id,
129 : : const struct rte_comp_xform *xform, void **private_xform)
130 : : {
131 : 9 : return ut_rte_compressdev_private_xform_create;
132 : : }
133 : :
134 : : uint8_t ut_rte_compressdev_count = 0;
135 : : uint8_t __rte_experimental mock_rte_compressdev_count(void);
136 : : #define rte_compressdev_count mock_rte_compressdev_count
137 : : uint8_t __rte_experimental
138 : 27 : mock_rte_compressdev_count(void)
139 : : {
140 : 27 : return ut_rte_compressdev_count;
141 : : }
142 : :
143 : : struct rte_mempool *ut_rte_comp_op_pool_create = NULL;
144 : : struct rte_mempool *__rte_experimental mock_rte_comp_op_pool_create(const char *name,
145 : : unsigned int nb_elts, unsigned int cache_size, uint16_t user_size,
146 : : int socket_id);
147 : : #define rte_comp_op_pool_create mock_rte_comp_op_pool_create
148 : : struct rte_mempool *__rte_experimental
149 : 18 : mock_rte_comp_op_pool_create(const char *name, unsigned int nb_elts,
150 : : unsigned int cache_size, uint16_t user_size, int socket_id)
151 : : {
152 : 18 : return ut_rte_comp_op_pool_create;
153 : : }
154 : :
155 : : void mock_rte_pktmbuf_free(struct rte_mbuf *m);
156 : : #define rte_pktmbuf_free mock_rte_pktmbuf_free
157 : : void
158 : 24 : mock_rte_pktmbuf_free(struct rte_mbuf *m)
159 : : {
160 : 24 : }
161 : :
162 : : void mock_rte_pktmbuf_free_bulk(struct rte_mbuf **m, unsigned int cnt);
163 : : #define rte_pktmbuf_free_bulk mock_rte_pktmbuf_free_bulk
164 : : void
165 : 36 : mock_rte_pktmbuf_free_bulk(struct rte_mbuf **m, unsigned int cnt)
166 : : {
167 : 36 : }
168 : :
169 : : static bool ut_boundary_alloc = false;
170 : : static int ut_rte_pktmbuf_alloc_bulk = 0;
171 : : int mock_rte_pktmbuf_alloc_bulk(struct rte_mempool *pool, struct rte_mbuf **mbufs,
172 : : unsigned count);
173 : : #define rte_pktmbuf_alloc_bulk mock_rte_pktmbuf_alloc_bulk
174 : : int
175 : 84 : mock_rte_pktmbuf_alloc_bulk(struct rte_mempool *pool, struct rte_mbuf **mbufs,
176 : : unsigned count)
177 : : {
178 : 28 : int i;
179 : :
180 : : /* This mocked function only supports the alloc of up to 3 src and 3 dst. */
181 : 84 : ut_rte_pktmbuf_alloc_bulk += count;
182 : :
183 [ + + ]: 84 : if (ut_rte_pktmbuf_alloc_bulk == 1) {
184 : : /* allocation of an extra mbuf for boundary cross test */
185 : 15 : ut_boundary_alloc = true;
186 [ - + - + : 15 : g_src_mbufs[UT_MBUFS_PER_OP_BOUND_TEST - 1]->next = NULL;
- + - + -
+ ]
187 [ - + - + : 15 : *mbufs = g_src_mbufs[UT_MBUFS_PER_OP_BOUND_TEST - 1];
- + - + ]
188 : 15 : ut_rte_pktmbuf_alloc_bulk = 0;
189 [ + + ]: 74 : } else if (ut_rte_pktmbuf_alloc_bulk == UT_MBUFS_PER_OP) {
190 : : /* first test allocation, src mbufs */
191 [ + + + - ]: 132 : for (i = 0; i < UT_MBUFS_PER_OP; i++) {
192 [ + - + - : 99 : g_src_mbufs[i]->next = NULL;
+ - + - +
- ]
193 [ + - + - : 99 : *mbufs++ = g_src_mbufs[i];
+ - + - +
- ]
194 : 33 : }
195 [ + + ]: 47 : } else if (ut_rte_pktmbuf_alloc_bulk == UT_MBUFS_PER_OP * 2) {
196 : : /* second test allocation, dst mbufs */
197 [ + + + - ]: 132 : for (i = 0; i < UT_MBUFS_PER_OP; i++) {
198 [ + - + - : 99 : g_dst_mbufs[i]->next = NULL;
+ - + - +
- ]
199 [ + - + - : 99 : *mbufs++ = g_dst_mbufs[i];
+ - + - +
- ]
200 : 33 : }
201 : 33 : ut_rte_pktmbuf_alloc_bulk = 0;
202 : 11 : } else {
203 : 3 : return -1;
204 : : }
205 : 81 : return 0;
206 : 28 : }
207 : :
208 : : struct rte_mempool *
209 : 18 : rte_pktmbuf_pool_create(const char *name, unsigned n, unsigned cache_size,
210 : : uint16_t priv_size, uint16_t data_room_size, int socket_id)
211 : : {
212 : 6 : struct spdk_mempool *tmp;
213 : :
214 : 18 : tmp = spdk_mempool_create("mbuf_mp", 1024, sizeof(struct rte_mbuf),
215 : : SPDK_MEMPOOL_DEFAULT_CACHE_SIZE,
216 : : SPDK_ENV_SOCKET_ID_ANY);
217 : :
218 : 24 : return (struct rte_mempool *)tmp;
219 : 6 : }
220 : :
221 : : void
222 : 15 : rte_mempool_free(struct rte_mempool *mp)
223 : : {
224 [ + - ]: 15 : if (mp) {
225 : 15 : spdk_mempool_free((struct spdk_mempool *)mp);
226 : 5 : }
227 : 15 : }
228 : :
229 : : #include "accel/dpdk_compressdev/accel_dpdk_compressdev.c"
230 : :
231 : : static void _compress_done(void *arg, int status);
232 : : static int ut_expected_task_status = 0;
233 : : void
234 : 12 : spdk_accel_task_complete(struct spdk_accel_task *accel_task, int status)
235 : : {
236 : 12 : CU_ASSERT(status == ut_expected_task_status);
237 [ + - + - : 12 : accel_task->cb_fn(accel_task, status);
+ - - + +
- ]
238 : 12 : }
239 : :
240 : : /* SPDK stubs */
241 : 0 : DEFINE_STUB_V(spdk_accel_module_finish, (void));
242 : 0 : DEFINE_STUB_V(spdk_accel_module_list_add, (struct spdk_accel_module_if *accel_module));
243 : :
244 : : /* DPDK stubs */
245 : 0 : DEFINE_STUB(rte_compressdev_capability_get, const struct rte_compressdev_capabilities *,
246 : : (uint8_t dev_id,
247 : : enum rte_comp_algorithm algo), NULL);
248 : : #define DPDK_DYNFIELD_OFFSET offsetof(struct rte_mbuf, dynfield1[1])
249 : 21 : DEFINE_STUB(rte_mbuf_dynfield_register, int, (const struct rte_mbuf_dynfield *params),
250 : : DPDK_DYNFIELD_OFFSET);
251 : 489 : DEFINE_STUB(rte_socket_id, unsigned, (void), 0);
252 : 0 : DEFINE_STUB(rte_vdev_init, int, (const char *name, const char *args), 0);
253 : 33 : DEFINE_STUB_V(rte_comp_op_free, (struct rte_comp_op *op));
254 : 39 : DEFINE_STUB(rte_comp_op_alloc, struct rte_comp_op *, (struct rte_mempool *mempool), NULL);
255 : :
256 : : int g_small_size_counter = 0;
257 : : int g_small_size_modify = 0;
258 : : uint64_t g_small_size = 0;
259 : : uint64_t
260 : 267 : spdk_vtophys(const void *buf, uint64_t *size)
261 : : {
262 [ + - ]: 267 : g_small_size_counter++;
263 [ + + ]: 267 : if (g_small_size_counter == g_small_size_modify) {
264 [ + - ]: 15 : *size = g_small_size;
265 : 15 : g_small_size_counter = 0;
266 : 15 : g_small_size_modify = 0;
267 : 5 : }
268 : 267 : return (uint64_t)buf;
269 : : }
270 : :
271 : : static uint16_t ut_rte_compressdev_dequeue_burst = 0;
272 : : uint16_t
273 : 9 : rte_compressdev_dequeue_burst(uint8_t dev_id, uint16_t qp_id, struct rte_comp_op **ops,
274 : : uint16_t nb_op)
275 : : {
276 [ + + ]: 9 : if (ut_rte_compressdev_dequeue_burst == 0) {
277 : 0 : return 0;
278 : : }
279 : :
280 [ + - + - : 9 : ops[0] = &g_comp_op[0];
+ - + - ]
281 [ + - + - : 9 : ops[1] = &g_comp_op[1];
+ - + - ]
282 : :
283 : 9 : return ut_rte_compressdev_dequeue_burst;
284 : 3 : }
285 : :
286 : : static uint16_t g_done_count = 1;
287 : : static void
288 : 12 : _compress_done(void *arg, int status)
289 : : {
290 : 12 : struct spdk_accel_task *task = arg;
291 : :
292 [ + + ]: 12 : if (status == 0) {
293 [ + - + - : 9 : CU_ASSERT(*task->output_size == g_comp_op[g_done_count++].produced);
+ - + - +
- + - + -
+ - ]
294 : 3 : }
295 : 12 : }
296 : :
297 : : static void
298 : 21 : _get_mbuf_array(struct rte_mbuf **mbuf_array, struct rte_mbuf *mbuf_head,
299 : : int mbuf_count, bool null_final)
300 : : {
301 : 7 : int i;
302 : :
303 [ + + + - ]: 93 : for (i = 0; i < mbuf_count; i++) {
304 [ + - + - ]: 72 : mbuf_array[i] = mbuf_head;
305 [ + + ]: 72 : if (mbuf_head) {
306 [ + - + - ]: 69 : mbuf_head = mbuf_head->next;
307 : 23 : }
308 : 24 : }
309 [ + + + - ]: 21 : if (null_final) {
310 [ # # # # : 0 : mbuf_array[i - 1] = NULL;
# # ]
311 : 0 : }
312 : 21 : }
313 : :
314 : : #define FAKE_ENQUEUE_SUCCESS 255
315 : : #define FAKE_ENQUEUE_ERROR 128
316 : : #define FAKE_ENQUEUE_BUSY 64
317 : : static uint16_t ut_enqueue_value = FAKE_ENQUEUE_SUCCESS;
318 : : static struct rte_comp_op ut_expected_op;
319 : : uint16_t
320 : 21 : rte_compressdev_enqueue_burst(uint8_t dev_id, uint16_t qp_id, struct rte_comp_op **ops,
321 : : uint16_t nb_ops)
322 : : {
323 [ + - ]: 21 : struct rte_comp_op *op = *ops;
324 : 14 : struct rte_mbuf *op_mbuf[UT_MBUFS_PER_OP_BOUND_TEST];
325 : 14 : struct rte_mbuf *exp_mbuf[UT_MBUFS_PER_OP_BOUND_TEST];
326 : 21 : int i, num_src_mbufs = UT_MBUFS_PER_OP;
327 : :
328 [ + + + + ]: 21 : switch (ut_enqueue_value) {
329 : 2 : case FAKE_ENQUEUE_BUSY:
330 [ + - + - ]: 3 : op->status = RTE_COMP_OP_STATUS_NOT_PROCESSED;
331 : 3 : return 0;
332 : 10 : case FAKE_ENQUEUE_SUCCESS:
333 [ + - + - ]: 15 : op->status = RTE_COMP_OP_STATUS_SUCCESS;
334 : 15 : return 1;
335 : 2 : case FAKE_ENQUEUE_ERROR:
336 [ + - + - ]: 3 : op->status = RTE_COMP_OP_STATUS_ERROR;
337 : 3 : return 0;
338 : 0 : default:
339 : 0 : break;
340 : : }
341 : :
342 : : /* by design the compress module will never send more than 1 op at a time */
343 [ # # # # : 0 : CU_ASSERT(op->private_xform == ut_expected_op.private_xform);
# # # # #
# ]
344 : :
345 : : /* setup our local pointers to the chained mbufs, those pointed to in the
346 : : * operation struct and the expected values.
347 : : */
348 [ # # # # ]: 0 : _get_mbuf_array(op_mbuf, op->m_src, SPDK_COUNTOF(op_mbuf), true);
349 [ # # ]: 0 : _get_mbuf_array(exp_mbuf, ut_expected_op.m_src, SPDK_COUNTOF(exp_mbuf), true);
350 : :
351 [ # # # # ]: 0 : if (ut_boundary_alloc == true) {
352 : : /* if we crossed a boundary, we need to check the 4th src mbuf and
353 : : * reset the global that is used to identify whether we crossed
354 : : * or not
355 : : */
356 : 0 : num_src_mbufs = UT_MBUFS_PER_OP_BOUND_TEST;
357 [ # # # # : 0 : exp_mbuf[UT_MBUFS_PER_OP_BOUND_TEST - 1] = ut_expected_op.m_src->next->next->next;
# # # # #
# # # # #
# # # # #
# ]
358 [ # # # # : 0 : op_mbuf[UT_MBUFS_PER_OP_BOUND_TEST - 1] = op->m_src->next->next->next;
# # # # #
# # # # #
# # # # #
# # # ]
359 : 0 : ut_boundary_alloc = false;
360 : 0 : }
361 : :
362 [ # # # # ]: 0 : for (i = 0; i < num_src_mbufs; i++) {
363 [ # # # # : 0 : CU_ASSERT(op_mbuf[i]->buf_addr == exp_mbuf[i]->buf_addr);
# # # # #
# # # # #
# # # # #
# ]
364 [ # # # # : 0 : CU_ASSERT(op_mbuf[i]->buf_iova == exp_mbuf[i]->buf_iova);
# # # # #
# # # # #
# # # # #
# ]
365 [ # # # # : 0 : CU_ASSERT(op_mbuf[i]->buf_len == exp_mbuf[i]->buf_len);
# # # # #
# # # # #
# # # # #
# ]
366 [ # # # # : 0 : CU_ASSERT(op_mbuf[i]->pkt_len == exp_mbuf[i]->pkt_len);
# # # # #
# # # # #
# # # # #
# ]
367 : 0 : }
368 : :
369 : : /* if only 3 mbufs were used in the test, the 4th should be zeroed */
370 [ # # ]: 0 : if (num_src_mbufs == UT_MBUFS_PER_OP) {
371 [ # # # # : 0 : CU_ASSERT(op_mbuf[UT_MBUFS_PER_OP_BOUND_TEST - 1] == NULL);
# # ]
372 [ # # # # : 0 : CU_ASSERT(exp_mbuf[UT_MBUFS_PER_OP_BOUND_TEST - 1] == NULL);
# # ]
373 : 0 : }
374 [ # # # # : 0 : CU_ASSERT(*RTE_MBUF_DYNFIELD(op->m_src, g_mbuf_offset, uint64_t *) ==
# # # # #
# ]
375 : : *RTE_MBUF_DYNFIELD(ut_expected_op.m_src, g_mbuf_offset, uint64_t *));
376 [ # # # # : 0 : CU_ASSERT(op->src.offset == ut_expected_op.src.offset);
# # # # #
# ]
377 [ # # # # : 0 : CU_ASSERT(op->src.length == ut_expected_op.src.length);
# # # # #
# ]
378 : :
379 : : /* check dst mbuf values */
380 [ # # # # ]: 0 : _get_mbuf_array(op_mbuf, op->m_dst, SPDK_COUNTOF(op_mbuf), true);
381 [ # # ]: 0 : _get_mbuf_array(exp_mbuf, ut_expected_op.m_dst, SPDK_COUNTOF(exp_mbuf), true);
382 : :
383 [ # # # # ]: 0 : for (i = 0; i < UT_MBUFS_PER_OP; i++) {
384 [ # # # # : 0 : CU_ASSERT(op_mbuf[i]->buf_addr == exp_mbuf[i]->buf_addr);
# # # # #
# # # # #
# # # # #
# ]
385 [ # # # # : 0 : CU_ASSERT(op_mbuf[i]->buf_iova == exp_mbuf[i]->buf_iova);
# # # # #
# # # # #
# # # # #
# ]
386 [ # # # # : 0 : CU_ASSERT(op_mbuf[i]->buf_len == exp_mbuf[i]->buf_len);
# # # # #
# # # # #
# # # # #
# ]
387 [ # # # # : 0 : CU_ASSERT(op_mbuf[i]->pkt_len == exp_mbuf[i]->pkt_len);
# # # # #
# # # # #
# # # # #
# ]
388 : 0 : }
389 [ # # # # : 0 : CU_ASSERT(op->dst.offset == ut_expected_op.dst.offset);
# # # # #
# ]
390 : :
391 : 0 : return ut_enqueue_value;
392 : 7 : }
393 : :
394 : : /* Global setup for all tests that share a bunch of preparation... */
395 : : static int
396 : 3 : test_setup(void)
397 : : {
398 : 1 : struct spdk_thread *thread;
399 : 1 : int i;
400 : :
401 : 3 : spdk_thread_lib_init(NULL, 0);
402 : :
403 : 3 : thread = spdk_thread_create(NULL, NULL);
404 : 3 : spdk_set_thread(thread);
405 : :
406 : 4 : g_comp_xform = (struct rte_comp_xform) {
407 : : .type = RTE_COMP_COMPRESS,
408 : 2 : .compress = {
409 : : .algo = RTE_COMP_ALGO_DEFLATE,
410 : 1 : .deflate.huffman = RTE_COMP_HUFFMAN_DEFAULT,
411 : : .level = RTE_COMP_LEVEL_MAX,
412 : : .window_size = DEFAULT_WINDOW_SIZE,
413 : : .chksum = RTE_COMP_CHECKSUM_NONE,
414 : : .hash_algo = RTE_COMP_HASH_ALGO_NONE
415 : : }
416 : : };
417 : :
418 : 4 : g_decomp_xform = (struct rte_comp_xform) {
419 : : .type = RTE_COMP_DECOMPRESS,
420 : 1 : .decompress = {
421 : : .algo = RTE_COMP_ALGO_DEFLATE,
422 : : .chksum = RTE_COMP_CHECKSUM_NONE,
423 : : .window_size = DEFAULT_WINDOW_SIZE,
424 : : .hash_algo = RTE_COMP_HASH_ALGO_NONE
425 : : }
426 : : };
427 [ + - ]: 3 : g_device.comp_xform = &g_comp_xform;
428 [ + - ]: 3 : g_device.decomp_xform = &g_decomp_xform;
429 [ + - + - ]: 3 : g_cdev_cap.comp_feature_flags = RTE_COMP_FF_SHAREABLE_PRIV_XFORM;
430 : 3 : g_device.cdev_info.driver_name = "compressdev";
431 [ + - ]: 3 : g_device.cdev_info.capabilities = &g_cdev_cap;
432 [ + + + - ]: 15 : for (i = 0; i < UT_MBUFS_PER_OP_BOUND_TEST; i++) {
433 [ + - + - : 12 : g_src_mbufs[i] = spdk_zmalloc(sizeof(struct rte_mbuf), 0x40, NULL,
+ - ]
434 : : SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
435 : 4 : }
436 [ + + + - ]: 12 : for (i = 0; i < UT_MBUFS_PER_OP; i++) {
437 [ + - + - : 9 : g_dst_mbufs[i] = spdk_zmalloc(sizeof(struct rte_mbuf), 0x40, NULL,
+ - ]
438 : : SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
439 : 3 : }
440 : :
441 : 3 : g_io_ch = calloc(1, sizeof(struct spdk_io_channel) + sizeof(struct compress_io_channel));
442 [ + - + - ]: 3 : g_io_ch->thread = thread;
443 : 3 : g_comp_ch = (struct compress_io_channel *)spdk_io_channel_get_ctx(g_io_ch);
444 [ + - + - ]: 3 : g_comp_ch->device_qp = &g_device_qp;
445 [ + - + - : 3 : g_comp_ch->device_qp->device = &g_device;
+ - + - ]
446 [ + - + - ]: 3 : g_device_qp.device->sgl_in = true;
447 [ + - + - ]: 3 : g_device_qp.device->sgl_out = true;
448 [ + - + - ]: 3 : g_comp_ch->src_mbufs = calloc(UT_MBUFS_PER_OP_BOUND_TEST, sizeof(void *));
449 [ + - + - ]: 3 : g_comp_ch->dst_mbufs = calloc(UT_MBUFS_PER_OP, sizeof(void *));
450 [ + - + - : 3 : STAILQ_INIT(&g_comp_ch->queued_tasks);
+ - + - +
- + - + -
+ - ]
451 : :
452 [ + + + - ]: 12 : for (i = 0; i < UT_MBUFS_PER_OP_BOUND_TEST - 1; i++) {
453 [ + - + - : 9 : g_expected_src_mbufs[i].next = &g_expected_src_mbufs[i + 1];
+ - + - +
- + - +
- ]
454 : 3 : }
455 [ + - + - : 3 : g_expected_src_mbufs[UT_MBUFS_PER_OP_BOUND_TEST - 1].next = NULL;
+ - + - ]
456 : :
457 : : /* we only test w/4 mbufs on src side */
458 [ + + + - ]: 9 : for (i = 0; i < UT_MBUFS_PER_OP - 1; i++) {
459 [ + - + - : 6 : g_expected_dst_mbufs[i].next = &g_expected_dst_mbufs[i + 1];
+ - + - +
- + - +
- ]
460 : 2 : }
461 [ + - + - : 3 : g_expected_dst_mbufs[UT_MBUFS_PER_OP - 1].next = NULL;
+ - + - ]
462 : 3 : g_mbuf_offset = DPDK_DYNFIELD_OFFSET;
463 : :
464 : 3 : return 0;
465 : 1 : }
466 : :
467 : : /* Global teardown for all tests */
468 : : static int
469 : 3 : test_cleanup(void)
470 : : {
471 : 1 : struct spdk_thread *thread;
472 : 1 : int i;
473 : :
474 [ + + + - ]: 15 : for (i = 0; i < UT_MBUFS_PER_OP_BOUND_TEST; i++) {
475 [ + - + - : 12 : spdk_free(g_src_mbufs[i]);
+ - ]
476 : 4 : }
477 [ + + + - ]: 12 : for (i = 0; i < UT_MBUFS_PER_OP; i++) {
478 [ + - + - : 9 : spdk_free(g_dst_mbufs[i]);
+ - ]
479 : 3 : }
480 [ + - + - ]: 3 : free(g_comp_ch->src_mbufs);
481 [ + - + - ]: 3 : free(g_comp_ch->dst_mbufs);
482 : 3 : free(g_io_ch);
483 : :
484 : 3 : thread = spdk_get_thread();
485 : 3 : spdk_thread_exit(thread);
486 [ + + ]: 6 : while (!spdk_thread_is_exited(thread)) {
487 : 3 : spdk_thread_poll(thread, 0, 0);
488 : : }
489 : 3 : spdk_thread_destroy(thread);
490 : :
491 : 3 : spdk_thread_lib_fini();
492 : :
493 : 3 : return 0;
494 : 1 : }
495 : :
496 : : static void
497 : 3 : test_compress_operation(void)
498 : : {
499 : 3 : struct iovec src_iovs[3] = {};
500 : 1 : int src_iovcnt;
501 : 3 : struct iovec dst_iovs[3] = {};
502 : 1 : int dst_iovcnt;
503 : 3 : struct spdk_accel_task task = {};
504 : 1 : int rc, i;
505 : 2 : struct rte_mbuf *exp_src_mbuf[UT_MBUFS_PER_OP];
506 : 2 : struct rte_mbuf *exp_dst_mbuf[UT_MBUFS_PER_OP];
507 : 2 : uint32_t output_size;
508 : :
509 : 3 : src_iovcnt = dst_iovcnt = 3;
510 [ + + + - ]: 12 : for (i = 0; i < dst_iovcnt; i++) {
511 [ + - + - : 9 : src_iovs[i].iov_len = 0x1000;
+ - + - ]
512 [ + - + - : 9 : dst_iovs[i].iov_len = 0x1000;
+ - + - ]
513 [ + - + - : 9 : src_iovs[i].iov_base = (void *)0x10000000 + 0x1000 * i;
+ - + - +
- ]
514 [ + - + - : 9 : dst_iovs[i].iov_base = (void *)0x20000000 + 0x1000 * i;
+ - + - +
- ]
515 : 3 : }
516 : :
517 [ + - + - ]: 3 : task.cb_fn = _compress_done;
518 [ + - ]: 3 : task.op_code = SPDK_ACCEL_OPC_COMPRESS;
519 [ + - + - ]: 3 : task.output_size = &output_size;
520 [ + - + - : 3 : task.d.iovs = dst_iovs;
+ - ]
521 [ + - + - : 3 : task.d.iovcnt = dst_iovcnt;
+ - ]
522 [ + - + - : 3 : task.s.iovs = src_iovs;
+ - ]
523 [ + - + - : 3 : task.s.iovcnt = src_iovcnt;
+ - ]
524 : :
525 : : /* test rte_comp_op_alloc failure */
526 : 3 : MOCK_SET(rte_comp_op_alloc, NULL);
527 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
528 : 3 : rc = _compress_operation(g_comp_ch, &task);
529 : 3 : CU_ASSERT(rc == 0);
530 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == false);
+ - ]
531 [ + + + - : 8 : while (!STAILQ_EMPTY(&g_comp_ch->queued_tasks)) {
+ - + + ]
532 [ + + + - : 3 : STAILQ_REMOVE_HEAD(&g_comp_ch->queued_tasks, link);
+ - + - +
- + - + -
+ - + - -
+ + - + -
+ - + - +
- ]
533 : : }
534 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
535 : :
536 : : /* test mempool get failure */
537 [ + - + - ]: 3 : MOCK_SET(rte_comp_op_alloc, &g_comp_op[0]);
538 : 3 : ut_rte_pktmbuf_alloc_bulk = -1;
539 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
540 : 3 : rc = _compress_operation(g_comp_ch, &task);
541 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == false);
+ - ]
542 [ + + + - : 8 : while (!STAILQ_EMPTY(&g_comp_ch->queued_tasks)) {
+ - + + ]
543 [ + + + - : 3 : STAILQ_REMOVE_HEAD(&g_comp_ch->queued_tasks, link);
+ - + - +
- + - + -
+ - + - -
+ + - + -
+ - + - +
- ]
544 : : }
545 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
546 : 3 : CU_ASSERT(rc == 0);
547 : 3 : ut_rte_pktmbuf_alloc_bulk = 0;
548 : :
549 : : /* test enqueue failure busy */
550 : 3 : ut_enqueue_value = FAKE_ENQUEUE_BUSY;
551 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
552 : 3 : rc = _compress_operation(g_comp_ch, &task);
553 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == false);
+ - ]
554 [ + + + - : 8 : while (!STAILQ_EMPTY(&g_comp_ch->queued_tasks)) {
+ - + + ]
555 [ + + + - : 3 : STAILQ_REMOVE_HEAD(&g_comp_ch->queued_tasks, link);
+ - + - +
- + - + -
+ - + - -
+ + - + -
+ - + - +
- ]
556 : : }
557 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
558 : 3 : CU_ASSERT(rc == 0);
559 : 3 : ut_enqueue_value = 1;
560 : :
561 : : /* test enqueue failure error */
562 : 3 : ut_enqueue_value = FAKE_ENQUEUE_ERROR;
563 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
564 : 3 : rc = _compress_operation(g_comp_ch, &task);
565 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
566 : 3 : CU_ASSERT(rc == -EINVAL);
567 : 3 : ut_enqueue_value = FAKE_ENQUEUE_SUCCESS;
568 : :
569 : : /* test success with 3 vector iovec */
570 [ + - + - ]: 3 : ut_expected_op.private_xform = &g_decomp_xform;
571 [ + - + - ]: 3 : ut_expected_op.src.offset = 0;
572 [ + - + - : 3 : ut_expected_op.src.length = src_iovs[0].iov_len + src_iovs[1].iov_len + src_iovs[2].iov_len;
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - ]
573 : :
574 : : /* setup the src expected values */
575 [ + - + - ]: 3 : _get_mbuf_array(exp_src_mbuf, &g_expected_src_mbufs[0], SPDK_COUNTOF(exp_src_mbuf), false);
576 [ + - + - : 3 : ut_expected_op.m_src = exp_src_mbuf[0];
+ - ]
577 : :
578 [ + + + - ]: 12 : for (i = 0; i < UT_MBUFS_PER_OP; i++) {
579 [ + - + - : 9 : *RTE_MBUF_DYNFIELD(exp_src_mbuf[i], g_mbuf_offset, uint64_t *) = (uint64_t)&task;
+ - + - ]
580 [ + - + - : 9 : exp_src_mbuf[i]->buf_addr = src_iovs[i].iov_base;
+ - + - +
- + - + -
+ - + - ]
581 [ + - + - : 9 : exp_src_mbuf[i]->buf_iova = spdk_vtophys(src_iovs[i].iov_base, &src_iovs[i].iov_len);
+ - + - +
- + - + -
+ - + - +
- + - +
- ]
582 [ + - + - : 9 : exp_src_mbuf[i]->buf_len = src_iovs[i].iov_len;
+ - + - +
- + - + -
+ - + - ]
583 [ + - + - : 9 : exp_src_mbuf[i]->pkt_len = src_iovs[i].iov_len;
+ - + - +
- + - + -
+ - + - ]
584 : 3 : }
585 : :
586 : : /* setup the dst expected values */
587 [ + - + - ]: 3 : _get_mbuf_array(exp_dst_mbuf, &g_expected_dst_mbufs[0], SPDK_COUNTOF(exp_dst_mbuf), false);
588 [ + - + - ]: 3 : ut_expected_op.dst.offset = 0;
589 [ + - + - : 3 : ut_expected_op.m_dst = exp_dst_mbuf[0];
+ - ]
590 : :
591 [ + + + - ]: 12 : for (i = 0; i < UT_MBUFS_PER_OP; i++) {
592 [ + - + - : 9 : exp_dst_mbuf[i]->buf_addr = dst_iovs[i].iov_base;
+ - + - +
- + - + -
+ - + - ]
593 [ + - + - : 9 : exp_dst_mbuf[i]->buf_iova = spdk_vtophys(dst_iovs[i].iov_base, &dst_iovs[i].iov_len);
+ - + - +
- + - + -
+ - + - +
- + - +
- ]
594 [ + - + - : 9 : exp_dst_mbuf[i]->buf_len = dst_iovs[i].iov_len;
+ - + - +
- + - + -
+ - + - ]
595 [ + - + - : 9 : exp_dst_mbuf[i]->pkt_len = dst_iovs[i].iov_len;
+ - + - +
- + - + -
+ - + - ]
596 : 3 : }
597 : :
598 : 3 : rc = _compress_operation(g_comp_ch, &task);
599 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
600 : 3 : CU_ASSERT(rc == 0);
601 : :
602 : : /* test sgl out failure */
603 : 3 : g_device.sgl_out = false;
604 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
605 : 3 : rc = _compress_operation(g_comp_ch, &task);
606 : 3 : CU_ASSERT(rc == -EINVAL);
607 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
608 : 3 : g_device.sgl_out = true;
609 : :
610 : : /* test sgl in failure */
611 [ + - ]: 3 : g_device.sgl_in = false;
612 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
613 : 3 : rc = _compress_operation(g_comp_ch, &task);
614 : 3 : CU_ASSERT(rc == -EINVAL);
615 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
616 [ + - ]: 3 : g_device.sgl_in = true;
617 : 3 : }
618 : :
619 : : static void
620 : 3 : test_compress_operation_cross_boundary(void)
621 : : {
622 : 3 : struct iovec src_iovs[3] = {};
623 : 1 : int src_iovcnt;
624 : 3 : struct iovec dst_iovs[3] = {};
625 : 1 : int dst_iovcnt;
626 : 1 : int rc, i;
627 : 2 : struct rte_mbuf *exp_src_mbuf[UT_MBUFS_PER_OP_BOUND_TEST];
628 : 2 : struct rte_mbuf *exp_dst_mbuf[UT_MBUFS_PER_OP_BOUND_TEST];
629 : 3 : struct spdk_accel_task task = {};
630 : 2 : uint32_t output_size;
631 : :
632 : : /* Setup the same basic 3 IOV test as used in the simple success case
633 : : * but then we'll start testing a vtophy boundary crossing at each
634 : : * position.
635 : : */
636 : 3 : src_iovcnt = dst_iovcnt = 3;
637 [ + + + - ]: 12 : for (i = 0; i < dst_iovcnt; i++) {
638 [ + - + - : 9 : src_iovs[i].iov_len = 0x1000;
+ - + - ]
639 [ + - + - : 9 : dst_iovs[i].iov_len = 0x1000;
+ - + - ]
640 [ + - + - : 9 : src_iovs[i].iov_base = (void *)0x10000000 + 0x1000 * i;
+ - + - +
- ]
641 [ + - + - : 9 : dst_iovs[i].iov_base = (void *)0x20000000 + 0x1000 * i;
+ - + - +
- ]
642 : 3 : }
643 : :
644 [ + - + - ]: 3 : ut_expected_op.private_xform = &g_decomp_xform;
645 [ + - + - ]: 3 : ut_expected_op.src.offset = 0;
646 [ + - + - : 3 : ut_expected_op.src.length = src_iovs[0].iov_len + src_iovs[1].iov_len + src_iovs[2].iov_len;
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - ]
647 : :
648 : : /* setup the src expected values */
649 [ + - + - ]: 3 : _get_mbuf_array(exp_src_mbuf, &g_expected_src_mbufs[0], SPDK_COUNTOF(exp_src_mbuf), false);
650 [ + - + - : 3 : ut_expected_op.m_src = exp_src_mbuf[0];
+ - ]
651 : :
652 [ + + + - ]: 12 : for (i = 0; i < UT_MBUFS_PER_OP; i++) {
653 [ + - + - : 9 : *RTE_MBUF_DYNFIELD(exp_src_mbuf[i], g_mbuf_offset, uint64_t *) = (uint64_t)&task;
+ - + - ]
654 [ + - + - : 9 : exp_src_mbuf[i]->buf_addr = src_iovs[i].iov_base;
+ - + - +
- + - + -
+ - + - ]
655 [ + - + - : 9 : exp_src_mbuf[i]->buf_iova = spdk_vtophys(src_iovs[i].iov_base, &src_iovs[i].iov_len);
+ - + - +
- + - + -
+ - + - +
- + - +
- ]
656 [ + - + - : 9 : exp_src_mbuf[i]->buf_len = src_iovs[i].iov_len;
+ - + - +
- + - + -
+ - + - ]
657 [ + - + - : 9 : exp_src_mbuf[i]->pkt_len = src_iovs[i].iov_len;
+ - + - +
- + - + -
+ - + - ]
658 : 3 : }
659 : :
660 : : /* setup the dst expected values, we don't test needing a 4th dst mbuf */
661 [ + - + - ]: 3 : _get_mbuf_array(exp_dst_mbuf, &g_expected_dst_mbufs[0], SPDK_COUNTOF(exp_dst_mbuf), false);
662 [ + - + - ]: 3 : ut_expected_op.dst.offset = 0;
663 [ + - + - : 3 : ut_expected_op.m_dst = exp_dst_mbuf[0];
+ - ]
664 : :
665 [ + + + - ]: 12 : for (i = 0; i < UT_MBUFS_PER_OP; i++) {
666 [ + - + - : 9 : exp_dst_mbuf[i]->buf_addr = dst_iovs[i].iov_base;
+ - + - +
- + - + -
+ - + - ]
667 [ + - + - : 9 : exp_dst_mbuf[i]->buf_iova = spdk_vtophys(dst_iovs[i].iov_base, &dst_iovs[i].iov_len);
+ - + - +
- + - + -
+ - + - +
- + - +
- ]
668 [ + - + - : 9 : exp_dst_mbuf[i]->buf_len = dst_iovs[i].iov_len;
+ - + - +
- + - + -
+ - + - ]
669 [ + - + - : 9 : exp_dst_mbuf[i]->pkt_len = dst_iovs[i].iov_len;
+ - + - +
- + - + -
+ - + - ]
670 : 3 : }
671 : :
672 : : /* force the 1st IOV to get partial length from spdk_vtophys */
673 : 3 : g_small_size_counter = 0;
674 : 3 : g_small_size_modify = 1;
675 : 3 : g_small_size = 0x800;
676 [ + - + - : 3 : *RTE_MBUF_DYNFIELD(exp_src_mbuf[3], g_mbuf_offset, uint64_t *) = (uint64_t)&task;
+ - + - ]
677 : :
678 : : /* first only has shorter length */
679 [ + - + - : 3 : exp_src_mbuf[0]->pkt_len = exp_src_mbuf[0]->buf_len = 0x800;
+ - + - +
- + - + -
+ - ]
680 : :
681 : : /* 2nd was inserted by the boundary crossing condition and finishes off
682 : : * the length from the first */
683 [ + - + - : 3 : exp_src_mbuf[1]->buf_addr = (void *)0x10000800;
+ - + - +
- ]
684 [ + - + - : 3 : exp_src_mbuf[1]->buf_iova = 0x10000800;
+ - + - +
- ]
685 [ + - + - : 3 : exp_src_mbuf[1]->pkt_len = exp_src_mbuf[1]->buf_len = 0x800;
+ - + - +
- + - + -
+ - + - +
- ]
686 : :
687 : : /* 3rd looks like that the 2nd would have */
688 [ + - + - : 3 : exp_src_mbuf[2]->buf_addr = (void *)0x10001000;
+ - + - +
- ]
689 [ + - + - : 3 : exp_src_mbuf[2]->buf_iova = 0x10001000;
+ - + - +
- ]
690 [ + - + - : 3 : exp_src_mbuf[2]->pkt_len = exp_src_mbuf[2]->buf_len = 0x1000;
+ - + - +
- + - + -
+ - + - +
- ]
691 : :
692 : : /* a new 4th looks like what the 3rd would have */
693 [ + - + - : 3 : exp_src_mbuf[3]->buf_addr = (void *)0x10002000;
+ - + - +
- ]
694 [ + - + - : 3 : exp_src_mbuf[3]->buf_iova = 0x10002000;
+ - + - +
- ]
695 [ + - + - : 3 : exp_src_mbuf[3]->pkt_len = exp_src_mbuf[3]->buf_len = 0x1000;
+ - + - +
- + - + -
+ - + - +
- ]
696 : :
697 [ + - + - ]: 3 : task.cb_fn = _compress_done;
698 [ + - ]: 3 : task.op_code = SPDK_ACCEL_OPC_COMPRESS;
699 [ + - + - ]: 3 : task.output_size = &output_size;
700 [ + - + - : 3 : task.d.iovs = dst_iovs;
+ - ]
701 [ + - + - : 3 : task.d.iovcnt = dst_iovcnt;
+ - ]
702 [ + - + - : 3 : task.s.iovs = src_iovs;
+ - ]
703 [ + - + - : 3 : task.s.iovcnt = src_iovcnt;
+ - ]
704 : :
705 : 3 : rc = _compress_operation(g_comp_ch, &task);
706 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
707 : 3 : CU_ASSERT(rc == 0);
708 : :
709 : : /* Now force the 2nd IOV to get partial length from spdk_vtophys */
710 : 3 : g_small_size_counter = 0;
711 : 3 : g_small_size_modify = 2;
712 : 3 : g_small_size = 0x800;
713 : :
714 : : /* first is normal */
715 [ + - + - : 3 : exp_src_mbuf[0]->buf_addr = (void *)0x10000000;
+ - + - ]
716 [ + - + - : 3 : exp_src_mbuf[0]->buf_iova = 0x10000000;
+ - + - ]
717 [ + - + - : 3 : exp_src_mbuf[0]->pkt_len = exp_src_mbuf[0]->buf_len = 0x1000;
+ - + - +
- + - + -
+ - ]
718 : :
719 : : /* second only has shorter length */
720 [ + - + - : 3 : exp_src_mbuf[1]->buf_addr = (void *)0x10001000;
+ - + - +
- ]
721 [ + - + - : 3 : exp_src_mbuf[1]->buf_iova = 0x10001000;
+ - + - +
- ]
722 [ + - + - : 3 : exp_src_mbuf[1]->pkt_len = exp_src_mbuf[1]->buf_len = 0x800;
+ - + - +
- + - + -
+ - + - +
- ]
723 : :
724 : : /* 3rd was inserted by the boundary crossing condition and finishes off
725 : : * the length from the first */
726 [ + - + - : 3 : exp_src_mbuf[2]->buf_addr = (void *)0x10001800;
+ - + - +
- ]
727 [ + - + - : 3 : exp_src_mbuf[2]->buf_iova = 0x10001800;
+ - + - +
- ]
728 [ + - + - : 3 : exp_src_mbuf[2]->pkt_len = exp_src_mbuf[2]->buf_len = 0x800;
+ - + - +
- + - + -
+ - + - +
- ]
729 : :
730 : : /* a new 4th looks like what the 3rd would have */
731 [ + - + - : 3 : exp_src_mbuf[3]->buf_addr = (void *)0x10002000;
+ - + - +
- ]
732 [ + - + - : 3 : exp_src_mbuf[3]->buf_iova = 0x10002000;
+ - + - +
- ]
733 [ + - + - : 3 : exp_src_mbuf[3]->pkt_len = exp_src_mbuf[3]->buf_len = 0x1000;
+ - + - +
- + - + -
+ - + - +
- ]
734 : :
735 : 3 : rc = _compress_operation(g_comp_ch, &task);
736 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
737 : 3 : CU_ASSERT(rc == 0);
738 : :
739 : : /* Finally force the 3rd IOV to get partial length from spdk_vtophys */
740 : 3 : g_small_size_counter = 0;
741 : 3 : g_small_size_modify = 3;
742 : 3 : g_small_size = 0x800;
743 : :
744 : : /* first is normal */
745 [ + - + - : 3 : exp_src_mbuf[0]->buf_addr = (void *)0x10000000;
+ - + - ]
746 [ + - + - : 3 : exp_src_mbuf[0]->buf_iova = 0x10000000;
+ - + - ]
747 [ + - + - : 3 : exp_src_mbuf[0]->pkt_len = exp_src_mbuf[0]->buf_len = 0x1000;
+ - + - +
- + - + -
+ - ]
748 : :
749 : : /* second is normal */
750 [ + - + - : 3 : exp_src_mbuf[1]->buf_addr = (void *)0x10001000;
+ - + - +
- ]
751 [ + - + - : 3 : exp_src_mbuf[1]->buf_iova = 0x10001000;
+ - + - +
- ]
752 [ + - + - : 3 : exp_src_mbuf[1]->pkt_len = exp_src_mbuf[1]->buf_len = 0x1000;
+ - + - +
- + - + -
+ - + - +
- ]
753 : :
754 : : /* 3rd has shorter length */
755 [ + - + - : 3 : exp_src_mbuf[2]->buf_addr = (void *)0x10002000;
+ - + - +
- ]
756 [ + - + - : 3 : exp_src_mbuf[2]->buf_iova = 0x10002000;
+ - + - +
- ]
757 [ + - + - : 3 : exp_src_mbuf[2]->pkt_len = exp_src_mbuf[2]->buf_len = 0x800;
+ - + - +
- + - + -
+ - + - +
- ]
758 : :
759 : : /* a new 4th handles the remainder from the 3rd */
760 [ + - + - : 3 : exp_src_mbuf[3]->buf_addr = (void *)0x10002800;
+ - + - +
- ]
761 [ + - + - : 3 : exp_src_mbuf[3]->buf_iova = 0x10002800;
+ - + - +
- ]
762 [ + - + - : 3 : exp_src_mbuf[3]->pkt_len = exp_src_mbuf[3]->buf_len = 0x800;
+ - + - +
- + - + -
+ - + - +
- ]
763 : :
764 : 3 : rc = _compress_operation(g_comp_ch, &task);
765 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
766 : 3 : CU_ASSERT(rc == 0);
767 : :
768 : : /* Single input iov is split on page boundary, sgl_in is not supported */
769 [ + - ]: 3 : g_device.sgl_in = false;
770 : 3 : g_small_size_counter = 0;
771 : 3 : g_small_size_modify = 1;
772 : 3 : g_small_size = 0x800;
773 : 3 : rc = _compress_operation(g_comp_ch, &task);
774 : 3 : CU_ASSERT(rc == -EINVAL);
775 [ + - ]: 3 : g_device.sgl_in = true;
776 : :
777 : : /* Single output iov is split on page boundary, sgl_out is not supported */
778 : 3 : g_device.sgl_out = false;
779 : 3 : g_small_size_counter = 0;
780 : 3 : g_small_size_modify = 2;
781 : 3 : g_small_size = 0x800;
782 : 3 : rc = _compress_operation(g_comp_ch, &task);
783 : 3 : CU_ASSERT(rc == -EINVAL);
784 : 3 : g_device.sgl_out = true;
785 : 3 : }
786 : :
787 : : static void
788 : 3 : test_setup_compress_mbuf(void)
789 : : {
790 : 3 : struct iovec src_iovs = {};
791 : 3 : int src_iovcnt = 1;
792 : 3 : struct spdk_accel_task task = {};
793 : 3 : int src_mbuf_added = 0;
794 : 2 : uint64_t total_length;
795 : 2 : struct rte_mbuf *exp_src_mbuf[UT_MBUFS_PER_OP_BOUND_TEST];
796 : 1 : int rc, i;
797 : :
798 : : /* setup the src expected values */
799 [ + - + - ]: 3 : _get_mbuf_array(exp_src_mbuf, &g_expected_src_mbufs[0], SPDK_COUNTOF(exp_src_mbuf), false);
800 : :
801 : : /* no splitting */
802 : 3 : total_length = 0;
803 : 3 : ut_total_rte_pktmbuf_attach_extbuf = 0;
804 [ + - ]: 3 : src_iovs.iov_len = 0x1000;
805 : 3 : src_iovs.iov_base = (void *)0x10000000 + 0x1000;
806 : 4 : rc = _setup_compress_mbuf(exp_src_mbuf, &src_mbuf_added, &total_length,
807 : 1 : &src_iovs, src_iovcnt, &task);
808 : 3 : CU_ASSERT(rc == 0);
809 [ + - ]: 3 : CU_ASSERT(total_length = src_iovs.iov_len);
810 : 3 : CU_ASSERT(src_mbuf_added == 0);
811 : 3 : CU_ASSERT(ut_total_rte_pktmbuf_attach_extbuf == 1);
812 : :
813 : : /* one split, for splitting tests we need the global mbuf array unlinked,
814 : : * otherwise the functional code will attempt to link them but if they are
815 : : * already linked, it will just create a chain that links to itself */
816 [ + + + - ]: 12 : for (i = 0; i < UT_MBUFS_PER_OP_BOUND_TEST - 1; i++) {
817 [ + - + - : 9 : g_expected_src_mbufs[i].next = NULL;
+ - + - ]
818 : 3 : }
819 : 3 : total_length = 0;
820 : 3 : ut_total_rte_pktmbuf_attach_extbuf = 0;
821 [ + - + - ]: 3 : src_iovs.iov_len = 0x1000 + MBUF_SPLIT;
822 [ + - + - : 3 : exp_src_mbuf[0]->buf_len = src_iovs.iov_len;
+ - + - +
- ]
823 [ + - + - : 3 : exp_src_mbuf[0]->pkt_len = src_iovs.iov_len;
+ - + - +
- ]
824 : 4 : rc = _setup_compress_mbuf(exp_src_mbuf, &src_mbuf_added, &total_length,
825 : 1 : &src_iovs, src_iovcnt, &task);
826 : 3 : CU_ASSERT(rc == 0);
827 [ + - ]: 3 : CU_ASSERT(total_length = src_iovs.iov_len);
828 : 3 : CU_ASSERT(src_mbuf_added == 0);
829 : 3 : CU_ASSERT(ut_total_rte_pktmbuf_attach_extbuf == 2);
830 : :
831 : : /* two splits */
832 [ + + + - ]: 12 : for (i = 0; i < UT_MBUFS_PER_OP_BOUND_TEST - 1; i++) {
833 [ + - + - : 9 : g_expected_src_mbufs[i].next = NULL;
+ - + - ]
834 : 3 : }
835 : 3 : total_length = 0;
836 : 3 : ut_total_rte_pktmbuf_attach_extbuf = 0;
837 [ + - + - ]: 3 : src_iovs.iov_len = 0x1000 + 2 * MBUF_SPLIT;
838 [ + - + - : 3 : exp_src_mbuf[0]->buf_len = src_iovs.iov_len;
+ - + - +
- ]
839 [ + - + - : 3 : exp_src_mbuf[0]->pkt_len = src_iovs.iov_len;
+ - + - +
- ]
840 : :
841 : 4 : rc = _setup_compress_mbuf(exp_src_mbuf, &src_mbuf_added, &total_length,
842 : 1 : &src_iovs, src_iovcnt, &task);
843 : 3 : CU_ASSERT(rc == 0);
844 [ + - ]: 3 : CU_ASSERT(total_length = src_iovs.iov_len);
845 : 3 : CU_ASSERT(src_mbuf_added == 0);
846 : 3 : CU_ASSERT(ut_total_rte_pktmbuf_attach_extbuf == 3);
847 : :
848 : : /* relink the global mbuf array */
849 [ + + + - ]: 12 : for (i = 0; i < UT_MBUFS_PER_OP_BOUND_TEST - 1; i++) {
850 [ + - + - : 9 : g_expected_src_mbufs[i].next = &g_expected_src_mbufs[i + 1];
+ - + - +
- + - +
- ]
851 : 3 : }
852 : 3 : }
853 : :
854 : : static void
855 : 3 : test_poller(void)
856 : : {
857 : 1 : int rc;
858 : 1 : struct compress_io_channel *args;
859 : 2 : struct rte_mbuf mbuf[4]; /* one src, one dst, 2 ops */
860 : 3 : struct iovec src_iovs[3] = {};
861 : 3 : struct iovec dst_iovs[3] = {};
862 : 2 : uint32_t output_size[2];
863 : 3 : struct spdk_accel_task task[2] = {};
864 : 1 : struct spdk_accel_task *task_to_resubmit;
865 : 2 : struct rte_mbuf *exp_src_mbuf[UT_MBUFS_PER_OP];
866 : 2 : struct rte_mbuf *exp_dst_mbuf[UT_MBUFS_PER_OP];
867 : 1 : int i;
868 : :
869 : 3 : args = calloc(1, sizeof(*args));
870 [ + + # # ]: 3 : SPDK_CU_ASSERT_FATAL(args != NULL);
871 [ + + + - : 3 : memset(&g_comp_op[0], 0, sizeof(struct rte_comp_op));
+ - ]
872 [ + - + - : 3 : g_comp_op[0].m_src = &mbuf[0];
+ - + - +
- ]
873 [ + - + - : 3 : g_comp_op[1].m_src = &mbuf[1];
+ - + - +
- + - ]
874 [ + - + - : 3 : g_comp_op[0].m_dst = &mbuf[2];
+ - + - +
- ]
875 [ + - + - : 3 : g_comp_op[1].m_dst = &mbuf[3];
+ - + - +
- + - ]
876 [ + + + - ]: 12 : for (i = 0; i < 3; i++) {
877 [ + - + - : 9 : src_iovs[i].iov_len = 0x1000;
+ - + - ]
878 [ + - + - : 9 : dst_iovs[i].iov_len = 0x1000;
+ - + - ]
879 [ + - + - : 9 : src_iovs[i].iov_base = (void *)0x10000000 + 0x1000 * i;
+ - + - +
- ]
880 [ + - + - : 9 : dst_iovs[i].iov_base = (void *)0x20000000 + 0x1000 * i;
+ - + - +
- ]
881 : 3 : }
882 [ + - + - : 3 : task[0].cb_fn = task[1].cb_fn = _compress_done;
+ - + - +
- + - + -
+ - + - ]
883 [ + - + - : 3 : task[0].output_size = &output_size[0];
+ - + - +
- + - ]
884 [ + - + - : 3 : task[1].output_size = &output_size[1];
+ - + - +
- + - +
- ]
885 : :
886 : : /* Error from dequeue, nothing needing to be resubmitted.
887 : : */
888 : 3 : ut_rte_compressdev_dequeue_burst = 1;
889 : 3 : ut_expected_task_status = RTE_COMP_OP_STATUS_NOT_PROCESSED;
890 : : /* setup what we want dequeue to return for the op */
891 [ + - + - : 3 : *RTE_MBUF_DYNFIELD(g_comp_op[0].m_src, g_mbuf_offset, uint64_t *) = (uint64_t)&task[0];
+ - + - +
- + - ]
892 [ + - + - : 3 : g_comp_op[0].produced = 1;
+ - ]
893 : 3 : g_done_count = 0;
894 [ + - + - : 3 : g_comp_op[0].status = RTE_COMP_OP_STATUS_NOT_PROCESSED;
+ - ]
895 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
896 : 3 : rc = comp_dev_poller((void *)g_comp_ch);
897 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
898 : 3 : CU_ASSERT(rc == SPDK_POLLER_BUSY);
899 : 3 : ut_expected_task_status = RTE_COMP_OP_STATUS_SUCCESS;
900 : :
901 : : /* Success from dequeue, 2 ops. nothing needing to be resubmitted.
902 : : */
903 : 3 : ut_rte_compressdev_dequeue_burst = 2;
904 : : /* setup what we want dequeue to return for the op */
905 [ + - + - : 3 : *RTE_MBUF_DYNFIELD(g_comp_op[0].m_src, g_mbuf_offset, uint64_t *) = (uint64_t)&task[0];
+ - + - +
- + - ]
906 [ + - + - : 3 : g_comp_op[0].produced = 16;
+ - ]
907 [ + - + - : 3 : g_comp_op[0].status = RTE_COMP_OP_STATUS_SUCCESS;
+ - ]
908 [ + - + - : 3 : *RTE_MBUF_DYNFIELD(g_comp_op[1].m_src, g_mbuf_offset, uint64_t *) = (uint64_t)&task[1];
+ - + - +
- + - +
- ]
909 [ + - + - : 3 : g_comp_op[1].produced = 32;
+ - + - ]
910 [ + - + - : 3 : g_comp_op[1].status = RTE_COMP_OP_STATUS_SUCCESS;
+ - + - ]
911 : 3 : g_done_count = 0;
912 : 3 : ut_enqueue_value = FAKE_ENQUEUE_SUCCESS;
913 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
914 : 3 : rc = comp_dev_poller((void *)g_comp_ch);
915 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
916 : 3 : CU_ASSERT(rc == SPDK_POLLER_BUSY);
917 : :
918 : : /* One to dequeue, one op to be resubmitted. */
919 : 3 : ut_rte_compressdev_dequeue_burst = 1;
920 : : /* setup what we want dequeue to return for the op */
921 [ + - + - : 3 : *RTE_MBUF_DYNFIELD(g_comp_op[0].m_src, g_mbuf_offset, uint64_t *) = (uint64_t)&task[0];
+ - + - +
- + - ]
922 [ + - + - : 3 : g_comp_op[0].produced = 16;
+ - ]
923 [ + - + - : 3 : g_comp_op[0].status = 0;
+ - ]
924 : 3 : g_done_count = 0;
925 : 3 : task_to_resubmit = calloc(1, sizeof(struct spdk_accel_task));
926 [ + + # # ]: 3 : SPDK_CU_ASSERT_FATAL(task_to_resubmit != NULL);
927 [ + - + - : 3 : task_to_resubmit->s.iovs = &src_iovs[0];
+ - + - +
- + - ]
928 [ + - + - : 3 : task_to_resubmit->s.iovcnt = 3;
+ - + - ]
929 [ + - + - : 3 : task_to_resubmit->d.iovs = &dst_iovs[0];
+ - + - +
- + - ]
930 [ + - + - : 3 : task_to_resubmit->d.iovcnt = 3;
+ - + - ]
931 [ + - + - ]: 3 : task_to_resubmit->op_code = SPDK_ACCEL_OPC_COMPRESS;
932 [ + - + - ]: 3 : task_to_resubmit->cb_arg = args;
933 : 3 : ut_enqueue_value = FAKE_ENQUEUE_SUCCESS;
934 [ + - + - ]: 3 : ut_expected_op.private_xform = &g_decomp_xform;
935 [ + - + - ]: 3 : ut_expected_op.src.offset = 0;
936 [ + - + - : 3 : ut_expected_op.src.length = src_iovs[0].iov_len + src_iovs[1].iov_len + src_iovs[2].iov_len;
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - ]
937 : :
938 : : /* setup the src expected values */
939 [ + - + - ]: 3 : _get_mbuf_array(exp_src_mbuf, &g_expected_src_mbufs[0], SPDK_COUNTOF(exp_src_mbuf), false);
940 [ + - + - : 3 : ut_expected_op.m_src = exp_src_mbuf[0];
+ - ]
941 : :
942 [ + + + - ]: 12 : for (i = 0; i < UT_MBUFS_PER_OP; i++) {
943 [ + - + - : 9 : *RTE_MBUF_DYNFIELD(exp_src_mbuf[i], g_mbuf_offset, uint64_t *) = (uint64_t)&task[0];
+ - + - +
- + - ]
944 [ + - + - : 9 : exp_src_mbuf[i]->buf_addr = src_iovs[i].iov_base;
+ - + - +
- + - + -
+ - + - ]
945 [ + - + - : 9 : exp_src_mbuf[i]->buf_iova = spdk_vtophys(src_iovs[i].iov_base, &src_iovs[i].iov_len);
+ - + - +
- + - + -
+ - + - +
- + - +
- ]
946 [ + - + - : 9 : exp_src_mbuf[i]->buf_len = src_iovs[i].iov_len;
+ - + - +
- + - + -
+ - + - ]
947 [ + - + - : 9 : exp_src_mbuf[i]->pkt_len = src_iovs[i].iov_len;
+ - + - +
- + - + -
+ - + - ]
948 : 3 : }
949 : :
950 : : /* setup the dst expected values */
951 [ + - + - ]: 3 : _get_mbuf_array(exp_dst_mbuf, &g_expected_dst_mbufs[0], SPDK_COUNTOF(exp_dst_mbuf), false);
952 [ + - + - ]: 3 : ut_expected_op.dst.offset = 0;
953 [ + - + - : 3 : ut_expected_op.m_dst = exp_dst_mbuf[0];
+ - ]
954 : :
955 [ + + + - ]: 12 : for (i = 0; i < UT_MBUFS_PER_OP; i++) {
956 [ + - + - : 9 : exp_dst_mbuf[i]->buf_addr = dst_iovs[i].iov_base;
+ - + - +
- + - + -
+ - + - ]
957 [ + - + - : 9 : exp_dst_mbuf[i]->buf_iova = spdk_vtophys(dst_iovs[i].iov_base, &dst_iovs[i].iov_len);
+ - + - +
- + - + -
+ - + - +
- + - +
- ]
958 [ + - + - : 9 : exp_dst_mbuf[i]->buf_len = dst_iovs[i].iov_len;
+ - + - +
- + - + -
+ - + - ]
959 [ + - + - : 9 : exp_dst_mbuf[i]->pkt_len = dst_iovs[i].iov_len;
+ - + - +
- + - + -
+ - + - ]
960 : 3 : }
961 [ + - + - ]: 3 : MOCK_SET(rte_comp_op_alloc, &g_comp_op[0]);
962 [ + - + - : 3 : STAILQ_INSERT_TAIL(&g_comp_ch->queued_tasks,
+ - + - +
- + - + -
+ - + - +
- + - +
- ]
963 : : task_to_resubmit,
964 : : link);
965 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == false);
+ - ]
966 : 3 : rc = comp_dev_poller((void *)g_comp_ch);
967 [ + - + - : 3 : CU_ASSERT(STAILQ_EMPTY(&g_comp_ch->queued_tasks) == true);
+ - ]
968 : 3 : CU_ASSERT(rc == SPDK_POLLER_BUSY);
969 : :
970 : 3 : free(task_to_resubmit);
971 : 3 : free(args);
972 : 3 : }
973 : :
974 : : static void
975 : 3 : test_initdrivers(void)
976 : : {
977 : 1 : int rc;
978 : :
979 : : /* compressdev count 0 */
980 : 3 : rc = accel_init_compress_drivers();
981 : 3 : CU_ASSERT(rc == 0);
982 : :
983 : : /* bogus count */
984 : 3 : ut_rte_compressdev_count = RTE_COMPRESS_MAX_DEVS + 1;
985 : 3 : rc = accel_init_compress_drivers();
986 : 3 : CU_ASSERT(rc == -EINVAL);
987 : :
988 : : /* failure with rte_mbuf_dynfield_register */
989 : 3 : ut_rte_compressdev_count = 1;
990 : 3 : MOCK_SET(rte_mbuf_dynfield_register, -1);
991 : 3 : rc = accel_init_compress_drivers();
992 : 3 : CU_ASSERT(rc == -EINVAL);
993 : 3 : MOCK_SET(rte_mbuf_dynfield_register, DPDK_DYNFIELD_OFFSET);
994 : :
995 : : /* error on create_compress_dev() */
996 : 3 : ut_rte_comp_op_pool_create = (struct rte_mempool *)0xDEADBEEF;
997 : 3 : ut_rte_compressdev_count = 1;
998 : 3 : ut_rte_compressdev_configure = -1;
999 : 3 : rc = accel_init_compress_drivers();
1000 : 3 : CU_ASSERT(rc == -1);
1001 : :
1002 : : /* error on create_compress_dev() but coverage for large num queues */
1003 : 3 : ut_max_nb_queue_pairs = 99;
1004 : 3 : rc = accel_init_compress_drivers();
1005 : 3 : CU_ASSERT(rc == -1);
1006 : :
1007 : : /* qpair setup fails */
1008 : 3 : ut_rte_compressdev_configure = 0;
1009 : 3 : ut_max_nb_queue_pairs = 0;
1010 : 3 : ut_rte_compressdev_queue_pair_setup = -1;
1011 : 3 : rc = accel_init_compress_drivers();
1012 : 3 : CU_ASSERT(rc == -EINVAL);
1013 : :
1014 : : /* rte_compressdev_start fails */
1015 : 3 : ut_rte_compressdev_queue_pair_setup = 0;
1016 : 3 : ut_rte_compressdev_start = -1;
1017 : 3 : rc = accel_init_compress_drivers();
1018 : 3 : CU_ASSERT(rc == -1);
1019 : :
1020 : : /* rte_compressdev_private_xform_create() fails */
1021 : 3 : ut_rte_compressdev_start = 0;
1022 : 3 : ut_rte_compressdev_private_xform_create = -2;
1023 : 3 : rc = accel_init_compress_drivers();
1024 : 3 : CU_ASSERT(rc == -2);
1025 : :
1026 : : /* success */
1027 : 3 : ut_rte_compressdev_private_xform_create = 0;
1028 : 3 : rc = accel_init_compress_drivers();
1029 : 3 : CU_ASSERT(rc == 0);
1030 : 3 : }
1031 : :
1032 : : int
1033 : 3 : main(int argc, char **argv)
1034 : : {
1035 : 3 : CU_pSuite suite = NULL;
1036 : 1 : unsigned int num_failures;
1037 : :
1038 : 3 : CU_initialize_registry();
1039 : :
1040 : 3 : suite = CU_add_suite("compress", test_setup, test_cleanup);
1041 : 3 : CU_ADD_TEST(suite, test_compress_operation);
1042 : 3 : CU_ADD_TEST(suite, test_compress_operation_cross_boundary);
1043 : 3 : CU_ADD_TEST(suite, test_setup_compress_mbuf);
1044 : 3 : CU_ADD_TEST(suite, test_initdrivers);
1045 : 3 : CU_ADD_TEST(suite, test_poller);
1046 : :
1047 : 3 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
1048 : 3 : CU_cleanup_registry();
1049 : 4 : return num_failures;
1050 : 1 : }
|