Can a header with declared functions be mocked? - c

I'm working in a project targeting a Silicon Labs microcontroller. I want to create a wrapper for the Bluetooth SDK calls. SDK libraries are heavy on dependencies, so by creating a seem in that interface, I can avoid adding them to my tests. Note that this problem is not specific of the Silicon Labs platform, but I will leave the SiLabs SDK file names in case the reader is familiar with the platform.
I'm using CPPUTest as my testing framework. My code is a mix of C and C++, but for the purposes of this question, it's C.
For example, one of my wrapping functions (in a module called Bluetooth_HW) would be
/* On "Bluetooth_HW.c" */
#include "native_gecko.h" // declares gecko_cmd_le_gap_bt5_set_adv_data()
// Set a new advertisement, either as advertisement packet or as a response.
bool BT_setAdvertisementMessage(uint8_t scanResponse, uint8_t adLength, uint8_t* newAdvertisement) {
uint16_t result = gecko_cmd_le_gap_bt5_set_adv_data(0, scanResponse, adLength, newAdvertisement)->result;
if (result != bg_err_success) {
return false;
} // Else, no errors setting the advertisement
return true;
}
BT_setAdvertisementMessage() wraps gecko_cmd_le_gap_bt5_set_adv_data(), which is defined in native_gecko.h, an SDK header file. I declare BT_setAdvertisementMessage() in Bluetooth_HW.h and define it in bluetooth_HW.c. My code that needs to set the advertisement message then includes Bluetooth_HW.h instead of native_gecko.h, and Bluetooth_HW.h is easy to mock.
I would like to test Bluetooth_HW.c. I need to mock native_gecko.h for that, as I am not interested in running its code (it's provided by the manufacturer, I trust it, plus I'm not unit testing native_gecko, I'm unit testing Bluetooth_HW). Normally, I would include the production .h file in my tests, to get declarations of the functions, and then substitute the .c file that contains the production code definitions with my fake implementation.
My problem is that native_gecko.h defines gecko_cmd_le_gap_bt5_set_adv_data() as an inline inside the header, instead of the more common approach of doing it on a .c file.
I could wrap native_gecko.h itself on a header that just declares the functions that I need, and make my code include that header, but then I don't have access to other stuff declared in native_gecko.h, like custom types and enums. I can't move those types and enums to the wrapper, as I can't remove them from native_gecko.h and the compiler would then complain of being defined twice, and I don't want to touch native_gecko.h, because it's an SDK file.
So, my question is how to mock modules that define code in their headers?

I managed to get it working by providing a fake native_gecko.h. The test environment is then pointer to the fake header instead of the production one. In my case, as native_gecko.h is massive, I just surgically added the minimum amount of elements required for it to work. I added just the declarations for the functions needed. Although I could have mimicked the behaviour of the real module and add them as inline functions, this would require including the mocking framework from CPPUTest to be included to native_gecko.h, which is C++. When the compiler tries to compile Bluetooth_HW.c as C code and pulls the header, it will complain about the presence of the C++ code. By adding the mocked function definitions to their own file, I could leave the mocking framework code out of the header, and my original, production code, C file would compile with just C code.
Roughly, the steps would be
Make sure that the test project can't see the real, production code, native_gecko.h.
Provide a fake version of it, substituting any defined functions for declarations (if the file is too big, as is the case of native_gecko.h, just create declarations for the functions used in your Code-Under-Test).
Provide definitions for those functions.
Creating a fake header is not ideal, as the contents can change with an SDK update, for example, and there's room for human error, but it's the cleanest solution I could come up with.

Related

Test embedded code by replacing static symbols at compile time

Background
I'm building a C application for an embedded Cortex M4 TI-RTOS SYS/BIOS target, however this question should apply to all embedded targets where a single binary is loaded onto some microprocessor.
What I want
I'd like to do some in situ regression tests on the target where I just replace a single function with some test function instead. E.g. a GetAdcMeasurement() function would return predefined values from a read-only array instead of doing the actual measurement and returning that value.
This could of course be done with a mess of #ifndefs, but I'd rather keep the production code as untouched as possible.
My attempt
I figure one way to achieve this would be to have duplicate symbol definitions at the linker stage, and then have the linker prioritise the definitions from the test suite (given some #define).
I've looked into using LD_PRELOAD, but that doesn't really seem to apply here (since I'm using only static objects).
Details
I'm using TI Code Composer, with TI-RTOS & SYS/BIOS on the Sitara AM57xx platform, compiling for the M4 remote processor (denoted IPU1).
Here's the path to the compiler and linker
/opt/ti/ccsv7/tools/compiler/ti-cgt-arm_16.9.6.LTS/bin/armcl
One solution could be to have multiple .c files for each module, one the production code and one the test code, and compile and link with one of the two. The globals and function signatures in both .c file must be at least the same (at least: there may be more symbols but not less).
Another solution, building on the previous one, is to have two libraries, one with the production code and one with the test code, and link with one of both. You could ieven link with both lubraries, with the test version first, as linkers often resolve symbols in the order they are encountered.
And, as you said, you could work with a bunch of #ifdefs, which would have the advantage of having just one .c file, but making tyhe code less readable.
I would not go for #ifdefs on the function level, i.e. defining just one function of a .c file for test and keeping the others as is; however, if necessary, it could be away. And if necessary, you could have one .c file (two) for each function, but that would negate the module concept.
I think the first approach would be the cleanest.
One additional approach (apart from Paul Ogilvie's) would be to have your mocking header also create a define which will replace the original function symbol at the pre-processing stage.
I.e. if your mocking header looks like this:
// mock.h
#ifdef MOCKING_ENABLED
adcdata_t GetAdcMeasurement_mocked(void);
stuff_t GetSomeStuff_mocked(void);
#define GetAdcMeasurement GetAdcMeasurement_mocked
#define GetSomeStuff GetSomeStuff_mocked
#endif
Then whenever you include the file, the preprocessor will replace the calls before it even hits the compiler:
#include "mock.h"
void SomeOtherFunc(void)
{
// preprocessor will change this symbol into 'GetAdcMeasurement_mocked'
adcdata_t data = GetAdcMeasurement();
}
The approach might confuse the unsuspected reader of your code, because they won't necessarily realize that you are calling a different function altogether. Nevertheless, I find this approach to have the least impact to the production code (apart from adding the include, obviously).
(This is a quick sum up the discussion in the comments, thanks for answers)
A function can be redefined if it has the weak attribute, see
https://en.wikipedia.org/wiki/Weak_symbol
On GCC that would be the weak attribute, e.g.
int __attribute__((weak)) power2(int x);
and on the armcl (as in my question) that would be the pragma directive
#pragma weak power2
int power2(int x);
Letting the production code consist of partly weak functions will allow a test framework to replace single functions.

C unit testing mocking of "private" functions

I am trying to implement TDD in C coding. I am building the program structure in a quite modularised way and using as atomic functions as possible. I make one test file (including several suits) for one module (module = header file + source file). I am struggling to make the program files "not know that they are being tested", in other words - I don't want testing parts of code in the proper program. Therefore almost often I need to include the source file in the test file in order to have access to the "private" variables and functions.
That was the intro, now the problem: if in a module I have an aaa() function, which uses inside a bbb() function, which uses some xxx() function from an external module, I can easily test the bbb() function in the atomic way by mocking the x() function: #define bbb mock_bbb and providing a mock xxx module for #include. However, I am unable to find a way of atomic testing of the aaa() function, which uses a function from the same module. Is it possible to do? (note, that apart of mocking bbb() for aaa(), I have to be also able to use the original bbb() to test it)
My closest try was to use -Wl,-wrap,xxx, but the problem is that I haven't found a way to automate this (wildcard or something?) - I will have almost 100 testing files, each containing several functions to test - I cannot allow myself to put manually every function in the makefile.
I never test "private" functions in an atomic way. I usually unit-test a c-module using its public functions and checking its calls to other modules (using mocks through dependency injection) and checking its private data members (by exposing its private data members with a GetDataPtr()-function that is compiled only for the unit test project).
For me that the best tradeof between effort and complexity of the unit test framework, although it not possible to reach 100% statement coverage in some "private" functions.

Multiple Header Files and Function Prototypes in C

Assuming that I work on a big project in C with multiple .c files, is there any reason why I should prefer to have multiple header files instead of a single header file?
And another question:
Let's say that I have 3 files: header.h, main.c and other.c.
I have a function named func() that is defined and used only in the file other.c. Should I place the function prototype in the header file or in the file other.c ?
Multiple headers vs a single header.
A primary reason for using multiple headers is that some of the code may be usable independently of the rest, and that code should probably have its own header. In the extreme, each source file (or small group of source files) that provides a service should have its own header that defines the interface to the service.
Also note that what goes in the header is the information needed to use the module — function declarations and type declarations needed by the function declarations (you don't have global variables, do you?). The header should not include headers only needed by the implementation of the module. It should not define types only needed by the implementation of the module. It should not define functions that are not part of the formal interface of the module (functions used internally by the module).
All functions in a module that can be static should be static.
You might still have an omnibus header for your current project that includes all, or most, or the separate headers, but if you think of headers as defining the interfaces to modules, you will find that most consumer modules don't need to know about all possible provider modules.
The function func() is only used in other.c so the function should be made static so that it is only visible in other.c. It should not go in a header unless some other file uses the function — and at that point, it is crucial that it does go into a header.
You may find useful information in these other questions, and there are, no doubt, a lot of other questions that would help too:
What are extern variables in C?
Where to document functions in C?
Design principles — Best practices and design patterns for C
Should I use #include in headers?
If it's a BIG project, you almost certainly HAVE to have multiple headerfiles to make anything sensible out of your project.
I have worked on projects that have several thousand source files, and many hundred header files, totalling millions of lines. You couldn't put all those headerfiles together into one file, and do any meaningful work.
A headerfile should provide one "funcionality". So, if you have a program dealing with customer accounts, stock, invoices, and such, you may have one "customer.h", a "stock.h" and a "invoice.h". You'll probably also have a "dateutils.h" for calculating the "when does this invoice need to be paid by, and how long is it since the invoice was sent out, to send out reminders.
In general, keeping headerfiles SMALL is a good thing. If one headerfile needs something from another one, have it include that.
Of course, if a function is not used outside a particular file, it should not go in a headerfile, and to avoid "leaking names", it should be static. E.g:
static void func(int x)
{
return x * 2;
}
If, for some reason, you need to forward declare func (because some function before func needs to call func), then declare it at the beginning of the source file. There is no need to "spread it around" by adding it to a header file.
By marking it static, you are making it clear that "nobody else, outside this file, uses this function". If at a later stage, you find that "Hmm, this func is really useful in module B as well", then add it to a suitable header file (or make a new header file), and remove the static. Now, anyone reading the source file knows that they will need to check outside of this source file to make sure that any changes to func are OK in the rest of the code.
Commonly, there is a header file per module describing its interface for clean separation of concerns/readability/re-usability.
If the function in other.c is local, there is no need to include it in the header file.

Override a C function defined in a static library

I have a static library of C files, compiled with g++ on Cygwin. I wish to unit test one function that is defined in the library. That function calls another function defined in that library and I wish to override the dependency to replace it with my own version of that function. I can't modify what's in the static library, so this solution [ Override a function call in C ] doesn't apply.
Usually, I can write a .cpp file and include the .c file containing the function I want to unit test, which essentially extends that file with the code I add. It's a dirty trick I'd never use for production code but it's handy for unit testing C files, because it gives my test code access to static things in that C file. Then, I can write in my fake version of the dependency, and my unit test function that calls the function I'm testing. I compile my.cpp to get my.o, then link it with the static library. In theory, since the linker has found a definition for the dependency already (the one I provide) it won't look in the library and there will be no conflict. Usually this works, but now I'm getting a "multiple definition" error where the linker first finds my fake and then finds the real one. I don't know what might cause this and don't know what to look for. I also can't boil this down to a simple example because my simple examples don't have this problem.
Ideas please?
One possibility (admittedly, and ugly one, but...) is to extract the individual object files from the static library. If the function you're calling and the function it's calling are in separate object files, you can link against the object file containing the function you need to call, but not against the one containing the function it calls.
This only gives you granularity on the level of complete object files though, so if the two functions involved are both in the same object file, it won't work. If you really need to get things to work, and don't mind making a really minor modification to the object file in question, you may be able to use a binary editor to mark the second function as a weak external, which means it'll be used in the absence of any other external with the same name, but if another is provided, that will be used instead.
Whether that latter qualifies as "modifying the library" or not depends a bit on your viewpoint. It's not modifying the code in the library, but is modifying a bit of the object file wrapper around that code. My guess is that you'd rather not do it, but it may still be the cleanest way out of an otherwise untenable situation.
It turns out the reason the linker found both defintions of the function is that the faked function's source file defined a variable which is extern'ed in its header file. That unresolved external in the header file caused the linker to link the faked function's object file (the whole thing) to the tested function's file inside the library. So, it's impossible to extract the definition of the tested function without the definition for the dependency.
What I ended up doing was similar to Override a function call in C where I used a different function name instead of the same one, and a preprocessor directive to swap the two. I put the preprocessor directive and the fake function in a separate file which can be included in a unit test, so the production code in the library does not have to be touched. Plus, if I want to fake that same function for another unit test somewhere else, I can re-use the new file.
Depending on your platform and performance requirements, you might be able to use pin to dynamically modify the application and replace one function with another at runtime.
There's no direct example in the manual, but you could easily modify one of the sample pin tools to do this.

A Java programmer has questions regarding C header files

I have a fair amount of practice with Java as a programming language, but I am completely new to C. I understand that a header file contains forward declarations for methods and variables. How is this different from an abstract class in Java?
The short answer:
Abstract classes are a concept of object oriented programming. Header files are a necessity due to the way that the C language is constructed. It cannot be compared in any way
The long answer
To understand the header file, and the need for header files, you must understand the concepts of "declaration" and "definition". In C and C++, a declaration means, that you declare that something exists somewhere, for example a function.
void Test(int i);
We have now declared, that somewhere in the program, there exists a function Test, that takes a single int parameter. When you have a definition, you define what it is:
void Test(int i)
{
...
}
Here we have defined what the function void Test(int) actually is.
Global variables are declared using the extern keyword
extern int i;
They are defined without the extern keyword
int i;
When you compile a C program, you compile each source file (.c file) into an .obj file. Definitions will be compiled into the .obj file as actual code. When all these have been compiled, they are linked to the final executable. Therefore, a function should only be defined on one .c file, otherwise, the same function will end up multiple times in the executable. This is not really critical if the function definitions are identical. It is more problematic if a global variable is linked into the same executable twice. That will leave half the code to use the one instance, and the other half of the code to use the other instance.
But functions defined in one .c file cannot see functions defined in another .c files. So if from file1.c file you need to access function Test(int) defined in file2.c, you need to have a declaration of Test(int) present when compiling file1.c. When file1.c is compiled into file1.obj, the resulting .obj file will contain information that it needs Test(int) to be defined somewhere. When the program is linked, the linker will identify that file2.obj contains the function that file1.obj depends on.
If there is no .obj file containing the definition for this function, you will get a linker error, not a compiler error (linker errors are considerably more difficult to find and correct that compiler errors because you get no filename and line number for the resulting file)
So you use the header file to store declarations for the definitions stored in the corresponding source file.
IMO it's mainly because many C programmers seem to think that Java programmers don't know how to program “for real”, e.g. handling pointers, memory and so on.
I would rather compare headers to Java interfaces, in the sense that they generally define how the API must be used.
Headers are basically just a way to avoid copy-pasting: the preprocessor simply includes the content of the header in the source file when encounters an #include directive.
You put in a header every declaration that the user will commonly use.
Here's the answers:
Java has had a bad reputation among some hardcore C programmers mainly because they think:
it's "too easy" (no memory-management, segfaults)
"can't be used for serious work"
"just for the web" or,
"slow".
Java is hardly the easiest language in the world these days, compared to some lanmguages like Python, etc.
It is used in many desktop apps - applets aren't even used that often. Finally, Java will always be slower than C, because it is not compiled directly to machine code. Sometimes, though, extreme speed isn't needed. Anyway, the JVM isn't the slowest language VM ever.
When you're working in C, there aren't abstract classes.
All a header file does is contain code which is pasted into other files. The main reason you put it in a header file is so that it is at the top of the file - this way, you don't need to care where you put your functions in the actual implementation file.
While you can kind-of use OO concepts in C, it doesn't have built-in support for classes and similar fundamentals of OO. It is nigh-impossible to implement inheritance in plain C, therefore there can never actually have OO, or abstract classes for that matter. I would suggest sticking to plain old structs.
If it makes it easier for you to learn, by all means think of them as abstract classes (with the implementation file being the inheriting class) - but IMHO it is a difficult mindset to use when for working in a language without explicit support of said features.
I'm not sure if Java has them, but I think a closer analogue could be partial classes in C#.
If you forward declare something, you have to actually deliver and implement it, else the compiler will complain. The header allows you to display a "module"'s public API and make the declarations available (for type checking and so) to other parts of the program.
Comprehensive reading: Learning C from Java. Recommended reading for developers who are coming from Java to C.
I think that there is much derision (mockery, laughter, contempt, ridicule) for Java simply because it's popular.
Abstract classes and interfaces specify a contract or a set of functions that can be invoked on an object of a certain type. Function prototypes in C only really do compile time type checking of function arguments/return values.
While your first question seems subjective to me, I will answer to the second one:
A header file contains the declarations which are then made available to other files via #inclusion by the preprocessor.
For instance you will declare in a header a function, and you will implement in a .c file. Other files will be able to use the function so long they can see the declaration (by including the header file).
At linking time the linker will look among the object files, or the various libraries linked, for some object which provides the code for the function.
A typical pattern is: you distribute the header files for your library, and a dll (for instance) which contains the object code. Then in your application you include the header, and the compiler will be able to compile because it will find the declaration in the header. No need to provide the actual implementation of the code, which will be available for the linker through the dll.
C programs run directy, while Java programs run inside the JVM, so a common belief is that Java programs are slow. Also in Java you are hidden from some low level constructs (pointer, direct memory access), memory management, etc...
In C the declaration and definition of a function is separated. Declaration "declares" that there exists a function that called by those arguments returns something. Definition "defines" what the function actually does. The former is done in header files, the latter in the actual code. When you are compiling your code, you must use the header files to tell your compiler that there is such a function, and link in a binary that contains the binary code for the function.
In Java, the binary code itself also contains the declaration of the functions, so it is enough for the compiler to look at the class files to get both the definition and declaration of the available functions.

Resources