Merge in code such that we are much closer to running the same test
[m6w6/libmemcached] / libtest / test.h
1 /* uTest
2 * Copyright (C) 2011 Data Differential, http://datadifferential.com/
3 * Copyright (C) 2006-2009 Brian Aker
4 * All rights reserved.
5 *
6 * Use and distribution licensed under the BSD license. See
7 * the COPYING file in the parent directory for full text.
8 */
9
10 /*
11 Structures for generic tests.
12 */
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <stdbool.h>
17 #include <stdint.h>
18 #include <libtest/visibility.h>
19
20 #pragma once
21
22 enum test_return_t {
23 TEST_SUCCESS= 0, /* Backwards compatibility */
24 TEST_FAILURE,
25 TEST_MEMORY_ALLOCATION_FAILURE,
26 TEST_SKIPPED,
27 TEST_FATAL, // Collection should not be continued
28 TEST_MAXIMUM_RETURN /* Always add new error code before */
29 };
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 typedef void* (test_callback_create_fn)(enum test_return_t*);
36 typedef enum test_return_t (test_callback_fn)(void *);
37 typedef enum test_return_t (test_callback_runner_fn)(test_callback_fn*, void *);
38 typedef enum test_return_t (test_callback_error_fn)(const enum test_return_t, void *);
39
40 #ifdef __cplusplus
41 }
42 #endif
43
44 /**
45 A structure describing the test case.
46 */
47 struct test_st {
48 const char *name;
49 bool requires_flush;
50 test_callback_fn *test_fn;
51 };
52
53
54 /**
55 A structure which describes a collection of test cases.
56 */
57 struct collection_st {
58 const char *name;
59 test_callback_fn *pre;
60 test_callback_fn *post;
61 struct test_st *tests;
62 };
63
64
65 /**
66 Structure which houses the actual callers for the test cases contained in
67 the collections.
68 */
69 struct world_runner_st {
70 test_callback_runner_fn *pre;
71 test_callback_runner_fn *run;
72 test_callback_runner_fn *post;
73 };
74
75
76 /**
77 world_st is the structure which is passed to the test implementation to be filled.
78 This must be implemented in order for the test framework to load the tests. We call
79 get_world() in order to fill this structure.
80 */
81
82 struct world_st {
83 collection_st *collections;
84
85 /* These methods are called outside of any collection call. */
86 test_callback_create_fn *create;
87 test_callback_fn *destroy;
88
89 /* This is called a the beginning of any collection run. */
90 test_callback_fn *collection_startup;
91
92 /* This is called a the end of any collection run. */
93 test_callback_fn *collection_shutdown;
94
95 /* This is called a the beginning of any run. */
96 test_callback_fn *run_startup;
97
98 /* This called on a test if the test requires a flush call (the bool is from test_st) */
99 test_callback_fn *flush;
100
101 /**
102 These are run before/after the test. If implemented. Their execution is not controlled
103 by the test.
104 */
105 test_callback_fn *pre_run;
106 test_callback_fn *post_run;
107
108 /**
109 If an error occurs during the test, this is called.
110 */
111 test_callback_error_fn *on_error;
112
113 /**
114 Runner represents the callers for the tests. If not implemented we will use
115 a set of default implementations.
116 */
117 world_runner_st *runner;
118
119 world_st() :
120 collections(NULL),
121 create(NULL),
122 destroy(NULL),
123 collection_startup(NULL),
124 collection_shutdown(NULL),
125 run_startup(NULL),
126 flush(NULL),
127 pre_run(NULL),
128 post_run(NULL),
129 on_error(NULL),
130 runner(NULL)
131 { }
132
133 virtual ~world_st()
134 { }
135
136 private:
137 world_st(const world_st&);
138 world_st& operator=(const world_st&);
139 };
140
141
142
143 /**
144 @note world_stats_st is a simple structure for tracking test successes.
145 */
146 struct world_stats_st {
147 int32_t collection_success;
148 int32_t collection_skipped;
149 int32_t collection_failed;
150 int32_t collection_total;
151
152 uint32_t success;
153 uint32_t skipped;
154 uint32_t failed;
155 uint32_t total;
156
157 world_stats_st() :
158 collection_success(0),
159 collection_skipped(0),
160 collection_failed(0),
161 collection_total(0),
162 success(0),
163 skipped(0),
164 failed(0),
165 total(0)
166 { }
167 };
168
169 #define TEST_STRINGIFY(x) #x
170 #define TEST_TOSTRING(x) TEST_STRINGIFY(x)
171 #define TEST_AT __FILE__ ":" TEST_TOSTRING(__LINE__)
172
173 #ifdef __cplusplus
174 extern "C" {
175 #endif
176
177 /* How we make all of this work :) */
178 LIBTEST_API
179 void get_world(world_st *world);
180
181 LIBTEST_INTERNAL_API
182 void create_core(void);
183
184 /**
185 @note Friendly print function for errors.
186 */
187 LIBTEST_INTERNAL_API
188 const char *test_strerror(test_return_t code);
189
190 #define test_assert_errno(A) \
191 do \
192 { \
193 if ((A)) { \
194 fprintf(stderr, "\nAssertion failed at %s:%d: ", __FILE__, __LINE__);\
195 perror(#A); \
196 fprintf(stderr, "\n"); \
197 create_core(); \
198 assert((A)); \
199 } \
200 } while (0)
201
202 #define test_truth(A) \
203 do \
204 { \
205 if (! (A)) { \
206 fprintf(stderr, "\nAssertion failed at %s:%d: %s\n", __FILE__, __LINE__, #A);\
207 create_core(); \
208 return TEST_FAILURE; \
209 } \
210 } while (0)
211
212 #define test_true(A) \
213 do \
214 { \
215 if (! (A)) { \
216 fprintf(stderr, "\nAssertion failed at %s:%d: %s\n", __FILE__, __LINE__, #A);\
217 create_core(); \
218 return TEST_FAILURE; \
219 } \
220 } while (0)
221
222 #define test_true_got(A,B) \
223 do \
224 { \
225 if (! (A)) { \
226 fprintf(stderr, "\nAssertion failed at %s:%d: \"%s\" received \"%s\"\n", __FILE__, __LINE__, #A, (B));\
227 create_core(); \
228 return TEST_FAILURE; \
229 } \
230 } while (0)
231
232 #define test_skip(A,B) \
233 do \
234 { \
235 if ((A) != (B)) \
236 { \
237 return TEST_SKIPPED; \
238 } \
239 } while (0)
240
241 #define test_fail(A) \
242 do \
243 { \
244 if (1) { \
245 fprintf(stderr, "\nFailed at %s:%d: %s\n", __FILE__, __LINE__, #A);\
246 create_core(); \
247 return TEST_FAILURE; \
248 } \
249 } while (0)
250
251
252 #define test_false(A) \
253 do \
254 { \
255 if ((A)) { \
256 fprintf(stderr, "\nAssertion failed in %s:%d: %s\n", __FILE__, __LINE__, #A);\
257 create_core(); \
258 return TEST_FAILURE; \
259 } \
260 } while (0)
261
262 #define test_false_with(A,B) \
263 do \
264 { \
265 if ((A)) { \
266 fprintf(stderr, "\nAssertion failed at %s:%d: %s with %s\n", __FILE__, __LINE__, #A, (B));\
267 create_core(); \
268 return TEST_FAILURE; \
269 } \
270 } while (0)
271
272
273 #define test_compare(A,B) \
274 do \
275 { \
276 if ((A) != (B)) \
277 { \
278 fprintf(stderr, "\n%s:%d: Expected %s, got %lu\n", __FILE__, __LINE__, #A, (unsigned long)(B)); \
279 create_core(); \
280 return TEST_FAILURE; \
281 } \
282 } while (0)
283
284 #define test_compare_got(A,B,C) \
285 do \
286 { \
287 if ((A) != (B)) \
288 { \
289 fprintf(stderr, "\n%s:%d: Expected %s, got %s\n", __FILE__, __LINE__, #A, (C)); \
290 create_core(); \
291 return TEST_FAILURE; \
292 } \
293 } while (0)
294
295
296 #define test_strcmp(A,B) \
297 do \
298 { \
299 if (strcmp((A), (B))) \
300 { \
301 fprintf(stderr, "\n%s:%d: Expected %s, got %s\n", __FILE__, __LINE__, (A), (B)); \
302 create_core(); \
303 return TEST_FAILURE; \
304 } \
305 } while (0)
306
307 #define test_memcmp(A,B,C) \
308 do \
309 { \
310 if (memcmp((A), (B), (C))) \
311 { \
312 fprintf(stderr, "\n%s:%d: %.*s -> %.*s\n", __FILE__, __LINE__, (int)(C), (char *)(A), (int)(C), (char *)(B)); \
313 create_core(); \
314 return TEST_FAILURE; \
315 } \
316 } while (0)
317
318 #ifdef __cplusplus
319 }
320 #endif
321
322 #ifdef __cplusplus
323 #define test_literal_param(X) (X), (static_cast<size_t>((sizeof(X) - 1)))
324 #else
325 #define test_literal_param(X) (X), ((size_t)((sizeof(X) - 1)))
326 #endif
327
328 #define test_string_make_from_cstr(X) (X), ((X) ? strlen(X) : 0)