test: Simplify the mock library

Unify the regular mocks and the pointer mocks. Simplify
several of the #defines.

Change-Id: Ica8c69dbb70a685a55b5961b73fd7872f451c305
Signed-off-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.gerrithub.io/418884
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
Ben Walker 2018-07-10 10:47:14 -07:00 committed by Jim Harris
parent d5de73e017
commit f56b230063
8 changed files with 208 additions and 209 deletions

View File

@ -36,41 +36,44 @@
#include "spdk/stdinc.h"
/* used to signify pass through */
#define MOCK_PASS_THRU (0xdeadbeef)
#define MOCK_PASS_THRU_P (void*)0xdeadbeef
/* helper for initializing struct value with mock macros */
#define MOCK_STRUCT_INIT(...) \
{ __VA_ARGS__ }
#define DEFINE_RETURN_MOCK(fn, ret) \
bool ut_ ## fn ## _mocked = false; \
ret ut_ ## fn
/*
* For controlling mocked function behavior, setting
* and getting values from the stub, the _P macros are
* for mocking functions that return pointer values.
*/
#define MOCK_SET(fn, ret, val) \
ut_ ## fn = (ret)val
#define MOCK_SET_P(fn, ret, val) \
ut_p_ ## fn = (ret)val
#define MOCK_SET(fn, val) \
ut_ ## fn ## _mocked = true; \
ut_ ## fn = val
#define MOCK_GET(fn) \
ut_ ## fn
#define MOCK_GET_P(fn) \
ut_p_ ## fn
#define MOCK_CLEAR(fn) \
ut_ ## fn ## _mocked = false;
#define MOCK_CLEAR_P(fn) \
ut_ ## fn ## _mocked = false; \
ut_ ## fn = NULL;
/* for declaring function protoypes for wrappers */
#define DECLARE_WRAPPER(fn, ret, args) \
extern bool ut_ ## fn ## _mocked; \
extern ret ut_ ## fn; \
ret __wrap_ ## fn args; ret __real_ ## fn args;
/* for defining the implmentation of wrappers for syscalls */
#define DEFINE_WRAPPER(fn, ret, dargs, pargs, val) \
ret ut_ ## fn = val; \
#define DEFINE_WRAPPER(fn, ret, dargs, pargs) \
DEFINE_RETURN_MOCK(fn, ret); \
__attribute__((used)) ret __wrap_ ## fn dargs \
{ \
if (ut_ ## fn == (ret)MOCK_PASS_THRU) { \
if (!ut_ ## fn ## _mocked) { \
return __real_ ## fn pargs; \
} else { \
return MOCK_GET(fn); \
@ -79,6 +82,7 @@
/* DEFINE_STUB is for defining the implmentation of stubs for SPDK funcs. */
#define DEFINE_STUB(fn, ret, dargs, val) \
bool ut_ ## fn ## _mocked = true; \
ret ut_ ## fn = val; \
ret fn dargs; \
ret fn dargs \
@ -86,16 +90,6 @@
return MOCK_GET(fn); \
}
/* DEFINE_STUB_P macro is for stubs that return pointer values */
#define DEFINE_STUB_P(fn, ret, dargs, val) \
ret ut_ ## fn = val; \
ret* ut_p_ ## fn = &(ut_ ## fn); \
ret* fn dargs; \
ret* fn dargs \
{ \
return MOCK_GET_P(fn); \
}
/* DEFINE_STUB_V macro is for stubs that don't have a return value */
#define DEFINE_STUB_V(fn, dargs) \
void fn dargs; \
@ -103,15 +97,12 @@
{ \
}
/* DEFINE_STUB_VP macro is for stubs that return void pointer values */
#define DEFINE_STUB_VP(fn, dargs, val) \
void* ut_p_ ## fn = val; \
void* fn dargs; \
void* fn dargs \
{ \
return MOCK_GET_P(fn); \
#define HANDLE_RETURN_MOCK(fn) \
if (ut_ ## fn ## _mocked) { \
return ut_ ## fn; \
}
/* declare wrapper protos (alphabetically please) here */
DECLARE_WRAPPER(calloc, void *, (size_t nmemb, size_t size));

View File

@ -33,13 +33,13 @@
#include "spdk_internal/mock.h"
DEFINE_WRAPPER(calloc, void *, (size_t nmemb, size_t size), (nmemb, size), (void *)MOCK_PASS_THRU)
DEFINE_WRAPPER(calloc, void *, (size_t nmemb, size_t size), (nmemb, size))
DEFINE_WRAPPER(pthread_mutex_init, int,
(pthread_mutex_t *mtx, const pthread_mutexattr_t *attr),
(mtx, attr), MOCK_PASS_THRU)
(mtx, attr))
DEFINE_WRAPPER(pthread_mutexattr_init, int,
(pthread_mutexattr_t *attr), (attr), MOCK_PASS_THRU)
(pthread_mutexattr_t *attr), (attr))
DEFINE_WRAPPER(pthread_self, pthread_t, (void), (), (pthread_t)MOCK_PASS_THRU)
DEFINE_WRAPPER(pthread_self, pthread_t, (void), ())

View File

@ -38,129 +38,104 @@
#include "spdk/env.h"
#include "spdk/queue.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.
*/
/*
* these stubs have a return value set with one of the MOCK_SET macros
*/
DEFINE_STUB(spdk_process_is_primary, bool, (void), true)
DEFINE_STUB_VP(spdk_memzone_lookup, (const char *name), NULL)
DEFINE_STUB(spdk_memzone_lookup, void *, (const char *name), NULL)
/*
* these mocks don't fit well with the library macro model because
* they do 'something' other than just return a pre-set value
* These mocks don't use the DEFINE_STUB macros because
* their default implementation is more complex.
*/
/* setup the mock control to pass thru by default */
void *ut_p_spdk_memzone_reserve = MOCK_PASS_THRU_P;
DEFINE_RETURN_MOCK(spdk_memzone_reserve, void *);
void *
spdk_memzone_reserve(const char *name, size_t len, int socket_id, unsigned flags)
{
if (ut_p_spdk_memzone_reserve &&
ut_p_spdk_memzone_reserve == MOCK_PASS_THRU_P) {
return malloc(len);
} else {
return ut_p_spdk_memzone_reserve;
}
HANDLE_RETURN_MOCK(spdk_memzone_reserve);
return malloc(len);
}
/* setup the mock control to pass thru by default */
void *ut_p_spdk_memzone_reserve_aligned = MOCK_PASS_THRU_P;
DEFINE_RETURN_MOCK(spdk_memzone_reserve_aligned, void *);
void *
spdk_memzone_reserve_aligned(const char *name, size_t len, int socket_id,
unsigned flags, unsigned align)
{
if (ut_p_spdk_memzone_reserve_aligned &&
ut_p_spdk_memzone_reserve_aligned == MOCK_PASS_THRU_P) {
return malloc(len);
} else {
return ut_p_spdk_memzone_reserve_aligned;
}
HANDLE_RETURN_MOCK(spdk_memzone_reserve_aligned);
return malloc(len);
}
int ut_spdk_dma_malloc = (int)MOCK_PASS_THRU;
void *ut_p_spdk_dma_malloc = &ut_spdk_dma_malloc;
DEFINE_RETURN_MOCK(spdk_dma_malloc, void *);
void *
spdk_dma_malloc(size_t size, size_t align, uint64_t *phys_addr)
{
if (ut_p_spdk_dma_malloc &&
ut_spdk_dma_malloc == (int)MOCK_PASS_THRU) {
void *buf = NULL;
if (posix_memalign(&buf, align, size)) {
return NULL;
}
if (phys_addr) {
*phys_addr = (uint64_t)buf;
}
return buf;
} else {
return ut_p_spdk_dma_malloc;
HANDLE_RETURN_MOCK(spdk_dma_malloc);
void *buf = NULL;
if (posix_memalign(&buf, align, size)) {
return NULL;
}
if (phys_addr) {
*phys_addr = (uint64_t)buf;
}
return buf;
}
int ut_spdk_dma_zmalloc = (int)MOCK_PASS_THRU;
void *ut_p_spdk_dma_zmalloc = &ut_spdk_dma_zmalloc;
DEFINE_RETURN_MOCK(spdk_dma_zmalloc, void *);
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);
HANDLE_RETURN_MOCK(spdk_dma_zmalloc);
if (buf != NULL) {
memset(buf, 0, size);
}
return buf;
} else {
return ut_p_spdk_dma_zmalloc;
void *buf = spdk_dma_malloc(size, align, phys_addr);
if (buf != NULL) {
memset(buf, 0, size);
}
return buf;
}
DEFINE_RETURN_MOCK(spdk_dma_malloc_socket, void *);
void *
spdk_dma_malloc_socket(size_t size, size_t align, uint64_t *phys_addr, int socket_id)
{
HANDLE_RETURN_MOCK(spdk_dma_malloc_socket);
return spdk_dma_malloc(size, align, phys_addr);
}
DEFINE_RETURN_MOCK(spdk_dma_zmalloc_socket, void *);
void *
spdk_dma_zmalloc_socket(size_t size, size_t align, uint64_t *phys_addr, int socket_id)
{
HANDLE_RETURN_MOCK(spdk_dma_zmalloc_socket);
return spdk_dma_zmalloc(size, align, phys_addr);
}
DEFINE_RETURN_MOCK(spdk_dma_realloc, void *);
void *
spdk_dma_realloc(void *buf, size_t size, size_t align, uint64_t *phys_addr)
{
HANDLE_RETURN_MOCK(spdk_dma_realloc);
return realloc(buf, size);
}
void spdk_dma_free(void *buf)
void
spdk_dma_free(void *buf)
{
if (ut_p_spdk_dma_zmalloc &&
ut_spdk_dma_zmalloc == (int)MOCK_PASS_THRU) {
free(buf);
}
free(buf);
}
bool ut_fail_vtophys = false;
uint64_t spdk_vtophys(void *buf)
DEFINE_RETURN_MOCK(spdk_vtophys, uint64_t);
uint64_t
spdk_vtophys(void *buf)
{
if (ut_fail_vtophys) {
return (uint64_t) - 1;
} else {
return (uintptr_t)buf;
}
HANDLE_RETURN_MOCK(spdk_vtophys);
return (uintptr_t)buf;
}
void
@ -169,9 +144,12 @@ spdk_memzone_dump(FILE *f)
return;
}
DEFINE_RETURN_MOCK(spdk_memzone_free, int);
int
spdk_memzone_free(const char *name)
{
HANDLE_RETURN_MOCK(spdk_memzone_free);
return 0;
}
@ -179,12 +157,15 @@ struct test_mempool {
size_t count;
};
DEFINE_RETURN_MOCK(spdk_mempool_create, struct spdk_mempool *);
struct spdk_mempool *
spdk_mempool_create(const char *name, size_t count,
size_t ele_size, size_t cache_size, int socket_id)
{
struct test_mempool *mp;
HANDLE_RETURN_MOCK(spdk_mempool_create);
mp = calloc(1, sizeof(*mp));
if (mp == NULL) {
return NULL;
@ -203,16 +184,14 @@ spdk_mempool_free(struct spdk_mempool *_mp)
free(mp);
}
bool ut_spdk_mempool_get = false;
DEFINE_RETURN_MOCK(spdk_mempool_get, void *);
void *
spdk_mempool_get(struct spdk_mempool *_mp)
{
struct test_mempool *mp = (struct test_mempool *)_mp;
void *buf;
if (ut_spdk_mempool_get) {
return NULL;
}
HANDLE_RETURN_MOCK(spdk_mempool_get);
if (mp && mp->count == 0) {
return NULL;
@ -259,11 +238,14 @@ spdk_mempool_put_bulk(struct spdk_mempool *mp, void **ele_arr, size_t count)
}
}
DEFINE_RETURN_MOCK(spdk_mempool_count, size_t);
size_t
spdk_mempool_count(const struct spdk_mempool *_mp)
{
struct test_mempool *mp = (struct test_mempool *)_mp;
HANDLE_RETURN_MOCK(spdk_mempool_count);
if (mp) {
return mp->count;
} else {
@ -280,11 +262,14 @@ struct spdk_ring {
TAILQ_HEAD(, spdk_ring_ele) elements;
};
DEFINE_RETURN_MOCK(spdk_ring_create, struct spdk_ring *);
struct spdk_ring *
spdk_ring_create(enum spdk_ring_type type, size_t count, int socket_id)
{
struct spdk_ring *ring;
HANDLE_RETURN_MOCK(spdk_ring_create);
ring = calloc(1, sizeof(*ring));
if (ring) {
TAILQ_INIT(&ring->elements);
@ -293,19 +278,21 @@ spdk_ring_create(enum spdk_ring_type type, size_t count, int socket_id)
return ring;
}
void
spdk_ring_free(struct spdk_ring *ring)
{
free(ring);
}
DEFINE_RETURN_MOCK(spdk_ring_enqueue, size_t);
size_t
spdk_ring_enqueue(struct spdk_ring *ring, void **objs, size_t count)
{
struct spdk_ring_ele *ele;
size_t i;
HANDLE_RETURN_MOCK(spdk_ring_enqueue);
for (i = 0; i < count; i++) {
ele = calloc(1, sizeof(*ele));
if (!ele) {
@ -319,12 +306,15 @@ spdk_ring_enqueue(struct spdk_ring *ring, void **objs, size_t count)
return i;
}
DEFINE_RETURN_MOCK(spdk_ring_dequeue, size_t);
size_t
spdk_ring_dequeue(struct spdk_ring *ring, void **objs, size_t count)
{
struct spdk_ring_ele *ele, *tmp;
size_t i = 0;
HANDLE_RETURN_MOCK(spdk_ring_dequeue);
if (count == 0) {
return 0;
}
@ -343,27 +333,38 @@ spdk_ring_dequeue(struct spdk_ring *ring, void **objs, size_t count)
}
uint64_t ut_tsc = 0;
uint64_t spdk_get_ticks(void)
DEFINE_RETURN_MOCK(spdk_get_ticks, uint64_t);
uint64_t
spdk_get_ticks(void)
{
return ut_tsc;
HANDLE_RETURN_MOCK(spdk_get_ticks);
return ut_spdk_get_ticks;
}
uint64_t spdk_get_ticks_hz(void)
DEFINE_RETURN_MOCK(spdk_get_ticks_hz, uint64_t);
uint64_t
spdk_get_ticks_hz(void)
{
HANDLE_RETURN_MOCK(spdk_get_ticks_hz);
return 1000000;
}
void spdk_delay_us(unsigned int us)
void
spdk_delay_us(unsigned int us)
{
ut_tsc += us;
ut_spdk_get_ticks += us;
}
DEFINE_RETURN_MOCK(spdk_pci_addr_parse, int);
int
spdk_pci_addr_parse(struct spdk_pci_addr *addr, const char *bdf)
{
unsigned domain, bus, dev, func;
HANDLE_RETURN_MOCK(spdk_pci_addr_parse);
if (addr == NULL || bdf == NULL) {
return -EINVAL;
}
@ -396,11 +397,14 @@ spdk_pci_addr_parse(struct spdk_pci_addr *addr, const char *bdf)
return 0;
}
DEFINE_RETURN_MOCK(spdk_pci_addr_fmt, int);
int
spdk_pci_addr_fmt(char *bdf, size_t sz, const struct spdk_pci_addr *addr)
{
int rc;
HANDLE_RETURN_MOCK(spdk_pci_addr_fmt);
rc = snprintf(bdf, sz, "%04x:%02x:%02x.%x",
addr->domain, addr->bus,
addr->dev, addr->func);
@ -412,9 +416,12 @@ spdk_pci_addr_fmt(char *bdf, size_t sz, const struct spdk_pci_addr *addr)
return -1;
}
DEFINE_RETURN_MOCK(spdk_pci_addr_compare, int);
int
spdk_pci_addr_compare(const struct spdk_pci_addr *a1, const struct spdk_pci_addr *a2)
{
HANDLE_RETURN_MOCK(spdk_pci_addr_compare);
if (a1->domain > a2->domain) {
return 1;
} else if (a1->domain < a2->domain) {

View File

@ -110,13 +110,19 @@ __stop_poller(struct spdk_poller *poller, void *thread_ctx)
free(poller);
}
static uintptr_t g_thread_id = MOCK_PASS_THRU;
#define INVALID_THREAD 0x1000
static uintptr_t g_thread_id = INVALID_THREAD;
static void
set_thread(uintptr_t thread_id)
{
g_thread_id = thread_id;
MOCK_SET(pthread_self, pthread_t, (pthread_t)thread_id);
if (thread_id == INVALID_THREAD) {
MOCK_CLEAR(pthread_self);
} else {
MOCK_SET(pthread_self, (pthread_t)thread_id);
}
}
int
@ -141,7 +147,7 @@ allocate_threads(int num_threads)
TAILQ_INIT(&g_ut_threads[i].pollers);
}
set_thread(MOCK_PASS_THRU);
set_thread(INVALID_THREAD);
return 0;
}
@ -205,7 +211,7 @@ poll_thread(uintptr_t thread_id)
uintptr_t original_thread_id;
TAILQ_HEAD(, ut_poller) tmp_pollers;
CU_ASSERT(thread_id != (uintptr_t)MOCK_PASS_THRU);
CU_ASSERT(thread_id != (uintptr_t)INVALID_THREAD);
CU_ASSERT(thread_id < g_ut_num_threads);
original_thread_id = g_thread_id;

View File

@ -1536,12 +1536,12 @@ blob_rw_verify_iov_nomem(void)
iov_write[1].iov_len = 5 * 4096;
iov_write[2].iov_base = payload_write + 6 * 4096;
iov_write[2].iov_len = 4 * 4096;
MOCK_SET(calloc, void *, NULL);
MOCK_SET(calloc, NULL);
req_count = bs_channel_get_req_count(channel);
spdk_blob_io_writev(blob, channel, iov_write, 3, 250, 10, blob_op_complete, NULL);
CU_ASSERT(g_bserrno = -ENOMEM);
CU_ASSERT(req_count == bs_channel_get_req_count(channel));
MOCK_SET(calloc, void *, (void *)MOCK_PASS_THRU);
MOCK_CLEAR(calloc);
spdk_blob_close(blob, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
@ -4624,7 +4624,7 @@ blob_relations(void)
spdk_blob_id blobid, cloneid, snapshotid, cloneid2, snapshotid2;
int rc;
size_t count;
spdk_blob_id ids[10];
spdk_blob_id ids[10] = {};
dev = init_dev();
spdk_bs_opts_init(&bs_opts);

View File

@ -78,10 +78,10 @@ DEFINE_STUB(dummy_probe_cb, bool,
(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
struct spdk_nvme_ctrlr_opts *opts), false)
DEFINE_STUB_P(nvme_transport_ctrlr_construct, struct spdk_nvme_ctrlr,
(const struct spdk_nvme_transport_id *trid,
const struct spdk_nvme_ctrlr_opts *opts,
void *devhandle), {0})
DEFINE_STUB(nvme_transport_ctrlr_construct, struct spdk_nvme_ctrlr *,
(const struct spdk_nvme_transport_id *trid,
const struct spdk_nvme_ctrlr_opts *opts,
void *devhandle), NULL)
DEFINE_STUB(spdk_nvme_qpair_process_completions, int32_t,
(struct spdk_nvme_qpair *qpair,
@ -153,8 +153,8 @@ test_spdk_nvme_probe(void)
g_spdk_nvme_driver = &dummy;
/* driver init fails */
MOCK_SET(spdk_process_is_primary, bool, false);
MOCK_SET_P(spdk_memzone_lookup, void *, NULL);
MOCK_SET(spdk_process_is_primary, false);
MOCK_SET(spdk_memzone_lookup, NULL);
rc = spdk_nvme_probe(trid, cb_ctx, probe_cb, attach_cb, remove_cb);
CU_ASSERT(rc == -1);
@ -163,40 +163,40 @@ test_spdk_nvme_probe(void)
* called for any controllers already initialized by the primary
* process.
*/
MOCK_SET(spdk_nvme_transport_available, bool, false);
MOCK_SET(spdk_process_is_primary, bool, true);
MOCK_SET(spdk_nvme_transport_available, false);
MOCK_SET(spdk_process_is_primary, true);
dummy.initialized = true;
g_spdk_nvme_driver = &dummy;
rc = spdk_nvme_probe(trid, cb_ctx, probe_cb, attach_cb, remove_cb);
CU_ASSERT(rc == -1);
/* driver init passes, transport available, secondary call attach_cb */
MOCK_SET(spdk_nvme_transport_available, bool, true);
MOCK_SET(spdk_process_is_primary, bool, false);
MOCK_SET_P(spdk_memzone_lookup, void *, g_spdk_nvme_driver);
MOCK_SET(spdk_nvme_transport_available, true);
MOCK_SET(spdk_process_is_primary, false);
MOCK_SET(spdk_memzone_lookup, g_spdk_nvme_driver);
dummy.initialized = true;
memset(&ctrlr, 0, sizeof(struct spdk_nvme_ctrlr));
CU_ASSERT(pthread_mutexattr_init(&attr) == 0);
CU_ASSERT(pthread_mutex_init(&dummy.lock, &attr) == 0);
TAILQ_INIT(&dummy.shared_attached_ctrlrs);
TAILQ_INSERT_TAIL(&dummy.shared_attached_ctrlrs, &ctrlr, tailq);
MOCK_SET(attach_cb_called, bool, false);
ut_attach_cb_called = false;
/* setup nvme_transport_ctrlr_scan() stub to also check the trype */
MOCK_SET(check_trtype, bool, true);
ut_check_trtype = true;
rc = spdk_nvme_probe(trid, cb_ctx, probe_cb, attach_cb, remove_cb);
CU_ASSERT(rc == 0);
CU_ASSERT(ut_attach_cb_called == true);
/* driver init passes, transport available, we are primary */
MOCK_SET(spdk_process_is_primary, bool, true);
MOCK_SET(spdk_process_is_primary, true);
TAILQ_INIT(&g_nvme_init_ctrlrs);
rc = spdk_nvme_probe(trid, cb_ctx, probe_cb, attach_cb, remove_cb);
CU_ASSERT(rc == 0);
g_spdk_nvme_driver = NULL;
/* reset to pre-test values */
MOCK_SET_P(spdk_memzone_lookup, void *, MOCK_PASS_THRU_P);
MOCK_SET(check_trtype, bool, false);
MOCK_CLEAR(spdk_memzone_lookup);
ut_check_trtype = false;
pthread_mutex_destroy(&dummy.lock);
pthread_mutexattr_destroy(&attr);
@ -224,9 +224,9 @@ test_spdk_nvme_connect(void)
CU_ASSERT(ret_ctrlr == NULL);
/* driver init passes, transport available, secondary process connects ctrlr */
MOCK_SET(spdk_process_is_primary, bool, false);
MOCK_SET_P(spdk_memzone_lookup, void *, g_spdk_nvme_driver);
MOCK_SET(spdk_nvme_transport_available, bool, true);
MOCK_SET(spdk_process_is_primary, false);
MOCK_SET(spdk_memzone_lookup, g_spdk_nvme_driver);
MOCK_SET(spdk_nvme_transport_available, true);
memset(&trid, 0, sizeof(trid));
trid.trtype = SPDK_NVME_TRANSPORT_PCIE;
ret_ctrlr = spdk_nvme_connect(&trid, NULL, 0);
@ -256,7 +256,7 @@ test_spdk_nvme_connect(void)
CU_ASSERT(TAILQ_EMPTY(&g_spdk_nvme_driver->shared_attached_ctrlrs));
/* driver init passes, transport available, primary process connects ctrlr */
MOCK_SET(spdk_process_is_primary, bool, true);
MOCK_SET(spdk_process_is_primary, true);
/* setup one ctrlr on the attached_list */
memset(&ctrlr, 0, sizeof(struct spdk_nvme_ctrlr));
snprintf(ctrlr.trid.traddr, sizeof(ctrlr.trid.traddr), "0000:02:00.0");
@ -281,8 +281,8 @@ test_spdk_nvme_connect(void)
CU_ASSERT(TAILQ_EMPTY(&g_spdk_nvme_driver->shared_attached_ctrlrs));
/* test driver init failure return */
MOCK_SET(spdk_process_is_primary, bool, false);
MOCK_SET_P(spdk_memzone_lookup, void *, NULL);
MOCK_SET(spdk_process_is_primary, false);
MOCK_SET(spdk_memzone_lookup, NULL);
ret_ctrlr = spdk_nvme_connect(&trid, NULL, 0);
CU_ASSERT(ret_ctrlr == NULL);
}
@ -310,7 +310,7 @@ test_nvme_init_controllers(void)
* Try to initialize, but nvme_ctrlr_process_init will fail.
* Verify correct behavior when it does.
*/
MOCK_SET(nvme_ctrlr_process_init, int, 1);
MOCK_SET(nvme_ctrlr_process_init, 1);
g_spdk_nvme_driver->initialized = false;
ut_destruct_called = false;
rc = nvme_init_controllers(cb_ctx, attach_cb);
@ -326,7 +326,7 @@ test_nvme_init_controllers(void)
*/
TAILQ_INSERT_TAIL(&g_nvme_init_ctrlrs, &ctrlr, tailq);
ctrlr.state = NVME_CTRLR_STATE_READY;
MOCK_SET(nvme_ctrlr_process_init, int, 0);
MOCK_SET(nvme_ctrlr_process_init, 0);
rc = nvme_init_controllers(cb_ctx, attach_cb);
CU_ASSERT(rc == 0);
CU_ASSERT(ut_attach_cb_called == true);
@ -342,7 +342,7 @@ test_nvme_init_controllers(void)
ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_RDMA;
TAILQ_INSERT_TAIL(&g_nvme_init_ctrlrs, &ctrlr, tailq);
ctrlr.state = NVME_CTRLR_STATE_READY;
MOCK_SET(nvme_ctrlr_process_init, int, 0);
MOCK_SET(nvme_ctrlr_process_init, 0);
rc = nvme_init_controllers(cb_ctx, attach_cb);
CU_ASSERT(rc == 0);
CU_ASSERT(ut_attach_cb_called == true);
@ -367,7 +367,7 @@ test_nvme_driver_init(void)
g_nvme_driver_timeout_ms = 100;
/* process is primary and mem already reserved */
MOCK_SET(spdk_process_is_primary, bool, true);
MOCK_SET(spdk_process_is_primary, true);
dummy.initialized = true;
rc = nvme_driver_init();
CU_ASSERT(rc == 0);
@ -377,37 +377,37 @@ test_nvme_driver_init(void)
* to spdk_memzone_reserve() returns NULL.
*/
g_spdk_nvme_driver = NULL;
MOCK_SET(spdk_process_is_primary, bool, true);
MOCK_SET_P(spdk_memzone_reserve, void *, NULL);
MOCK_SET(spdk_process_is_primary, true);
MOCK_SET(spdk_memzone_reserve, NULL);
rc = nvme_driver_init();
CU_ASSERT(rc == -1);
/* process is not primary, no mem already reserved */
MOCK_SET(spdk_process_is_primary, bool, false);
MOCK_SET_P(spdk_memzone_lookup, void *, NULL);
MOCK_SET(spdk_process_is_primary, false);
MOCK_SET(spdk_memzone_lookup, NULL);
g_spdk_nvme_driver = NULL;
rc = nvme_driver_init();
CU_ASSERT(rc == -1);
/* process is not primary, mem is already reserved & init'd */
MOCK_SET(spdk_process_is_primary, bool, false);
MOCK_SET_P(spdk_memzone_lookup, void *, &dummy);
MOCK_SET(spdk_process_is_primary, false);
MOCK_SET(spdk_memzone_lookup, (void *)&dummy);
dummy.initialized = true;
rc = nvme_driver_init();
CU_ASSERT(rc == 0);
/* process is not primary, mem is reserved but not intiialized */
/* and times out */
MOCK_SET(spdk_process_is_primary, bool, false);
MOCK_SET_P(spdk_memzone_reserve, void *, &dummy);
MOCK_SET(spdk_process_is_primary, false);
MOCK_SET(spdk_memzone_reserve, (void *)&dummy);
dummy.initialized = false;
rc = nvme_driver_init();
CU_ASSERT(rc == -1);
/* process is primary, got mem but mutex won't init */
MOCK_SET(spdk_process_is_primary, bool, true);
MOCK_SET_P(spdk_memzone_reserve, void *, &dummy);
MOCK_SET(pthread_mutexattr_init, int, -1);
MOCK_SET(spdk_process_is_primary, true);
MOCK_SET(spdk_memzone_reserve, (void *)&dummy);
MOCK_SET(pthread_mutexattr_init, -1);
g_spdk_nvme_driver = NULL;
dummy.initialized = true;
rc = nvme_driver_init();
@ -419,8 +419,8 @@ test_nvme_driver_init(void)
#endif
/* process is primary, got mem, mutex OK */
MOCK_SET(spdk_process_is_primary, bool, true);
MOCK_SET(pthread_mutexattr_init, int, MOCK_PASS_THRU);
MOCK_SET(spdk_process_is_primary, true);
MOCK_CLEAR(pthread_mutexattr_init);
g_spdk_nvme_driver = NULL;
rc = nvme_driver_init();
CU_ASSERT(g_spdk_nvme_driver->initialized == false);
@ -429,8 +429,8 @@ test_nvme_driver_init(void)
CU_ASSERT(rc == 0);
g_spdk_nvme_driver = NULL;
MOCK_SET_P(spdk_memzone_reserve, void *, MOCK_PASS_THRU_P);
MOCK_SET_P(spdk_memzone_lookup, void *, NULL);
MOCK_CLEAR(spdk_memzone_reserve);
MOCK_CLEAR(spdk_memzone_lookup);
}
static void
@ -456,7 +456,7 @@ test_spdk_nvme_detach(void)
* called (we aren't testing what the real destuct function does
* here.)
*/
MOCK_SET(nvme_ctrlr_get_ref_count, int, 0);
MOCK_SET(nvme_ctrlr_get_ref_count, 0);
rc = spdk_nvme_detach(&ctrlr);
ret_ctrlr = TAILQ_FIRST(&test_driver.shared_attached_ctrlrs);
CU_ASSERT(ret_ctrlr == NULL);
@ -468,7 +468,7 @@ test_spdk_nvme_detach(void)
* function is not called and that attached ctrl list is
* not empty.
*/
MOCK_SET(nvme_ctrlr_get_ref_count, int, 1);
MOCK_SET(nvme_ctrlr_get_ref_count, 1);
TAILQ_INSERT_TAIL(&test_driver.shared_attached_ctrlrs, &ctrlr, tailq);
ut_destruct_called = false;
rc = spdk_nvme_detach(&ctrlr);
@ -486,7 +486,7 @@ test_spdk_nvme_detach(void)
ctrlr.trid.trtype = SPDK_NVME_TRANSPORT_RDMA;
TAILQ_INIT(&g_nvme_attached_ctrlrs);
TAILQ_INSERT_TAIL(&g_nvme_attached_ctrlrs, &ctrlr, tailq);
MOCK_SET(nvme_ctrlr_get_ref_count, int, 0);
MOCK_SET(nvme_ctrlr_get_ref_count, 0);
rc = spdk_nvme_detach(&ctrlr);
CU_ASSERT(TAILQ_EMPTY(&g_nvme_attached_ctrlrs));
CU_ASSERT(ut_destruct_called == true);
@ -541,7 +541,7 @@ test_nvme_user_copy_cmd_complete(void)
SPDK_CU_ASSERT_FATAL(req.user_buffer != NULL);
memset(req.user_buffer, 0, buff_size);
req.payload_size = buff_size;
buff = malloc(buff_size);
buff = spdk_dma_zmalloc(buff_size, 0x100, NULL);
SPDK_CU_ASSERT_FATAL(buff != NULL);
req.payload = NVME_PAYLOAD_CONTIG(buff, NULL);
memcpy(buff, &test_data, buff_size);
@ -551,11 +551,6 @@ test_nvme_user_copy_cmd_complete(void)
/* zero out the test value set in the callback */
memset(&ut_spdk_nvme_cpl, 0, sizeof(ut_spdk_nvme_cpl));
/*
* Mocking this to prevent the calling code from freeing the
* buff as it confuses either valgrind or the static analyzer.
*/
MOCK_SET_P(spdk_dma_zmalloc, void *, NULL);
nvme_user_copy_cmd_complete(&req, &cpl);
CU_ASSERT(memcmp(req.user_buffer, &test_data, buff_size) == 0);
CU_ASSERT(memcmp(&ut_spdk_nvme_cpl, &cpl, sizeof(cpl)) == 0);
@ -566,6 +561,10 @@ test_nvme_user_copy_cmd_complete(void)
*/
memset(&ut_spdk_nvme_cpl, 0, sizeof(ut_spdk_nvme_cpl));
memset(req.user_buffer, 0, buff_size);
buff = spdk_dma_zmalloc(buff_size, 0x100, NULL);
SPDK_CU_ASSERT_FATAL(buff != NULL);
req.payload = NVME_PAYLOAD_CONTIG(buff, NULL);
memcpy(buff, &test_data, buff_size);
req.cmd.opc = SPDK_NVME_OPC_SET_FEATURES;
nvme_user_copy_cmd_complete(&req, &cpl);
CU_ASSERT(memcmp(req.user_buffer, &test_data, buff_size) != 0);
@ -573,10 +572,6 @@ test_nvme_user_copy_cmd_complete(void)
/* clean up */
free(req.user_buffer);
free(buff);
/* return spdk_dma_zmalloc/freee to unmocked */
MOCK_SET_P(spdk_dma_zmalloc, void *, &ut_spdk_dma_zmalloc);
}
static void
@ -722,47 +717,47 @@ test_nvme_allocate_request_user_copy(void)
/* 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);
MOCK_SET(spdk_dma_zmalloc, 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);
MOCK_CLEAR(spdk_dma_zmalloc);
}
static void
test_nvme_ctrlr_probe(void)
{
int rc = 0;
struct spdk_nvme_ctrlr ctrlr = {};
const struct spdk_nvme_transport_id trid = {};
void *devhandle = NULL;
void *cb_ctx = NULL;
struct spdk_nvme_ctrlr *dummy = NULL;
/* test when probe_cb returns false */
MOCK_SET(dummy_probe_cb, bool, false);
MOCK_SET(dummy_probe_cb, false);
rc = nvme_ctrlr_probe(&trid, devhandle, dummy_probe_cb, cb_ctx);
CU_ASSERT(rc == 1);
/* probe_cb returns true but we can't construct a ctrl */
MOCK_SET(dummy_probe_cb, bool, true);
MOCK_SET_P(nvme_transport_ctrlr_construct,
struct spdk_nvme_ctrlr *, NULL);
MOCK_SET(dummy_probe_cb, true);
MOCK_SET(nvme_transport_ctrlr_construct, NULL);
rc = nvme_ctrlr_probe(&trid, devhandle, dummy_probe_cb, cb_ctx);
CU_ASSERT(rc == -1);
/* happy path */
g_spdk_nvme_driver = malloc(sizeof(struct nvme_driver));
SPDK_CU_ASSERT_FATAL(g_spdk_nvme_driver != NULL);
MOCK_SET(dummy_probe_cb, bool, true);
MOCK_SET_P(nvme_transport_ctrlr_construct,
struct spdk_nvme_ctrlr *, &ut_nvme_transport_ctrlr_construct);
MOCK_SET(dummy_probe_cb, true);
MOCK_SET(nvme_transport_ctrlr_construct, &ctrlr);
TAILQ_INIT(&g_nvme_init_ctrlrs);
rc = nvme_ctrlr_probe(&trid, devhandle, dummy_probe_cb, cb_ctx);
CU_ASSERT(rc == 0);
dummy = TAILQ_FIRST(&g_nvme_init_ctrlrs);
CU_ASSERT(dummy == &ut_nvme_transport_ctrlr_construct);
CU_ASSERT(dummy == ut_nvme_transport_ctrlr_construct);
TAILQ_REMOVE(&g_nvme_init_ctrlrs, dummy, tailq);
MOCK_CLEAR_P(nvme_transport_ctrlr_construct);
free(g_spdk_nvme_driver);
}
@ -774,14 +769,14 @@ test_nvme_robust_mutex_init_shared(void)
int rc = 0;
/* test where both pthread calls succeed */
MOCK_SET(pthread_mutexattr_init, int, 0);
MOCK_SET(pthread_mutex_init, int, 0);
MOCK_SET(pthread_mutexattr_init, 0);
MOCK_SET(pthread_mutex_init, 0);
rc = nvme_robust_mutex_init_shared(&mtx);
CU_ASSERT(rc == 0);
/* test where we can't init attr's but init mutex works */
MOCK_SET(pthread_mutexattr_init, int, -1);
MOCK_SET(pthread_mutex_init, int, 0);
MOCK_SET(pthread_mutexattr_init, -1);
MOCK_SET(pthread_mutex_init, 0);
rc = nvme_robust_mutex_init_shared(&mtx);
/* for FreeBSD the only possible return value is 0 */
#ifndef __FreeBSD__
@ -791,8 +786,8 @@ test_nvme_robust_mutex_init_shared(void)
#endif
/* test where we can init attr's but the mutex init fails */
MOCK_SET(pthread_mutexattr_init, int, 0);
MOCK_SET(pthread_mutex_init, int, -1);
MOCK_SET(pthread_mutexattr_init, 0);
MOCK_SET(pthread_mutex_init, -1);
rc = nvme_robust_mutex_init_shared(&mtx);
/* for FreeBSD the only possible return value is 0 */
#ifndef __FreeBSD__

View File

@ -791,10 +791,10 @@ test_prp_list_append(void)
CU_ASSERT(prp_index == 2);
/* 4K buffer, 4K aligned, but vtophys fails */
ut_fail_vtophys = true;
MOCK_SET(spdk_vtophys, SPDK_VTOPHYS_ERROR);
prp_list_prep(&tr, &req, &prp_index);
CU_ASSERT(nvme_pcie_prp_list_append(&tr, &prp_index, (void *)0x100000, 0x1000, 0x1000) == -EINVAL);
ut_fail_vtophys = false;
MOCK_CLEAR(spdk_vtophys);
/* Largest aligned buffer that can be described in NVME_MAX_PRP_LIST_ENTRIES (plus PRP1) */
prp_list_prep(&tr, &req, &prp_index);

View File

@ -330,8 +330,8 @@ test_connect(void)
req.cmd = &cmd;
req.rsp = &rsp;
MOCK_SET(spdk_nvmf_tgt_find_subsystem, struct spdk_nvmf_subsystem *, &subsystem);
MOCK_SET(spdk_nvmf_poll_group_create, struct spdk_nvmf_poll_group *, &group);
MOCK_SET(spdk_nvmf_tgt_find_subsystem, &subsystem);
MOCK_SET(spdk_nvmf_poll_group_create, &group);
/* Valid admin connect command */
memset(&rsp, 0, sizeof(rsp));
@ -377,7 +377,7 @@ test_connect(void)
/* Subsystem not found */
memset(&rsp, 0, sizeof(rsp));
MOCK_SET(spdk_nvmf_tgt_find_subsystem, struct spdk_nvmf_subsystem *, NULL);
MOCK_SET(spdk_nvmf_tgt_find_subsystem, NULL);
rc = spdk_nvmf_ctrlr_connect(&req);
CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC);
@ -385,7 +385,7 @@ test_connect(void)
CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 1);
CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 256);
CU_ASSERT(qpair.ctrlr == NULL);
MOCK_SET(spdk_nvmf_tgt_find_subsystem, struct spdk_nvmf_subsystem *, &subsystem);
MOCK_SET(spdk_nvmf_tgt_find_subsystem, &subsystem);
/* Unterminated hostnqn */
memset(&rsp, 0, sizeof(rsp));
@ -401,13 +401,13 @@ test_connect(void)
/* Host not allowed */
memset(&rsp, 0, sizeof(rsp));
MOCK_SET(spdk_nvmf_subsystem_host_allowed, bool, false);
MOCK_SET(spdk_nvmf_subsystem_host_allowed, false);
rc = spdk_nvmf_ctrlr_connect(&req);
CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC);
CU_ASSERT(rsp.nvme_cpl.status.sc == SPDK_NVMF_FABRIC_SC_INVALID_HOST);
CU_ASSERT(qpair.ctrlr == NULL);
MOCK_SET(spdk_nvmf_subsystem_host_allowed, bool, true);
MOCK_SET(spdk_nvmf_subsystem_host_allowed, true);
/* Invalid sqsize == 0 */
memset(&rsp, 0, sizeof(rsp));
@ -450,7 +450,7 @@ test_connect(void)
/* Valid I/O queue connect command */
memset(&rsp, 0, sizeof(rsp));
MOCK_SET(spdk_nvmf_subsystem_get_ctrlr, struct spdk_nvmf_ctrlr *, &ctrlr);
MOCK_SET(spdk_nvmf_subsystem_get_ctrlr, &ctrlr);
cmd.connect_cmd.qid = 1;
rc = spdk_nvmf_ctrlr_connect(&req);
CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
@ -460,7 +460,7 @@ test_connect(void)
/* Non-existent controller */
memset(&rsp, 0, sizeof(rsp));
MOCK_SET(spdk_nvmf_subsystem_get_ctrlr, struct spdk_nvmf_ctrlr *, NULL);
MOCK_SET(spdk_nvmf_subsystem_get_ctrlr, NULL);
rc = spdk_nvmf_ctrlr_connect(&req);
CU_ASSERT(rc == SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS);
CU_ASSERT(rsp.nvme_cpl.status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC);
@ -468,7 +468,7 @@ test_connect(void)
CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.iattr == 1);
CU_ASSERT(rsp.connect_rsp.status_code_specific.invalid.ipo == 16);
CU_ASSERT(qpair.ctrlr == NULL);
MOCK_SET(spdk_nvmf_subsystem_get_ctrlr, struct spdk_nvmf_ctrlr *, &ctrlr);
MOCK_SET(spdk_nvmf_subsystem_get_ctrlr, &ctrlr);
/* I/O connect to discovery controller */
memset(&rsp, 0, sizeof(rsp));
@ -546,8 +546,8 @@ test_connect(void)
CU_ASSERT(qpair.ctrlr == NULL);
/* Clean up globals */
MOCK_SET(spdk_nvmf_tgt_find_subsystem, struct spdk_nvmf_subsystem *, NULL);
MOCK_SET(spdk_nvmf_poll_group_create, struct spdk_nvmf_poll_group *, NULL);
MOCK_CLEAR(spdk_nvmf_tgt_find_subsystem);
MOCK_CLEAR(spdk_nvmf_poll_group_create);
spdk_bit_array_free(&ctrlr.qpair_mask);
spdk_free_thread();