Tor
0.4.9.2-alpha-dev
Toggle main menu visibility
Main Page
Related Pages
Modules
Data Structures
Data Structures
Data Structure Index
Data Fields
All
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
Functions
Variables
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
Enumerator
Files
File List
Globals
All
_
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
z
Functions
a
b
c
d
e
f
g
h
i
k
l
m
n
o
p
q
r
s
t
u
v
w
x
Variables
a
b
c
d
e
f
g
h
i
k
l
m
n
o
p
q
r
s
t
u
v
w
x
z
Typedefs
b
c
d
f
g
h
l
m
n
o
p
r
s
v
Enumerations
a
b
c
d
f
g
h
i
k
l
m
n
o
p
q
r
s
t
u
v
w
Enumerator
a
b
c
d
e
g
h
i
m
n
o
p
q
r
s
t
v
w
Macros
_
a
b
c
d
e
f
g
h
i
j
l
m
n
o
p
r
s
t
u
v
w
x
•
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Modules
Pages
lib
testsupport
testsupport.h
Go to the documentation of this file.
1
/* Copyright (c) 2013-2021, The Tor Project, Inc. */
2
/* See LICENSE for licensing information */
3
4
/**
5
* \file testsupport.h
6
*
7
* \brief Macros to implement mocking and selective exposure for the test code.
8
*
9
* Each Tor source file is built twice: once with TOR_UNIT_TESTS defined, and
10
* once with it undefined. The only difference between these configurations
11
* should be that when building for the tests, more functions are exposed as
12
* non-static, and a number of functions are declared as mockable.
13
**/
14
15
#ifndef TOR_TESTSUPPORT_H
16
#define TOR_TESTSUPPORT_H
17
18
/** The "STATIC" macro marks a function or variable that is static when
19
* building Tor for production, but non-static when building the unit
20
* tests.
21
*
22
* For example, a function declared as:
23
*
24
* STATIC int internal_function(void);
25
*
26
* should be only visible for the file on which it is declared, and in the
27
* unit tests.
28
*/
29
#ifdef TOR_UNIT_TESTS
30
#define STATIC
31
#else
/* !defined(TOR_UNIT_TESTS) */
32
#define STATIC static
33
#endif
/* defined(TOR_UNIT_TESTS) */
34
35
/** The "EXTERN" macro is used along with "STATIC" for variables declarations:
36
* it expands to an extern declaration when Tor building unit tests, and to
37
* nothing otherwise.
38
*
39
* For example, to declare a variable as visible only visible in one
40
* file and in the unit tests, you would put this in the header:
41
*
42
* EXTERN(int, local_variable)
43
*
44
* and this in the source:
45
*
46
* STATIC int local_variable;
47
*/
48
#ifdef TOR_UNIT_TESTS
49
#define EXTERN(type, name) extern type name;
50
#else
51
#define EXTERN(type, name)
52
#endif
53
54
/** Quick and dirty macros to implement test mocking.
55
*
56
* To use them, suppose that you have a function you'd like to mock
57
* with the signature "void writebuf(size_t n, char *buf)". You can then
58
* declare the function as:
59
*
60
* MOCK_DECL(void, writebuf, (size_t n, char *buf));
61
*
62
* and implement it as:
63
*
64
* MOCK_IMPL(void,
65
* writebuf,(size_t n, char *buf))
66
* {
67
* ...
68
* }
69
*
70
* For the non-testing build, this will expand simply into:
71
*
72
* void writebuf(size_t n, char *buf);
73
* void
74
* writebuf(size_t n, char *buf)
75
* {
76
* ...
77
* }
78
*
79
* But for the testing case, it will expand into:
80
*
81
* void writebuf__real(size_t n, char *buf);
82
* extern void (*writebuf)(size_t n, char *buf);
83
*
84
* void (*writebuf)(size_t n, char *buf) = writebuf__real;
85
* void
86
* writebuf__real(size_t n, char *buf)
87
* {
88
* ...
89
* }
90
*
91
* This is not a great mocking system! It is deliberately "the simplest
92
* thing that could work", and pays for its simplicity in its lack of
93
* features, and in its uglification of the Tor code. Replacing it with
94
* something clever would be a fine thing.
95
*
96
* @{ */
97
#ifdef TOR_UNIT_TESTS
98
/** Declare a mocked function. For use in headers. */
99
#define MOCK_DECL(rv, funcname, arglist) \
100
rv funcname ##__real arglist; \
101
extern rv(*funcname) arglist
102
/** Define the implementation of a mocked function. */
103
#define MOCK_IMPL(rv, funcname, arglist) \
104
rv(*funcname) arglist = funcname ##__real; \
105
rv funcname ##__real arglist
106
/** As MOCK_DECL(), but allow attributes. */
107
#define MOCK_DECL_ATTR(rv, funcname, arglist, attr) \
108
rv funcname ##__real arglist attr; \
109
extern rv(*funcname) arglist
110
/**
111
* Replace <b>func</b> (a mockable function) with a replacement function.
112
*
113
* Only usable when Tor has been built for unit tests. */
114
#define MOCK(func, replacement) \
115
do { \
116
(func) = (replacement); \
117
} while (0)
118
/** Replace <b>func</b> (a mockable function) with its original value.
119
*
120
* Only usable when Tor has been built for unit tests. */
121
#define UNMOCK(func) \
122
do { \
123
func = func ##__real; \
124
} while (0)
125
#else
/* !defined(TOR_UNIT_TESTS) */
126
/** Declare a mocked function. For use in headers. */
127
#define MOCK_DECL(rv, funcname, arglist) \
128
rv funcname arglist
129
/** As MOCK_DECL(), but allow */
130
#define MOCK_DECL_ATTR(rv, funcname, arglist, attr) \
131
rv funcname arglist attr
132
/** Define the implementation of a mocked function. */
133
#define MOCK_IMPL(rv, funcname, arglist) \
134
rv funcname arglist
135
#endif
/* defined(TOR_UNIT_TESTS) */
136
/** @} */
137
138
#endif
/* !defined(TOR_TESTSUPPORT_H) */
Generated by
1.9.4