Mock only some functions of a C static library with GMock - c

Given a C library (liblegacy.a) that contains:
function_legacy1()
function_legacy2()
function_legacy3()
...
function_legacy500()
and a C binary (mybin) which links against liblegacy.a:
function_binary1() {
function_legacy1();
function_legacy2();
function_legacy3();
}
function_binary200() {
function_legacy500();
}
and mybin is partially tested with Google Test framework (in progress).
The technical debt is high and it will be a big work to test mybin and/or liblegacy.a.
As a step to remove this debt, I like to start implementing a test for function_binary1 without impacting the rest. My idea would be to mock only the 3 functions used by it (function_legacy1, function_legacy2, function_legacy3) and keep linking against the lib so that I don't have to split the .c/.h files to have only the interesting part in the translation unit.
A first approach would probably to make a dynamic shared library that contains the 3 functions, and use LD_PRELOAD to override these ones at runtime.
Since I'm new with GMock, maybe we can do that in a better way directly with this framework.
Is is possible to mock only some functions of an external lib with GMock to avoid refactoring in this case?
Note: This question is somehow related to, but answers are not very clear to me
Can gmock be used for stubbing C functions?

You might run into problems if you are working with a static library
(liblegacy.a) and a shared library libmock.so (libmock.dylib on
macOS) and if any of the mocked functions is defined in an object file
that also contains an unmocked function.
For example, if you mock function_legacy1() but in liblegacy.a it is
defined in the same object file as function_legacy2(), you might run
into linking conflicts with function_legacy1() being multiply defined,
or you might run into the wrong code being executed at runtime.
Consider the following setup:
legacy.h — declares the legacy functions.
legacy_1_2.c — defines function_legacy1() and function_legacy2().
legacy_3_4.c — defines function_legacy3() and function_legacy4().
mock_1.c — defines function_legacy1().
mock_2.c — defines function_legacy2().
testprog1.c — defines a main() function that calls each of the legacy functions.
testprog2.c — a copy of testprog1.c.
Each of the legacy functions in each source file is the same apart from the name:
void function_legacy1(void)
{
printf("%s:%d:%s()\n", __FILE__, __LINE__, __func__);
}
The main() program looks like:
#include "legacy.h"
#include <stdio.h>
int main(void)
{
printf("%s:%d:%s()\n", __FILE__, __LINE__, __func__);
function_legacy1();
function_legacy2();
function_legacy3();
function_legacy4();
printf("%s:%d:%s()\n", __FILE__, __LINE__, __func__);
return 0;
}
The code can be compiled and run as shown below:
$ gcc -shared -o libmock1.dylib mock_1.c
$ gcc -shared -o libmock2.dylib mock_1.c mock_2.c
$ gcc -o testprog1 testprog1.c -L. -lmock1 -llegacy
$ gcc -o testprog2 testprog2.c -L. -lmock2 -llegacy
$ testprog1
testprog1.c:6:main()
legacy_1_2.c:6:function_legacy1()
legacy_1_2.c:11:function_legacy2()
legacy_3_4.c:6:function_legacy3()
legacy_3_4.c:11:function_legacy4()
testprog1.c:11:main()
$ testprog2
testprog2.c:6:main()
mock_1.c:6:function_legacy1()
mock_2.c:6:function_legacy2()
legacy_3_4.c:6:function_legacy3()
legacy_3_4.c:11:function_legacy4()
testprog2.c:11:main()
$
As you can see, there are no problems linking.
However, testprog1 is linked with a mock library that only includes a
mock for function_legacy1(), and it doesn't see the mocked version of
function_legacy1().
By contrast, testprog2 is linked with a mock library that includes a
mock for function_legacy1() and function_legacy2() and it does see
both the mocked functions.
YMMV on a Linux system, or other non-macOS systems.
Thus, your mocking may or may not work if the legacy functions are defined
several per object file in the static library.

