Commit a6b19922 authored by Maciej Szwed's avatar Maciej Szwed Committed by Darek Stojaczyk
Browse files

blobstore/ut: Delete snapshot and power failure unit test



This is unit test for power failure event during snapshot
deletion. At the same time this is an example how to
use new power failure event functionality in unit tests.

Signed-off-by: default avatarMaciej Szwed <maciej.szwed@intel.com>
Change-Id: I9212392f665576fa16edd28c609199d0e02dc434
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/454608


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
parent bfda995b
Loading
Loading
Loading
Loading
+118 −0
Original line number Diff line number Diff line
@@ -6239,6 +6239,122 @@ blob_relations2(void)
	g_bs = NULL;
}

static void
blob_delete_snapshot_power_failure(void)
{
	struct spdk_blob_store *bs;
	struct spdk_bs_dev *dev;
	struct spdk_blob_opts opts;
	struct spdk_blob *blob, *snapshot;
	struct spdk_power_failure_thresholds thresholds = {};
	spdk_blob_id blobid, snapshotid;
	const void *value;
	size_t value_len;
	size_t count;
	spdk_blob_id ids[3] = {};
	int rc;
	bool deleted = false;

	dev = init_dev();

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

	/* Create blob */
	spdk_blob_opts_init(&opts);
	opts.num_clusters = 10;

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

	/* Create snapshot */
	spdk_bs_create_snapshot(bs, blobid, NULL, blob_op_with_id_complete, NULL);
	poll_threads();
	CU_ASSERT(g_bserrno == 0);
	CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
	snapshotid = g_blobid;

	thresholds.general_threshold = 1;
	while (!deleted) {
		dev_set_power_failure_thresholds(thresholds);

		spdk_bs_delete_blob(bs, snapshotid, blob_op_complete, NULL);
		poll_threads();
		CU_ASSERT(g_bserrno != 0);

		spdk_bs_unload(g_bs, bs_op_complete, NULL);
		poll_threads();

		dev_reset_power_failure_event();

		dev = init_dev();
		spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
		poll_threads();
		CU_ASSERT(g_bserrno == 0);
		SPDK_CU_ASSERT_FATAL(g_bs != NULL);
		bs = g_bs;

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

		spdk_bs_open_blob(bs, snapshotid, blob_op_with_handle_complete, NULL);
		poll_threads();

		if (g_bserrno == 0) {
			SPDK_CU_ASSERT_FATAL(g_blob != NULL);
			snapshot = g_blob;
			CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == snapshotid);
			count = SPDK_COUNTOF(ids);
			rc = spdk_blob_get_clones(bs, snapshotid, ids, &count);
			CU_ASSERT(rc == 0);
			CU_ASSERT(count == 1);
			CU_ASSERT(ids[0] == blobid);
			rc = spdk_blob_get_xattr_value(snapshot, SNAPSHOT_PENDING_REMOVAL, &value, &value_len);
			CU_ASSERT(rc != 0);

			spdk_blob_close(snapshot, blob_op_complete, NULL);
			poll_threads();
			CU_ASSERT(g_bserrno == 0);
		} else {
			CU_ASSERT(spdk_blob_get_parent_snapshot(bs, blobid) == SPDK_BLOBID_INVALID);
			deleted = true;
		}

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

		/* Reload blobstore to have the same starting conditions (as the previous blobstore load
		 * may trigger cleanup after power failure or may not) */
		spdk_bs_unload(g_bs, bs_op_complete, NULL);
		poll_threads();
		CU_ASSERT(g_bserrno == 0);

		dev = init_dev();
		spdk_bs_load(dev, NULL, bs_op_with_handle_complete, NULL);
		poll_threads();
		CU_ASSERT(g_bserrno == 0);
		SPDK_CU_ASSERT_FATAL(g_bs != NULL);
		bs = g_bs;

		thresholds.general_threshold++;
	}

	spdk_bs_unload(g_bs, bs_op_complete, NULL);
	poll_threads();
	CU_ASSERT(g_bserrno == 0);
	g_bs = NULL;
}

static void
test_io_write(struct spdk_bs_dev *dev, struct spdk_blob *blob, struct spdk_io_channel *channel)
{
@@ -7199,6 +7315,8 @@ int main(int argc, char **argv)
		CU_add_test(suite, "blob_snapshot_rw_iov", blob_snapshot_rw_iov) == NULL ||
		CU_add_test(suite, "blob_relations", blob_relations) == NULL ||
		CU_add_test(suite, "blob_relations2", blob_relations2) == NULL ||
		CU_add_test(suite, "blob_delete_snapshot_power_failure",
			    blob_delete_snapshot_power_failure) == 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 ||