Commit d859e3cc authored by Ben Walker's avatar Ben Walker Committed by Daniel Verkamp
Browse files

bdev: Remove implementation assumptions from QoS unit test



This will allow a bit of internal refactoring to occur
without breaking the unit test.

Change-Id: Id7da6b14e9cd4cab5fc4dc004b5858dbbb34bc3a
Signed-off-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.gerrithub.io/407366


Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarGangCao <gang.cao@intel.com>
parent 5d94d6d3
Loading
Loading
Loading
Loading
+104 −320
Original line number Diff line number Diff line
@@ -616,442 +616,227 @@ io_during_reset(void)
static void
basic_qos(void)
{
	struct spdk_io_channel *io_ch[3];
	struct spdk_bdev_channel *bdev_ch[3], *qos_bdev_ch;
	struct spdk_io_channel *io_ch[2];
	struct spdk_bdev *bdev;
	enum spdk_bdev_io_status status;
	struct spdk_bdev_module_channel *module_ch;
	int rc;

	setup_test();

	/*
	 * First test normal case - submit an I/O on the channel (QoS not enabled)
	 *  and verify it completes successfully.
	 */
	set_thread(0);
	g_get_io_channel = false;
	io_ch[0] = spdk_bdev_get_io_channel(g_desc);
	CU_ASSERT(io_ch[0] == NULL);
	g_get_io_channel = true;
	io_ch[0] = spdk_bdev_get_io_channel(g_desc);
	bdev_ch[0] = spdk_io_channel_get_ctx(io_ch[0]);
	status = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_read_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &status);
	CU_ASSERT(rc == 0);
	CU_ASSERT(bdev_ch[0]->flags == 0);
	/* Enable QoS */
	bdev = &g_bdev.bdev;
	bdev->ios_per_sec = 2000; /* 2 I/O per millisecond */

	CU_ASSERT(status == SPDK_BDEV_IO_STATUS_PENDING);
	g_get_io_channel = true;

	set_thread(0);
	stub_complete_io(g_bdev.io_target, 0);
	CU_ASSERT(status == SPDK_BDEV_IO_STATUS_SUCCESS);

	poll_threads();
	io_ch[0] = spdk_bdev_get_io_channel(g_desc);

	set_thread(1);
	bdev = &g_bdev.bdev;
	bdev->ios_per_sec = 2000;
	g_get_io_channel = false;
	io_ch[1] = spdk_bdev_get_io_channel(g_desc);
	CU_ASSERT(io_ch[1] == NULL);
	bdev_ch[1] = spdk_io_channel_get_ctx(io_ch[1]);
	qos_bdev_ch = bdev->qos_channel;
	CU_ASSERT(qos_bdev_ch == NULL);
	g_get_io_channel = true;
	io_ch[1] = spdk_bdev_get_io_channel(g_desc);
	bdev_ch[1] = spdk_io_channel_get_ctx(io_ch[1]);
	qos_bdev_ch = bdev->qos_channel;
	CU_ASSERT(bdev->qos_channel->flags == BDEV_CH_QOS_ENABLED);
	CU_ASSERT(qos_bdev_ch != NULL);
	module_ch = qos_bdev_ch->module_ch;
	CU_ASSERT(module_ch->io_outstanding == 0);
	CU_ASSERT(g_ut_threads[1].thread == bdev->qos_thread);

	/*
	 * Now sending one I/O on first channel
	 * Send an I/O on thread 0, which is where the QoS thread is running.
	 */
	set_thread(0);
	status = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_read_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &status);
	CU_ASSERT(rc == 0);

	poll_threads();
	CU_ASSERT(module_ch->io_outstanding == 1);
	CU_ASSERT(status == SPDK_BDEV_IO_STATUS_PENDING);

	/*
	 * IO is operated on thread_id(1) via the QoS thread
	 */
	set_thread(1);
	stub_complete_io(g_bdev.io_target, 1);

	poll_threads();
	stub_complete_io(g_bdev.io_target, 0);
	poll_threads();
	CU_ASSERT(status == SPDK_BDEV_IO_STATUS_SUCCESS);

	/*
	 * QoS thread is on thread 1. Put I/O channel on thread 1 first
	 * to trigger an async destruction of QoS bdev channel.
	 */
	/* Send an I/O on thread 1. The QoS thread is not running here. */
	status = SPDK_BDEV_IO_STATUS_PENDING;
	set_thread(1);
	spdk_put_io_channel(io_ch[0]);
	set_thread(0);
	spdk_put_io_channel(io_ch[1]);

	/*
	 * Handle the messages on thread 1 first so that the QoS bdev
	 * channel destroy message from thread 0 handling will be active
	 * there.
	 */
	poll_thread(1);
	poll_thread(0);

	/*
	 * Create a new I/O channel when the async destruction of QoS
	 * bdev channel is on going. The expected result is the QoS bdev
	 * channel will be properly setup again.
	 */
	set_thread(2);
	io_ch[2] = spdk_bdev_get_io_channel(g_desc);
	bdev_ch[2] = spdk_io_channel_get_ctx(io_ch[2]);

	rc = spdk_bdev_read_blocks(g_desc, io_ch[1], NULL, 0, 1, io_during_io_done, &status);
	CU_ASSERT(rc == 0);
	CU_ASSERT(status == SPDK_BDEV_IO_STATUS_PENDING);
	poll_threads();

	qos_bdev_ch = bdev->qos_channel;
	CU_ASSERT(qos_bdev_ch->flags == BDEV_CH_QOS_ENABLED);
	CU_ASSERT(qos_bdev_ch != NULL);
	module_ch = qos_bdev_ch->module_ch;
	CU_ASSERT(module_ch->io_outstanding == 0);
	CU_ASSERT(g_ut_threads[2].thread == bdev->qos_thread);

	/*
	 * Destroy the last I/O channel so that the QoS bdev channel
	 * will be destroyed.
	 */
	set_thread(2);
	spdk_put_io_channel(io_ch[2]);

	/* Complete I/O on thread 1. This should not complete the I/O we submitted */
	stub_complete_io(g_bdev.io_target, 0);
	poll_threads();

	teardown_test();
}