Sounds like you want to conditionally delegate some functions to the real implementation (function_legacy1, function_legacy2, function_legacy3) and the rest to the mock.
I think you should be able to use this recipe.
For mocking stand-alone functions such as function_legacy1, you probably need to wrap them inside a virtual class first. Something like this:
class LegacyInterface {
public:
...
virtual bool function_legacy1(int p) = 0;
virtual bool function_legacy2(int p) = 0;
...
virtual bool function_legacyn(int p) = 0;
};
// This should be used in production.
class LegacyProduction : public LegacyInterface {
public:
bool function_legacy1(int p) override {
return ::function_legacy1(p); // Calling the real function_legacy1
}
bool function_legacy2(int p) override {
return ::function_legacy2(p); // Calling the real function_legacy2
}
...
bool function_legacyn(int p) override {
return ::function_legacyn(p); // Calling the real function_legacyn
}
};
// This should be used in test.
class LegacyMock : public LegacyInterface {
public:
// Normal mock method definitions using gMock.
MOCK_METHOD(bool, function_legacy1, (int p), (override));
MOCK_METHOD(bool, function_legacy2, (int p), (override));
...
MOCK_METHOD(bool, function_legacyn, (int p), (override));
// Delegates the default actions of function_legacy500 to the real implementation.
void Delegate500ToReal() {
ON_CALL(*this, function_legacy500).WillByDefault([this](int n) {
return ::function_legacy500(n); // Calling the real function_legacy500
});
}
};
Now you should change your code to use the wrapper class:
function_binary1(LegacyInterface *legacy_wrapper) {
legacy_wrapper->function_legacy1();
legacy_wrapper->function_legacy2();
legacy_wrapper->function_legacy3();
}
function_binary200(LegacyInterface *legacy_wrapper) {
legacy_wrapper->function_legacy500();
}
where you initialize legacy_wrapper for test:
LegacyInterface *legacy_wrapper = new LegacyMock;
And for production:
LegacyInterface *legacy_wrapper = new LegacyProduction;
So your test would be:
TEST(LegacyTest, function_binary1) {
LegacyMock legacy_wrapper;
EXPECT_CALL(foo, function_binary1(_));
EXPECT_CALL(foo, function_binary2(_));
EXPECT_CALL(foo, function_binary3(_));
// Assert
EXPECT_EQ(function_binary1(&legacy_wrapper), ...);
}
TEST(LegacyTest, function_binary200) {
LegacyMock legacy_wrapper;
legacy_wrapper.Delegate500ToReal();
// No action specified, meaning to use the default action, which is calling the real function_legacy500.
EXPECT_CALL(foo, function_legacy500(_));
// Assert
EXPECT_EQ(function_binary200(), ...);
}
The above code can still be linked against the legacy lib as was before.

Related

Ways to mock C functions for unit-testing?

I've tried multiple sources for solutions to this problem. They all either require modifying the source code, and architecture specific exploit such as writing in a jmp instruction to detour the function, or using a macro and including the c file. The first one is extremely annoying to deal with, the second is usually not possible due to page protections, and the third introduces a lot of problems with linking multiple files containing different mocks and unit test for the same source file. Is there any better method of doing this?
You can user function pointer in your nominal code. You assign them at init with nominal implemetation in your application. In your unit test you can then assign the function pointer to the mock implmentation. Function pointer is a common practice used to implement interface in C.
Here is a gist of how that could be done:
typedef struct {
void (*method) ();
} interface;
void run(itf *interface)
{
itf->method();
}
void methodImpl()
{
printf("nominal code");
}
void methodMock()
{
printf("mock code");
}
void do_run()
{
interface itf;
itf.method = methodImpl;
run(&itf);
}
void test_run()
{
interface itf;
itf.method = methodMock;
run(&itf);
}

Attempting to mock `abort` using CMocka and `gcc -Wl,wrap...`

