1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 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 bool ut_ ## fn ## _mocked = false; \ 53 ret ut_ ## fn; \ 54 __attribute__((used)) ret __wrap_ ## fn dargs \ 55 { \ 56 if (!ut_ ## fn ## _mocked) { \ 57 return __real_ ## fn pargs; \ 58 } else { \ 59 return ut_ ## fn; \ 60 } \ 61 } 62 63 /* DEFINE_STUB is for defining the implementation of stubs for SPDK funcs. */ 64 #define DEFINE_STUB(fn, ret, dargs, val) \ 65 bool ut_ ## fn ## _mocked = true; \ 66 ret ut_ ## fn = val; \ 67 ret fn dargs; \ 68 ret fn dargs \ 69 { \ 70 return MOCK_GET(fn); \ 71 } 72 73 /* DEFINE_STUB_V macro is for stubs that don't have a return value */ 74 #define DEFINE_STUB_V(fn, dargs) \ 75 void fn dargs; \ 76 void fn dargs \ 77 { \ 78 } 79 80 #define HANDLE_RETURN_MOCK(fn) \ 81 if (ut_ ## fn ## _mocked) { \ 82 return ut_ ## fn; \ 83 } 84 85 86 /* declare wrapper protos (alphabetically please) here */ 87 DECLARE_WRAPPER(calloc, void *, (size_t nmemb, size_t size)); 88 89 DECLARE_WRAPPER(pthread_mutex_init, int, 90 (pthread_mutex_t *mtx, const pthread_mutexattr_t *attr)); 91 92 DECLARE_WRAPPER(pthread_mutexattr_init, int, 93 (pthread_mutexattr_t *attr)); 94 95 DECLARE_WRAPPER(recvmsg, ssize_t, (int sockfd, struct msghdr *msg, int flags)); 96 97 DECLARE_WRAPPER(sendmsg, ssize_t, (int sockfd, const struct msghdr *msg, int flags)); 98 99 DECLARE_WRAPPER(writev, ssize_t, (int fd, const struct iovec *iov, int iovcnt)); 100 101 /* unlink is done a bit differently. */ 102 extern char *g_unlink_path; 103 extern void (*g_unlink_callback)(void); 104 /* If g_unlink_path is NULL, __wrap_unlink will return ENOENT. 105 * If the __wrap_unlink() parameter does not match g_unlink_path, it will return ENOENT. 106 * If g_unlink_path does match, and g_unlink_callback has been set, g_unlink_callback will 107 * be called before returning 0. 108 */ 109 int __wrap_unlink(const char *path); 110 111 #endif /* SPDK_INTERNAL_MOCK_H */ 112