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.
18 #include <sys/types.h>
26 #include <libtest/test.h>
28 #ifndef __INTEL_COMPILER
29 #pragma GCC diagnostic ignored "-Wold-style-cast"
32 static void world_stats_print(world_stats_st
*stats
)
34 std::cout
<< "\tTotal Collections\t\t\t\t" << stats
->collection_total
<< std::endl
;
35 std::cout
<< "\tFailed Collections\t\t\t\t" << stats
->collection_failed
<< std::endl
;
36 std::cout
<< "\tSkipped Collections\t\t\t\t" << stats
->collection_skipped
<< std::endl
;
37 std::cout
<< "\tSucceeded Collections\t\t\t\t" << stats
->collection_success
<< std::endl
;
38 std::cout
<< std::endl
;
39 std::cout
<< "Total\t\t\t\t" << stats
->total
<< std::endl
;
40 std::cout
<< "\tFailed\t\t\t" << stats
->failed
<< std::endl
;
41 std::cout
<< "\tSkipped\t\t\t" << stats
->skipped
<< std::endl
;
42 std::cout
<< "\tSucceeded\t\t" << stats
->success
<< std::endl
;
45 static long int timedif(struct timeval a
, struct timeval b
)
49 us
= (long)(a
.tv_usec
- b
.tv_usec
);
51 s
= (long)(a
.tv_sec
- b
.tv_sec
);
56 const char *test_strerror(test_return_t code
)
65 case TEST_MEMORY_ALLOCATION_FAILURE
:
66 return "memory allocation";
69 case TEST_MAXIMUM_RETURN
:
71 std::cerr
<< "Unknown return value." << std::endl
;
76 void create_core(void)
78 if (getenv("LIBMEMCACHED_NO_COREDUMP") == NULL
)
88 while (waitpid(pid
, NULL
, 0) != pid
) {};
94 static test_return_t
_runner_default(test_callback_fn func
, void *p
)
102 static world_runner_st defualt_runners
= {
108 static test_return_t
_default_callback(void *p
)
115 static collection_st
*init_world(world_st
*world
)
117 if (world
->runner
== NULL
)
119 world
->runner
= &defualt_runners
;
122 if (world
->collection_startup
== NULL
)
123 world
->collection_startup
= _default_callback
;
125 if (world
->collection_shutdown
== NULL
)
126 world
->collection_shutdown
= _default_callback
;
128 return world
->collections
;
132 int main(int argc
, char *argv
[])
137 world_stats_st stats
;
141 if (not world
.runner
)
143 world
.runner
= &defualt_runners
;
146 collection_st
*collection
= init_world(&world
);
151 world_ptr
= world
.create(&error
);
152 if (error
!= TEST_SUCCESS
)
162 char *collection_to_run
= NULL
;
165 collection_to_run
= argv
[1];
167 else if (getenv("TEST_COLLECTION"))
169 collection_to_run
= getenv("TEST_COLLECTION");
172 if (collection_to_run
)
174 std::cout
<< "Only testing " << collection_to_run
<< std::endl
;
177 char *wildcard
= NULL
;
183 for (collection_st
*next
= collection
; next
->name
; next
++)
185 test_return_t collection_rc
= TEST_SUCCESS
;
189 if (collection_to_run
&& fnmatch(collection_to_run
, next
->name
, 0))
192 stats
.collection_total
++;
194 collection_rc
= world
.collection_startup(world_ptr
);
196 if (collection_rc
== TEST_SUCCESS
and next
->pre
)
198 collection_rc
= world
.runner
->pre(next
->pre
, world_ptr
);
201 switch (collection_rc
)
204 std::cerr
<< std::endl
<< next
->name
<< std::endl
<< std::endl
;
209 std::cerr
<< std::endl
<< next
->name
<< " [ failed ]" << std::endl
<< std::endl
;
210 stats
.collection_failed
++;
214 std::cerr
<< std::endl
<< next
->name
<< " [ skipping ]" << std::endl
<< std::endl
;
215 stats
.collection_skipped
++;
218 case TEST_MEMORY_ALLOCATION_FAILURE
:
219 case TEST_MAXIMUM_RETURN
:
225 for (test_st
*run
= next
->tests
; run
->name
; run
++)
227 struct timeval start_time
, end_time
;
228 long int load_time
= 0;
230 if (wildcard
&& fnmatch(wildcard
, run
->name
, 0))
235 std::cerr
<< "\tTesting " << run
->name
;
237 if (world
.run_startup
)
239 world
.run_startup(world_ptr
);
242 if (run
->requires_flush
&& world
.flush
)
244 world
.flush(world_ptr
);
249 world
.pre_run(world_ptr
);
253 test_return_t return_code
;
256 if (next
->pre
and world
.runner
->pre
)
258 return_code
= world
.runner
->pre(next
->pre
, world_ptr
);
260 if (return_code
!= TEST_SUCCESS
)
267 gettimeofday(&start_time
, NULL
);
268 return_code
= world
.runner
->run(run
->test_fn
, world_ptr
);
269 gettimeofday(&end_time
, NULL
);
270 load_time
= timedif(end_time
, start_time
);
273 if (next
->post
&& world
.runner
->post
)
275 (void) world
.runner
->post(next
->post
, world_ptr
);
282 world
.post_run(world_ptr
);
287 std::cerr
<< "\t\t\t\t\t";
292 std::cerr
<< load_time
/ 1000 << "." << load_time
% 1000;
307 case TEST_MEMORY_ALLOCATION_FAILURE
:
308 case TEST_MAXIMUM_RETURN
:
314 std::cerr
<< "[ " << test_strerror(return_code
) << " ]" << std::endl
;
318 test_return_t rc
= world
.on_error(return_code
, world_ptr
);
320 if (rc
!= TEST_SUCCESS
)
326 if (next
->post
&& world
.runner
->post
)
328 (void) world
.runner
->post(next
->post
, world_ptr
);
331 if (failed
== 0 and skipped
== 0)
333 stats
.collection_success
++;
337 if (world
.collection_shutdown
)
339 world
.collection_shutdown(world_ptr
);
343 if (stats
.collection_failed
|| stats
.collection_skipped
)
345 std::cerr
<< std::endl
<< std::endl
<< "Some test failures and/or skipped test occurred." << std::endl
<< std::endl
;
352 std::cout
<< std::endl
<< std::endl
<< "All tests completed successfully." << std::endl
<< std::endl
;
357 test_return_t error
= world
.destroy(world_ptr
);
359 if (error
!= TEST_SUCCESS
)
361 std::cerr
<< "Failure during shutdown." << std::endl
;
362 stats
.failed
++; // We do this to make our exit code return EXIT_FAILURE
366 world_stats_print(&stats
);
368 return stats
.failed
== 0 ? 0 : 1;