I am building unit tests with CMocka. My function char some_func(some_enum e) maps valid values of e to a char. It uses assert to check e is valid, which by definition calls abort if not.
Mocking abort is proving to be hard. Following this example and building a function ...
static volatile abort_calls = 0;
void
__wrap_abort(void)
{
fprintf(stderr, "Call to __wrap_abort()\n");
abort_calls++;
}
static void
test_some_func(void **state)
{
some_func( (some_enum)99);
assert_int_equal(1, abort_calls);
}
.. that when compiled with -Wl,--wrap=abort makes no complaints. However, when executed it does not call __wrap_abort.
Is what I'm attempting even possible?

C99: Dynamic dispatch in a static library

Say I am developing a Math library and I want it to be such that it will detect whether or not user's machine support SSE (and which version) and based on that, separate internal functions will be called for the same API function. I can think of three ways to implement that:
Have global function pointers in the library and let user call mathInit() in their source. When they do, figure out the hardware details and assign the function pointers to different functions.
Same, except instead of having global function pointers, put them in a struct which is returned by mathInit(). This way, user will have to call math.vec3Add(...) or similar.
Same as 1, but instead of having global pointers, make mathInit() a macro so that the function pointers will have local scope in user's main() function (and require mathInit() to be called from main()). It will be in a header, of course.
Is any of these methods preferable? Is there some other, better way?
This is largely opinion-based, IMHO.
And my opinion is, a math library should expose the least possible amount of details about its internal workings and should not require tricky function pointers or data structures or even macros to work with to the user code, if possible.
I'd go with (1) and assume you would completely hide the function pointers in your library, i.e. call them through an indirection in library code.
(3) is definitely the worst option, because it puts restrictions on the user code that are not directly obvious. It might also create non-obvious problems/observations when debugging user code.
(2) Is a pretty uncommon way to present a library and requires at least intermediate C fluency, and might put off non-expert C users.
You could also expose a hasSSEfunction along with SSE and non-SSE functions and leave the decision what to use to the user code. Not sure that would have any benefits over (1), though.
My suggestion will be compiling a separate unit for each instruction set (e.g. Xnosse.o Xsse3.o Xsse4.o, etc.) and use an automatic dispatcher for those. The user needs to get the best performance for his PC, and not care about the inside detailing.
Since you wrote your code runs in a library, you can make the dispatch decision on load time automatically by using an init function that will be called on library load. You can also make this decision run only the firsts time a function is actually called, this is for lazy binding.
Here is a code example (gcc only!)
Compilation units:
//Xnosse.c
void do_some_math_stuff_no_sse(int x, int y)
{
...do some sophisticated math stuff with no sse support
}
void do_some_other_math_stuff_no_sse(int x, int y)
{
...do some other sophisticated math stuff with no sse support
}
//Xsse3.c
void do_some_math_stuff_sse3(int x, int y)
{
...do some sophisticated math stuff with sse3 support
}
void do_some_other_math_stuff_sse3(int x, int y)
{
...do some other sophisticated math stuff with sse3 support
}
//Xsse4.c
void do_some_math_stuff_sse4(int x, int y)
{
...do some sophisticated math stuff with sse4 support
}
void do_some_other_math_stuff_sse4(int x, int y)
{
...do some other sophisticated math stuff with sse4 support
}
Now to the library:
//my_math.h
/* Following definitions are in my_math.c */
extern void (*do_some_math_stuff)(int x, int, y);
extern void (*do_some_other_math_stuff)(int x, int y);
//my_math.c
void not_set(int x, int y)
{
// If you don't want to use the constructor for any reason,
// say you want lazy binding, this will do the trick as our
// functions do_math_stuff and do_other_math_stuff are initialized
// to this one
setup();
}
void (*do_some_math_stuff)(int x, int, y) = not_set;
void (*do_some_other_math_stuff)(int x, int y) = not_set;
int detect_sse()
{
..Do runtime detection of sse version
}
/* The following function will be called when your library loads */
void __attribute__ ((constructor)) setup(void)
{
if (detect_sse() == 0)
{
do_some_math_stuff = do_some_math_stuff_no_sse;
do_some_other_math_stuff = do_some_other_math_stuff_no_sse;
}
else if (detect_sse() == 3)
{
do_some_math_stuff = do_some_math_stuff_sse3;
do_some_other_math_stuff = do_some_other_math_stuff_sse3;
}
else if (detect_sse() == 4)
{
do_some_math_stuff = do_some_math_stuff_sse4;
do_some_other_math_stuff = do_some_other_math_stuff_sse4;
}
}
If you want lazy binding, remove constructor decorater from setup and compile with:
gcc -Wall -shared -fPIC -o libmy_math.so my_math.c Xnosse.c Xsse3.c Xsse4.c
If you want the dynamic dispatcher to run when the library loads use the following additional parameters to gcc:
gcc -Wall -shared -Wl,-init,setup -fPIC -o libmy_math.so my_math.c Xnosse.c Xsse3.c Xsse4.c

