1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2018 Intel Corporation. 3 * Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. 4 * All rights reserved. 5 */ 6 7 #include "spdk_cunit.h" 8 9 #include "common/lib/ut_multithread.c" 10 #include "spdk_internal/mock.h" 11 #include "thread/thread_internal.h" 12 #include "unit/lib/json_mock.c" 13 14 #include <rte_crypto.h> 15 #include <rte_cryptodev.h> 16 #include <rte_version.h> 17 18 unsigned ut_rte_crypto_op_bulk_alloc; 19 int ut_rte_crypto_op_attach_sym_session = 0; 20 #define MOCK_INFO_GET_1QP_AESNI 0 21 #define MOCK_INFO_GET_1QP_QAT 1 22 #define MOCK_INFO_GET_1QP_MLX5 2 23 #define MOCK_INFO_GET_1QP_BOGUS_PMD 3 24 int ut_rte_cryptodev_info_get = 0; 25 bool ut_rte_cryptodev_info_get_mocked = false; 26 27 #include "bdev/crypto/vbdev_crypto.c" 28 29 /* SPDK stubs */ 30 DEFINE_STUB(spdk_bdev_queue_io_wait, int, (struct spdk_bdev *bdev, struct spdk_io_channel *ch, 31 struct spdk_bdev_io_wait_entry *entry), 0); 32 DEFINE_STUB_V(spdk_bdev_module_list_add, (struct spdk_bdev_module *bdev_module)); 33 DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *g_bdev_io)); 34 DEFINE_STUB_V(spdk_bdev_io_put_aux_buf, (struct spdk_bdev_io *bdev_io, void *aux_buf)); 35 DEFINE_STUB(spdk_bdev_io_type_supported, bool, (struct spdk_bdev *bdev, 36 enum spdk_bdev_io_type io_type), 0); 37 DEFINE_STUB_V(spdk_bdev_module_release_bdev, (struct spdk_bdev *bdev)); 38 DEFINE_STUB_V(spdk_bdev_close, (struct spdk_bdev_desc *desc)); 39 DEFINE_STUB(spdk_bdev_get_name, const char *, (const struct spdk_bdev *bdev), 0); 40 DEFINE_STUB(spdk_bdev_get_buf_align, size_t, (const struct spdk_bdev *bdev), 64); 41 DEFINE_STUB(spdk_bdev_get_io_channel, struct spdk_io_channel *, (struct spdk_bdev_desc *desc), 0); 42 DEFINE_STUB_V(spdk_bdev_unregister, (struct spdk_bdev *bdev, spdk_bdev_unregister_cb cb_fn, 43 void *cb_arg)); 44 DEFINE_STUB(spdk_bdev_unregister_by_name, int, (const char *bdev_name, 45 struct spdk_bdev_module *module, 46 spdk_bdev_unregister_cb cb_fn, void *cb_arg), 0); 47 DEFINE_STUB(spdk_bdev_open_ext, int, (const char *bdev_name, bool write, 48 spdk_bdev_event_cb_t event_cb, 49 void *event_ctx, struct spdk_bdev_desc **_desc), 0); 50 DEFINE_STUB(spdk_bdev_desc_get_bdev, struct spdk_bdev *, (struct spdk_bdev_desc *desc), NULL); 51 DEFINE_STUB(spdk_bdev_module_claim_bdev, int, (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, 52 struct spdk_bdev_module *module), 0); 53 DEFINE_STUB_V(spdk_bdev_module_examine_done, (struct spdk_bdev_module *module)); 54 DEFINE_STUB(spdk_bdev_register, int, (struct spdk_bdev *vbdev), 0); 55 DEFINE_STUB_V(spdk_bdev_destruct_done, (struct spdk_bdev *bdev, int bdeverrno)); 56 57 DEFINE_STUB(spdk_accel_crypto_key_destroy, int, (struct spdk_accel_crypto_key *key), 0); 58 59 /* global vars and setup/cleanup functions used for all test functions */ 60 struct spdk_bdev_io *g_bdev_io; 61 struct crypto_bdev_io *g_io_ctx; 62 struct crypto_io_channel *g_crypto_ch; 63 struct spdk_io_channel *g_io_ch; 64 struct vbdev_crypto g_crypto_bdev; 65 struct vbdev_crypto_opts g_crypto_bdev_opts; 66 67 void 68 spdk_bdev_io_get_aux_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_aux_buf_cb cb) 69 { 70 cb(g_io_ch, g_bdev_io, (void *)0xDEADBEEF); 71 } 72 73 void 74 spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb, uint64_t len) 75 { 76 cb(g_io_ch, g_bdev_io, true); 77 } 78 79 struct ut_vbdev_crypto_bdev_cpl_args { 80 spdk_bdev_io_completion_cb cb_fn; 81 struct spdk_bdev_io *bdev_io; 82 void *cb_arg; 83 bool result; 84 }; 85 86 static void 87 _ut_vbdev_crypto_bdev_cpl(void *arg) 88 { 89 struct ut_vbdev_crypto_bdev_cpl_args *cpl_args = arg; 90 91 cpl_args->cb_fn(cpl_args->bdev_io, cpl_args->result, cpl_args->cb_arg); 92 free(cpl_args); 93 } 94 95 static void 96 ut_vbdev_crypto_bdev_cpl(spdk_bdev_io_completion_cb cb_fn, struct spdk_bdev_io *bdev_io, 97 bool result, void *cb_arg) 98 { 99 struct ut_vbdev_crypto_bdev_cpl_args *cpl_args = calloc(1, sizeof(*cpl_args)); 100 101 SPDK_CU_ASSERT_FATAL(cpl_args); 102 cpl_args->cb_fn = cb_fn; 103 cpl_args->bdev_io = bdev_io; 104 cpl_args->result = result; 105 cpl_args->cb_arg = cb_arg; 106 107 spdk_thread_send_msg(spdk_get_thread(), _ut_vbdev_crypto_bdev_cpl, cpl_args); 108 } 109 110 /* Mock these functions to call the callback and then return the value we require */ 111 DEFINE_RETURN_MOCK(spdk_bdev_readv_blocks, int); 112 int 113 spdk_bdev_readv_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 114 struct iovec *iov, int iovcnt, 115 uint64_t offset_blocks, uint64_t num_blocks, 116 spdk_bdev_io_completion_cb cb, void *cb_arg) 117 { 118 HANDLE_RETURN_MOCK(spdk_bdev_readv_blocks); 119 ut_vbdev_crypto_bdev_cpl(cb, g_bdev_io, !ut_spdk_bdev_readv_blocks, cb_arg); 120 return 0; 121 } 122 123 DEFINE_RETURN_MOCK(spdk_bdev_writev_blocks, int); 124 int 125 spdk_bdev_writev_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 126 struct iovec *iov, int iovcnt, 127 uint64_t offset_blocks, uint64_t num_blocks, 128 spdk_bdev_io_completion_cb cb, void *cb_arg) 129 { 130 HANDLE_RETURN_MOCK(spdk_bdev_writev_blocks); 131 ut_vbdev_crypto_bdev_cpl(cb, g_bdev_io, !ut_spdk_bdev_writev_blocks, cb_arg); 132 return 0; 133 } 134 135 DEFINE_RETURN_MOCK(spdk_bdev_unmap_blocks, int); 136 int 137 spdk_bdev_unmap_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 138 uint64_t offset_blocks, uint64_t num_blocks, 139 spdk_bdev_io_completion_cb cb, void *cb_arg) 140 { 141 HANDLE_RETURN_MOCK(spdk_bdev_unmap_blocks); 142 ut_vbdev_crypto_bdev_cpl(cb, g_bdev_io, !ut_spdk_bdev_unmap_blocks, cb_arg); 143 return 0; 144 } 145 146 DEFINE_RETURN_MOCK(spdk_bdev_flush_blocks, int); 147 int 148 spdk_bdev_flush_blocks(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 149 uint64_t offset_blocks, uint64_t num_blocks, spdk_bdev_io_completion_cb cb, 150 void *cb_arg) 151 { 152 HANDLE_RETURN_MOCK(spdk_bdev_flush_blocks); 153 ut_vbdev_crypto_bdev_cpl(cb, g_bdev_io, !ut_spdk_bdev_flush_blocks, cb_arg); 154 return 0; 155 } 156 157 DEFINE_RETURN_MOCK(spdk_bdev_reset, int); 158 int 159 spdk_bdev_reset(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 160 spdk_bdev_io_completion_cb cb, void *cb_arg) 161 { 162 HANDLE_RETURN_MOCK(spdk_bdev_reset); 163 ut_vbdev_crypto_bdev_cpl(cb, g_bdev_io, !ut_spdk_bdev_reset, cb_arg); 164 return 0; 165 } 166 167 bool g_completion_called = false; 168 void 169 spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io, enum spdk_bdev_io_status status) 170 { 171 bdev_io->internal.status = status; 172 g_completion_called = true; 173 } 174 175 struct ut_vbdev_crypto_accel_cpl_args { 176 spdk_accel_completion_cb cb_fn; 177 void *cb_arg; 178 int rc; 179 }; 180 181 static void 182 _vbdev_crypto_ut_accel_cpl(void *arg) 183 { 184 struct ut_vbdev_crypto_accel_cpl_args *cpl_args = arg; 185 186 cpl_args->cb_fn(cpl_args->cb_arg, cpl_args->rc); 187 free(cpl_args); 188 } 189 190 static void 191 vbdev_crypto_ut_accel_cpl(spdk_accel_completion_cb cb_fn, void *cb_arg, int rc) 192 { 193 struct ut_vbdev_crypto_accel_cpl_args *cpl_args = calloc(1, sizeof(*cpl_args)); 194 195 SPDK_CU_ASSERT_FATAL(cpl_args); 196 cpl_args->cb_fn = cb_fn; 197 cpl_args->cb_arg = cb_arg; 198 cpl_args->rc = rc; 199 200 spdk_thread_send_msg(spdk_get_thread(), _vbdev_crypto_ut_accel_cpl, cpl_args); 201 } 202 203 DEFINE_RETURN_MOCK(spdk_accel_submit_encrypt, int); 204 int ut_spdk_accel_submit_encrypt_cb_rc = 0; 205 int 206 spdk_accel_submit_encrypt(struct spdk_io_channel *ch, struct spdk_accel_crypto_key *key, 207 struct iovec *dst_iovs, uint32_t dst_iovcnt, 208 struct iovec *src_iovs, uint32_t src_iovcnt, 209 uint64_t iv, uint32_t block_size, int flags, 210 spdk_accel_completion_cb cb_fn, void *cb_arg) 211 { 212 HANDLE_RETURN_MOCK(spdk_accel_submit_encrypt); 213 /* We must not call cb_fn immediately */ 214 vbdev_crypto_ut_accel_cpl(cb_fn, cb_arg, ut_spdk_accel_submit_encrypt_cb_rc); 215 216 return 0; 217 } 218 219 int ut_spdk_accel_submit_decrypt_cb_rc; 220 DEFINE_RETURN_MOCK(spdk_accel_submit_decrypt, int); 221 int 222 spdk_accel_submit_decrypt(struct spdk_io_channel *ch, struct spdk_accel_crypto_key *key, 223 struct iovec *dst_iovs, uint32_t dst_iovcnt, 224 struct iovec *src_iovs, uint32_t src_iovcnt, 225 uint64_t iv, uint32_t block_size, int flags, 226 spdk_accel_completion_cb cb_fn, void *cb_arg) 227 { 228 HANDLE_RETURN_MOCK(spdk_accel_submit_decrypt); 229 /* We must not call cb_fn immediately */ 230 vbdev_crypto_ut_accel_cpl(cb_fn, cb_arg, ut_spdk_accel_submit_decrypt_cb_rc); 231 232 return 0; 233 } 234 235 struct spdk_io_channel *spdk_accel_get_io_channel(void) 236 { 237 return (struct spdk_io_channel *)0xfeedbeef; 238 } 239 240 /* Global setup for all tests that share a bunch of preparation... */ 241 static int 242 test_setup(void) 243 { 244 /* Prepare essential variables for test routines */ 245 g_bdev_io = calloc(1, sizeof(struct spdk_bdev_io) + sizeof(struct crypto_bdev_io)); 246 g_bdev_io->u.bdev.iovs = calloc(1, sizeof(struct iovec) * 128); 247 g_bdev_io->bdev = &g_crypto_bdev.crypto_bdev; 248 g_io_ch = calloc(1, sizeof(struct spdk_io_channel) + sizeof(struct crypto_io_channel)); 249 g_crypto_ch = (struct crypto_io_channel *)spdk_io_channel_get_ctx(g_io_ch); 250 g_io_ctx = (struct crypto_bdev_io *)g_bdev_io->driver_ctx; 251 memset(&g_crypto_bdev, 0, sizeof(struct vbdev_crypto)); 252 memset(&g_crypto_bdev_opts, 0, sizeof(struct vbdev_crypto_opts)); 253 g_crypto_bdev.crypto_bdev.blocklen = 512; 254 g_io_ctx->crypto_ch = g_crypto_ch; 255 g_io_ctx->crypto_bdev = &g_crypto_bdev; 256 g_io_ctx->crypto_bdev->opts = &g_crypto_bdev_opts; 257 TAILQ_INIT(&g_crypto_ch->in_accel_fw); 258 259 return 0; 260 } 261 262 /* Global teardown for all tests */ 263 static int 264 test_cleanup(void) 265 { 266 free(g_bdev_io->u.bdev.iovs); 267 free(g_bdev_io); 268 free(g_io_ch); 269 return 0; 270 } 271 272 static void 273 test_error_paths(void) 274 { 275 g_crypto_bdev.crypto_bdev.blocklen = 512; 276 277 g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 278 g_bdev_io->u.bdev.iovcnt = 1; 279 g_bdev_io->u.bdev.num_blocks = 1; 280 g_bdev_io->u.bdev.iovs[0].iov_len = 512; 281 g_bdev_io->u.bdev.iovs[0].iov_base = (void *)0xDEADBEEF; 282 g_bdev_io->type = SPDK_BDEV_IO_TYPE_WRITE; 283 284 /* test error returned by accel fw */ 285 MOCK_SET(spdk_accel_submit_encrypt, -ENOMEM); 286 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 287 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS); 288 CU_ASSERT(g_io_ctx->bdev_io_wait.bdev == &g_crypto_bdev.crypto_bdev); 289 CU_ASSERT(g_io_ctx->bdev_io_wait.cb_fn == vbdev_crypto_resubmit_io); 290 CU_ASSERT(g_io_ctx->bdev_io_wait.cb_arg == g_bdev_io); 291 CU_ASSERT(g_io_ctx->resubmit_state == CRYPTO_IO_NEW); 292 memset(&g_io_ctx->bdev_io_wait, 0, sizeof(g_io_ctx->bdev_io_wait)); 293 294 MOCK_SET(spdk_accel_submit_encrypt, -EINVAL); 295 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 296 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED); 297 MOCK_CLEAR(spdk_accel_submit_encrypt); 298 299 /* Test error returned in accel cpl cb */ 300 ut_spdk_accel_submit_encrypt_cb_rc = -EINVAL; 301 g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 302 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 303 poll_threads(); 304 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED); 305 ut_spdk_accel_submit_encrypt_cb_rc = 0; 306 307 /* Test error returned from bdev */ 308 g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 309 MOCK_SET(spdk_bdev_writev_blocks, -ENOMEM); 310 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 311 poll_threads(); 312 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS); 313 CU_ASSERT(g_io_ctx->bdev_io_wait.bdev == &g_crypto_bdev.crypto_bdev); 314 CU_ASSERT(g_io_ctx->bdev_io_wait.cb_fn == vbdev_crypto_resubmit_io); 315 CU_ASSERT(g_io_ctx->bdev_io_wait.cb_arg == g_bdev_io); 316 CU_ASSERT(g_io_ctx->resubmit_state == CRYPTO_IO_ENCRYPT_DONE); 317 memset(&g_io_ctx->bdev_io_wait, 0, sizeof(g_io_ctx->bdev_io_wait)); 318 MOCK_CLEAR(spdk_bdev_readv_blocks); 319 320 g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 321 MOCK_SET(spdk_bdev_writev_blocks, -EINVAL); 322 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 323 poll_threads(); 324 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED); 325 MOCK_CLEAR(spdk_bdev_writev_blocks); 326 327 /* Test error returned in bdev cpl */ 328 g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 329 ut_spdk_bdev_writev_blocks = -EINVAL; 330 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 331 poll_threads(); 332 poll_threads(); 333 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED); 334 ut_spdk_bdev_writev_blocks = 0; 335 336 /* the same for read path */ 337 /* Test error returned from bdev */ 338 g_bdev_io->type = SPDK_BDEV_IO_TYPE_READ; 339 g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 340 341 MOCK_SET(spdk_bdev_readv_blocks, -ENOMEM); 342 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 343 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS); 344 CU_ASSERT(g_io_ctx->bdev_io_wait.bdev == &g_crypto_bdev.crypto_bdev); 345 CU_ASSERT(g_io_ctx->bdev_io_wait.cb_fn == vbdev_crypto_resubmit_io); 346 CU_ASSERT(g_io_ctx->bdev_io_wait.cb_arg == g_bdev_io); 347 CU_ASSERT(g_io_ctx->resubmit_state == CRYPTO_IO_NEW); 348 memset(&g_io_ctx->bdev_io_wait, 0, sizeof(g_io_ctx->bdev_io_wait)); 349 MOCK_CLEAR(spdk_bdev_readv_blocks); 350 351 g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 352 MOCK_SET(spdk_bdev_readv_blocks, -EINVAL); 353 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 354 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED); 355 MOCK_CLEAR(spdk_bdev_readv_blocks); 356 357 /* Test error returned in bdev cpl */ 358 g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 359 ut_spdk_bdev_readv_blocks = -EINVAL; 360 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 361 poll_threads(); 362 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED); 363 ut_spdk_bdev_readv_blocks = 0; 364 365 /* test error returned by accel fw */ 366 g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 367 MOCK_SET(spdk_accel_submit_decrypt, -ENOMEM); 368 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 369 poll_threads(); 370 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS); 371 CU_ASSERT(g_io_ctx->bdev_io_wait.bdev == &g_crypto_bdev.crypto_bdev); 372 CU_ASSERT(g_io_ctx->bdev_io_wait.cb_fn == vbdev_crypto_resubmit_io); 373 CU_ASSERT(g_io_ctx->bdev_io_wait.cb_arg == g_bdev_io); 374 CU_ASSERT(g_io_ctx->resubmit_state == CRYPTO_IO_READ_DONE); 375 memset(&g_io_ctx->bdev_io_wait, 0, sizeof(g_io_ctx->bdev_io_wait)); 376 MOCK_CLEAR(spdk_accel_submit_decrypt); 377 378 /* test error returned in accel cpl */ 379 ut_spdk_accel_submit_decrypt_cb_rc = -EINVAL; 380 g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 381 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 382 poll_threads(); 383 poll_threads(); 384 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED); 385 ut_spdk_accel_submit_decrypt_cb_rc = 0; 386 387 } 388 389 static void 390 test_simple_write(void) 391 { 392 /* Single element block size write */ 393 g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 394 g_bdev_io->u.bdev.iovcnt = 1; 395 g_bdev_io->u.bdev.num_blocks = 1; 396 g_bdev_io->u.bdev.offset_blocks = 0; 397 g_bdev_io->u.bdev.iovs[0].iov_len = 512; 398 g_bdev_io->u.bdev.iovs[0].iov_base = &test_simple_write; 399 g_crypto_bdev.crypto_bdev.blocklen = 512; 400 g_bdev_io->type = SPDK_BDEV_IO_TYPE_WRITE; 401 402 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 403 /* 1st poll to trigger accel completions, 2nd for bdev */ 404 poll_threads(); 405 poll_threads(); 406 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS); 407 CU_ASSERT(g_io_ctx->aux_buf_iov.iov_len == 512); 408 CU_ASSERT(g_io_ctx->aux_buf_iov.iov_base != NULL); 409 CU_ASSERT(g_io_ctx->aux_offset_blocks == 0); 410 CU_ASSERT(g_io_ctx->aux_num_blocks == 1); 411 } 412 413 static void 414 test_simple_read(void) 415 { 416 /* Single element block size read */ 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.iovs[0].iov_len = 512; 421 g_bdev_io->u.bdev.iovs[0].iov_base = &test_simple_read; 422 g_crypto_bdev.crypto_bdev.blocklen = 512; 423 g_bdev_io->type = SPDK_BDEV_IO_TYPE_READ; 424 425 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 426 /* 1st poll to trigger dev completions, 2nd for accel */ 427 poll_threads(); 428 poll_threads(); 429 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS); 430 } 431 432 static void 433 test_passthru(void) 434 { 435 /* Make sure these follow our completion callback, test success & fail. */ 436 g_bdev_io->type = SPDK_BDEV_IO_TYPE_UNMAP; 437 MOCK_CLEAR(spdk_bdev_unmap_blocks); 438 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 439 poll_threads(); 440 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS); 441 MOCK_SET(spdk_bdev_unmap_blocks, -EINVAL); 442 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 443 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED); 444 MOCK_CLEAR(spdk_bdev_unmap_blocks); 445 446 g_bdev_io->type = SPDK_BDEV_IO_TYPE_FLUSH; 447 MOCK_CLEAR(spdk_bdev_flush_blocks); 448 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 449 poll_threads(); 450 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS); 451 MOCK_SET(spdk_bdev_flush_blocks, -EINVAL); 452 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 453 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED); 454 MOCK_CLEAR(spdk_bdev_flush_blocks); 455 456 /* We should never get a WZ command, we report that we don't support it. */ 457 g_bdev_io->type = SPDK_BDEV_IO_TYPE_WRITE_ZEROES; 458 vbdev_crypto_submit_request(g_io_ch, g_bdev_io); 459 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED); 460 } 461 462 static void 463 test_reset(void) 464 { 465 /* TODO: There are a few different ways to do this given that 466 * the code uses spdk_for_each_channel() to implement reset 467 * handling. Submitting w/o UT for this function for now and 468 * will follow up with something shortly. 469 */ 470 } 471 472 static void 473 test_crypto_op_complete(void) 474 { 475 /* Make sure completion code respects failure. */ 476 g_completion_called = false; 477 _crypto_operation_complete(g_bdev_io, -1); 478 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED); 479 CU_ASSERT(g_completion_called == true); 480 481 /* Test read completion. */ 482 g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 483 g_bdev_io->type = SPDK_BDEV_IO_TYPE_READ; 484 g_completion_called = false; 485 _crypto_operation_complete(g_bdev_io, 0); 486 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS); 487 CU_ASSERT(g_completion_called == true); 488 489 /* Test write completion success. */ 490 g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 491 g_bdev_io->type = SPDK_BDEV_IO_TYPE_WRITE; 492 g_completion_called = false; 493 MOCK_CLEAR(spdk_bdev_writev_blocks); 494 _crypto_operation_complete(g_bdev_io, 0); 495 poll_threads(); 496 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_SUCCESS); 497 CU_ASSERT(g_completion_called == true); 498 499 /* Test write completion failed. */ 500 g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 501 g_bdev_io->type = SPDK_BDEV_IO_TYPE_WRITE; 502 g_completion_called = false; 503 MOCK_SET(spdk_bdev_writev_blocks, -EINVAL); 504 _crypto_operation_complete(g_bdev_io, 0); 505 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED); 506 CU_ASSERT(g_completion_called == true); 507 MOCK_CLEAR(spdk_bdev_writev_blocks); 508 509 /* Test bogus type for this completion. */ 510 g_bdev_io->internal.status = SPDK_BDEV_IO_STATUS_SUCCESS; 511 g_bdev_io->type = SPDK_BDEV_IO_TYPE_RESET; 512 g_completion_called = false; 513 _crypto_operation_complete(g_bdev_io, 0); 514 CU_ASSERT(g_bdev_io->internal.status == SPDK_BDEV_IO_STATUS_FAILED); 515 CU_ASSERT(g_completion_called == true); 516 } 517 518 static void 519 test_supported_io(void) 520 { 521 void *ctx = NULL; 522 bool rc = true; 523 524 /* Make sure we always report false to WZ, we need the bdev layer to 525 * send real 0's so we can encrypt/decrypt them. 526 */ 527 rc = vbdev_crypto_io_type_supported(ctx, SPDK_BDEV_IO_TYPE_WRITE_ZEROES); 528 CU_ASSERT(rc == false); 529 } 530 int 531 main(int argc, char **argv) 532 { 533 CU_pSuite suite = NULL; 534 unsigned int num_failures; 535 536 CU_set_error_action(CUEA_ABORT); 537 CU_initialize_registry(); 538 539 suite = CU_add_suite("crypto", test_setup, test_cleanup); 540 CU_ADD_TEST(suite, test_error_paths); 541 CU_ADD_TEST(suite, test_simple_write); 542 CU_ADD_TEST(suite, test_simple_read); 543 CU_ADD_TEST(suite, test_passthru); 544 CU_ADD_TEST(suite, test_crypto_op_complete); 545 CU_ADD_TEST(suite, test_supported_io); 546 CU_ADD_TEST(suite, test_reset); 547 548 allocate_threads(1); 549 set_thread(0); 550 551 CU_basic_set_mode(CU_BRM_VERBOSE); 552 CU_basic_run_tests(); 553 554 free_threads(); 555 556 num_failures = CU_get_number_of_failures(); 557 CU_cleanup_registry(); 558 return num_failures; 559 } 560