1 | /* Copyright (c) 2006, 2010, Oracle and/or its affiliates |
2 | |
3 | This program is free software; you can redistribute it and/or modify |
4 | it under the terms of the GNU General Public License as published by |
5 | the Free Software Foundation; version 2 of the License. |
6 | |
7 | This program is distributed in the hope that it will be useful, |
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | GNU General Public License for more details. |
11 | |
12 | You should have received a copy of the GNU General Public License |
13 | along with this program; if not, write to the Free Software |
14 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
15 | |
16 | Library for providing TAP support for testing C and C++ was written |
17 | by Mats Kindahl <mats@mysql.com>. |
18 | */ |
19 | |
20 | #ifndef TAP_H |
21 | #define TAP_H |
22 | |
23 | #include "my_global.h" |
24 | |
25 | /* |
26 | @defgroup MyTAP MySQL support for performing unit tests according to |
27 | the Test Anything Protocol (TAP). |
28 | */ |
29 | |
30 | #define NO_PLAN (0) |
31 | |
32 | /** |
33 | Data about test plan. |
34 | |
35 | @ingroup MyTAP_Internal |
36 | |
37 | @internal We are using the "typedef struct X { ... } X" idiom to |
38 | create class/struct X both in C and C++. |
39 | */ |
40 | |
41 | typedef struct TEST_DATA { |
42 | /** |
43 | Number of tests that is planned to execute. |
44 | |
45 | Can be zero (<code>NO_PLAN</code>) meaning that the plan string |
46 | will be printed at the end of test instead. |
47 | */ |
48 | int plan; |
49 | |
50 | /** Number of last test that was done or skipped. */ |
51 | int last; |
52 | |
53 | /** Number of tests that failed. */ |
54 | int failed; |
55 | |
56 | /** Todo reason. */ |
57 | char todo[128]; |
58 | } TEST_DATA; |
59 | |
60 | #ifdef __cplusplus |
61 | extern "C" { |
62 | #endif |
63 | |
64 | /** |
65 | Defines whether "big" tests should be skipped. |
66 | |
67 | This variable is set by plan() function unless MYTAP_CONFIG environment |
68 | variable is set to the string "big". It is supposed to be used as |
69 | |
70 | @code |
71 | if (skip_big_tests) { |
72 | skip(1, "Big test skipped"); |
73 | } else { |
74 | ok(life_universe_and_everything() == 42, "The answer is CORRECT"); |
75 | } |
76 | @endcode |
77 | |
78 | @see SKIP_BIG_TESTS |
79 | */ |
80 | extern int skip_big_tests; |
81 | |
82 | /** |
83 | @defgroup MyTAP_API MyTAP API |
84 | |
85 | MySQL support for performing unit tests according to TAP. |
86 | |
87 | @{ |
88 | */ |
89 | |
90 | /** |
91 | Set number of tests that is planned to execute. |
92 | |
93 | The function also accepts the predefined constant <code>NO_PLAN</code>. |
94 | If invoked with this constant -- or not invoked at all -- |
95 | the test plan will be printed after all the test lines. |
96 | |
97 | The plan() function will install signal handlers for all signals |
98 | that generate a core, so if you want to override these signals, do |
99 | it <em>after</em> you have called the plan() function. |
100 | |
101 | It will also set skip_big_tests variable if MYTAP_CONFIG environment |
102 | variable is defined. |
103 | |
104 | @see skip_big_tests |
105 | |
106 | @param count The planned number of tests to run. |
107 | */ |
108 | |
109 | void plan(int count); |
110 | |
111 | |
112 | /** |
113 | Report test result as a TAP line. |
114 | |
115 | Function used to write status of an individual test. Call this |
116 | function in the following manner: |
117 | |
118 | @code |
119 | ok(ducks == paddling, |
120 | "%d ducks did not paddle", ducks - paddling); |
121 | @endcode |
122 | |
123 | @param pass Zero if the test failed, non-zero if it passed. |
124 | @param fmt Format string in printf() format. NULL is not allowed, |
125 | use ok1() in this case. |
126 | */ |
127 | |
128 | void ok(int pass, char const *fmt, ...) |
129 | __attribute__((format(printf,2,3))); |
130 | |
131 | |
132 | /** |
133 | Report test result as a TAP line. |
134 | |
135 | Same as ok() but does not take a message to be printed. |
136 | |
137 | @param pass Zero if the test failed, non-zero if it passed. |
138 | */ |
139 | |
140 | void ok1(int const pass); |
141 | |
142 | |
143 | /** |
144 | Skip a determined number of tests. |
145 | |
146 | Function to print that <em>how_many</em> tests have been skipped. |
147 | The reason is printed for each skipped test. Observe that this |
148 | function does not do the actual skipping for you, it just prints |
149 | information that tests have been skipped. This function is not |
150 | usually used, but rather the macro @c SKIP_BLOCK_IF, which does the |
151 | skipping for you. |
152 | |
153 | It shall be used in the following manner: |
154 | |
155 | @code |
156 | if (ducks == 0) { |
157 | skip(2, "No ducks in the pond"); |
158 | } else { |
159 | int i; |
160 | for (i = 0 ; i < 2 ; ++i) |
161 | ok(duck[i] == paddling, "is duck %d paddling?", i); |
162 | } |
163 | @endcode |
164 | |
165 | @see SKIP_BLOCK_IF |
166 | |
167 | @param how_many Number of tests that are to be skipped. |
168 | @param reason A reason for skipping the tests |
169 | */ |
170 | |
171 | void skip(int how_many, char const *const reason, ...) |
172 | __attribute__((format(printf,2,3))); |
173 | |
174 | |
175 | /** |
176 | Helper macro to skip a block of code. The macro can be used to |
177 | simplify conditionally skipping a block of code. It is used in the |
178 | following manner: |
179 | |
180 | @code |
181 | SKIP_BLOCK_IF(ducks == 0, 2, "No ducks in the pond") |
182 | { |
183 | int i; |
184 | for (i = 0 ; i < 2 ; ++i) |
185 | ok(duck[i] == paddling, "is duck %d paddling?", i); |
186 | } |
187 | @endcode |
188 | |
189 | @see skip |
190 | */ |
191 | |
192 | #define SKIP_BLOCK_IF(SKIP_IF_TRUE, COUNT, REASON) \ |
193 | if (SKIP_IF_TRUE) skip((COUNT),(REASON)); else |
194 | |
195 | |
196 | /** |
197 | Helper macro to skip a group of "big" tests. It is used in the following |
198 | manner: |
199 | |
200 | @code |
201 | SKIP_BIG_TESTS(1) |
202 | { |
203 | ok(life_universe_and_everything() == 42, "The answer is CORRECT"); |
204 | } |
205 | @endcode |
206 | |
207 | @see skip_big_tests |
208 | */ |
209 | |
210 | #define SKIP_BIG_TESTS(COUNT) \ |
211 | if (skip_big_tests) skip((COUNT), "big test"); else |
212 | |
213 | |
214 | /** |
215 | Print a diagnostics message. |
216 | |
217 | @param fmt Diagnostics message in printf() format. |
218 | */ |
219 | |
220 | void diag(char const *fmt, ...) |
221 | __attribute__((format(printf,1,2))); |
222 | |
223 | |
224 | /** |
225 | Print a bail out message. |
226 | |
227 | A bail out message can be issued when no further testing can be |
228 | done, e.g., when there are missing dependencies. |
229 | |
230 | The test will exit with status 255. This function does not return. |
231 | |
232 | @code |
233 | BAIL_OUT("Lost connection to server %s", server_name); |
234 | @endcode |
235 | |
236 | @note A bail out message is printed if a signal that generates a |
237 | core is raised. |
238 | |
239 | @param fmt Bail out message in printf() format. |
240 | */ |
241 | |
242 | void BAIL_OUT(char const *fmt, ...) |
243 | __attribute__((noreturn, format(printf,1,2))); |
244 | |
245 | |
246 | /** |
247 | Print summary report and return exit status. |
248 | |
249 | This function will print a summary report of how many tests passed, |
250 | how many were skipped, and how many remains to do. The function |
251 | should be called after all tests are executed in the following |
252 | manner: |
253 | |
254 | @code |
255 | return exit_status(); |
256 | @endcode |
257 | |
258 | @returns @c EXIT_SUCCESS if all tests passed, @c EXIT_FAILURE if |
259 | one or more tests failed. |
260 | */ |
261 | |
262 | int exit_status(void); |
263 | |
264 | |
265 | /** |
266 | Skip entire test suite. |
267 | |
268 | To skip the entire test suite, use this function. It will |
269 | automatically call exit(), so there is no need to have checks |
270 | around it. |
271 | */ |
272 | |
273 | void skip_all(char const *reason, ...) |
274 | __attribute__((noreturn, format(printf, 1, 2))); |
275 | |
276 | |
277 | /** |
278 | Start section of tests that are not yet ready. |
279 | |
280 | To start a section of tests that are not ready and are expected to |
281 | fail, use this function and todo_end() in the following manner: |
282 | |
283 | @code |
284 | todo_start("Not ready yet"); |
285 | ok(is_rocketeering(duck), "Rocket-propelled ducks"); |
286 | ok(is_kamikaze(duck), "Kamikaze ducks"); |
287 | todo_end(); |
288 | @endcode |
289 | |
290 | @see todo_end |
291 | |
292 | @note |
293 | It is not possible to nest todo sections. |
294 | |
295 | @param message Message that will be printed before the todo tests. |
296 | */ |
297 | |
298 | void todo_start(char const *message, ...) |
299 | __attribute__((format(printf, 1, 2))); |
300 | |
301 | |
302 | /** |
303 | End a section of tests that are not yet ready. |
304 | */ |
305 | |
306 | void todo_end(); |
307 | |
308 | /** @} */ |
309 | |
310 | #ifdef __cplusplus |
311 | } |
312 | #endif |
313 | |
314 | #endif /* TAP_H */ |
315 | |