xref: /spdk/test/unit/lib/bdev/crypto.c/crypto_ut.c (revision c4d9daeb7bf491bc0eb6e8d417b75d44773cb009)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk_cunit.h"
35 
36 #include "common/lib/test_env.c"
37 #include "spdk_internal/mock.h"
38 #include "unit/lib/json_mock.c"
39 
40 #include <rte_crypto.h>
41 #include <rte_cryptodev.h>
42 
43 #define MAX_TEST_BLOCKS 8192
44 struct rte_crypto_op *g_test_crypto_ops[MAX_TEST_BLOCKS];
45 struct rte_crypto_op *g_test_dev_full_ops[MAX_TEST_BLOCKS];
46 
47 uint16_t g_dequeue_mock;
48 uint16_t g_enqueue_mock;
49 unsigned ut_rte_crypto_op_bulk_alloc;
50 int ut_rte_crypto_op_attach_sym_session = 0;
51 int ut_rte_cryptodev_info_get = 0;
52 bool ut_rte_cryptodev_info_get_mocked = false;
53 
54 /* Those functions are defined as static inline in DPDK, so we can't
55  * mock them straight away. We use defines to redirect them into
56  * our custom functions.
57  */
58 #define rte_cryptodev_enqueue_burst mock_rte_cryptodev_enqueue_burst
59 static inline uint16_t
60 mock_rte_cryptodev_enqueue_burst(uint8_t dev_id, uint16_t qp_id,
61 				 struct rte_crypto_op **ops, uint16_t nb_ops)
62 {
63 	int i;
64 
65 	CU_ASSERT(nb_ops > 0);
66 
67 	for (i = 0; i < nb_ops; i++) {
68 		/* Use this empty (til now) array of pointers to store
69 		 * enqueued operations for assertion in dev_full test.
70 		 */
71 		g_test_dev_full_ops[i] = *ops++;
72 	}
73 
74 	return g_enqueue_mock;
75 }
76 
77 /* This is pretty ugly but in order to complete an IO via the
78  * poller in the submit path, we need to first call to this func
79  * to return the dequeued value and also decrement it.  On the subsequent
80  * call it needs to return 0 to indicate to the caller that there are
81  * no more IOs to drain.
82  */
83 int g_test_overflow = 0;
84 #define rte_cryptodev_dequeue_burst mock_rte_cryptodev_dequeue_burst
85 static inline uint16_t
86 mock_rte_cryptodev_dequeue_burst(uint8_t dev_id, uint16_t qp_id,
87 				 struct rte_crypto_op **ops, uint16_t nb_ops)
88 {
89 	CU_ASSERT(nb_ops > 0);
90 
91 	/* A crypto device can be full on enqueue, the driver is designed to drain
92 	 * the device at the time by calling the poller until it's empty, then
93 	 * submitting the remaining crypto ops.
94 	 */
95 	if (g_test_overflow) {
96 		if (g_dequeue_mock == 0) {
97 			return 0;
98 		}
99 		*ops = g_test_crypto_ops[g_enqueue_mock];
100 		(*ops)->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
101 		g_dequeue_mock -= 1;
102 	}
103 	return (g_dequeue_mock + 1);
104 }
105 
106 /* Instead of allocating real memory, assign the allocations to our
107  * test array for assertion in tests.
108  */
109 #define rte_crypto_op_bulk_alloc mock_rte_crypto_op_bulk_alloc
110 static inline unsigned
111 mock_rte_crypto_op_bulk_alloc(struct rte_mempool *mempool,
112 			      enum rte_crypto_op_type type,
113 			      struct rte_crypto_op **ops, uint16_t nb_ops)
114 {
115 	int i;
116 
117 	for (i = 0; i < nb_ops; i++) {
118 		*ops++ = g_test_crypto_ops[i];
119 	}
120 	return ut_rte_crypto_op_bulk_alloc;
121 }
122 
123 #define rte_mempool_put_bulk mock_rte_mempool_put_bulk
124 static __rte_always_inline void
125 mock_rte_mempool_put_bulk(struct rte_mempool *mp, void *const *obj_table,
126 			  unsigned int n)
127 {
128 	return;
129 }
130 
131 #define rte_crypto_op_attach_sym_session mock_rte_crypto_op_attach_sym_session
132 static inline int
133 mock_rte_crypto_op_attach_sym_session(struct rte_crypto_op *op,
134 				      struct rte_cryptodev_sym_session *sess)
135 {
136 	return ut_rte_crypto_op_attach_sym_session;
137 }
138 
139 #include "bdev/crypto/vbdev_crypto.c"
140 
141 /* SPDK stubs */
142 DEFINE_STUB(spdk_conf_find_section, struct spdk_conf_section *,
143 	    (struct spdk_conf *cp, const char *name), NULL);
144 DEFINE_STUB(spdk_conf_section_get_nval, char *,
145 	    (struct spdk_conf_section *sp, const char *key, int idx), NULL);
146 DEFINE_STUB(spdk_conf_section_get_nmval, char *,
147 	    (struct spdk_conf_section *sp, const char *key, int idx1, int idx2), NULL);
148 DEFINE_STUB_V(spdk_bdev_module_list_add, (struct spdk_bdev_module *bdev_module));
149 DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *g_bdev_io));
150 DEFINE_STUB(spdk_bdev_io_type_supported, bool, (struct spdk_bdev *bdev,
151 		enum spdk_bdev_io_type io_type), 0);
152 DEFINE_STUB_V(spdk_bdev_module_release_bdev, (struct spdk_bdev *bdev));
153 DEFINE_STUB_V(spdk_bdev_close, (struct spdk_bdev_desc *desc));
154 DEFINE_STUB(spdk_bdev_get_name, const char *, (const struct spdk_bdev *bdev), 0);
155 DEFINE_STUB(spdk_bdev_get_buf_align, size_t, (const struct spdk_bdev *bdev), 0);
156 DEFINE_STUB(spdk_bdev_get_io_channel, struct spdk_io_channel *, (struct spdk_bdev_desc *desc), 0);
157 DEFINE_STUB_V(spdk_bdev_unregister, (struct spdk_bdev *bdev, spdk_bdev_unregister_cb cb_fn,
158 				     void *cb_arg));
159 DEFINE_STUB(spdk_bdev_open, int, (struct spdk_bdev *bdev, bool write,
160 				  spdk_bdev_remove_cb_t remove_cb,
161 				  void *remove_ctx, struct spdk_bdev_desc **_desc), 0);
162 DEFINE_STUB(spdk_bdev_module_claim_bdev, int, (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc,
163 		struct spdk_bdev_module *module), 0);
164 DEFINE_STUB_V(spdk_bdev_module_examine_done, (struct spdk_bdev_module *module));
165 DEFINE_STUB(spdk_bdev_register, int, (struct spdk_bdev *vbdev), 0);
166 DEFINE_STUB(spdk_env_get_socket_id, uint32_t, (uint32_t core), 0);
167 
168 /* DPDK stubs */
169 DEFINE_STUB(rte_cryptodev_count, uint8_t, (void), 0);
170 DEFINE_STUB(rte_eal_get_configuration, struct rte_config *, (void), NULL);
171 DEFINE_STUB_V(rte_mempool_free, (struct rte_mempool *mp));
172 DEFINE_STUB(rte_mempool_create, struct rte_mempool *, (const char *name, unsigned n,
173 		unsigned elt_size,
174 		unsigned cache_size, unsigned private_data_size,
175 		rte_mempool_ctor_t *mp_init, void *mp_init_arg,
176 		rte_mempool_obj_cb_t *obj_init, void *obj_init_arg,
177 		int socket_id, unsigned flags), (struct rte_mempool *)1);
178 DEFINE_STUB(rte_socket_id, unsigned, (void), 0);
179 DEFINE_STUB(rte_crypto_op_pool_create, struct rte_mempool *,
180 	    (const char *name, enum rte_crypto_op_type type, unsigned nb_elts,
181 	     unsigned cache_size, uint16_t priv_size, int socket_id), (struct rte_mempool *)1);
182 DEFINE_STUB(rte_cryptodev_device_count_by_driver, uint8_t, (uint8_t driver_id), 0);
183 DEFINE_STUB(rte_cryptodev_configure, int, (uint8_t dev_id, struct rte_cryptodev_config *config), 0);
184 #if RTE_VERSION >= RTE_VERSION_NUM(19, 02, 0, 0)
185 DEFINE_STUB(rte_cryptodev_queue_pair_setup, int, (uint8_t dev_id, uint16_t queue_pair_id,
186 		const struct rte_cryptodev_qp_conf *qp_conf, int socket_id), 0);
187 DEFINE_STUB(rte_cryptodev_sym_session_pool_create, struct rte_mempool *, (const char *name,
188 		uint32_t nb_elts,
189 		uint32_t elt_size, uint32_t cache_size, uint16_t priv_size,
190 		int socket_id), (struct rte_mempool *)1);
191 #else
192 DEFINE_STUB(rte_cryptodev_queue_pair_setup, int, (uint8_t dev_id, uint16_t queue_pair_id,
193 		const struct rte_cryptodev_qp_conf *qp_conf,
194 		int socket_id, struct rte_mempool *session_pool), 0);
195 #endif
196 DEFINE_STUB(rte_cryptodev_start, int, (uint8_t dev_id), 0);
197 DEFINE_STUB_V(rte_cryptodev_stop, (uint8_t dev_id));
198 DEFINE_STUB(rte_cryptodev_sym_session_create, struct rte_cryptodev_sym_session *,
199 	    (struct rte_mempool *mempool), (struct rte_cryptodev_sym_session *)1);
200 DEFINE_STUB(rte_cryptodev_sym_session_init, int, (uint8_t dev_id,
201 		struct rte_cryptodev_sym_session *sess,
202 		struct rte_crypto_sym_xform *xforms, struct rte_mempool *mempool), 0);
203 DEFINE_STUB(rte_vdev_init, int, (const char *name, const char *args), 0);
204 DEFINE_STUB(rte_cryptodev_sym_session_free, int, (struct rte_cryptodev_sym_session *sess), 0);
205 DEFINE_STUB(rte_vdev_uninit, int, (const char *name), 0);
206 
207 struct rte_cryptodev *rte_cryptodevs;
208 
209 /* global vars and setup/cleanup functions used for all test functions */
210 struct spdk_bdev_io *g_bdev_io;
211 struct crypto_bdev_io *g_io_ctx;
212 struct crypto_io_channel *g_crypto_ch;
213 struct spdk_io_channel *g_io_ch;
214 struct vbdev_dev g_device;
215 struct vbdev_crypto g_crypto_bdev;
216 struct rte_config *g_test_config;
217 struct device_qp g_dev_qp;
218 
219 void
220 rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
221 {
222 	dev_info->max_nb_queue_pairs = ut_rte_cryptodev_info_get;
223 }
224 
225 unsigned int
226 rte_cryptodev_sym_get_private_session_size(uint8_t dev_id)
227 {
228 	return (unsigned int)dev_id;
229 }
230 
231 void
232 spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb, uint64_t len)
233 {
234 	cb(g_io_ch, g_bdev_io, true);
235 }
236 
237 /* Mock these functions to call the callback and then return the value we require */
238 int ut_spdk_bdev_readv_blocks = 0;
239 bool ut_spdk_bdev_readv_blocks_mocked = false;
240 int
241 spdk_bdev_readv_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
242 		       struct iovec *iov, int iovcnt,
243 		       uint64_t offset_blocks, uint64_t num_blocks,
244 		       spdk_bdev_io_completion_cb cb, void *cb_arg)
245 {
246 	cb(g_bdev_io, !ut_spdk_bdev_readv_blocks, cb_arg);
247 	return ut_spdk_bdev_readv_blocks;
248 }
249 
250 int ut_spdk_bdev_writev_blocks = 0;
251 bool ut_spdk_bdev_writev_blocks_mocked = false;
252 int
253 spdk_bdev_writev_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
254 			struct iovec *iov, int iovcnt,
255 			uint64_t offset_blocks, uint64_t num_blocks,
256 			spdk_bdev_io_completion_cb cb, void *cb_arg)
257 {
258 	cb(g_bdev_io, !ut_spdk_bdev_writev_blocks, cb_arg);
259 	return ut_spdk_bdev_writev_blocks;
260 }
261 
262 int ut_spdk_bdev_unmap_blocks = 0;
263 bool ut_spdk_bdev_unmap_blocks_mocked = false;
264 int
265 spdk_bdev_unmap_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
266 		       uint64_t offset_blocks, uint64_t num_blocks,
267 		       spdk_bdev_io_completion_cb cb, void *cb_arg)
268 {
269 	cb(g_bdev_io, !ut_spdk_bdev_unmap_blocks, cb_arg);
270 	return ut_spdk_bdev_unmap_blocks;
271 }
272 
273 int ut_spdk_bdev_flush_blocks = 0;
274 bool ut_spdk_bdev_flush_blocks_mocked = false;
275 int
276 spdk_bdev_flush_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
277 		       uint64_t offset_blocks, uint64_t num_blocks, spdk_bdev_io_completion_cb cb,
278 		       void *cb_arg)
279 {
280 	cb(g_bdev_io, !ut_spdk_bdev_flush_blocks, cb_arg);
281 	return ut_spdk_bdev_flush_blocks;
282 }
283 
284 int ut_spdk_bdev_reset = 0;
285 bool ut_spdk_bdev_reset_mocked = false;
286 int
287 spdk_bdev_reset(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
288 		spdk_bdev_io_completion_cb cb, void *cb_arg)
289 {
290 	cb(g_bdev_io, !ut_spdk_bdev_reset, cb_arg);
291 	return ut_spdk_bdev_reset;
292 }
293 
294 bool g_completion_called = false;
295 void
296 spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status status)
297 {
298 	bdev_io->internal.status = status;
299 	g_completion_called = true;
300 }
301 
302 /* Global setup for all tests that share a bunch of preparation... */
303 static int
304 test_setup(void)
305 {
306 	int i, rc;
307 
308 	/* Prepare essential variables for test routines */
309 	g_bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct crypto_bdev_io));
310 	g_bdev_io->u.bdev.iovs = calloc(1, sizeof(struct iovec) * 128);
311 	g_bdev_io->bdev = &g_crypto_bdev.crypto_bdev;
312 	g_io_ch = calloc(1, sizeof(struct spdk_io_channel) + sizeof(struct crypto_io_channel));
313 	g_crypto_ch = (struct crypto_io_channel *)((uint8_t *)g_io_ch + sizeof(struct spdk_io_channel));
314 	g_io_ctx = (struct crypto_bdev_io *)g_bdev_io->driver_ctx;
315 	memset(&g_device, 0, sizeof(struct vbdev_dev));
316 	memset(&g_crypto_bdev, 0, sizeof(struct vbdev_crypto));
317 	g_dev_qp.device = &g_device;
318 	g_io_ctx->crypto_ch = g_crypto_ch;
319 	g_io_ctx->crypto_bdev = &g_crypto_bdev;
320 	g_crypto_ch->device_qp = &g_dev_qp;
321 	g_test_config = calloc(1, sizeof(struct rte_config));
322 	g_test_config->lcore_count = 1;
323 	TAILQ_INIT(&g_crypto_ch->pending_cry_ios);
324 
325 	/* Allocate a real mbuf pool so we can test error paths */
326 	g_mbuf_mp = spdk_mempool_create("mbuf_mp", NUM_MBUFS, sizeof(struct rte_mbuf),
327 					SPDK_MEMPOOL_DEFAULT_CACHE_SIZE,
328 					SPDK_ENV_SOCKET_ID_ANY);
329 
330 	/* Instead of allocating real rte mempools for these, it's easier and provides the
331 	 * same coverage just calloc them here.
332 	 */
333 	for (i = 0; i < MAX_TEST_BLOCKS; i++) {
334 		rc = posix_memalign((void **)&g_test_crypto_ops[i], 64,
335 				    sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op) +
336 				    AES_CBC_IV_LENGTH);
337 		if (rc != 0) {
338 			assert(false);
339 		}
340 		memset(g_test_crypto_ops[i], 0, sizeof(struct rte_crypto_op) +
341 		       sizeof(struct rte_crypto_sym_op));
342 	}
343 	return 0;
344 }
345 
346 /* Global teardown for all tests */
347 static int
348 test_cleanup(void)
349 {
350 	int i;
351 
352 	free(g_test_config);
353 	spdk_mempool_free(g_mbuf_mp);
354 	for (i = 0; i < MAX_TEST_BLOCKS; i++) {
355 		free(g_test_crypto_ops[i]);
356 	}
357 	free(g_bdev_io->u.bdev.iovs);
358 	free(g_bdev_io);
359 	free(g_io_ch);
360 	return 0;
361 }
362 
363 static void
364 test_error_paths(void)
365 {
366 	/* Single element block size write, just to test error paths
367 	 * in vbdev_crypto_submit_request().
368 	 */
369 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
370 	g_bdev_io->u.bdev.iovcnt = 1;
371 	g_bdev_io->u.bdev.num_blocks = 1;
372 	g_bdev_io->u.bdev.iovs[0].iov_len = 512;
373 	g_crypto_bdev.crypto_bdev.blocklen = 512;
374 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_WRITE;
375 	g_enqueue_mock = g_dequeue_mock = ut_rte_crypto_op_bulk_alloc = 1;
376 
377 	/* test failure of spdk_mempool_get_bulk() */
378 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
379 	MOCK_SET(spdk_mempool_get, NULL);
380 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
381 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED);
382 
383 	/* same thing but switch to reads to test error path in _crypto_complete_io() */
384 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_READ;
385 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
386 	TAILQ_INSERT_TAIL(&g_crypto_ch->pending_cry_ios, g_bdev_io, module_link);
387 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
388 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED);
389 	/* Now with the read_blocks failing */
390 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_READ;
391 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
392 	MOCK_SET(spdk_bdev_readv_blocks, -1);
393 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
394 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED);
395 	MOCK_SET(spdk_bdev_readv_blocks, 0);
396 	MOCK_CLEAR(spdk_mempool_get);
397 
398 	/* test failure of rte_crypto_op_bulk_alloc() */
399 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
400 	ut_rte_crypto_op_bulk_alloc = 0;
401 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
402 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED);
403 	ut_rte_crypto_op_bulk_alloc = 1;
404 
405 	/* test failure of rte_crypto_op_attach_sym_session() */
406 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
407 	ut_rte_crypto_op_attach_sym_session = -1;
408 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
409 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED);
410 	ut_rte_crypto_op_attach_sym_session = 0;
411 }
412 
413 static void
414 test_simple_write(void)
415 {
416 	/* Single element block size write */
417 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
418 	g_bdev_io->u.bdev.iovcnt = 1;
419 	g_bdev_io->u.bdev.num_blocks = 1;
420 	g_bdev_io->u.bdev.offset_blocks = 0;
421 	g_bdev_io->u.bdev.iovs[0].iov_len = 512;
422 	g_bdev_io->u.bdev.iovs[0].iov_base = &test_simple_write;
423 	g_crypto_bdev.crypto_bdev.blocklen = 512;
424 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_WRITE;
425 	g_enqueue_mock = g_dequeue_mock = ut_rte_crypto_op_bulk_alloc = 1;
426 
427 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
428 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
429 	CU_ASSERT(g_io_ctx->cryop_cnt_remaining == 1);
430 	CU_ASSERT(g_io_ctx->cry_iov.iov_len == 512);
431 	CU_ASSERT(g_io_ctx->cry_iov.iov_base != NULL);
432 	CU_ASSERT(g_io_ctx->cry_offset_blocks == 0);
433 	CU_ASSERT(g_io_ctx->cry_num_blocks == 1);
434 	CU_ASSERT(g_test_crypto_ops[0]->sym->m_src->buf_addr == &test_simple_write);
435 	CU_ASSERT(g_test_crypto_ops[0]->sym->m_src->data_len == 512);
436 	CU_ASSERT(g_test_crypto_ops[0]->sym->m_src->next == NULL);
437 	CU_ASSERT(g_test_crypto_ops[0]->sym->cipher.data.length == 512);
438 	CU_ASSERT(g_test_crypto_ops[0]->sym->cipher.data.offset == 0);
439 	CU_ASSERT(g_test_crypto_ops[0]->sym->m_src->userdata == g_bdev_io);
440 	CU_ASSERT(g_test_crypto_ops[0]->sym->m_dst->buf_addr != NULL);
441 	CU_ASSERT(g_test_crypto_ops[0]->sym->m_dst->data_len == 512);
442 
443 	spdk_free(g_io_ctx->cry_iov.iov_base);
444 	spdk_mempool_put(g_mbuf_mp, g_test_crypto_ops[0]->sym->m_src);
445 	spdk_mempool_put(g_mbuf_mp, g_test_crypto_ops[0]->sym->m_dst);
446 }
447 
448 static void
449 test_simple_read(void)
450 {
451 	/* Single element block size read */
452 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
453 	g_bdev_io->u.bdev.iovcnt = 1;
454 	g_bdev_io->u.bdev.num_blocks = 1;
455 	g_bdev_io->u.bdev.iovs[0].iov_len = 512;
456 	g_bdev_io->u.bdev.iovs[0].iov_base = &test_simple_read;
457 	g_crypto_bdev.crypto_bdev.blocklen = 512;
458 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_READ;
459 	g_enqueue_mock = g_dequeue_mock = ut_rte_crypto_op_bulk_alloc = 1;
460 
461 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
462 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
463 	CU_ASSERT(g_io_ctx->cryop_cnt_remaining == 1);
464 	CU_ASSERT(g_test_crypto_ops[0]->sym->m_src->buf_addr == &test_simple_read);
465 	CU_ASSERT(g_test_crypto_ops[0]->sym->m_src->data_len == 512);
466 	CU_ASSERT(g_test_crypto_ops[0]->sym->m_src->next == NULL);
467 	CU_ASSERT(g_test_crypto_ops[0]->sym->cipher.data.length == 512);
468 	CU_ASSERT(g_test_crypto_ops[0]->sym->cipher.data.offset == 0);
469 	CU_ASSERT(g_test_crypto_ops[0]->sym->m_src->userdata == g_bdev_io);
470 	CU_ASSERT(g_test_crypto_ops[0]->sym->m_dst == NULL);
471 
472 	spdk_mempool_put(g_mbuf_mp, g_test_crypto_ops[0]->sym->m_src);
473 }
474 
475 static void
476 test_large_rw(void)
477 {
478 	unsigned block_len = 512;
479 	unsigned num_blocks = CRYPTO_MAX_IO / block_len;
480 	unsigned io_len = block_len * num_blocks;
481 	unsigned i;
482 
483 	/* Multi block size read, multi-element */
484 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
485 	g_bdev_io->u.bdev.iovcnt = 1;
486 	g_bdev_io->u.bdev.num_blocks = num_blocks;
487 	g_bdev_io->u.bdev.iovs[0].iov_len = io_len;
488 	g_bdev_io->u.bdev.iovs[0].iov_base = &test_large_rw;
489 	g_crypto_bdev.crypto_bdev.blocklen = block_len;
490 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_READ;
491 	g_enqueue_mock = g_dequeue_mock = ut_rte_crypto_op_bulk_alloc = num_blocks;
492 
493 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
494 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
495 	CU_ASSERT(g_io_ctx->cryop_cnt_remaining == (int)num_blocks);
496 
497 	for (i = 0; i < num_blocks; i++) {
498 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src->buf_addr == &test_large_rw + (i * block_len));
499 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src->data_len == block_len);
500 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src->next == NULL);
501 		CU_ASSERT(g_test_crypto_ops[i]->sym->cipher.data.length == block_len);
502 		CU_ASSERT(g_test_crypto_ops[i]->sym->cipher.data.offset == 0);
503 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src->userdata == g_bdev_io);
504 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_dst == NULL);
505 		spdk_mempool_put(g_mbuf_mp, g_test_crypto_ops[i]->sym->m_src);
506 	}
507 
508 	/* Multi block size write, multi-element */
509 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
510 	g_bdev_io->u.bdev.iovcnt = 1;
511 	g_bdev_io->u.bdev.num_blocks = num_blocks;
512 	g_bdev_io->u.bdev.iovs[0].iov_len = io_len;
513 	g_bdev_io->u.bdev.iovs[0].iov_base = &test_large_rw;
514 	g_crypto_bdev.crypto_bdev.blocklen = block_len;
515 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_WRITE;
516 	g_enqueue_mock = g_dequeue_mock = ut_rte_crypto_op_bulk_alloc = num_blocks;
517 
518 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
519 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
520 	CU_ASSERT(g_io_ctx->cryop_cnt_remaining == (int)num_blocks);
521 
522 	for (i = 0; i < num_blocks; i++) {
523 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src->buf_addr == &test_large_rw + (i * block_len));
524 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src->data_len == block_len);
525 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src->next == NULL);
526 		CU_ASSERT(g_test_crypto_ops[i]->sym->cipher.data.length == block_len);
527 		CU_ASSERT(g_test_crypto_ops[i]->sym->cipher.data.offset == 0);
528 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src->userdata == g_bdev_io);
529 		CU_ASSERT(g_io_ctx->cry_iov.iov_len == io_len);
530 		CU_ASSERT(g_io_ctx->cry_iov.iov_base != NULL);
531 		CU_ASSERT(g_io_ctx->cry_offset_blocks == 0);
532 		CU_ASSERT(g_io_ctx->cry_num_blocks == num_blocks);
533 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_dst->buf_addr != NULL);
534 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_dst->data_len == block_len);
535 		spdk_mempool_put(g_mbuf_mp, g_test_crypto_ops[i]->sym->m_src);
536 		spdk_mempool_put(g_mbuf_mp, g_test_crypto_ops[i]->sym->m_dst);
537 	}
538 	spdk_free(g_io_ctx->cry_iov.iov_base);
539 }
540 
541 static void
542 test_dev_full(void)
543 {
544 	unsigned block_len = 512;
545 	unsigned num_blocks = 2;
546 	unsigned io_len = block_len * num_blocks;
547 	unsigned i;
548 
549 	g_test_overflow = 1;
550 
551 	/* Multi block size read, multi-element */
552 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
553 	g_bdev_io->u.bdev.iovcnt = 1;
554 	g_bdev_io->u.bdev.num_blocks = num_blocks;
555 	g_bdev_io->u.bdev.iovs[0].iov_len = io_len;
556 	g_bdev_io->u.bdev.iovs[0].iov_base = &test_dev_full;
557 	g_crypto_bdev.crypto_bdev.blocklen = block_len;
558 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_READ;
559 	g_enqueue_mock = g_dequeue_mock = 1;
560 	ut_rte_crypto_op_bulk_alloc = num_blocks;
561 
562 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
563 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
564 
565 	/* this test only completes one of the 2 IOs (in the drain path) */
566 	CU_ASSERT(g_io_ctx->cryop_cnt_remaining == 1);
567 
568 	for (i = 0; i < num_blocks; i++) {
569 		/* One of the src_mbufs was freed because of the device full condition so
570 		 * we can't assert its value here.
571 		 */
572 		CU_ASSERT(g_test_dev_full_ops[i]->sym->cipher.data.length == block_len);
573 		CU_ASSERT(g_test_dev_full_ops[i]->sym->cipher.data.offset == 0);
574 		CU_ASSERT(g_test_dev_full_ops[i]->sym->m_src == g_test_dev_full_ops[i]->sym->m_src);
575 		CU_ASSERT(g_test_dev_full_ops[i]->sym->m_dst == NULL);
576 	}
577 
578 	/* Only one of the 2 blocks in the test was freed on completion by design, so
579 	 * we need to free th other one here.
580 	 */
581 	spdk_mempool_put(g_mbuf_mp, g_test_crypto_ops[0]->sym->m_src);
582 	g_test_overflow = 0;
583 }
584 
585 static void
586 test_crazy_rw(void)
587 {
588 	unsigned block_len = 512;
589 	int num_blocks = 4;
590 	int i;
591 
592 	/* Multi block size read, single element, strange IOV makeup */
593 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
594 	g_bdev_io->u.bdev.iovcnt = 3;
595 	g_bdev_io->u.bdev.num_blocks = num_blocks;
596 	g_bdev_io->u.bdev.iovs[0].iov_len = 512;
597 	g_bdev_io->u.bdev.iovs[0].iov_base = &test_crazy_rw;
598 	g_bdev_io->u.bdev.iovs[1].iov_len = 1024;
599 	g_bdev_io->u.bdev.iovs[1].iov_base = &test_crazy_rw + 512;
600 	g_bdev_io->u.bdev.iovs[2].iov_len = 512;
601 	g_bdev_io->u.bdev.iovs[2].iov_base = &test_crazy_rw + 512 + 1024;
602 
603 	g_crypto_bdev.crypto_bdev.blocklen = block_len;
604 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_READ;
605 	g_enqueue_mock = g_dequeue_mock = ut_rte_crypto_op_bulk_alloc = num_blocks;
606 
607 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
608 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
609 	CU_ASSERT(g_io_ctx->cryop_cnt_remaining == num_blocks);
610 
611 	for (i = 0; i < num_blocks; i++) {
612 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src->buf_addr == &test_crazy_rw + (i * block_len));
613 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src->data_len == block_len);
614 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src->next == NULL);
615 		CU_ASSERT(g_test_crypto_ops[i]->sym->cipher.data.length == block_len);
616 		CU_ASSERT(g_test_crypto_ops[i]->sym->cipher.data.offset == 0);
617 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src->userdata == g_bdev_io);
618 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src == g_test_crypto_ops[i]->sym->m_src);
619 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_dst == NULL);
620 		spdk_mempool_put(g_mbuf_mp, g_test_crypto_ops[i]->sym->m_src);
621 	}
622 
623 	/* Multi block size write, single element strange IOV makeup */
624 	num_blocks = 8;
625 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
626 	g_bdev_io->u.bdev.iovcnt = 4;
627 	g_bdev_io->u.bdev.num_blocks = num_blocks;
628 	g_bdev_io->u.bdev.iovs[0].iov_len = 2048;
629 	g_bdev_io->u.bdev.iovs[0].iov_base = &test_crazy_rw;
630 	g_bdev_io->u.bdev.iovs[1].iov_len = 512;
631 	g_bdev_io->u.bdev.iovs[1].iov_base = &test_crazy_rw + 2048;
632 	g_bdev_io->u.bdev.iovs[2].iov_len = 512;
633 	g_bdev_io->u.bdev.iovs[2].iov_base = &test_crazy_rw + 2048 + 512;
634 	g_bdev_io->u.bdev.iovs[3].iov_len = 1024;
635 	g_bdev_io->u.bdev.iovs[3].iov_base = &test_crazy_rw + 2048 + 512 + 512;
636 
637 	g_crypto_bdev.crypto_bdev.blocklen = block_len;
638 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_WRITE;
639 	g_enqueue_mock = g_dequeue_mock = ut_rte_crypto_op_bulk_alloc = num_blocks;
640 
641 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
642 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
643 	CU_ASSERT(g_io_ctx->cryop_cnt_remaining == num_blocks);
644 
645 	for (i = 0; i < num_blocks; i++) {
646 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src->buf_addr == &test_crazy_rw + (i * block_len));
647 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src->data_len == block_len);
648 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src->next == NULL);
649 		CU_ASSERT(g_test_crypto_ops[i]->sym->cipher.data.length == block_len);
650 		CU_ASSERT(g_test_crypto_ops[i]->sym->cipher.data.offset == 0);
651 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src->userdata == g_bdev_io);
652 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_src == g_test_crypto_ops[i]->sym->m_src);
653 		CU_ASSERT(g_test_crypto_ops[i]->sym->m_dst == g_test_crypto_ops[i]->sym->m_dst);
654 		spdk_mempool_put(g_mbuf_mp, g_test_crypto_ops[i]->sym->m_src);
655 		spdk_mempool_put(g_mbuf_mp, g_test_crypto_ops[i]->sym->m_dst);
656 	}
657 	spdk_free(g_io_ctx->cry_iov.iov_base);
658 }
659 
660 static void
661 test_passthru(void)
662 {
663 	/* Make sure these follow our completion callback, test success & fail. */
664 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_UNMAP;
665 	MOCK_SET(spdk_bdev_unmap_blocks, 0);
666 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
667 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
668 	MOCK_SET(spdk_bdev_unmap_blocks, -1);
669 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
670 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED);
671 	MOCK_CLEAR(spdk_bdev_unmap_blocks);
672 
673 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_FLUSH;
674 	MOCK_SET(spdk_bdev_flush_blocks, 0);
675 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
676 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
677 	MOCK_SET(spdk_bdev_flush_blocks, -1);
678 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
679 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED);
680 	MOCK_CLEAR(spdk_bdev_flush_blocks);
681 
682 	/* We should never get a WZ command, we report that we don't support it. */
683 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_WRITE_ZEROES;
684 	vbdev_crypto_submit_request(g_io_ch, g_bdev_io);
685 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED);
686 }
687 
688 static void
689 test_reset(void)
690 {
691 	/* TODO: There are a few different ways to do this given that
692 	 * the code uses spdk_for_each_channel() to implement reset
693 	 * handling. SUbmitting w/o UT for this function for now and
694 	 * will follow up with something shortly.
695 	 */
696 }
697 
698 static void
699 test_initdrivers(void)
700 {
701 	int rc;
702 	static struct spdk_mempool *orig_mbuf_mp;
703 	static struct rte_mempool *orig_session_mp;
704 	static struct rte_mempool *orig_session_mp_priv;
705 
706 
707 	/* These tests will alloc and free our g_mbuf_mp
708 	 * so save that off here and restore it after each test is over.
709 	 */
710 	orig_mbuf_mp = g_mbuf_mp;
711 	orig_session_mp = g_session_mp;
712 	orig_session_mp_priv = g_session_mp_priv;
713 
714 	g_session_mp_priv = NULL;
715 	g_session_mp = NULL;
716 	g_mbuf_mp = NULL;
717 
718 	/* No drivers available, not an error though */
719 	MOCK_SET(rte_eal_get_configuration, g_test_config);
720 	MOCK_SET(rte_cryptodev_count, 0);
721 	rc = vbdev_crypto_init_crypto_drivers();
722 	CU_ASSERT(rc == 0);
723 	CU_ASSERT(g_mbuf_mp == NULL);
724 	CU_ASSERT(g_session_mp == NULL);
725 	CU_ASSERT(g_session_mp_priv == NULL);
726 
727 	/* Test failure of DPDK dev init. */
728 	MOCK_SET(rte_cryptodev_count, 2);
729 	MOCK_SET(rte_vdev_init, -1);
730 	rc = vbdev_crypto_init_crypto_drivers();
731 	CU_ASSERT(rc == -EINVAL);
732 	CU_ASSERT(g_mbuf_mp == NULL);
733 	CU_ASSERT(g_session_mp == NULL);
734 	CU_ASSERT(g_session_mp_priv == NULL);
735 	MOCK_SET(rte_vdev_init, 0);
736 
737 	/* Can't create session pool. */
738 	MOCK_SET(spdk_mempool_create, NULL);
739 	rc = vbdev_crypto_init_crypto_drivers();
740 	CU_ASSERT(rc == -ENOMEM);
741 	CU_ASSERT(g_mbuf_mp == NULL);
742 	CU_ASSERT(g_session_mp == NULL);
743 	CU_ASSERT(g_session_mp_priv == NULL);
744 	MOCK_CLEAR(spdk_mempool_create);
745 
746 	/* Can't create op pool. */
747 	MOCK_SET(rte_crypto_op_pool_create, NULL);
748 	rc = vbdev_crypto_init_crypto_drivers();
749 	CU_ASSERT(rc == -ENOMEM);
750 	CU_ASSERT(g_mbuf_mp == NULL);
751 	CU_ASSERT(g_session_mp == NULL);
752 	CU_ASSERT(g_session_mp_priv == NULL);
753 	MOCK_SET(rte_crypto_op_pool_create, (struct rte_mempool *)1);
754 
755 	/* Check resources are not sufficient */
756 	MOCK_CLEARED_ASSERT(spdk_mempool_create);
757 	rc = vbdev_crypto_init_crypto_drivers();
758 	CU_ASSERT(rc == -EINVAL);
759 
760 	/* Test crypto dev configure failure. */
761 	MOCK_SET(rte_cryptodev_device_count_by_driver, 2);
762 	MOCK_SET(rte_cryptodev_info_get, 1);
763 	MOCK_SET(rte_cryptodev_configure, -1);
764 	MOCK_CLEARED_ASSERT(spdk_mempool_create);
765 	rc = vbdev_crypto_init_crypto_drivers();
766 	MOCK_SET(rte_cryptodev_configure, 0);
767 	CU_ASSERT(g_mbuf_mp == NULL);
768 	CU_ASSERT(g_session_mp == NULL);
769 	CU_ASSERT(g_session_mp_priv == NULL);
770 	CU_ASSERT(rc == -EINVAL);
771 
772 	/* Test failure of qp setup. */
773 	MOCK_SET(rte_cryptodev_queue_pair_setup, -1);
774 	MOCK_CLEARED_ASSERT(spdk_mempool_create);
775 	rc = vbdev_crypto_init_crypto_drivers();
776 	CU_ASSERT(rc == -EINVAL);
777 	CU_ASSERT(g_mbuf_mp == NULL);
778 	CU_ASSERT(g_session_mp == NULL);
779 	CU_ASSERT(g_session_mp_priv == NULL);
780 	MOCK_SET(rte_cryptodev_queue_pair_setup, 0);
781 
782 	/* Test failure of dev start. */
783 	MOCK_SET(rte_cryptodev_start, -1);
784 	MOCK_CLEARED_ASSERT(spdk_mempool_create);
785 	rc = vbdev_crypto_init_crypto_drivers();
786 	CU_ASSERT(rc == -EINVAL);
787 	CU_ASSERT(g_mbuf_mp == NULL);
788 	CU_ASSERT(g_session_mp == NULL);
789 	CU_ASSERT(g_session_mp_priv == NULL);
790 	MOCK_SET(rte_cryptodev_start, 0);
791 
792 	/* Test happy path. */
793 	MOCK_CLEARED_ASSERT(spdk_mempool_create);
794 	rc = vbdev_crypto_init_crypto_drivers();
795 	/* We don't have spdk_mempool_create mocked right now, so make sure to free the mempools. */
796 	CU_ASSERT(g_mbuf_mp != NULL);
797 	CU_ASSERT(g_session_mp != NULL);
798 	spdk_mempool_free(g_mbuf_mp);
799 	rte_mempool_free(g_session_mp);
800 	if (g_session_mp_priv != NULL) {
801 		/* g_session_mp_priv may or may not be set depending on the DPDK version */
802 		rte_mempool_free(g_session_mp_priv);
803 	}
804 	CU_ASSERT(rc == 0);
805 
806 	/* restore our initial values. */
807 	g_mbuf_mp = orig_mbuf_mp;
808 	g_session_mp = orig_session_mp;
809 	g_session_mp_priv = orig_session_mp_priv;
810 }
811 
812 static void
813 test_crypto_op_complete(void)
814 {
815 	/* Need to prove to scan-build that we are setting iov_bases properly. */
816 	void *old_iov_base;
817 	struct crypto_bdev_io *orig_ctx;
818 
819 	/* Make sure completion code respects failure. */
820 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_FAILED;
821 	g_completion_called = false;
822 	_crypto_operation_complete(g_bdev_io);
823 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED);
824 	CU_ASSERT(g_completion_called == true);
825 
826 	/* Test read completion. */
827 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
828 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_READ;
829 	g_completion_called = false;
830 	_crypto_operation_complete(g_bdev_io);
831 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
832 	CU_ASSERT(g_completion_called == true);
833 
834 	/* Test write completion success. */
835 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
836 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_WRITE;
837 	g_completion_called = false;
838 	MOCK_SET(spdk_bdev_writev_blocks, 0);
839 	/* Code under test will free this, if not ASAN will complain. */
840 	g_io_ctx->cry_iov.iov_base = spdk_malloc(16, 0x10, NULL, SPDK_ENV_LCORE_ID_ANY,
841 				     SPDK_MALLOC_DMA);
842 	orig_ctx = (struct crypto_bdev_io *)g_bdev_io->driver_ctx;
843 	old_iov_base = orig_ctx->cry_iov.iov_base;
844 	_crypto_operation_complete(g_bdev_io);
845 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS);
846 	CU_ASSERT(g_completion_called == true);
847 
848 	/* Test write completion failed. */
849 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
850 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_WRITE;
851 	g_completion_called = false;
852 	MOCK_SET(spdk_bdev_writev_blocks, -1);
853 	/* Code under test will free this, if not ASAN will complain. */
854 	g_io_ctx->cry_iov.iov_base = spdk_malloc(16, 0x40, NULL, SPDK_ENV_LCORE_ID_ANY,
855 				     SPDK_MALLOC_DMA);
856 	/* To Do: remove this garbage assert as soon as scan-build stops throwing a
857 	 * heap use after free error.
858 	 */
859 	SPDK_CU_ASSERT_FATAL(old_iov_base != orig_ctx->cry_iov.iov_base);
860 	_crypto_operation_complete(g_bdev_io);
861 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED);
862 	CU_ASSERT(g_completion_called == true);
863 
864 	/* Test bogus type for this completion. */
865 	g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS;
866 	g_bdev_io->type = SPDK_BDEV_IO_TYPE_RESET;
867 	g_completion_called = false;
868 	_crypto_operation_complete(g_bdev_io);
869 	CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED);
870 	CU_ASSERT(g_completion_called == true);
871 }
872 
873 static void
874 test_supported_io(void)
875 {
876 	void *ctx = NULL;
877 	bool rc = true;
878 
879 	/* Make sure we always report false to WZ, we need the bdev layer to
880 	 * send real 0's so we can encrypt/decrypt them.
881 	 */
882 	rc = vbdev_crypto_io_type_supported(ctx, SPDK_BDEV_IO_TYPE_WRITE_ZEROES);
883 	CU_ASSERT(rc == false);
884 }
885 
886 int
887 main(int argc, char **argv)
888 {
889 	CU_pSuite	suite = NULL;
890 	unsigned int	num_failures;
891 
892 	if (CU_initialize_registry() != CUE_SUCCESS) {
893 		return CU_get_error();
894 	}
895 
896 	suite = CU_add_suite("crypto", test_setup, test_cleanup);
897 	if (suite == NULL) {
898 		CU_cleanup_registry();
899 		return CU_get_error();
900 	}
901 
902 	if (CU_add_test(suite, "test_error_paths",
903 			test_error_paths) == NULL ||
904 	    CU_add_test(suite, "test_simple_write",
905 			test_simple_write) == NULL ||
906 	    CU_add_test(suite, "test_simple_read",
907 			test_simple_read) == NULL ||
908 	    CU_add_test(suite, "test_large_rw",
909 			test_large_rw) == NULL ||
910 	    CU_add_test(suite, "test_dev_full",
911 			test_dev_full) == NULL ||
912 	    CU_add_test(suite, "test_crazy_rw",
913 			test_crazy_rw) == NULL ||
914 	    CU_add_test(suite, "test_passthru",
915 			test_passthru) == NULL ||
916 	    CU_add_test(suite, "test_initdrivers",
917 			test_initdrivers) == NULL ||
918 	    CU_add_test(suite, "test_crypto_op_complete",
919 			test_crypto_op_complete) == NULL ||
920 	    CU_add_test(suite, "test_supported_io",
921 			test_supported_io) == NULL ||
922 	    CU_add_test(suite, "test_reset",
923 			test_reset) == NULL
924 	   ) {
925 		CU_cleanup_registry();
926 		return CU_get_error();
927 	}
928 
929 	CU_basic_set_mode(CU_BRM_VERBOSE);
930 	CU_basic_run_tests();
931 	num_failures = CU_get_number_of_failures();
932 	CU_cleanup_registry();
933 	return num_failures;
934 }
935