Move testing framework out to its own library.
[m6w6/libmemcached] / libtest / test.h
1 /* uTest
2 * Copyright (C) 2006-2009 Brian Aker
3 * All rights reserved.
4 *
5 * Use and distribution licensed under the BSD license. See
6 * the COPYING file in the parent directory for full text.
7 */
8
9 /*
10 Structures for generic tests.
11 */
12
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <stdint.h>
20
21 #if !defined(__cplusplus)
22 # include <stdbool.h>
23 #endif
24
25 typedef struct world_st world_st;
26 typedef struct collection_st collection_st;
27 typedef struct test_st test_st;
28
29 typedef enum {
30 TEST_SUCCESS= 0, /* Backwards compatibility */
31 TEST_FAILURE,
32 TEST_MEMORY_ALLOCATION_FAILURE,
33 TEST_SKIPPED,
34 TEST_MAXIMUM_RETURN /* Always add new error code before */
35 } test_return_t;
36
37 typedef void *(*test_callback_create_fn)(test_return_t *error);
38 typedef test_return_t (*test_callback_fn)(void *);
39 typedef test_return_t (*test_callback_runner_fn)(test_callback_fn, void *);
40 typedef test_return_t (*test_callback_error_fn)(test_return_t, void *);
41
42 /* Help function for use with gettimeofday() */
43 long int timedif(struct timeval a, struct timeval b);
44
45 /**
46 A structure describing the test case.
47 */
48 struct test_st {
49 const char *name;
50 bool requires_flush;
51 test_callback_fn test_fn;
52 };
53
54
55 /**
56 A structure which describes a collection of test cases.
57 */
58 struct collection_st {
59 const char *name;
60 test_callback_fn pre;
61 test_callback_fn post;
62 test_st *tests;
63 };
64
65
66 /**
67 Structure which houses the actual callers for the test cases contained in
68 the collections.
69 */
70 typedef struct {
71 test_callback_runner_fn pre;
72 test_callback_runner_fn run;
73 test_callback_runner_fn post;
74 } world_runner_st;
75
76
77 /**
78 world_st is the structure which is passed to the test implementation to be filled.
79 This must be implemented in order for the test framework to load the tests. We call
80 get_world() in order to fill this structure.
81 */
82
83 struct world_st {
84 collection_st *collections;
85
86 /* These methods are called outside of any collection call. */
87 test_callback_create_fn create;
88 test_callback_fn destroy;
89
90 struct {
91 /* This is called a the beginning of any test run. */
92 test_callback_fn startup;
93
94 /* This called on a test if the test requires a flush call (the bool is from test_st) */
95 test_callback_fn flush;
96
97 /**
98 These are run before/after the test. If implemented. Their execution is not controlled
99 by the test.
100 */
101 test_callback_fn pre_run;
102 test_callback_fn post_run;
103
104 /**
105 If an error occurs during the test, this is called.
106 */
107 test_callback_error_fn on_error;
108 } test;
109
110 struct {
111 /* This is called a the beginning of any collection run. */
112 test_callback_fn startup;
113
114 /* This is called at the end of any collection run. */
115 test_callback_fn shutdown;
116 } collection;
117
118
119 /**
120 Runner represents the callers for the tests. If not implemented we will use
121 a set of default implementations.
122 */
123 world_runner_st *runner;
124 };
125
126
127
128 /**
129 @note world_stats_st is a simple structure for tracking test successes.
130 */
131 typedef struct {
132 uint32_t collection_success;
133 uint32_t collection_skipped;
134 uint32_t collection_failed;
135 uint32_t collection_total;
136 uint32_t success;
137 uint32_t skipped;
138 uint32_t failed;
139 uint32_t total;
140 } world_stats_st;
141
142 /* How we make all of this work :) */
143 void get_world(world_st *world);
144
145 void create_core(void);
146
147 /**
148 @note Friendly print function for errors.
149 */
150 const char *test_strerror(test_return_t code);
151
152 #define test_fail(A) \
153 do \
154 { \
155 if (1) { \
156 fprintf(stderr, "\nFailed at %s:%d: %s\n", __FILE__, __LINE__, #A);\
157 create_core(); \
158 return TEST_FAILURE; \
159 } \
160 } while (0)
161
162 #define test_true(A) \
163 do \
164 { \
165 if (! (A)) { \
166 fprintf(stderr, "\nAssertion failed at %s:%d: %s\n", __FILE__, __LINE__, #A);\
167 create_core(); \
168 return TEST_FAILURE; \
169 } \
170 } while (0)
171
172 #define test_true_got(A,B) \
173 do \
174 { \
175 if (! (A)) { \
176 fprintf(stderr, "\nAssertion failed at %s:%d: \"%s\" received \"%s\"\n", __FILE__, __LINE__, #A, (B));\
177 create_core(); \
178 return TEST_FAILURE; \
179 } \
180 } while (0)
181
182 #define test_false(A) \
183 do \
184 { \
185 if ((A)) { \
186 fprintf(stderr, "\nAssertion failed at %s:%d: %s\n", __FILE__, __LINE__, #A);\
187 create_core(); \
188 return TEST_FAILURE; \
189 } \
190 } while (0)
191
192 #define test_strcmp(A,B) \
193 do \
194 { \
195 if (strcmp((A), (B))) \
196 { \
197 fprintf(stderr, "\n%s:%d: %s -> %s\n", __FILE__, __LINE__, (A), (B)); \
198 create_core(); \
199 return TEST_FAILURE; \
200 } \
201 } while (0)
202
203 #ifdef __cplusplus
204 }
205 #endif