1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* Copyright (c) 2013-2020, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* \file testsupport.h
*
* \brief 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.
**/
/** 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.
*/
/* defined(TOR_UNIT_TESTS) */
/** 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;
*/
/** 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. */
/** Define the implementation of a mocked function. */
/** As MOCK_DECL(), but allow attributes. */
/**
* Replace <b>func</b> (a mockable function) with a replacement function.
*
* Only usable when Tor has been built for unit tests. */
/** Replace <b>func</b> (a mockable function) with its original value.
*
* Only usable when Tor has been built for unit tests. */
/** Declare a mocked function. For use in headers. */
/** As MOCK_DECL(), but allow */
/** Define the implementation of a mocked function. */
/* defined(TOR_UNIT_TESTS) */
/** @} */
/* !defined(TOR_TESTSUPPORT_H) */