1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2017 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #ifndef SPDK_INTERNAL_MOCK_H 7 #define SPDK_INTERNAL_MOCK_H 8 9 #include "spdk/stdinc.h" 10 11 #define MOCK_STRUCT_INIT(...) \ 12 { __VA_ARGS__ } 13 14 #define DEFINE_RETURN_MOCK(fn, ret) \ 15 bool ut_ ## fn ## _mocked = false; \ 16 ret ut_ ## fn 17 18 /* 19 * For controlling mocked function behavior, setting 20 * and getting values from the stub, the _P macros are 21 * for mocking functions that return pointer values. 22 */ 23 #define MOCK_SET(fn, val) \ 24 ut_ ## fn ## _mocked = true; \ 25 ut_ ## fn = val 26 27 #define MOCK_GET(fn) \ 28 ut_ ## fn 29 30 #define MOCK_CLEAR(fn) \ 31 ut_ ## fn ## _mocked = false 32 33 #define MOCK_CLEAR_P(fn) \ 34 ut_ ## fn ## _mocked = false; \ 35 ut_ ## fn = NULL 36 37 /* for proving to *certain* static analysis tools that we didn't reset the mock function. */ 38 #define MOCK_CLEARED_ASSERT(fn) \ 39 SPDK_CU_ASSERT_FATAL(ut_ ## fn ## _mocked == false) 40 41 /* for declaring function protoypes for wrappers */ 42 #define DECLARE_WRAPPER(fn, ret, args) \ 43 extern bool ut_ ## fn ## _mocked; \ 44 extern ret ut_ ## fn; \ 45 ret __wrap_ ## fn args; ret __real_ ## fn args 46 47 /* 48 * For defining the implementation of wrappers for syscalls. 49 * Avoid nested macro calls to prevent macro expansion of fn. 50 */ 51 #define DEFINE_WRAPPER(fn, ret, dargs, pargs) \ 52 DEFINE_WRAPPER_MOCK(fn, ret); \ 53 __attribute__((used)) ret __wrap_ ## fn dargs \ 54 { \ 55 if (!ut_ ## fn ## _mocked) { \ 56 return __real_ ## fn pargs; \ 57 } else { \ 58 return ut_ ## fn; \ 59 } \ 60 } 61 62 #define DEFINE_WRAPPER_MOCK(fn, ret) \ 63 bool ut_ ## fn ## _mocked = false; \ 64 ret ut_ ## fn 65 66 /* DEFINE_STUB is for defining the implementation of stubs for SPDK funcs. */ 67 #define DEFINE_STUB(fn, ret, dargs, val) \ 68 bool ut_ ## fn ## _mocked = true; \ 69 ret ut_ ## fn = val; \ 70 ret fn dargs; \ 71 ret fn dargs \ 72 { \ 73 return MOCK_GET(fn); \ 74 } 75 76 /* DEFINE_STUB_V macro is for stubs that don't have a return value */ 77 #define DEFINE_STUB_V(fn, dargs) \ 78 void fn dargs; \ 79 void fn dargs \ 80 { \ 81 } 82 83 #define HANDLE_RETURN_MOCK(fn) \ 84 if (ut_ ## fn ## _mocked) { \ 85 return ut_ ## fn; \ 86 } 87 88 89 /* declare wrapper protos (alphabetically please) here */ 90 DECLARE_WRAPPER(calloc, void *, (size_t nmemb, size_t size)); 91 92 DECLARE_WRAPPER(pthread_mutex_init, int, 93 (pthread_mutex_t *mtx, const pthread_mutexattr_t *attr)); 94 95 DECLARE_WRAPPER(pthread_mutexattr_init, int, 96 (pthread_mutexattr_t *attr)); 97 98 DECLARE_WRAPPER(recvmsg, ssize_t, (int sockfd, struct msghdr *msg, int flags)); 99 100 DECLARE_WRAPPER(sendmsg, ssize_t, (int sockfd, const struct msghdr *msg, int flags)); 101 102 DECLARE_WRAPPER(writev, ssize_t, (int fd, const struct iovec *iov, int iovcnt)); 103 104 /* unlink is done a bit differently. */ 105 extern char *g_unlink_path; 106 extern void (*g_unlink_callback)(void); 107 /* If g_unlink_path is NULL, __wrap_unlink will return ENOENT. 108 * If the __wrap_unlink() parameter does not match g_unlink_path, it will return ENOENT. 109 * If g_unlink_path does match, and g_unlink_callback has been set, g_unlink_callback will 110 * be called before returning 0. 111 */ 112 int __wrap_unlink(const char *path); 113 114 #endif /* SPDK_INTERNAL_MOCK_H */ 115