Commit 2ce1db8f authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Jim Harris
Browse files

ut/blob: Add test for IOV split operation



This patch adds UT for IOV split operation.
Next patch will refactor split of vectored read/write a little.

Change-Id: I77fbaf042fd894b23ad5ae846f54c28498e8e62b
Signed-off-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/422768


Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
parent 81662156
Loading
Loading
Loading
Loading
+171 −1
Original line number Diff line number Diff line
@@ -1809,6 +1809,175 @@ blob_operation_split_rw(void)
	free(payload_pattern);
}

static void
blob_operation_split_rw_iov(void)
{
	struct spdk_blob_store *bs;
	struct spdk_bs_dev *dev;
	struct spdk_blob *blob;
	struct spdk_io_channel *channel;
	struct spdk_blob_opts opts;
	spdk_blob_id blobid;
	uint64_t cluster_size;

	uint64_t payload_size;
	uint8_t *payload_read;
	uint8_t *payload_write;
	uint8_t *payload_pattern;

	uint64_t page_size;
	uint64_t pages_per_cluster;
	uint64_t pages_per_payload;

	struct iovec iov_read[2];
	struct iovec iov_write[2];

	uint64_t i;

	dev = init_dev();

	spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
	CU_ASSERT(g_bserrno == 0);
	SPDK_CU_ASSERT_FATAL(g_bs != NULL);
	bs = g_bs;

	cluster_size = spdk_bs_get_cluster_size(bs);
	page_size = spdk_bs_get_page_size(bs);
	pages_per_cluster = cluster_size / page_size;
	pages_per_payload = pages_per_cluster * 5;
	payload_size = cluster_size * 5;

	payload_read = malloc(payload_size);
	SPDK_CU_ASSERT_FATAL(payload_read != NULL);

	payload_write = malloc(payload_size);
	SPDK_CU_ASSERT_FATAL(payload_write != NULL);

	payload_pattern = malloc(payload_size);
	SPDK_CU_ASSERT_FATAL(payload_pattern != NULL);

	/* Prepare random pattern to write */
	for (i = 0; i < pages_per_payload; i++) {
		*((uint64_t *)(payload_pattern + page_size * i)) = (i + 1);
	}

	channel = spdk_bs_alloc_io_channel(bs);
	SPDK_CU_ASSERT_FATAL(channel != NULL);

	/* Create blob */
	spdk_blob_opts_init(&opts);
	opts.thin_provision = false;
	opts.num_clusters = 5;

	spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
	CU_ASSERT(g_bserrno == 0);
	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
	blobid = g_blobid;

	spdk_bs_open_blob(bs, blobid, blob_op_with_handle_complete, NULL);
	CU_ASSERT(g_bserrno == 0);
	SPDK_CU_ASSERT_FATAL(g_blob != NULL);
	blob = g_blob;

	CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);

	/* Initial read should return zeroes payload */
	memset(payload_read, 0xFF, payload_size);
	iov_read[0].iov_base = payload_read;
	iov_read[0].iov_len = cluster_size * 3;
	iov_read[1].iov_base = payload_read + cluster_size * 3;
	iov_read[1].iov_len = cluster_size * 2;
	spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL);
	CU_ASSERT(g_bserrno == 0);
	CU_ASSERT(spdk_mem_all_zero(payload_read, payload_size));

	/* First of iovs fills whole blob except last page and second of iovs writes last page
	 *  with a pattern. */
	iov_write[0].iov_base = payload_pattern;
	iov_write[0].iov_len = payload_size - page_size;
	iov_write[1].iov_base = payload_pattern;
	iov_write[1].iov_len = page_size;
	spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL);
	CU_ASSERT(g_bserrno == 0);

	/* Read whole blob and check consistency */
	memset(payload_read, 0xFF, payload_size);
	iov_read[0].iov_base = payload_read;
	iov_read[0].iov_len = cluster_size * 2;
	iov_read[1].iov_base = payload_read + cluster_size * 2;
	iov_read[1].iov_len = cluster_size * 3;
	spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL);
	CU_ASSERT(g_bserrno == 0);
	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size - page_size) == 0);
	CU_ASSERT(memcmp(payload_pattern, payload_read + payload_size - page_size, page_size) == 0);

	/* First of iovs fills only first page and second of iovs writes whole blob except
	 *  first page with a pattern. */
	iov_write[0].iov_base = payload_pattern;
	iov_write[0].iov_len = page_size;
	iov_write[1].iov_base = payload_pattern;
	iov_write[1].iov_len = payload_size - page_size;
	spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL);
	CU_ASSERT(g_bserrno == 0);

	/* Read whole blob and check consistency */
	memset(payload_read, 0xFF, payload_size);
	iov_read[0].iov_base = payload_read;
	iov_read[0].iov_len = cluster_size * 4;
	iov_read[1].iov_base = payload_read + cluster_size * 4;
	iov_read[1].iov_len = cluster_size;
	spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL);
	CU_ASSERT(g_bserrno == 0);
	CU_ASSERT(memcmp(payload_pattern, payload_read + page_size, payload_size - page_size) == 0);
	CU_ASSERT(memcmp(payload_pattern, payload_read, page_size) == 0);


	/* Fill whole blob with a pattern (5 clusters) */

	/* 1. Read test. */
	_blob_io_write_no_split(blob, channel, payload_pattern, 0, pages_per_payload,
				blob_op_complete, NULL);
	CU_ASSERT(g_bserrno == 0);

	memset(payload_read, 0xFF, payload_size);
	iov_read[0].iov_base = payload_read;
	iov_read[0].iov_len = cluster_size;
	iov_read[1].iov_base = payload_read + cluster_size;
	iov_read[1].iov_len = cluster_size * 4;
	spdk_blob_io_readv(blob, channel, iov_read, 2, 0, pages_per_payload, blob_op_complete, NULL);
	CU_ASSERT(g_bserrno == 0);
	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0);

	/* 2. Write test. */
	iov_write[0].iov_base = payload_read;
	iov_write[0].iov_len = cluster_size * 2;
	iov_write[1].iov_base = payload_read + cluster_size * 2;
	iov_write[1].iov_len = cluster_size * 3;
	spdk_blob_io_writev(blob, channel, iov_write, 2, 0, pages_per_payload, blob_op_complete, NULL);
	CU_ASSERT(g_bserrno == 0);

	memset(payload_read, 0xFF, payload_size);
	_blob_io_read_no_split(blob, channel, payload_read, 0, pages_per_payload, blob_op_complete, NULL);
	CU_ASSERT(g_bserrno == 0);
	CU_ASSERT(memcmp(payload_pattern, payload_read, payload_size) == 0);

	spdk_blob_close(blob, blob_op_complete, NULL);
	CU_ASSERT(g_bserrno == 0);

	spdk_bs_free_io_channel(channel);

	/* Unload the blob store */
	spdk_bs_unload(g_bs, bs_op_complete, NULL);
	CU_ASSERT(g_bserrno == 0);
	g_bs = NULL;
	g_blob = NULL;
	g_blobid = 0;

	free(payload_read);
	free(payload_write);
	free(payload_pattern);
}

static void
blob_unmap(void)
{
@@ -4993,7 +5162,8 @@ int main(int argc, char **argv)
		CU_add_test(suite, "blob_relations", blob_relations) == NULL ||
		CU_add_test(suite, "blob_inflate_rw", blob_inflate_rw) == NULL ||
		CU_add_test(suite, "blob_snapshot_freeze_io", blob_snapshot_freeze_io) == NULL ||
		CU_add_test(suite, "blob_operation_split_rw", blob_operation_split_rw) == NULL
		CU_add_test(suite, "blob_operation_split_rw", blob_operation_split_rw) == NULL ||
		CU_add_test(suite, "blob_operation_split_rw_iov", blob_operation_split_rw_iov) == NULL
	) {
		CU_cleanup_registry();
		return CU_get_error();