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: Paul Luse <paul.e.luse@intel.com>
Reviewed-on: https://review.gerrithub.io/372529
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Paul Luse 2017-08-03 08:07:51 -07:00 committed by Daniel Verkamp
parent 7b7f2aa685
commit d63c9dce6a
2 changed files with 93 additions and 5 deletions

View File

@ -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)
{
void *buf = spdk_dma_malloc(size, align, 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);
if (buf != NULL) {
memset(buf, 0, size);
}
return buf;
} else {
return ut_p_spdk_dma_zmalloc;
}
return buf;
}
void *
@ -79,7 +100,10 @@ spdk_dma_realloc(void *buf, size_t size, size_t align, uint64_t *phys_addr)
void spdk_dma_free(void *buf)
{
free(buf);
if (ut_p_spdk_dma_zmalloc &&
ut_spdk_dma_zmalloc == (int)MOCK_PASS_THRU) {
free(buf);
}
}
bool ut_fail_vtophys = false;

View File

@ -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
) {