Commit d63c9dce authored by Paul Luse's avatar Paul Luse Committed by Daniel Verkamp
Browse files

ut/nvme: add coverage for nvme_allocate_request_user_copy()



Adding this coverage identified how the functions in test_env.c
are closely related to the new mock library. Given that there are
not that many here I don't think we *need* to try and consolidate
or make this any tighter. As it is now, I added a note at the top
of test_env.c to mention the use of mock globals to control when
a function is to be mocked or passed through and this first use
serves as an example.

Change-Id: Iac819f60f2028ac8bd8c75898e7dba7f4e12df35
Signed-off-by: default avatarPaul Luse <paul.e.luse@intel.com>
Reviewed-on: https://review.gerrithub.io/372529


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent 7b7f2aa6
Loading
Loading
Loading
Loading
+30 −6
Original line number Diff line number Diff line
@@ -33,8 +33,22 @@

#include "spdk/stdinc.h"

#include "spdk_internal/mock.h"

#include "spdk/env.h"

/*
 * NOTE:
 * Functions in this file are mocks for SPDK based functions
 * and work conceptually in the same way that mocks work in
 * /lib/ut_mock. However, the globals that control the behavior
 * of the mock are defined here, with each function, as
 * opposed to being defined as part of the macro that defines
 * the stub or wrapper for other types of functions. Be sure
 * to use the correct global variable naming convention when
 * working with these functions. See /lib/ut_mock for details.
 */

void *
spdk_dma_malloc(size_t size, size_t align, uint64_t *phys_addr)
{
@@ -48,15 +62,22 @@ spdk_dma_malloc(size_t size, size_t align, uint64_t *phys_addr)
	return buf;
}

int ut_spdk_dma_zmalloc = (int)MOCK_PASS_THRU;
void *ut_p_spdk_dma_zmalloc = &ut_spdk_dma_zmalloc;
void *
spdk_dma_zmalloc(size_t size, size_t align, uint64_t *phys_addr)
{
	if (ut_p_spdk_dma_zmalloc &&
	    ut_spdk_dma_zmalloc == (int)MOCK_PASS_THRU) {
		void *buf = spdk_dma_malloc(size, align, phys_addr);

		if (buf != NULL) {
			memset(buf, 0, size);
		}
		return buf;
	} else {
		return ut_p_spdk_dma_zmalloc;
	}
}

void *
@@ -79,8 +100,11 @@ spdk_dma_realloc(void *buf, size_t size, size_t align, uint64_t *phys_addr)

void spdk_dma_free(void *buf)
{
	if (ut_p_spdk_dma_zmalloc &&
	    ut_spdk_dma_zmalloc == (int)MOCK_PASS_THRU) {
		free(buf);
	}
}

bool ut_fail_vtophys = false;
uint64_t spdk_vtophys(void *buf)
+64 −0
Original line number Diff line number Diff line
@@ -108,6 +108,68 @@ memset_trid(struct spdk_nvme_transport_id *trid1, struct spdk_nvme_transport_id
	memset(trid2, 0, sizeof(struct spdk_nvme_transport_id));
}

static void
test_nvme_allocate_request_user_copy(void)
{
	struct spdk_nvme_qpair qpair;
	spdk_nvme_cmd_cb cb_fn = (spdk_nvme_cmd_cb)0x12345;
	void *cb_arg = (void *)0x12345;
	bool host_to_controller = true;
	struct nvme_request *req;
	struct nvme_request dummy_req;
	int test_data = 0xdeadbeef;
	void *buffer = NULL;
	uint32_t payload_size = sizeof(int);

	STAILQ_INIT(&qpair.free_req);
	STAILQ_INIT(&qpair.queued_req);

	/* no buffer or valid payload size, early NULL return */
	req = nvme_allocate_request_user_copy(&qpair, buffer, payload_size, cb_fn,
					      cb_arg, host_to_controller);
	CU_ASSERT(req == NULL);

	/* good buffer and valid payload size */
	buffer = malloc(payload_size);
	SPDK_CU_ASSERT_FATAL(buffer != NULL);
	memcpy(buffer, &test_data, payload_size);

	/* put a dummy on the queue */
	STAILQ_INSERT_HEAD(&qpair.free_req, &dummy_req, stailq);

	req = nvme_allocate_request_user_copy(&qpair, buffer, payload_size, cb_fn,
					      cb_arg, host_to_controller);
	CU_ASSERT(req->user_cb_fn == cb_fn);
	CU_ASSERT(req->user_cb_arg == cb_arg);
	CU_ASSERT(req->user_buffer == buffer);
	CU_ASSERT(req->cb_arg == req);
	CU_ASSERT(memcmp(req->payload.u.contig, buffer, payload_size) == 0);
	spdk_dma_free(req->payload.u.contig);

	/* same thing but additional path coverage, no copy */
	host_to_controller = false;
	STAILQ_INSERT_HEAD(&qpair.free_req, &dummy_req, stailq);

	req = nvme_allocate_request_user_copy(&qpair, buffer, payload_size, cb_fn,
					      cb_arg, host_to_controller);
	CU_ASSERT(req->user_cb_fn == cb_fn);
	CU_ASSERT(req->user_cb_arg == cb_arg);
	CU_ASSERT(req->user_buffer == buffer);
	CU_ASSERT(req->cb_arg == req);
	CU_ASSERT(memcmp(req->payload.u.contig, buffer, payload_size) != 0);
	spdk_dma_free(req->payload.u.contig);

	/* good buffer and valid payload size but make spdk_dma_zmalloc fail */
	/* set the mock pointer to NULL for spdk_dma_zmalloc */
	MOCK_SET_P(spdk_dma_zmalloc, void *, NULL);
	req = nvme_allocate_request_user_copy(&qpair, buffer, payload_size, cb_fn,
					      cb_arg, host_to_controller);
	CU_ASSERT(req == NULL);
	free(buffer);
	/* restore mock function back to the way it was */
	MOCK_SET_P(spdk_dma_zmalloc, void *, &ut_spdk_dma_zmalloc);
}

static void
test_nvme_ctrlr_probe(void)
{
@@ -460,6 +522,8 @@ int main(int argc, char **argv)
			    test_trid_adrfam_str) == NULL ||
		CU_add_test(suite, "test_nvme_ctrlr_probe",
			    test_nvme_ctrlr_probe) == NULL ||
		CU_add_test(suite, "test_nvme_allocate_request_user_copy",
			    test_nvme_allocate_request_user_copy) == NULL ||
		CU_add_test(suite, "test_nvme_robust_mutex_init_shared",
			    test_nvme_robust_mutex_init_shared) == NULL
	) {