static void
io_during_qos(void)
{
	struct spdk_io_channel *io_ch[3];
	struct spdk_bdev_channel *bdev_ch[3], *qos_bdev_ch;
	struct spdk_bdev *bdev;
	enum spdk_bdev_io_status status0, status1;
	struct spdk_bdev_module_channel *module_ch;
	int rc;

	setup_test();

	/*
	 * First test normal case - submit an I/O on each of two channels (QoS not enabled)
	 *  and verify they complete successfully.
	 */
	set_thread(0);
	io_ch[0] = spdk_bdev_get_io_channel(g_desc);
	bdev_ch[0] = spdk_io_channel_get_ctx(io_ch[0]);
	status0 = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_read_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &status0);
	CU_ASSERT(rc == 0);
	CU_ASSERT(bdev_ch[0]->flags == 0);

	set_thread(1);
	io_ch[1] = spdk_bdev_get_io_channel(g_desc);
	bdev_ch[1] = spdk_io_channel_get_ctx(io_ch[1]);
	status1 = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_read_blocks(g_desc, io_ch[1], NULL, 0, 1, io_during_io_done, &status1);
	CU_ASSERT(rc == 0);
	CU_ASSERT(bdev_ch[1]->flags == 0);

	CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_PENDING);
	CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_PENDING);

	CU_ASSERT(status == SPDK_BDEV_IO_STATUS_PENDING);
	/* Now complete I/O on thread 0 */
	set_thread(0);
	poll_threads();
	stub_complete_io(g_bdev.io_target, 0);
	CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_SUCCESS);
	poll_threads();
	CU_ASSERT(status == SPDK_BDEV_IO_STATUS_SUCCESS);

	/* Tear down the channels */
	set_thread(0);
	spdk_put_io_channel(io_ch[0]);
	set_thread(1);
	stub_complete_io(g_bdev.io_target, 0);
	CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_SUCCESS);

	spdk_put_io_channel(io_ch[1]);
	poll_threads();
	set_thread(0);

	set_thread(2);
	bdev = &g_bdev.bdev;
	/*
	 * 10 IOs allowed per millisecond
	 */
	bdev->ios_per_sec = 10000;
	io_ch[2] = spdk_bdev_get_io_channel(g_desc);
	bdev_ch[2] = spdk_io_channel_get_ctx(io_ch[2]);
	qos_bdev_ch = bdev->qos_channel;
	CU_ASSERT(bdev->qos_channel->flags == BDEV_CH_QOS_ENABLED);
	CU_ASSERT(qos_bdev_ch != NULL);
	module_ch = qos_bdev_ch->module_ch;
	CU_ASSERT(module_ch->io_outstanding == 0);
	/* Close the descriptor, which should stop the qos channel */
	spdk_bdev_close(g_desc);
	CU_ASSERT(bdev->qos_channel == NULL);

	/*
	 * Now sending some I/Os on different channels when QoS has been enabled
	 */
	set_thread(0);
	status0 = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_read_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &status0);
	CU_ASSERT(rc == 0);
	spdk_bdev_open(bdev, true, NULL, NULL, &g_desc);

	/* Create the channels in reverse order. */
	set_thread(1);
	status1 = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_read_blocks(g_desc, io_ch[1], NULL, 0, 1, io_during_io_done, &status1);
	CU_ASSERT(rc == 0);

	poll_threads();
	CU_ASSERT(module_ch->io_outstanding == 2);
	CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_PENDING);
	CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_PENDING);
	io_ch[1] = spdk_bdev_get_io_channel(g_desc);

	/*
	 * IOs are operated on thread_id(2) via the QoS thread
	 */
	set_thread(2);
	stub_complete_io(g_bdev.io_target, 2);
	set_thread(0);
	io_ch[0] = spdk_bdev_get_io_channel(g_desc);

	poll_threads();
	CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_SUCCESS);
	CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_SUCCESS);
	/* Confirm that the qos tracking was re-enabled */
	CU_ASSERT(bdev->qos_channel != NULL);

	/* Tear down the channels */
	set_thread(0);
	spdk_put_io_channel(io_ch[0]);
	set_thread(1);
	spdk_put_io_channel(io_ch[1]);
	set_thread(2);
	spdk_put_io_channel(io_ch[2]);

	poll_threads();

	set_thread(0);

	teardown_test();
}

