Tor 0.4.9.0-alpha-dev
Macros
testsupport.h File Reference

Macros to implement mocking and selective exposure for the test code. More...

Go to the source code of this file.

Macros

#define STATIC   static
 
#define EXTERN(type, name)
 
#define MOCK_DECL(rv, funcname, arglist)    rv funcname arglist
 
#define MOCK_DECL_ATTR(rv, funcname, arglist, attr)    rv funcname arglist attr
 
#define MOCK_IMPL(rv, funcname, arglist)    rv funcname arglist
 

Detailed Description

Macros to implement mocking and selective exposure for the test code.

Each Tor source file is built twice: once with TOR_UNIT_TESTS defined, and once with it undefined. The only difference between these configurations should be that when building for the tests, more functions are exposed as non-static, and a number of functions are declared as mockable.

Definition in file testsupport.h.

Macro Definition Documentation

◆ EXTERN

#define EXTERN (   type,
  name 
)

The "EXTERN" macro is used along with "STATIC" for variables declarations: it expands to an extern declaration when Tor building unit tests, and to nothing otherwise.

For example, to declare a variable as visible only visible in one file and in the unit tests, you would put this in the header:

EXTERN(int, local_variable)

and this in the source:

STATIC int local_variable;

Definition at line 51 of file testsupport.h.

◆ MOCK_DECL

#define MOCK_DECL (   rv,
  funcname,
  arglist 
)     rv funcname arglist

Quick and dirty macros to implement test mocking.

To use them, suppose that you have a function you'd like to mock with the signature "void writebuf(size_t n, char *buf)". You can then declare the function as:

MOCK_DECL(void, writebuf, (size_t n, char *buf));

and implement it as:

MOCK_IMPL(void,
writebuf,(size_t n, char *buf))
{
     ...
}

For the non-testing build, this will expand simply into:

void writebuf(size_t n, char *buf);
void
writebuf(size_t n, char *buf)
{
    ...
}

But for the testing case, it will expand into:

void writebuf__real(size_t n, char *buf);
extern void (*writebuf)(size_t n, char *buf);

void (*writebuf)(size_t n, char *buf) = writebuf__real;
void
writebuf__real(size_t n, char *buf)
{
    ...
}

This is not a great mocking system! It is deliberately "the simplest thing that could work", and pays for its simplicity in its lack of features, and in its uglification of the Tor code. Replacing it with something clever would be a fine thing. Declare a mocked function. For use in headers.

Definition at line 127 of file testsupport.h.

◆ MOCK_DECL_ATTR

#define MOCK_DECL_ATTR (   rv,
  funcname,
  arglist,
  attr 
)     rv funcname arglist attr

As MOCK_DECL(), but allow

Definition at line 130 of file testsupport.h.

◆ MOCK_IMPL

#define MOCK_IMPL (   rv,
  funcname,
  arglist 
)     rv funcname arglist

Define the implementation of a mocked function.

Definition at line 133 of file testsupport.h.

◆ STATIC

#define STATIC   static

The "STATIC" macro marks a function or variable that is static when building Tor for production, but non-static when building the unit tests.

For example, a function declared as:

STATIC int internal_function(void);

should be only visible for the file on which it is declared, and in the unit tests.

Definition at line 32 of file testsupport.h.