1 /*
2 * Copyright 2021-2022 the Pacemaker project contributors
3 *
4 * The version control history for this file may have further details.
5 *
6 * This source code is licensed under the GNU Lesser General Public License
7 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8 */
9
10 #include <pwd.h>
11 #include <stdlib.h>
12 #include <sys/types.h>
13 #include <sys/utsname.h>
14
15 #include "mock_private.h"
16
17 /* This file is only used when running "make check". It is built into
18 * libcrmcommon_test.a, not into libcrmcommon.so. It is used to support
19 * constructing mock versions of library functions for unit testing.
20 *
21 * Each unit test will only ever want to use a mocked version of one or two
22 * library functions. However, we need to mark all the mocked functions as
23 * wrapped (with -Wl,--wrap= in the LDFLAGS) in libcrmcommon_test.a so that
24 * all those unit tests can share the same special test library. The unit
25 * test then defines its own wrapped function. Because a unit test won't
26 * define every single wrapped function, there will be undefined references
27 * at link time.
28 *
29 * This file takes care of those undefined references. It defines a
30 * wrapped version of every function that simply calls the real libc
31 * version. These wrapped versions are defined with a weak attribute,
32 * which means the unit tests can define another wrapped version for
33 * unit testing that will override the version defined here.
34 *
35 * HOW TO ADD A MOCKED FUNCTION:
36 *
37 * - Define a __wrap_X function here below with the same prototype as the
38 * actual function and that just calls __real_X.
39 * - Add a __real_X and __wrap_X function prototype to mock_private.h.
40 * - Add the function name to the WRAPPED variable in Makefile.am.
41 *
42 * HOW TO USE A MOCKED FUNCTION:
43 *
44 * - In the Makefile.am for your new test, add:
45 *
46 * your_fn_test_LDADD = $(top_builddir)/lib/common/libcrmcommon_test.la -lcmocka
47 * your_fn_test_LDFLAGS = -Wl,--wrap=X
48 *
49 * You can use multiple wrapped functions by adding multiple -Wl
50 * arguments.
51 * - #include "mock_private.h" in your test file.
52 * - Add a __wrap_X function with the same prototype as the real function.
53 * - Write your test cases, using will_return(), mock_type(), and
54 * mock_ptr_type() from cmocka. See existing test cases for details.
55 */
56
57 void *__attribute__((weak))
58 __wrap_calloc(size_t nmemb, size_t size) {
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
59 return __real_calloc(nmemb, size);
60 }
61
62 char *__attribute__((weak))
63 __wrap_getenv(const char *name) {
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
64 return __real_getenv(name);
65 }
66
67 int __attribute__((weak))
68 __wrap_getpwnam_r(const char *name, struct passwd *pwd,
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
69 char *buf, size_t buflen, struct passwd **result) {
70 return __real_getpwnam_r(name, pwd, buf, buflen, result);
71 }
72
73 int __attribute__((weak))
74 __wrap_uname(struct utsname *buf) {
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
75 return __real_uname(buf);
76 }