test/bdevio: fix bytes vs blocks => early return of test

blockdev_compare_and_write and blockdev_write_read check
if data_length is multiple of block size and silently
succeed if it is not. There are multiple test that test
e.g. invalid size but the actual bdev API is
never called and tested because of the early return.
The intend of this behavior presumably was to allow
to run test like e.g. the 512bytes rw test on a 4K
formatted namespace without failing. Instead of silently
succeeding which introduces the issues described this
patch changes all sizes to be multiple of block size and
removes the test for valid block size to let the
return value of the bdev API functions indicate failure like
intended. All previous 4k tests are now performing io of
1 block size. Previous 512byte tests now perform
8 * block size (to have 4k test size for 512byte formatted
namespaces). Write zeroes test are now using the
write zeroes buffer size instead of a hardcoded value
and align accordingly to block size io.
Furthermore, no cmp&write test is ever executed because
data_length is set to 1 trying to indicate 1 block but
it is tested against valid block bytes and silently
succeeded. Also write and read helpers in cmp&write test
expect bytes not blocks. For consistency use bytes in the
test and only convert to blocks when calling the cmp&write
blocks API.

Signed-off-by: Jonas Pfefferle <pepperjo@japf.ch>
Change-Id: I662094c2bcd08c0e9dc5573177a2e7a0edd275ce
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12382
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Jonas Pfefferle 2022-04-19 11:15:15 +02:00 committed by Jim Harris
parent 4e241cba01
commit a6e0224634

View File

