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;
32 static char global_socket
[1024];
34 in_port_t
default_port()
40 void set_default_port(in_port_t port
)
45 const char *default_socket()
47 assert(global_socket
[0]);
51 void set_default_socket(const char *socket
)
53 strncpy(global_socket
, socket
, strlen(socket
));
56 static void stats_print(Stats
*stats
)
58 std::cout
<< "\tTotal Collections\t\t\t\t" << stats
->collection_total
<< std::endl
;
59 std::cout
<< "\tFailed Collections\t\t\t\t" << stats
->collection_failed
<< std::endl
;
60 std::cout
<< "\tSkipped Collections\t\t\t\t" << stats
->collection_skipped
<< std::endl
;
61 std::cout
<< "\tSucceeded Collections\t\t\t\t" << stats
->collection_success
<< std::endl
;
62 std::cout
<< std::endl
;
63 std::cout
<< "Total\t\t\t\t" << stats
->total
<< std::endl
;
64 std::cout
<< "\tFailed\t\t\t" << stats
->failed
<< std::endl
;
65 std::cout
<< "\tSkipped\t\t\t" << stats
->skipped
<< std::endl
;
66 std::cout
<< "\tSucceeded\t\t" << stats
->success
<< std::endl
;
69 static long int timedif(struct timeval a
, struct timeval b
)
73 us
= (long)(a
.tv_usec
- b
.tv_usec
);
75 s
= (long)(a
.tv_sec
- b
.tv_sec
);
80 const char *test_strerror(test_return_t code
)
89 case TEST_MEMORY_ALLOCATION_FAILURE
:
90 return "memory allocation";
102 void create_core(void)
104 if (getenv("LIBMEMCACHED_NO_COREDUMP") == NULL
)
114 while (waitpid(pid
, NULL
, 0) != pid
) {};
120 static test_return_t
_runner_default(test_callback_fn func
, void *p
)
130 static Runner defualt_runners
= {
136 static test_return_t
_default_callback(void *p
)
143 Framework::Framework() :
147 collection_startup(_default_callback
),
148 collection_shutdown(_default_callback
),
150 runner(&defualt_runners
)
155 int main(int argc
, char *argv
[])
157 Framework
*world
= new Framework();
169 void *world_ptr
= world
->create(&error
);
170 if (test_failed(error
))
172 std::cerr
<< "create() failed" << std::endl
;
176 char *collection_to_run
= NULL
;
179 collection_to_run
= argv
[1];
181 else if (getenv("TEST_COLLECTION"))
183 collection_to_run
= getenv("TEST_COLLECTION");
186 if (collection_to_run
)
188 std::cout
<< "Only testing " << collection_to_run
<< std::endl
;
191 char *wildcard
= NULL
;
197 for (collection_st
*next
= world
->collections
; next
->name
; next
++)
199 test_return_t collection_rc
= TEST_SUCCESS
;
203 if (collection_to_run
&& fnmatch(collection_to_run
, next
->name
, 0))
206 stats
.collection_total
++;
208 collection_rc
= world
->startup(world_ptr
);
210 if (collection_rc
== TEST_SUCCESS
and next
->pre
)
212 collection_rc
= world
->runner
->pre(next
->pre
, world_ptr
);
215 switch (collection_rc
)
218 std::cerr
<< std::endl
<< next
->name
<< std::endl
<< std::endl
;
223 std::cerr
<< std::endl
<< next
->name
<< " [ failed ]" << std::endl
<< std::endl
;
224 stats
.collection_failed
++;
228 std::cerr
<< std::endl
<< next
->name
<< " [ skipping ]" << std::endl
<< std::endl
;
229 stats
.collection_skipped
++;
232 case TEST_MEMORY_ALLOCATION_FAILURE
:
233 test_assert(0, "Allocation failure, or unknown return");
236 for (test_st
*run
= next
->tests
; run
->name
; run
++)
238 struct timeval start_time
, end_time
;
239 long int load_time
= 0;
241 if (wildcard
&& fnmatch(wildcard
, run
->name
, 0))
246 std::cerr
<< "\tTesting " << run
->name
;
248 test_return_t return_code
;
249 if (test_success(return_code
= world
->item
.startup(world_ptr
)))
251 if (test_success(return_code
= world
->item
.flush(world_ptr
, run
)))
253 // @note pre will fail is SKIPPED is returned
254 if (test_success(return_code
= world
->item
.pre(world_ptr
)))
257 gettimeofday(&start_time
, NULL
);
258 return_code
= world
->runner
->run(run
->test_fn
, world_ptr
);
259 gettimeofday(&end_time
, NULL
);
260 load_time
= timedif(end_time
, start_time
);
264 // @todo do something if post fails
265 (void)world
->item
.post(world_ptr
);
269 std::cerr
<< __FILE__
<< ":" << __LINE__
<< " item.flush(failure)" << std::endl
;
274 std::cerr
<< __FILE__
<< ":" << __LINE__
<< " item.startup(failure)" << std::endl
;
279 std::cerr
<< "\t\t\t\t\t";
284 std::cerr
<< load_time
/ 1000 << "." << load_time
% 1000;
299 case TEST_MEMORY_ALLOCATION_FAILURE
:
300 test_assert(0, "Memory Allocation Error");
303 std::cerr
<< "[ " << test_strerror(return_code
) << " ]" << std::endl
;
305 if (test_failed(world
->on_error(return_code
, world_ptr
)))
311 if (next
->post
and world
->runner
->post
)
313 (void) world
->runner
->post(next
->post
, world_ptr
);
316 if (failed
== 0 and skipped
== 0)
318 stats
.collection_success
++;
322 world
->shutdown(world_ptr
);
325 if (stats
.collection_failed
|| stats
.collection_skipped
)
327 std::cerr
<< std::endl
<< std::endl
<< "Some test failures and/or skipped test occurred." << std::endl
<< std::endl
;
334 std::cout
<< std::endl
<< std::endl
<< "All tests completed successfully." << std::endl
<< std::endl
;
337 if (test_failed(world
->destroy(world_ptr
)))
339 stats
.failed
++; // We do this to make our exit code return EXIT_FAILURE
346 return stats
.failed
== 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;