static void
io_during_qos_queue(void)
{
	struct spdk_io_channel *io_ch[3];
	struct spdk_bdev_channel *bdev_ch[3], *qos_bdev_ch;
	struct spdk_io_channel *io_ch[2];
	struct spdk_bdev *bdev;
	enum spdk_bdev_io_status status0, status1;
	struct spdk_bdev_module_channel *module_ch;
	int rc;

	setup_test();
	reset_time();

	/*
	 * First test normal case - submit an I/O on each of two channels (QoS not enabled)
	 *  and verify they complete successfully.
	 */
	/* Enable QoS */
	bdev = &g_bdev.bdev;
	bdev->ios_per_sec = 1000; /* 1000 I/O per second, or 1 per millisecond */

	g_get_io_channel = true;

	/* Create channels */
	set_thread(0);
	io_ch[0] = spdk_bdev_get_io_channel(g_desc);
	bdev_ch[0] = spdk_io_channel_get_ctx(io_ch[0]);
	status0 = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_read_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &status0);
	CU_ASSERT(rc == 0);
	CU_ASSERT(bdev_ch[0]->flags == 0);

	set_thread(1);
	io_ch[1] = spdk_bdev_get_io_channel(g_desc);
	bdev_ch[1] = spdk_io_channel_get_ctx(io_ch[1]);

	/* Send two I/O */
	status1 = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_read_blocks(g_desc, io_ch[1], NULL, 0, 1, io_during_io_done, &status1);
	CU_ASSERT(rc == 0);
	CU_ASSERT(bdev_ch[1]->flags == 0);

	poll_threads();
	CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_PENDING);
	CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_PENDING);

	set_thread(0);
	stub_complete_io(g_bdev.io_target, 0);
	CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_SUCCESS);

	set_thread(1);
	stub_complete_io(g_bdev.io_target, 0);
	CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_SUCCESS);

	poll_threads();

	set_thread(2);
	bdev = bdev_ch[0]->bdev;
	/*
	 * Only 1 IO allowed per millisecond. More IOs will be queued.
	 */
	bdev->ios_per_sec = 1000;
	io_ch[2] = spdk_bdev_get_io_channel(g_desc);
	bdev_ch[2] = spdk_io_channel_get_ctx(io_ch[2]);
	qos_bdev_ch = bdev->qos_channel;
	CU_ASSERT(bdev->qos_channel->flags == BDEV_CH_QOS_ENABLED);
	CU_ASSERT(qos_bdev_ch != NULL);
	module_ch = qos_bdev_ch->module_ch;
	CU_ASSERT(module_ch->io_outstanding == 0);

	/*
	 * Now sending some I/Os on different channels when QoS has been enabled
	 */
	set_thread(0);
	status0 = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_read_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &status0);
	CU_ASSERT(rc == 0);
	CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_PENDING);

	/* Complete any I/O that arrived at the disk */
	poll_threads();
	set_thread(1);
	status1 = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_read_blocks(g_desc, io_ch[1], NULL, 0, 1, io_during_io_done, &status1);
	CU_ASSERT(rc == 0);

	/*
	 * Poll the QoS thread to send the allowed I/O down
	 */
	stub_complete_io(g_bdev.io_target, 0);
	set_thread(0);
	stub_complete_io(g_bdev.io_target, 0);
	poll_threads();
	CU_ASSERT(module_ch->io_outstanding == 1);
	CU_ASSERT(bdev_io_tailq_cnt(&qos_bdev_ch->qos_io) == 1);
	CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_PENDING);

	/*
	 * Increase the time and poll the QoS thread to run the periodical poller
	 */
	increment_time(1000);
	poll_threads();
	CU_ASSERT(module_ch->io_outstanding == 2);
	CU_ASSERT(bdev_io_tailq_cnt(&qos_bdev_ch->qos_io) == 0);
	/* Only one of the I/O should complete. (logical XOR) */
	if (status0 == SPDK_BDEV_IO_STATUS_SUCCESS) {
		CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_PENDING);
	} else {
		CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_SUCCESS);
	}

	/*
	 * IOs are handled on the thread(2) as the master thread
	 */
	set_thread(2);
	stub_complete_io(g_bdev.io_target, 0);
	spdk_put_io_channel(io_ch[0]);
	spdk_put_io_channel(io_ch[1]);
	spdk_put_io_channel(io_ch[2]);
	/* Advance in time by a millisecond */
	increment_time(1000);

	/* Complete more I/O */
	poll_threads();
	set_thread(1);
	stub_complete_io(g_bdev.io_target, 0);
	set_thread(0);
	stub_complete_io(g_bdev.io_target, 0);
	poll_threads();

	/* Now the second I/O should be done */
	CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_SUCCESS);
	CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_SUCCESS);

	/* Tear down the channels */
	set_thread(1);
	spdk_put_io_channel(io_ch[1]);
	set_thread(0);
	spdk_put_io_channel(io_ch[0]);
	poll_threads();

	teardown_test();
}