@ -218,6 +218,15 @@ quick_test_complete(struct spdk_bdev_io *bdev_io, bool success, void *arg)
wake_ut_thread(); wake_ut_thread();
} }
static uint64_t
bdev_bytes_to_blocks(struct spdk_bdev *bdev, uint64_t bytes)
{
uint32_t block_size = spdk_bdev_get_block_size(bdev);
CU_ASSERT(bytes % block_size == 0);
return bytes / block_size;
}
static void static void
__blockdev_write(void *arg) __blockdev_write(void *arg)
{ {
@ -259,10 +268,12 @@ __blockdev_compare_and_write(void *arg)
{ {
struct bdevio_request *req = arg; struct bdevio_request *req = arg;
struct io_target *target = req->target; struct io_target *target = req->target;
struct spdk_bdev *bdev = target->bdev;
int rc; int rc;
rc = spdk_bdev_comparev_and_writev_blocks(target->bdev_desc, target->ch, req->iov, req->iovcnt, rc = spdk_bdev_comparev_and_writev_blocks(target->bdev_desc, target->ch, req->iov, req->iovcnt,
req->fused_iov, req->fused_iovcnt, req->offset, req->data_len, quick_test_complete, NULL); req->fused_iov, req->fused_iovcnt, bdev_bytes_to_blocks(bdev, req->offset),
bdev_bytes_to_blocks(bdev, req->data_len), quick_test_complete, NULL);
if (rc) { if (rc) {
g_completion_success = false; g_completion_success = false;
@ -425,18 +436,6 @@ blockdev_write_read_data_match(char *rx_buf, char *tx_buf, int data_length)
return rc; return rc;
} }
static bool
blockdev_io_valid_blocks(struct spdk_bdev *bdev, uint64_t data_length)
{
if (data_length < spdk_bdev_get_block_size(bdev) ||
data_length % spdk_bdev_get_block_size(bdev) ||
data_length / spdk_bdev_get_block_size(bdev) > spdk_bdev_get_num_blocks(bdev)) {
return false;
}
return true;
}
static void static void
blockdev_write_read(uint32_t data_length, uint32_t iov_len, int pattern, uint64_t offset, blockdev_write_read(uint32_t data_length, uint32_t iov_len, int pattern, uint64_t offset,
int expected_rc, bool write_zeroes) int expected_rc, bool write_zeroes)
@ -448,10 +447,6 @@ blockdev_write_read(uint32_t data_length, uint32_t iov_len, int pattern, uint64_
target = g_current_io_target; target = g_current_io_target;
if (!blockdev_io_valid_blocks(target->bdev, data_length)) {
return;
}
if (!write_zeroes) { if (!write_zeroes) {
initialize_buffer(&tx_buf, pattern, data_length); initialize_buffer(&tx_buf, pattern, data_length);
initialize_buffer(&rx_buf, 0, data_length); initialize_buffer(&rx_buf, 0, data_length);
@ -497,10 +492,6 @@ blockdev_compare_and_write(uint32_t data_length, uint32_t iov_len, uint64_t offs
target = g_current_io_target; target = g_current_io_target;
if (!blockdev_io_valid_blocks(target->bdev, data_length)) {
return;
}
initialize_buffer(&tx_buf, 0xAA, data_length); initialize_buffer(&tx_buf, 0xAA, data_length);
initialize_buffer(&rx_buf, 0, data_length); initialize_buffer(&rx_buf, 0, data_length);
initialize_buffer(&write_buf, 0xBB, data_length); initialize_buffer(&write_buf, 0xBB, data_length);
@ -523,15 +514,17 @@ blockdev_compare_and_write(uint32_t data_length, uint32_t iov_len, uint64_t offs
} }
static void static void
blockdev_write_read_4k(void) blockdev_write_read_block(void)
{ {
uint32_t data_length; uint32_t data_length;
uint64_t offset; uint64_t offset;
int pattern; int pattern;
int expected_rc; int expected_rc;
struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev = target->bdev;
/* Data size = 4K */ /* Data size = 1 block */
data_length = 4096; data_length = spdk_bdev_get_block_size(bdev);
CU_ASSERT_TRUE(data_length < BUFFER_SIZE); CU_ASSERT_TRUE(data_length < BUFFER_SIZE);
offset = 0; offset = 0;
pattern = 0xA3; pattern = 0xA3;
@ -543,15 +536,17 @@ blockdev_write_read_4k(void)
} }
static void static void
blockdev_write_zeroes_read_4k(void) blockdev_write_zeroes_read_block(void)
{ {
uint32_t data_length; uint32_t data_length;
uint64_t offset; uint64_t offset;
int pattern; int pattern;
int expected_rc; int expected_rc;
struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev = target->bdev;
/* Data size = 4K */ /* Data size = 1 block */
data_length = 4096; data_length = spdk_bdev_get_block_size(bdev);
offset = 0; offset = 0;
pattern = 0xA3; pattern = 0xA3;
/* Params are valid, hence the expected return value /* Params are valid, hence the expected return value
@ -571,8 +566,12 @@ blockdev_write_zeroes_read_no_split(void)
uint64_t offset; uint64_t offset;
int pattern; int pattern;
int expected_rc; int expected_rc;
struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev = target->bdev;
/* Data size = block size aligned ZERO_BUFFER_SIZE */
data_length = ZERO_BUFFER_SIZE; /* from bdev_internal.h */ data_length = ZERO_BUFFER_SIZE; /* from bdev_internal.h */
data_length -= ZERO_BUFFER_SIZE % spdk_bdev_get_block_size(bdev);
offset = 0; offset = 0;
pattern = 0xA3; pattern = 0xA3;
/* Params are valid, hence the expected return value /* Params are valid, hence the expected return value
@ -593,8 +592,12 @@ blockdev_write_zeroes_read_split(void)
uint64_t offset; uint64_t offset;
int pattern; int pattern;
int expected_rc; int expected_rc;
struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev = target->bdev;
/* Data size = block size aligned 3 * ZERO_BUFFER_SIZE */
data_length = 3 * ZERO_BUFFER_SIZE; /* from bdev_internal.h */ data_length = 3 * ZERO_BUFFER_SIZE; /* from bdev_internal.h */
data_length -= data_length % spdk_bdev_get_block_size(bdev);
offset = 0; offset = 0;
pattern = 0xA3; pattern = 0xA3;
/* Params are valid, hence the expected return value /* Params are valid, hence the expected return value
@ -617,8 +620,13 @@ blockdev_write_zeroes_read_split_partial(void)
uint64_t offset; uint64_t offset;
int pattern; int pattern;
int expected_rc; int expected_rc;
struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev = target->bdev;
uint32_t block_size = spdk_bdev_get_block_size(bdev);
/* Data size = block size aligned 7 * ZERO_BUFFER_SIZE / 2 */
data_length = ZERO_BUFFER_SIZE * 7 / 2; data_length = ZERO_BUFFER_SIZE * 7 / 2;
data_length -= data_length % block_size;
offset = 0; offset = 0;
pattern = 0xA3; pattern = 0xA3;
/* Params are valid, hence the expected return value /* Params are valid, hence the expected return value
@ -629,16 +637,18 @@ blockdev_write_zeroes_read_split_partial(void)
} }
static void static void
blockdev_writev_readv_4k(void) blockdev_writev_readv_block(void)
{ {
uint32_t data_length, iov_len; uint32_t data_length, iov_len;
uint64_t offset; uint64_t offset;
int pattern; int pattern;
int expected_rc; int expected_rc;
struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev = target->bdev;
/* Data size = 4K */ /* Data size = 1 block */
data_length = 4096; data_length = spdk_bdev_get_block_size(bdev);
iov_len = 4096; iov_len = data_length;
CU_ASSERT_TRUE(data_length < BUFFER_SIZE); CU_ASSERT_TRUE(data_length < BUFFER_SIZE);
offset = 0; offset = 0;
pattern = 0xA3; pattern = 0xA3;
@ -654,9 +664,12 @@ blockdev_comparev_and_writev(void)
{ {
uint32_t data_length, iov_len; uint32_t data_length, iov_len;
uint64_t offset; uint64_t offset;
struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev = target->bdev;
data_length = 1; /* Data size = acwu size */
iov_len = 1; data_length = spdk_bdev_get_block_size(bdev) * spdk_bdev_get_acwu(bdev);
iov_len = data_length;
CU_ASSERT_TRUE(data_length < BUFFER_SIZE); CU_ASSERT_TRUE(data_length < BUFFER_SIZE);
offset = 0; offset = 0;
@ -664,16 +677,19 @@ blockdev_comparev_and_writev(void)
} }
static void static void
blockdev_writev_readv_30x4k(void) blockdev_writev_readv_30x1block(void)
{ {
uint32_t data_length, iov_len; uint32_t data_length, iov_len;
uint64_t offset; uint64_t offset;
int pattern; int pattern;
int expected_rc; int expected_rc;
struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev = target->bdev;
uint32_t block_size = spdk_bdev_get_block_size(bdev);
/* Data size = 4K */ /* Data size = 30 * block size */
data_length = 4096 * 30; data_length = block_size * 30;
iov_len = 4096; iov_len = block_size;
CU_ASSERT_TRUE(data_length < BUFFER_SIZE); CU_ASSERT_TRUE(data_length < BUFFER_SIZE);
offset = 0; offset = 0;
pattern = 0xA3; pattern = 0xA3;
@ -685,17 +701,19 @@ blockdev_writev_readv_30x4k(void)
} }
static void static void
blockdev_write_read_512Bytes(void) blockdev_write_read_8blocks(void)
{ {
uint32_t data_length; uint32_t data_length;
uint64_t offset; uint64_t offset;
int pattern; int pattern;
int expected_rc; int expected_rc;
struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev = target->bdev;
/* Data size = 512 */ /* Data size = 8 * block size */
data_length = 512; data_length = spdk_bdev_get_block_size(bdev) * 8;
CU_ASSERT_TRUE(data_length < BUFFER_SIZE); CU_ASSERT_TRUE(data_length < BUFFER_SIZE);
offset = 8192; offset = data_length;
pattern = 0xA3; pattern = 0xA3;
/* Params are valid, hence the expected return value /* Params are valid, hence the expected return value
* of write and read for all blockdevs is 0. */ * of write and read for all blockdevs is 0. */
@ -705,18 +723,20 @@ blockdev_write_read_512Bytes(void)
} }
static void static void
blockdev_writev_readv_512Bytes(void) blockdev_writev_readv_8blocks(void)
{ {
uint32_t data_length, iov_len; uint32_t data_length, iov_len;
uint64_t offset; uint64_t offset;
int pattern; int pattern;
int expected_rc; int expected_rc;
struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev = target->bdev;
/* Data size = 512 */ /* Data size = 8 * block size */
data_length = 512; data_length = spdk_bdev_get_block_size(bdev) * 8;
iov_len = 512; iov_len = data_length;
CU_ASSERT_TRUE(data_length < BUFFER_SIZE); CU_ASSERT_TRUE(data_length < BUFFER_SIZE);
offset = 8192; offset = data_length;
pattern = 0xA3; pattern = 0xA3;
/* Params are valid, hence the expected return value /* Params are valid, hence the expected return value
* of write and read for all blockdevs is 0. */ * of write and read for all blockdevs is 0. */
@ -732,11 +752,16 @@ blockdev_write_read_size_gt_128k(void)
uint64_t offset; uint64_t offset;
int pattern; int pattern;
int expected_rc; int expected_rc;
struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev = target->bdev;
uint32_t block_size = spdk_bdev_get_block_size(bdev);
/* Data size = 132K */ /* Data size = block size aligned 128K + 1 block */
data_length = 135168; data_length = 128 * 1024;
data_length -= data_length % block_size;
data_length += block_size;
CU_ASSERT_TRUE(data_length < BUFFER_SIZE); CU_ASSERT_TRUE(data_length < BUFFER_SIZE);
offset = 8192; offset = block_size * 2;
pattern = 0xA3; pattern = 0xA3;
/* Params are valid, hence the expected return value /* Params are valid, hence the expected return value
* of write and read for all blockdevs is 0. */ * of write and read for all blockdevs is 0. */
@ -752,12 +777,17 @@ blockdev_writev_readv_size_gt_128k(void)
uint64_t offset; uint64_t offset;
int pattern; int pattern;
int expected_rc; int expected_rc;
struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev = target->bdev;
uint32_t block_size = spdk_bdev_get_block_size(bdev);
/* Data size = 132K */ /* Data size = block size aligned 128K + 1 block */
data_length = 135168; data_length = 128 * 1024;
iov_len = 135168; data_length -= data_length % block_size;
data_length += block_size;
iov_len = data_length;
CU_ASSERT_TRUE(data_length < BUFFER_SIZE); CU_ASSERT_TRUE(data_length < BUFFER_SIZE);
offset = 8192; offset = block_size * 2;
pattern = 0xA3; pattern = 0xA3;
/* Params are valid, hence the expected return value /* Params are valid, hence the expected return value
* of write and read for all blockdevs is 0. */ * of write and read for all blockdevs is 0. */
@ -773,12 +803,17 @@ blockdev_writev_readv_size_gt_128k_two_iov(void)
uint64_t offset; uint64_t offset;
int pattern; int pattern;
int expected_rc; int expected_rc;
struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev = target->bdev;
uint32_t block_size = spdk_bdev_get_block_size(bdev);
/* Data size = 132K */ /* Data size = block size aligned 128K + 1 block */
data_length = 135168; data_length = 128 * 1024;
iov_len = 128 * 1024; data_length -= data_length % block_size;
iov_len = data_length;
data_length += block_size;
CU_ASSERT_TRUE(data_length < BUFFER_SIZE); CU_ASSERT_TRUE(data_length < BUFFER_SIZE);
offset = 8192; offset = block_size * 2;
pattern = 0xA3; pattern = 0xA3;
/* Params are valid, hence the expected return value /* Params are valid, hence the expected return value
* of write and read for all blockdevs is 0. */ * of write and read for all blockdevs is 0. */
@ -794,11 +829,14 @@ blockdev_write_read_invalid_size(void)
uint64_t offset; uint64_t offset;
int pattern; int pattern;
int expected_rc; int expected_rc;
struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev = target->bdev;
uint32_t block_size = spdk_bdev_get_block_size(bdev);
/* Data size is not a multiple of the block size */ /* Data size is not a multiple of the block size */
data_length = 0x1015; data_length = block_size - 1;
CU_ASSERT_TRUE(data_length < BUFFER_SIZE); CU_ASSERT_TRUE(data_length < BUFFER_SIZE);
offset = 8192; offset = block_size * 2;
pattern = 0xA3; pattern = 0xA3;
/* Params are invalid, hence the expected return value /* Params are invalid, hence the expected return value
* of write and read for all blockdevs is < 0 */ * of write and read for all blockdevs is < 0 */
@ -846,16 +884,17 @@ blockdev_write_read_offset_plus_nbytes_equals_bdev_size(void)
static void static void
blockdev_write_read_offset_plus_nbytes_gt_bdev_size(void) blockdev_write_read_offset_plus_nbytes_gt_bdev_size(void)
{ {
struct io_target *target; struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev; struct spdk_bdev *bdev = target->bdev;
char *tx_buf = NULL; char *tx_buf = NULL;
char *rx_buf = NULL; char *rx_buf = NULL;
int data_length; int data_length;
uint64_t offset; uint64_t offset;
int pattern; int pattern;
uint32_t block_size = spdk_bdev_get_block_size(bdev);
/* Tests the overflow condition of the blockdevs. */ /* Tests the overflow condition of the blockdevs. */
data_length = 4096; data_length = block_size * 2;
CU_ASSERT_TRUE(data_length < BUFFER_SIZE); CU_ASSERT_TRUE(data_length < BUFFER_SIZE);
pattern = 0xA3; pattern = 0xA3;
@ -865,7 +904,7 @@ blockdev_write_read_offset_plus_nbytes_gt_bdev_size(void)
/* The start offset has been set to a valid value /* The start offset has been set to a valid value
* but offset + nbytes is greater than the Total size * but offset + nbytes is greater than the Total size
* of the blockdev. The test should fail. */ * of the blockdev. The test should fail. */
offset = ((spdk_bdev_get_num_blocks(bdev) * spdk_bdev_get_block_size(bdev)) - 1024); offset = (spdk_bdev_get_num_blocks(bdev) - 1) * block_size;
initialize_buffer(&tx_buf, pattern, data_length); initialize_buffer(&tx_buf, pattern, data_length);
initialize_buffer(&rx_buf, 0, data_length); initialize_buffer(&rx_buf, 0, data_length);
@ -884,8 +923,10 @@ blockdev_write_read_max_offset(void)
uint64_t offset; uint64_t offset;
int pattern; int pattern;
int expected_rc; int expected_rc;
struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev = target->bdev;
data_length = 4096; data_length = spdk_bdev_get_block_size(bdev);
CU_ASSERT_TRUE(data_length < BUFFER_SIZE); CU_ASSERT_TRUE(data_length < BUFFER_SIZE);
/* The start offset has been set to UINT64_MAX such that /* The start offset has been set to UINT64_MAX such that
* adding nbytes wraps around and points to an invalid address. */ * adding nbytes wraps around and points to an invalid address. */
@ -899,15 +940,17 @@ blockdev_write_read_max_offset(void)
} }
static void static void
blockdev_overlapped_write_read_8k(void) blockdev_overlapped_write_read_2blocks(void)
{ {
int data_length; int data_length;
uint64_t offset; uint64_t offset;
int pattern; int pattern;
int expected_rc; int expected_rc;
struct io_target *target = g_current_io_target;
struct spdk_bdev *bdev = target->bdev;
/* Data size = 8K */ /* Data size = 2 blocks */
data_length = 8192; data_length = spdk_bdev_get_block_size(bdev) * 2;
CU_ASSERT_TRUE(data_length < BUFFER_SIZE); CU_ASSERT_TRUE(data_length < BUFFER_SIZE);
offset = 0; offset = 0;
pattern = 0xA3; pattern = 0xA3;
@ -918,13 +961,13 @@ blockdev_overlapped_write_read_8k(void)
* from the same offset for each blockdev */ * from the same offset for each blockdev */
blockdev_write_read(data_length, 0, pattern, offset, expected_rc, 0); blockdev_write_read(data_length, 0, pattern, offset, expected_rc, 0);
/* Overwrite the pattern 0xbb of size 8K on an address offset overlapping /* Overwrite the pattern 0xbb of size 2*block size on an address offset
* with the address written above and assert the new value in * overlapping with the address written above and assert the new value in
* the overlapped address range */ * the overlapped address range */
/* Populate 8k with value 0xBB */ /* Populate 2*block size with value 0xBB */
pattern = 0xBB; pattern = 0xBB;
/* Offset = 6144; Overlap offset addresses and write value 0xbb */ /* Offset = 1 block; Overlap offset addresses and write value 0xbb */
offset = 4096; offset = spdk_bdev_get_block_size(bdev);
/* Assert the write by comparing it with values read /* Assert the write by comparing it with values read
* from the overlapped offset for each blockdev */ * from the overlapped offset for each blockdev */
blockdev_write_read(data_length, 0, pattern, offset, expected_rc, 0); blockdev_write_read(data_length, 0, pattern, offset, expected_rc, 0);
@ -1171,17 +1214,20 @@ __setup_ut_on_single_target(struct io_target *target)
} }
if ( if (
CU_add_test(suite, "blockdev write read 4k", blockdev_write_read_4k) == NULL CU_add_test(suite, "blockdev write read block",
|| CU_add_test(suite, "blockdev write zeroes read 4k", blockdev_write_zeroes_read_4k) == NULL blockdev_write_read_block) == NULL
|| CU_add_test(suite, "blockdev write zeroes read block",
blockdev_write_zeroes_read_block) == NULL
|| CU_add_test(suite, "blockdev write zeroes read no split", || CU_add_test(suite, "blockdev write zeroes read no split",
blockdev_write_zeroes_read_no_split) == NULL blockdev_write_zeroes_read_no_split) == NULL
|| CU_add_test(suite, "blockdev write zeroes read split", blockdev_write_zeroes_read_split) == NULL || CU_add_test(suite, "blockdev write zeroes read split",
blockdev_write_zeroes_read_split) == NULL
|| CU_add_test(suite, "blockdev write zeroes read split partial", || CU_add_test(suite, "blockdev write zeroes read split partial",
blockdev_write_zeroes_read_split_partial) == NULL blockdev_write_zeroes_read_split_partial) == NULL
|| CU_add_test(suite, "blockdev reset", || CU_add_test(suite, "blockdev reset",
blockdev_test_reset) == NULL blockdev_test_reset) == NULL
|| CU_add_test(suite, "blockdev write read 512 bytes", || CU_add_test(suite, "blockdev write read 8 blocks",
blockdev_write_read_512Bytes) == NULL blockdev_write_read_8blocks) == NULL
|| CU_add_test(suite, "blockdev write read size > 128k", || CU_add_test(suite, "blockdev write read size > 128k",
blockdev_write_read_size_gt_128k) == NULL blockdev_write_read_size_gt_128k) == NULL
|| CU_add_test(suite, "blockdev write read invalid size", || CU_add_test(suite, "blockdev write read invalid size",
@ -1192,18 +1238,20 @@ __setup_ut_on_single_target(struct io_target *target)
blockdev_write_read_offset_plus_nbytes_gt_bdev_size) == NULL blockdev_write_read_offset_plus_nbytes_gt_bdev_size) == NULL
|| CU_add_test(suite, "blockdev write read max offset", || CU_add_test(suite, "blockdev write read max offset",
blockdev_write_read_max_offset) == NULL blockdev_write_read_max_offset) == NULL
|| CU_add_test(suite, "blockdev write read 8k on overlapped address offset", || CU_add_test(suite, "blockdev write read 2 blocks on overlapped address offset",
blockdev_overlapped_write_read_8k) == NULL blockdev_overlapped_write_read_2blocks) == NULL
|| CU_add_test(suite, "blockdev writev readv 4k", blockdev_writev_readv_4k) == NULL || CU_add_test(suite, "blockdev writev readv 8 blocks",
|| CU_add_test(suite, "blockdev writev readv 30 x 4k", blockdev_writev_readv_8blocks) == NULL
blockdev_writev_readv_30x4k) == NULL || CU_add_test(suite, "blockdev writev readv 30 x 1block",
|| CU_add_test(suite, "blockdev writev readv 512 bytes", blockdev_writev_readv_30x1block) == NULL
blockdev_writev_readv_512Bytes) == NULL || CU_add_test(suite, "blockdev writev readv block",
blockdev_writev_readv_block) == NULL
|| CU_add_test(suite, "blockdev writev readv size > 128k", || CU_add_test(suite, "blockdev writev readv size > 128k",
blockdev_writev_readv_size_gt_128k) == NULL blockdev_writev_readv_size_gt_128k) == NULL
|| CU_add_test(suite, "blockdev writev readv size > 128k in two iovs", || CU_add_test(suite, "blockdev writev readv size > 128k in two iovs",
blockdev_writev_readv_size_gt_128k_two_iov) == NULL blockdev_writev_readv_size_gt_128k_two_iov) == NULL
|| CU_add_test(suite, "blockdev comparev and writev", blockdev_comparev_and_writev) == NULL || CU_add_test(suite, "blockdev comparev and writev",
blockdev_comparev_and_writev) == NULL
|| CU_add_test(suite, "blockdev nvme passthru rw", || CU_add_test(suite, "blockdev nvme passthru rw",
blockdev_test_nvme_passthru_rw) == NULL blockdev_test_nvme_passthru_rw) == NULL
|| CU_add_test(suite, "blockdev nvme passthru vendor specific", || CU_add_test(suite, "blockdev nvme passthru vendor specific",