tests: macro-ize the creation and use of wrappers and stubs
Includes macros for wrappers (for syscalls) and stubs (for SPDK functions) including an example of syscall wrapper as well as a stub with both pointer and non pointer values. Change-Id: I9b19d81d5b9cbf2bbb327f58dbf985b3b253e800 Signed-off-by: Paul Luse <paul.e.luse@intel.com> Reviewed-on: https://review.gerrithub.io/366348 Reviewed-by: Jim Harris <james.r.harris@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
parent
a9428cb39e
commit
043d541132
@ -36,15 +36,64 @@
|
|||||||
|
|
||||||
#include "spdk/stdinc.h"
|
#include "spdk/stdinc.h"
|
||||||
|
|
||||||
|
/* used to signify pass through */
|
||||||
|
#define MOCK_PASS_THRU (0xdeadbeef)
|
||||||
|
|
||||||
|
/* 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_GET(fn) \
|
||||||
|
ut_ ## fn
|
||||||
|
|
||||||
|
#define MOCK_GET_P(fn) \
|
||||||
|
ut_p_ ## fn
|
||||||
|
|
||||||
|
/* for declaring function protoypes for wrappers */
|
||||||
#define DECLARE_WRAPPER(fn, ret, args) \
|
#define DECLARE_WRAPPER(fn, ret, args) \
|
||||||
|
extern ret ut_ ## fn; \
|
||||||
ret __wrap_ ## fn args; ret __real_ ## fn args;
|
ret __wrap_ ## fn args; ret __real_ ## fn args;
|
||||||
|
|
||||||
/* define new wrappers (alphabetically please) here using above helper macro */
|
/* for defining the implmentation of wrappers for syscalls */
|
||||||
extern int ut_fake_pthread_mutex_init;
|
#define DEFINE_WRAPPER(fn, ret, dargs, pargs, val) \
|
||||||
|
ret ut_ ## fn = val; \
|
||||||
|
ret __wrap_ ## fn dargs \
|
||||||
|
{ \
|
||||||
|
if (ut_ ## fn == (ret)MOCK_PASS_THRU) { \
|
||||||
|
return __real_ ## fn pargs; \
|
||||||
|
} else { \
|
||||||
|
return MOCK_GET(fn); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for defining the implmentation of stubs for SPDK funcs */
|
||||||
|
/* the _P macro is for stubs that return pointer values */
|
||||||
|
#define DEFINE_STUB(fn, ret, dargs, val) \
|
||||||
|
ret ut_ ## fn = val; \
|
||||||
|
ret fn dargs; \
|
||||||
|
ret fn dargs \
|
||||||
|
{ \
|
||||||
|
return MOCK_GET(fn); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#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); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* declare wrapper protos (alphabetically please) here */
|
||||||
DECLARE_WRAPPER(pthread_mutex_init, int,
|
DECLARE_WRAPPER(pthread_mutex_init, int,
|
||||||
(pthread_mutex_t *mtx, const pthread_mutexattr_t *attr));
|
(pthread_mutex_t *mtx, const pthread_mutexattr_t *attr));
|
||||||
|
|
||||||
extern int ut_fake_pthread_mutexattr_init;
|
|
||||||
DECLARE_WRAPPER(pthread_mutexattr_init, int,
|
DECLARE_WRAPPER(pthread_mutexattr_init, int,
|
||||||
(pthread_mutexattr_t *attr));
|
(pthread_mutexattr_t *attr));
|
||||||
|
|
@ -34,7 +34,7 @@
|
|||||||
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
|
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
|
||||||
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
||||||
|
|
||||||
C_SRCS = spdk_mock.c
|
C_SRCS = mock.c
|
||||||
LIBNAME = spdk_mock
|
LIBNAME = spdk_mock
|
||||||
|
|
||||||
include $(SPDK_ROOT_DIR)/mk/spdk.lib.mk
|
include $(SPDK_ROOT_DIR)/mk/spdk.lib.mk
|
||||||
|
@ -31,26 +31,11 @@
|
|||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "spdk_internal/spdk_mock.h"
|
#include "spdk_internal/mock.h"
|
||||||
|
|
||||||
int ut_fake_pthread_mutex_init = 0;
|
DEFINE_WRAPPER(pthread_mutex_init, int,
|
||||||
int
|
(pthread_mutex_t *mtx, const pthread_mutexattr_t *attr),
|
||||||
__wrap_pthread_mutex_init(pthread_mutex_t *mtx, const pthread_mutexattr_t *attr)
|
(mtx, attr), MOCK_PASS_THRU)
|
||||||
{
|
|
||||||
if (ut_fake_pthread_mutex_init == 0) {
|
|
||||||
return __real_pthread_mutex_init(mtx, attr);
|
|
||||||
} else {
|
|
||||||
return ut_fake_pthread_mutex_init;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int ut_fake_pthread_mutexattr_init = 0;
|
DEFINE_WRAPPER(pthread_mutexattr_init, int,
|
||||||
int
|
(pthread_mutexattr_t *attr), (attr), MOCK_PASS_THRU)
|
||||||
__wrap_pthread_mutexattr_init(pthread_mutexattr_t *attr)
|
|
||||||
{
|
|
||||||
if (ut_fake_pthread_mutexattr_init == 0) {
|
|
||||||
return __real_pthread_mutexattr_init(attr);
|
|
||||||
} else {
|
|
||||||
return ut_fake_pthread_mutexattr_init;
|
|
||||||
}
|
|
||||||
}
|
|
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
#include "lib/test_env.c"
|
#include "lib/test_env.c"
|
||||||
|
|
||||||
#include "spdk_internal/spdk_mock.h"
|
#include "spdk_internal/mock.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
spdk_pci_nvme_enumerate(spdk_pci_enum_cb enum_cb, void *enum_ctx)
|
spdk_pci_nvme_enumerate(spdk_pci_enum_cb enum_cb, void *enum_ctx)
|
||||||
@ -63,13 +63,6 @@ spdk_nvme_transport_available(enum spdk_nvme_transport_type trtype)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct spdk_nvme_ctrlr *nvme_transport_ctrlr_construct(const struct spdk_nvme_transport_id *trid,
|
|
||||||
const struct spdk_nvme_ctrlr_opts *opts,
|
|
||||||
void *devhandle)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
nvme_transport_ctrlr_scan(const struct spdk_nvme_transport_id *trid,
|
nvme_transport_ctrlr_scan(const struct spdk_nvme_transport_id *trid,
|
||||||
void *cb_ctx,
|
void *cb_ctx,
|
||||||
@ -153,19 +146,66 @@ memset_trid(struct spdk_nvme_transport_id *trid1, struct spdk_nvme_transport_id
|
|||||||
memset(trid2, 0, sizeof(struct spdk_nvme_transport_id));
|
memset(trid2, 0, sizeof(struct spdk_nvme_transport_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(dummy_probe_cb, bool,
|
||||||
|
(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
|
||||||
|
struct spdk_nvme_ctrlr_opts *opts), false)
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_nvme_ctrlr_probe(void)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
const struct spdk_nvme_transport_id *trid = NULL;
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
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);
|
||||||
|
TAILQ_INIT(&g_spdk_nvme_driver->init_ctrlrs);
|
||||||
|
rc = nvme_ctrlr_probe(trid, devhandle, dummy_probe_cb, cb_ctx);
|
||||||
|
CU_ASSERT(rc == 0);
|
||||||
|
dummy = TAILQ_FIRST(&g_spdk_nvme_driver->init_ctrlrs);
|
||||||
|
CU_ASSERT(dummy == &ut_nvme_transport_ctrlr_construct);
|
||||||
|
|
||||||
|
free(g_spdk_nvme_driver);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_nvme_robust_mutex_init_shared(void)
|
test_nvme_robust_mutex_init_shared(void)
|
||||||
{
|
{
|
||||||
pthread_mutex_t mtx;
|
pthread_mutex_t mtx;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
ut_fake_pthread_mutexattr_init = 0;
|
/* test where both pthread calls succeed */
|
||||||
ut_fake_pthread_mutex_init = 0;
|
MOCK_SET(pthread_mutexattr_init, int, 0)
|
||||||
|
MOCK_SET(pthread_mutex_init, int, 0)
|
||||||
rc = nvme_robust_mutex_init_shared(&mtx);
|
rc = nvme_robust_mutex_init_shared(&mtx);
|
||||||
CU_ASSERT(rc == 0);
|
CU_ASSERT(rc == 0);
|
||||||
|
|
||||||
ut_fake_pthread_mutexattr_init = -1;
|
/* test where we can't init attr's but init mutex works */
|
||||||
ut_fake_pthread_mutex_init = 0;
|
MOCK_SET(pthread_mutexattr_init, int, -1)
|
||||||
|
MOCK_SET(pthread_mutex_init, int, 0)
|
||||||
rc = nvme_robust_mutex_init_shared(&mtx);
|
rc = nvme_robust_mutex_init_shared(&mtx);
|
||||||
/* for FreeBSD the only possible return value is 0 */
|
/* for FreeBSD the only possible return value is 0 */
|
||||||
#ifndef __FreeBSD__
|
#ifndef __FreeBSD__
|
||||||
@ -174,9 +214,11 @@ test_nvme_robust_mutex_init_shared(void)
|
|||||||
CU_ASSERT(rc == 0);
|
CU_ASSERT(rc == 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ut_fake_pthread_mutexattr_init = 0;
|
/* test where we can init attr's but the mutex init fails */
|
||||||
ut_fake_pthread_mutex_init = -1;
|
MOCK_SET(pthread_mutexattr_init, int, 0)
|
||||||
|
MOCK_SET(pthread_mutex_init, int, -1)
|
||||||
rc = nvme_robust_mutex_init_shared(&mtx);
|
rc = nvme_robust_mutex_init_shared(&mtx);
|
||||||
|
/* for FreeBSD the only possible return value is 0 */
|
||||||
#ifndef __FreeBSD__
|
#ifndef __FreeBSD__
|
||||||
CU_ASSERT(rc != 0);
|
CU_ASSERT(rc != 0);
|
||||||
#else
|
#else
|
||||||
@ -447,8 +489,12 @@ int main(int argc, char **argv)
|
|||||||
test_spdk_nvme_transport_id_parse_adrfam) == NULL ||
|
test_spdk_nvme_transport_id_parse_adrfam) == NULL ||
|
||||||
CU_add_test(suite, "test_trid_parse_and_compare",
|
CU_add_test(suite, "test_trid_parse_and_compare",
|
||||||
test_trid_parse_and_compare) == NULL ||
|
test_trid_parse_and_compare) == NULL ||
|
||||||
CU_add_test(suite, "test_trid_trtype_str", test_trid_trtype_str) == NULL ||
|
CU_add_test(suite, "test_trid_trtype_str",
|
||||||
CU_add_test(suite, "test_trid_adrfam_str", test_trid_adrfam_str) == NULL ||
|
test_trid_trtype_str) == NULL ||
|
||||||
|
CU_add_test(suite, "test_trid_adrfam_str",
|
||||||
|
test_trid_adrfam_str) == NULL ||
|
||||||
|
CU_add_test(suite, "test_nvme_ctrlr_probe",
|
||||||
|
test_nvme_ctrlr_probe) == NULL ||
|
||||||
CU_add_test(suite, "test_nvme_robust_mutex_init_shared",
|
CU_add_test(suite, "test_nvme_robust_mutex_init_shared",
|
||||||
test_nvme_robust_mutex_init_shared) == NULL
|
test_nvme_robust_mutex_init_shared) == NULL
|
||||||
) {
|
) {
|
||||||
|
Loading…
Reference in New Issue
Block a user