2 * Copyright (C) 2011 Data Differential, http://datadifferential.com/
3 * Copyright (C) 2006-2009 Brian Aker
6 * Use and distribution licensed under the BSD license. See
7 * the COPYING file in the parent directory for full text.
11 #include <libtest/common.h>
17 #include <sys/types.h>
25 #include <libtest/stats.h>
27 #ifndef __INTEL_COMPILER
28 #pragma GCC diagnostic ignored "-Wold-style-cast"
31 static in_port_t global_port
= 0;
33 in_port_t
default_port()
39 void set_default_port(in_port_t port
)
44 static void stats_print(Stats
*stats
)
46 std::cout
<< "\tTotal Collections\t\t\t\t" << stats
->collection_total
<< std::endl
;
47 std::cout
<< "\tFailed Collections\t\t\t\t" << stats
->collection_failed
<< std::endl
;
48 std::cout
<< "\tSkipped Collections\t\t\t\t" << stats
->collection_skipped
<< std::endl
;
49 std::cout
<< "\tSucceeded Collections\t\t\t\t" << stats
->collection_success
<< std::endl
;
50 std::cout
<< std::endl
;
51 std::cout
<< "Total\t\t\t\t" << stats
->total
<< std::endl
;
52 std::cout
<< "\tFailed\t\t\t" << stats
->failed
<< std::endl
;
53 std::cout
<< "\tSkipped\t\t\t" << stats
->skipped
<< std::endl
;
54 std::cout
<< "\tSucceeded\t\t" << stats
->success
<< std::endl
;
57 static long int timedif(struct timeval a
, struct timeval b
)
61 us
= (long)(a
.tv_usec
- b
.tv_usec
);
63 s
= (long)(a
.tv_sec
- b
.tv_sec
);
68 const char *test_strerror(test_return_t code
)
77 case TEST_MEMORY_ALLOCATION_FAILURE
:
78 return "memory allocation";
90 void create_core(void)
92 if (getenv("LIBMEMCACHED_NO_COREDUMP") == NULL
)
102 while (waitpid(pid
, NULL
, 0) != pid
) {};
108 static test_return_t
_runner_default(test_callback_fn func
, void *p
)
118 static Runner defualt_runners
= {
124 static test_return_t
_default_callback(void *p
)
131 Framework::Framework() :
135 collection_startup(_default_callback
),
136 collection_shutdown(_default_callback
),
138 runner(&defualt_runners
)
143 int main(int argc
, char *argv
[])
151 if (not world
.runner
)
153 world
.runner
= &defualt_runners
;
157 void *world_ptr
= world
.create(&error
);
158 if (test_failed(error
))
163 char *collection_to_run
= NULL
;
166 collection_to_run
= argv
[1];
168 else if (getenv("TEST_COLLECTION"))
170 collection_to_run
= getenv("TEST_COLLECTION");
173 if (collection_to_run
)
175 std::cout
<< "Only testing " << collection_to_run
<< std::endl
;
178 char *wildcard
= NULL
;
184 for (collection_st
*next
= world
.collections
; next
->name
; next
++)
186 test_return_t collection_rc
= TEST_SUCCESS
;
190 if (collection_to_run
&& fnmatch(collection_to_run
, next
->name
, 0))
193 stats
.collection_total
++;
195 collection_rc
= world
.startup(world_ptr
);
197 if (collection_rc
== TEST_SUCCESS
and next
->pre
)
199 collection_rc
= world
.runner
->pre(next
->pre
, world_ptr
);
202 switch (collection_rc
)
205 std::cerr
<< std::endl
<< next
->name
<< std::endl
<< std::endl
;
210 std::cerr
<< std::endl
<< next
->name
<< " [ failed ]" << std::endl
<< std::endl
;
211 stats
.collection_failed
++;
215 std::cerr
<< std::endl
<< next
->name
<< " [ skipping ]" << std::endl
<< std::endl
;
216 stats
.collection_skipped
++;
219 case TEST_MEMORY_ALLOCATION_FAILURE
:
220 test_assert(0, "Allocation failure, or unknown return");
223 for (test_st
*run
= next
->tests
; run
->name
; run
++)
225 struct timeval start_time
, end_time
;
226 long int load_time
= 0;
228 if (wildcard
&& fnmatch(wildcard
, run
->name
, 0))
233 std::cerr
<< "\tTesting " << run
->name
;
235 world
.item
.startup(world_ptr
);
237 world
.item
.flush(world_ptr
, run
);
239 world
.item
.pre(world_ptr
);
241 test_return_t return_code
;
243 gettimeofday(&start_time
, NULL
);
244 return_code
= world
.runner
->run(run
->test_fn
, world_ptr
);
245 gettimeofday(&end_time
, NULL
);
246 load_time
= timedif(end_time
, start_time
);
249 world
.item
.post(world_ptr
);
253 std::cerr
<< "\t\t\t\t\t";
258 std::cerr
<< load_time
/ 1000 << "." << load_time
% 1000;
273 case TEST_MEMORY_ALLOCATION_FAILURE
:
274 test_assert(0, "Memory Allocation Error");
277 std::cerr
<< "[ " << test_strerror(return_code
) << " ]" << std::endl
;
279 if (test_failed(world
.on_error(return_code
, world_ptr
)))
285 if (next
->post
&& world
.runner
->post
)
287 (void) world
.runner
->post(next
->post
, world_ptr
);
290 if (failed
== 0 and skipped
== 0)
292 stats
.collection_success
++;
296 world
.shutdown(world_ptr
);
299 if (stats
.collection_failed
|| stats
.collection_skipped
)
301 std::cerr
<< std::endl
<< std::endl
<< "Some test failures and/or skipped test occurred." << std::endl
<< std::endl
;
308 std::cout
<< std::endl
<< std::endl
<< "All tests completed successfully." << std::endl
<< std::endl
;
311 if (test_failed(world
.destroy(world_ptr
)))
313 stats
.failed
++; // We do this to make our exit code return EXIT_FAILURE
318 return stats
.failed
== 0 ? 0 : 1;