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>
28 #include <libtest/stats.h>
30 #ifndef __INTEL_COMPILER
31 #pragma GCC diagnostic ignored "-Wold-style-cast"
34 static in_port_t global_port
= 0;
35 static char global_socket
[1024];
37 in_port_t
default_port()
43 void set_default_port(in_port_t port
)
48 const char *default_socket()
50 assert(global_socket
[0]);
56 return (getenv("LIBTEST_LOCAL"));
59 void set_default_socket(const char *socket
)
61 strncpy(global_socket
, socket
, strlen(socket
));
64 static void stats_print(Stats
*stats
)
66 std::cout
<< "\tTotal Collections\t\t\t\t" << stats
->collection_total
<< std::endl
;
67 std::cout
<< "\tFailed Collections\t\t\t\t" << stats
->collection_failed
<< std::endl
;
68 std::cout
<< "\tSkipped Collections\t\t\t\t" << stats
->collection_skipped
<< std::endl
;
69 std::cout
<< "\tSucceeded Collections\t\t\t\t" << stats
->collection_success
<< std::endl
;
70 std::cout
<< std::endl
;
71 std::cout
<< "Total\t\t\t\t" << stats
->total
<< std::endl
;
72 std::cout
<< "\tFailed\t\t\t" << stats
->failed
<< std::endl
;
73 std::cout
<< "\tSkipped\t\t\t" << stats
->skipped
<< std::endl
;
74 std::cout
<< "\tSucceeded\t\t" << stats
->success
<< std::endl
;
77 static long int timedif(struct timeval a
, struct timeval b
)
81 us
= (long)(a
.tv_usec
- b
.tv_usec
);
83 s
= (long)(a
.tv_sec
- b
.tv_sec
);
88 const char *test_strerror(test_return_t code
)
97 case TEST_MEMORY_ALLOCATION_FAILURE
:
98 return "memory allocation";
110 void create_core(void)
112 if (getenv("LIBMEMCACHED_NO_COREDUMP") == NULL
)
122 while (waitpid(pid
, NULL
, 0) != pid
) {};
133 static Framework
*world
= NULL
;
134 static volatile shutdown_t __shutdown
= SHUTDOWN_RUNNING
;
136 static void *sig_thread(void *arg
)
138 sigset_t
*set
= (sigset_t
*) arg
;
140 for (;__shutdown
== SHUTDOWN_RUNNING
;)
144 while ((error
= sigwait(set
, &sig
)) == EINTR
) ;
151 std::cerr
<< std::endl
<< "Signal handling thread got signal " << strsignal(sig
) << std::endl
;
152 __shutdown
= SHUTDOWN_FORCED
;
156 std::cerr
<< std::endl
<< "Signal handling thread got unexpected signal " << strsignal(sig
) << std::endl
;
166 static void setup_signals(pthread_t
& thread
)
171 sigaddset(&set
, SIGSEGV
);
172 sigaddset(&set
, SIGABRT
);
173 sigaddset(&set
, SIGINT
);
174 sigaddset(&set
, SIGUSR1
);
177 if ((error
= pthread_sigmask(SIG_BLOCK
, &set
, NULL
)) != 0)
179 std::cerr
<< __FILE__
<< ":" << __LINE__
<< " died during pthread_sigmask(" << strerror(error
) << ")" << std::endl
;
183 if ((error
= pthread_create(&thread
, NULL
, &sig_thread
, (void *) &set
)) != 0)
185 std::cerr
<< __FILE__
<< ":" << __LINE__
<< " died during pthread_create(" << strerror(error
) << ")" << std::endl
;
191 int main(int argc
, char *argv
[])
193 world
= new Framework();
201 setup_signals(thread
);
208 void *creators_ptr
= world
->create(error
);
209 if (test_failed(error
))
211 std::cerr
<< "create() failed" << std::endl
;
215 char *collection_to_run
= NULL
;
218 collection_to_run
= argv
[1];
220 else if (getenv("TEST_COLLECTION"))
222 collection_to_run
= getenv("TEST_COLLECTION");
225 if (collection_to_run
)
227 std::cout
<< "Only testing " << collection_to_run
<< std::endl
;
230 char *wildcard
= NULL
;
236 for (collection_st
*next
= world
->collections
; next
->name
and __shutdown
== SHUTDOWN_RUNNING
; next
++)
238 test_return_t collection_rc
= TEST_SUCCESS
;
242 if (collection_to_run
&& fnmatch(collection_to_run
, next
->name
, 0))
245 stats
.collection_total
++;
247 collection_rc
= world
->startup(creators_ptr
);
249 if (collection_rc
== TEST_SUCCESS
and next
->pre
)
251 collection_rc
= world
->runner
->pre(next
->pre
, creators_ptr
);
254 switch (collection_rc
)
257 std::cerr
<< std::endl
<< next
->name
<< std::endl
<< std::endl
;
262 std::cerr
<< std::endl
<< next
->name
<< " [ failed ]" << std::endl
<< std::endl
;
263 stats
.collection_failed
++;
267 std::cerr
<< std::endl
<< next
->name
<< " [ skipping ]" << std::endl
<< std::endl
;
268 stats
.collection_skipped
++;
271 case TEST_MEMORY_ALLOCATION_FAILURE
:
272 test_assert(0, "Allocation failure, or unknown return");
275 for (test_st
*run
= next
->tests
; run
->name
; run
++)
277 struct timeval start_time
, end_time
;
278 long int load_time
= 0;
280 if (wildcard
&& fnmatch(wildcard
, run
->name
, 0))
285 std::cerr
<< "\tTesting " << run
->name
;
287 test_return_t return_code
;
288 if (test_success(return_code
= world
->item
.startup(creators_ptr
)))
290 if (test_success(return_code
= world
->item
.flush(creators_ptr
, run
)))
292 // @note pre will fail is SKIPPED is returned
293 if (test_success(return_code
= world
->item
.pre(creators_ptr
)))
296 gettimeofday(&start_time
, NULL
);
297 return_code
= world
->runner
->run(run
->test_fn
, creators_ptr
);
298 gettimeofday(&end_time
, NULL
);
299 load_time
= timedif(end_time
, start_time
);
303 // @todo do something if post fails
304 (void)world
->item
.post(creators_ptr
);
308 std::cerr
<< __FILE__
<< ":" << __LINE__
<< " item.flush(failure)" << std::endl
;
313 std::cerr
<< __FILE__
<< ":" << __LINE__
<< " item.startup(failure)" << std::endl
;
318 std::cerr
<< "\t\t\t\t\t";
323 std::cerr
<< load_time
/ 1000 << "." << load_time
% 1000;
338 case TEST_MEMORY_ALLOCATION_FAILURE
:
339 test_assert(0, "Memory Allocation Error");
342 std::cerr
<< "[ " << test_strerror(return_code
) << " ]" << std::endl
;
344 if (test_failed(world
->on_error(return_code
, creators_ptr
)))
350 if (next
->post
and world
->runner
->post
)
352 (void) world
->runner
->post(next
->post
, creators_ptr
);
355 if (failed
== 0 and skipped
== 0)
357 stats
.collection_success
++;
361 world
->shutdown(creators_ptr
);
364 if (__shutdown
== SHUTDOWN_RUNNING
)
366 __shutdown
= SHUTDOWN_GRACEFUL
;
369 if (__shutdown
== SHUTDOWN_FORCED
)
371 std::cerr
<< std::endl
<< std::endl
<< "Tests were aborted." << std::endl
<< std::endl
;
373 else if (stats
.collection_failed
or stats
.collection_skipped
)
375 std::cerr
<< std::endl
<< std::endl
<< "Some test failures and/or skipped test occurred." << std::endl
<< std::endl
;
379 std::cout
<< std::endl
<< std::endl
<< "All tests completed successfully." << std::endl
<< std::endl
;
385 pthread_kill(thread
, SIGUSR1
);
386 pthread_join(thread
, &retval
);
390 return stats
.failed
== 0 and __shutdown
== SHUTDOWN_GRACEFUL
? EXIT_SUCCESS
: EXIT_FAILURE
;