Can you run a function on initialization in c?

Is there an mechanism or trick to run a function when a program loads?
What I'm trying to achieve...
void foo(void)
{
}
register_function(foo);
but obviously register_function won't run.
so a trick in C++ is to use initialization to make a function run
something like
int throwaway = register_function(foo);
but that doesn't work in C. So I'm looking for a way around this using standard C (nothing platform / compiler specific )
If you are using GCC, you can do this with a constructor function attribute, eg:
#include <stdio.h>
void foo() __attribute__((constructor));
void foo() {
printf("Hello, world!\n");
}
int main() { return 0; }
There is no portable way to do this in C, however.
If you don't mind messing with your build system, though, you have more options. For example, you can:
#define CONSTRUCTOR_METHOD(methodname) /* null definition */
CONSTRUCTOR_METHOD(foo)
Now write a build script to search for instances of CONSTRUCTOR_METHOD, and paste a sequence of calls to them into a function in a generated .c file. Invoke the generated function at the start of main().
Standard C does not support such an operation. If you don't wish to use compiler specific features to do this, then your next best bet might be to create a global static flag that is initialized to false. Then whenever someone invokes one of your operations that require the function pointer to be registered, you check that flag. If it is false you register the function then set the flag to true. Subsequent calls then won't have to perform the registration. This is similar to the lazy instantiation used in the OO Singleton design pattern.
There is no standard way of doing this although gcc provides a constructor attribute for functions.
The usual way of ensuring some pre-setup has been done (other than a simple variable initialization to a compile time value) is to make sure that all functions requiring that pre-setup. In other words, something like:
static int initialized = 0;
static int x;
int returnX (void) {
if (!initialized) {
x = complicatedFunction();
initialized = 1;
}
return x;
}
This is best done in a separate library since it insulates you from the implementation.

How can I check that all my init functions have been called?

