Skip to content

James Grenning’s Blog
Syndicate content
Blogging about Agile Development, especially embedded. Follow me on twitter: jwgrenning
Updated: 5 hours 15 min ago

Faking it, FFF and Variadic Macro Madness

Sun, 11/15/2015 - 21:50

I spend the day updating the Fake Function Framework, Mike Long’s (@meekrosoft) creation. With my client last week, one of the engineers had some problems with Visual Studio (don’t we all) and the Fake Function Framework (a.k.a FFF). I promised to integrate the changes into the FFF. The FFF is created with a ruby script, but you don’t have to care about that unless you have functions to fake that have more than 10 parameters. But anyway, I spent the day updating and reviewing the ruby script that generates the FFF.

FFF lets you make C test stubs using C macros. It can make it easier to do the right thing while you are programming. By the ‘right thing’, I mean make sure you know what your code is doing and that means automating unit tests for your code. Off the soapbox and back to the FFF…

If you had code that used pthread (or some other problem dependency), FFF let’s you create a stub very quickly. First, look at the signature for the function you want to stub, in this case pthread_create:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);

The way you create an FFF fake is to copy and paste the declaration into you test code; then edit it into this form using the FAKE_VALUE_FUNCTION macro (there is a FAKE_VOID_FUNCTION too):

FAKE_VALUE_FUNCTION(int, pthread_create, pthread_t *, const pthread_attr_t *,
                          void *(*) (void *), void *);

Basically you in insert some commas and remove all the parameter names, though in this case that’s not good enough. The function pointer syntax confounds the FFF. The problem is easily solved with a bridging type just for the FFF’s (and your) benefit.

typedef void *(*threadEntry) (void *);
FAKE_VALUE_FUNCTION(int, pthread_create, pthread_t *, const pthread_attr_t *,
                          threadEntry, void *);

Now you basically have a test stub that remembers each parameter, how many times its been called, and a few other things. It also lets you control the return result in your test scenario.

Any of you that have worked with macros know, they are not known for the clarity of the compiler errors. Make a mistake in the macro and you have no idea until you use it, and then then you know right where the problem is because C preprocessor errors are so clear. Oh wait, that is a different universe, not this one. Actually, the error is almost totally unhelpful.

I came across this handy way to trick the C preprocessor into telling me the macro expansion:

#pragma message "Macro: " FAKE_VALUE_FUNCTION(int, foobar)

Seems like there should be better way to show a macro expansion on demand. Let me know if you have one.

Look at fff.h and you will see some amazing macro madness. Be happy, as I am, that it is generated and did not have to be hand crafted. Thanks Mike for the great tool and figuring out that variadic macro madness. To find out more about the FFF, check it out on my fff gitbub fork of Mike Long’s original version.

Categories: Blogs