static void
io_during_qos_reset(void)
{
	struct spdk_io_channel *io_ch[3];
	struct spdk_bdev_channel *bdev_ch[3], *qos_bdev_ch;
	struct spdk_io_channel *io_ch[2];
	struct spdk_bdev *bdev;
	enum spdk_bdev_io_status status0, status1, status_reset;
	struct spdk_bdev_module_channel *module_ch;
	enum spdk_bdev_io_status status0, status1, reset_status;
	int rc;

	setup_test();
	reset_time();

	/*
	 * First test normal case - submit an I/O on each of two channels (QoS disabled and no reset)
	 *  and verify they complete successfully.
	 */
	/* Enable QoS */
	bdev = &g_bdev.bdev;
	bdev->ios_per_sec = 1000; /* 1000 I/O per second, or 1 per millisecond */

	g_get_io_channel = true;

	/* Create channels */
	set_thread(0);
	io_ch[0] = spdk_bdev_get_io_channel(g_desc);
	bdev_ch[0] = spdk_io_channel_get_ctx(io_ch[0]);
	status0 = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_read_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &status0);
	CU_ASSERT(rc == 0);
	CU_ASSERT(bdev_ch[0]->flags == 0);

	set_thread(1);
	io_ch[1] = spdk_bdev_get_io_channel(g_desc);
	bdev_ch[1] = spdk_io_channel_get_ctx(io_ch[1]);

	/* Send two I/O. One of these gets queued by QoS. The other is sitting at the disk. */
	status1 = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_read_blocks(g_desc, io_ch[1], NULL, 0, 1, io_during_io_done, &status1);
	CU_ASSERT(rc == 0);
	CU_ASSERT(bdev_ch[1]->flags == 0);
	set_thread(0);
	status0 = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_read_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &status0);
	CU_ASSERT(rc == 0);

	poll_threads();
	CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_PENDING);
	CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_PENDING);
	CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_PENDING);

	set_thread(0);
	stub_complete_io(g_bdev.io_target, 0);
	CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_SUCCESS);
	/* Reset the bdev. */
	reset_status = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_reset(g_desc, io_ch[0], io_during_io_done, &reset_status);
	CU_ASSERT(rc == 0);

	/* Complete any I/O that arrived at the disk */
	poll_threads();
	set_thread(1);
	stub_complete_io(g_bdev.io_target, 0);
	CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_SUCCESS);

	/*
	 * Enable QoS on the bdev
	 */
	set_thread(2);
	bdev = bdev_ch[0]->bdev;
	bdev->ios_per_sec = 2000;
	io_ch[2] = spdk_bdev_get_io_channel(g_desc);
	bdev_ch[2] = spdk_io_channel_get_ctx(io_ch[2]);
	qos_bdev_ch = bdev->qos_channel;
	module_ch = qos_bdev_ch->module_ch;
	CU_ASSERT(bdev->qos_channel->flags == BDEV_CH_QOS_ENABLED);
	CU_ASSERT(qos_bdev_ch != NULL);
	CU_ASSERT(module_ch != NULL);

	/*
	 * Now submit a reset, and leave it pending while we submit I/O on two different
	 *  channels.  These I/O should be failed by the bdev layer since the reset is in
	 *  progress.
	 */
	set_thread(0);
	status_reset = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_reset(g_desc, io_ch[0], io_during_io_done, &status_reset);
	CU_ASSERT(rc == 0);

	CU_ASSERT(bdev_ch[0]->flags == 0);
	CU_ASSERT(bdev_ch[1]->flags == 0);
	CU_ASSERT(bdev_ch[2]->flags == 0);
	CU_ASSERT(qos_bdev_ch->flags & BDEV_CH_QOS_ENABLED);
	stub_complete_io(g_bdev.io_target, 0);
	poll_threads();
	CU_ASSERT(bdev_ch[0]->flags == BDEV_CH_RESET_IN_PROGRESS);
	CU_ASSERT(bdev_ch[1]->flags == BDEV_CH_RESET_IN_PROGRESS);
	CU_ASSERT(bdev_ch[2]->flags == BDEV_CH_RESET_IN_PROGRESS);
	CU_ASSERT(qos_bdev_ch->flags & BDEV_CH_RESET_IN_PROGRESS);

	set_thread(0);
	status0 = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_read_blocks(g_desc, io_ch[0], NULL, 0, 1, io_during_io_done, &status0);
	CU_ASSERT(rc == 0);

	set_thread(1);
	status1 = SPDK_BDEV_IO_STATUS_PENDING;
	rc = spdk_bdev_read_blocks(g_desc, io_ch[1], NULL, 0, 1, io_during_io_done, &status1);
	CU_ASSERT(rc == 0);

	/*
	 * A reset is in progress so these read I/O should complete with failure when QoS has been
	 * enabled. Note that we need to poll_threads() since I/O completed inline have their
	 *  completion deferred.
	 */
	poll_threads();
	CU_ASSERT(status_reset == SPDK_BDEV_IO_STATUS_PENDING);
	CU_ASSERT(reset_status == SPDK_BDEV_IO_STATUS_SUCCESS);
	CU_ASSERT(status0 == SPDK_BDEV_IO_STATUS_FAILED);
	CU_ASSERT(status1 == SPDK_BDEV_IO_STATUS_FAILED);

	set_thread(0);
	stub_complete_io(g_bdev.io_target, 0);
	spdk_put_io_channel(io_ch[0]);
	/* Tear down the channels */
	set_thread(1);
	stub_complete_io(g_bdev.io_target, 0);
	spdk_put_io_channel(io_ch[1]);
	set_thread(2);
	stub_complete_io(g_bdev.io_target, 0);
	spdk_put_io_channel(io_ch[2]);
	set_thread(0);
	spdk_put_io_channel(io_ch[0]);
	poll_threads();
	CU_ASSERT(status_reset == SPDK_BDEV_IO_STATUS_SUCCESS);

	teardown_test();
}
@@ -1256,7 +1041,6 @@ main(int argc, char **argv)
		CU_add_test(suite, "put_channel_during_reset", put_channel_during_reset) == NULL ||
		CU_add_test(suite, "aborted_reset", aborted_reset) == NULL ||
		CU_add_test(suite, "io_during_reset", io_during_reset) == NULL ||
		CU_add_test(suite, "io_during_qos", io_during_qos) == NULL ||
		CU_add_test(suite, "io_during_qos_queue", io_during_qos_queue) == NULL ||
		CU_add_test(suite, "io_during_qos_reset", io_during_qos_reset) == NULL ||
		CU_add_test(suite, "enomem", enomem) == NULL ||