I am writing a large C program for embedded use. Every module in this program has an init() function (like a constructor) to set up its static variables.
The problem is that I have to remember to call all of these init functions from main(). I also have to remember to put them back if I have commented them out for some reason.
Is there anything clever I do to make sure that all of these functions are getting called? Something along the lines of putting a macro in each init function that, when you call a check_inited() function later, sends a warning to STDOUT if not all the functions are called.
I could increment a counter, but I'd have to maintain the correct number of init functions somewhere and that is also prone to error.
Thoughts?
The following is the solution I decided on, with input from several people in this thread
My goal is to make sure that all my init functions are actually being called. I want to do
this without maintaining lists or counts of modules across several files. I can't call
them automatically as Nick D suggested because they need to be called in a certain order.
To accomplish this, a macro included in every module uses the gcc constructor attribute to
add the init function name to a global list.
Another macro included in the body of the init function updates the global list to make a
note that the function was actually called.
Finally, a check function is called in main() after all of the inits are done.
Notes:
I chose to copy the strings into an array. This not strictly necessary because the
function names passed will always be static strings in normal usage. If memory was short
you could just store a pointer to the string that was passed in.
My reusable library of utility functions is called "nx_lib". Thus all the 'nxl' designations.
This isn't the most efficient code in the world but it's only called a boot time so that
doesn't matter for me.
There are two lines of code that need to be added to each module. If either is omitted,
the check function will let you know.
you might be able to make the constructor function static, which would avoid the need to give it a name that is unique across the project.
this code is only lightly tested and it's really late so please check carefully before trusting it.
Thank you to:
pierr who introduced me to the constructor attribute.
Nick D for demonstrating the ## preprocessor trick and giving me the framework.
tod frye for a clever linker-based approach that will work with many compilers.
Everyone else for helping out and sharing useful tidbits.
nx_lib_public.h
This is the relevant fragment of my library header file
#define NX_FUNC_RUN_CHECK_NAME_SIZE 20
typedef struct _nxl_function_element{
char func[NX_FUNC_RUN_CHECK_NAME_SIZE];
BOOL called;
} nxl_function_element;
void nxl_func_run_check_add(char *func_name);
BOOL nxl_func_run_check(void);
void nxl_func_run_check_hit(char *func_name);
#define NXL_FUNC_RUN_CHECK_ADD(function_name) \
void cons_ ## function_name() __attribute__((constructor)); \
void cons_ ## function_name() { nxl_func_run_check_add(#function_name); }
nxl_func_run_check.c
This is the libary code that is called to add function names and check them later.
#define MAX_CHECKED_FUNCTIONS 100
static nxl_function_element m_functions[MAX_CHECKED_FUNCTIONS];
static int m_func_cnt = 0;
// call automatically before main runs to register a function name.
void nxl_func_run_check_add(char *func_name)
{
// fail and complain if no more room.
if (m_func_cnt >= MAX_CHECKED_FUNCTIONS) {
print ("nxl_func_run_check_add failed, out of space\r\n");
return;
}
strncpy (m_functions[m_func_cnt].func, func_name,
NX_FUNC_RUN_CHECK_NAME_SIZE);
m_functions[m_func_cnt].func[NX_FUNC_RUN_CHECK_NAME_SIZE-1] = 0;
m_functions[m_func_cnt++].called = FALSE;
}
// call from inside the init function
void nxl_func_run_check_hit(char *func_name)
{
int i;
for (i=0; i< m_func_cnt; i++) {
if (! strncmp(m_functions[i].func, func_name,
NX_FUNC_RUN_CHECK_NAME_SIZE)) {
m_functions[i].called = TRUE;
return;
}
}
print("nxl_func_run_check_hit(): error, unregistered function was hit\r\n");
}
// checks that all registered functions were called
BOOL nxl_func_run_check(void) {
int i;
BOOL success=TRUE;
for (i=0; i< m_func_cnt; i++) {
if (m_functions[i].called == FALSE) {
success = FALSE;
xil_printf("nxl_func_run_check error: %s() not called\r\n",
m_functions[i].func);
}
}
return success;
}
solo.c
This is an example of a module that needs initialization
#include "nx_lib_public.h"
NXL_FUNC_RUN_CHECK_ADD(solo_init)
void solo_init(void)
{
nxl_func_run_check_hit((char *) __func__);
/* do module initialization here */
}
You can use gcc's extension __attribute__((constructor)) if gcc is ok for your project.
#include <stdio.h>
void func1() __attribute__((constructor));
void func2() __attribute__((constructor));
void func1()
{
printf("%s\n",__func__);
}
void func2()
{
printf("%s\n",__func__);
}
int main()
{
printf("main\n");
return 0;
}
//the output
func2
func1
main
I don't know how ugly the following looks but I post it anyway :-)
(The basic idea is to register function pointers, like what atexit function does.
Of course atexit implementation is different)
In the main module we can have something like this:
typedef int (*function_t)(void);
static function_t vfunctions[100]; // we can store max 100 function pointers
static int vcnt = 0; // count the registered function pointers
int add2init(function_t f)
{
// todo: error checks
vfunctions[vcnt++] = f;
return 0;
}
...
int main(void) {
...
// iterate vfunctions[] and call the functions
...
}
... and in some other module:
typedef int (*function_t)(void);
extern int add2init(function_t f);
#define M_add2init(function_name) static int int_ ## function_name = add2init(function_name)
int foo(void)
{
printf("foo\n");
return 0;
}
M_add2init(foo); // <--- register foo function
Why not write a post processing script to do the checking for you. Then run that script as part of your build process... Or better yet, make it one of your tests. You are writing tests, right? :)
For example, if each of your modules has a header file, modX.c. And if the signature of your init() function is "void init()"...
Have your script grep through all your .h files, and create a list of module names that need to be init()ed. Then have the script check that init() is indeed called on each module in main().
If your single module represents "class" entity and has instance constructor, you can use following construction:
static inline void init(void) { ... }
static int initialized = 0;
#define INIT if (__predict_false(!initialized)) { init(); initialized = 1; }
struct Foo *
foo_create(void)
{
INIT;
...
}
where "__predict_false" is your compiler's branch prediction hint. When first object is created, module is auto-initialized (for once).
Splint (and probably other Lint variants) can give a warning about functions that are defined but not called.
It's interesting that most compilers will warn you about unused variables, but not unused functions.
Larger running time is not a problem
You can conceivably implement a kind of "state-machine" for each module, wherein the actions of a function depend on the state the module is in. This state can be set to BEFORE_INIT or INITIALIZED.
For example, let's say we have module A with functions foo and bar.
The actual logic of the functions (i.e., what they actually do) would be declared like so:
void foo_logic();
void bar_logic();
Or whatever the signature is.
Then, the actual functions of the module (i.e., the actual function declared foo()) will perform a run-time check of the condition of the module, and decide what to do:
void foo() {
if (module_state == BEFORE_INIT) {
handle_not_initialized_error();
}
foo_logic();
}
This logic is repeated for all functions.
A few things to note:
This will obviously incur a huge penalty performance-wise, so is
probably not a good idea (I posted
anyway because you said runtime is
not a problem).
This is not a real state-machine, since there are only two states which are checked using a basic if, without some kind of smart general logic.
This kind of "design-pattern" works great when you're using separate threads/tasks, and the functions you're calling are actually called using some kind of IPC.
A state machine can be nicely implemented in C++, might be worth reading up on it. The same kind of idea can conceivably be coded in C with arrays of function pointers, but it's almost certainly not worth your time.
you can do something along these lines with a linker section. whenever you define an init function, place a pointer to it in a linker section just for init function pointers. then you can at least find out how many init functions have been compiled.
and if it does not matter what order the init functions are called, and the all have the same prototype, you can just call them all in a loop from main.
the exact details elude my memory, but it works soemthing like this::
in the module file...
//this is the syntax in GCC..(or would be if the underscores came through in this text editor)
initFuncPtr thisInit __attribute((section(.myinits)))__= &moduleInit;
void moduleInit(void)
{
// so init here
}
this places a pointer to the module init function in the .myinits section, but leaves the code in the .code section. so the .myinits section is nothing but pointers. you can think of this as a variable length array that module files can add to.
then you can access the section start and end address from the main. and go from there.
if the init functions all have the same protoytpe, you can just iterate over this section, calling them all.
this, in effect, is creating your own static constructor system in C.
if you are doing a large project and your linker is not at least this fully featured, you may have a problem...
Can I put up an answer to my question?
My idea was to have each function add it's name to a global list of functions, like Nick D's solution.
Then I would run through the symbol table produced by -gstab, and look for any functions named init_* that had not been called.
This is an embedded app so I have the elf image handy in flash memory.
However I don't like this idea because it means I always have to include debugging info in the binary.

Resources