diff --git a/lib/common/Makefile.am b/lib/common/Makefile.am index 2fa1c1db8c..ae8c0d08d8 100644 --- a/lib/common/Makefile.am +++ b/lib/common/Makefile.am @@ -1,99 +1,99 @@ # # Copyright 2004-2021 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. # include $(top_srcdir)/mk/common.mk AM_CPPFLAGS += -I$(top_builddir)/lib/gnu -I$(top_srcdir)/lib/gnu MOSTLYCLEANFILES = md5.c ## libraries lib_LTLIBRARIES = libcrmcommon.la # Disable -Wcast-qual if used, because we do some hacky casting, # and because libxml2 has some signatures that should be const but aren't # for backward compatibility reasons. # s390 needs -fPIC # s390-suse-linux/bin/ld: .libs/ipc.o: relocation R_390_PC32DBL against `__stack_chk_fail@@GLIBC_2.4' can not be used when making a shared object; recompile with -fPIC CFLAGS = $(CFLAGS_COPY:-Wcast-qual=) -fPIC SUBDIRS = tests -noinst_HEADERS = crmcommon_private.h +noinst_HEADERS = crmcommon_private.h mock_private.h libcrmcommon_la_LDFLAGS = -version-info 41:0:7 libcrmcommon_la_CFLAGS = $(CFLAGS_HARDENED_LIB) libcrmcommon_la_LDFLAGS += $(LDFLAGS_HARDENED_LIB) libcrmcommon_la_LIBADD = @LIBADD_DL@ # If configured with --with-profiling or --with-coverage, BUILD_PROFILING will # be set and -fno-builtin will be added to the CFLAGS. However, libcrmcommon # uses the fabs() function which is normally supplied by gcc as one of its # builtins. Therefore we need to explicitly link against libm here or the # tests won't link. if BUILD_PROFILING libcrmcommon_la_LIBADD += -lm endif # Use += rather than backlashed continuation lines for parsing by bumplibs libcrmcommon_la_SOURCES = libcrmcommon_la_SOURCES += acl.c libcrmcommon_la_SOURCES += agents.c libcrmcommon_la_SOURCES += alerts.c libcrmcommon_la_SOURCES += attrd_client.c if BUILD_CIBSECRETS libcrmcommon_la_SOURCES += cib_secrets.c endif libcrmcommon_la_SOURCES += cmdline.c libcrmcommon_la_SOURCES += digest.c libcrmcommon_la_SOURCES += io.c libcrmcommon_la_SOURCES += ipc_client.c libcrmcommon_la_SOURCES += ipc_common.c libcrmcommon_la_SOURCES += ipc_controld.c libcrmcommon_la_SOURCES += ipc_pacemakerd.c libcrmcommon_la_SOURCES += ipc_server.c libcrmcommon_la_SOURCES += iso8601.c libcrmcommon_la_SOURCES += lists.c libcrmcommon_la_SOURCES += logging.c libcrmcommon_la_SOURCES += mainloop.c libcrmcommon_la_SOURCES += messages.c libcrmcommon_la_SOURCES += nvpair.c libcrmcommon_la_SOURCES += operations.c libcrmcommon_la_SOURCES += options.c libcrmcommon_la_SOURCES += output.c libcrmcommon_la_SOURCES += output_html.c libcrmcommon_la_SOURCES += output_log.c libcrmcommon_la_SOURCES += output_none.c libcrmcommon_la_SOURCES += output_text.c libcrmcommon_la_SOURCES += output_xml.c libcrmcommon_la_SOURCES += patchset.c libcrmcommon_la_SOURCES += pid.c libcrmcommon_la_SOURCES += procfs.c libcrmcommon_la_SOURCES += remote.c libcrmcommon_la_SOURCES += results.c libcrmcommon_la_SOURCES += schemas.c libcrmcommon_la_SOURCES += strings.c libcrmcommon_la_SOURCES += utils.c libcrmcommon_la_SOURCES += watchdog.c libcrmcommon_la_SOURCES += xml.c libcrmcommon_la_SOURCES += xpath.c # It's possible to build the library adding ../gnu/md5.c directly to SOURCES, # but distclean chokes on that because it tries to include the source's .Plo # file, which may have already been cleaned. nodist_libcrmcommon_la_SOURCES = md5.c md5.c: ../gnu/md5.c cp "$<" "$@" clean-generic: rm -f *.log *.debug *.xml *~ diff --git a/lib/common/mock.c b/lib/common/mock.c new file mode 100644 index 0000000000..6a57fa0f7a --- /dev/null +++ b/lib/common/mock.c @@ -0,0 +1,52 @@ +/* + * Copyright 2021 the Pacemaker project contributors + * + * The version control history for this file may have further details. + * + * This source code is licensed under the GNU Lesser General Public License + * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. + */ + +#include +#include + +#include "mock_private.h" + +/* This file is only used when running "make check". It is built into + * libcrmcommon_test.a, not into libcrmcommon.so. It is used to support + * constructing mock versions of library functions for unit testing. + * + * Each unit test will only ever want to use a mocked version of one or two + * library functions. However, we need to mark all the mocked functions as + * wrapped (with -Wl,--wrap= in the LDFLAGS) in libcrmcommon_test.a so that + * all those unit tests can share the same special test library. The unit + * test then defines its own wrapped function. Because a unit test won't + * define every single wrapped function, there will be undefined references + * at link time. + * + * This file takes care of those undefined references. It defines a + * wrapped version of every function that simply calls the real libc + * version. These wrapped versions are defined with a weak attribute, + * which means the unit tests can define another wrapped version for + * unit testing that will override the version defined here. + * + * IN SUMMARY: + * + * - Define two functions for each function listed in WRAPPED in mock.mk. + * One function is a weakly defined __wrap_X function that just calls + * __real_X. + * - Add a __real_X and __wrap_X function prototype for each function to + * mock_private.h. + * - Each unit test defines its own __wrap_X for whatever function it's + * mocking that overrides the version here. + */ + +char *__attribute__((weak)) +__wrap_getenv(const char *name) { + return __real_getenv(name); +} + +int __attribute__((weak)) +__wrap_uname(struct utsname *buf) { + return __real_uname(buf); +} diff --git a/lib/common/mock_private.h b/lib/common/mock_private.h new file mode 100644 index 0000000000..8b455ec40b --- /dev/null +++ b/lib/common/mock_private.h @@ -0,0 +1,23 @@ +/* + * Copyright 2021 the Pacemaker project contributors + * + * The version control history for this file may have further details. + * + * This source code is licensed under the GNU Lesser General Public License + * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. + */ + +#ifndef MOCK_PRIVATE__H +# define MOCK_PRIVATE__H + +#include + +/* This header is for the sole use of libcrmcommon_test. */ + +char *__real_getenv(const char *name); +char *__wrap_getenv(const char *name); + +int __real_uname(struct utsname *buf); +int __wrap_uname(struct utsname *buf); + +#endif // MOCK_PRIVATE__H