2 * Copyright (C) 2006-2009 Brian Aker
5 * Use and distribution licensed under the BSD license. See
6 * the COPYING file in the parent directory for full text.
10 Sample test application.
21 #include <sys/types.h>
27 #include <libtest/test.h>
28 #include <libtest/failed.h>
30 static void world_stats_print(world_stats_st
*stats
)
33 fprintf(stderr
, "Total Collections\t\t\t\t%u\n", stats
->collection_total
);
34 fprintf(stderr
, "\tFailed Collections\t\t\t%u\n", stats
->collection_failed
);
35 fprintf(stderr
, "\tSkipped Collections\t\t\t%u\n", stats
->collection_skipped
);
36 fprintf(stderr
, "\tSucceeded Collections\t\t%u\n", stats
->collection_success
);
38 fprintf(stderr
, "Total\t\t\t\t%u\n", stats
->total
);
39 fprintf(stderr
, "\tFailed\t\t\t%u\n", stats
->failed
);
40 fprintf(stderr
, "\tSkipped\t\t\t%u\n", stats
->skipped
);
41 fprintf(stderr
, "\tSucceeded\t\t%u\n", stats
->success
);
44 long int timedif(struct timeval a
, struct timeval b
)
48 us
= (int)(a
.tv_usec
- b
.tv_usec
);
50 s
= (int)(a
.tv_sec
- b
.tv_sec
);
55 const char *test_strerror(test_return_t code
)
66 case TEST_MEMORY_ALLOCATION_FAILURE
:
67 return "memory allocation";
68 case TEST_MAXIMUM_RETURN
:
70 fprintf(stderr
, "Unknown return value\n");
75 void create_core(void)
77 if (getenv("LIBMEMCACHED_NO_COREDUMP") == NULL
)
87 while (waitpid(pid
, NULL
, 0) != pid
)
96 static test_return_t
_runner_default(test_callback_fn func
, void *p
)
108 static world_runner_st defualt_runners
= {
114 static test_return_t
_default_callback(void *p
)
121 static inline void set_default_fn(test_callback_fn
*fn
)
125 *fn
= _default_callback
;
129 static collection_st
*init_world(world_st
*world
)
133 world
->runner
= &defualt_runners
;
136 set_default_fn(&world
->collection
.startup
);
137 set_default_fn(&world
->collection
.shutdown
);
139 return world
->collections
;
143 int main(int argc
, char *argv
[])
145 test_return_t return_code
;
147 char *collection_to_run
= NULL
;
148 char *wildcard
= NULL
;
150 collection_st
*collection
;
153 world_stats_st stats
;
155 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
156 if (sasl_client_init(NULL
) != SASL_OK
)
158 fprintf(stderr
, "Failed to initialize sasl library!\n");
163 memset(&stats
, 0, sizeof(stats
));
164 memset(&world
, 0, sizeof(world
));
167 collection
= init_world(&world
);
172 world_ptr
= world
.create(&error
);
173 if (error
!= TEST_SUCCESS
)
183 collection_to_run
= argv
[1];
185 else if (getenv("TEST_COLLECTION"))
187 collection_to_run
= getenv("TEST_COLLECTION");
190 if (collection_to_run
)
191 printf("Only testing %s\n", collection_to_run
);
198 for (collection_st
*next
= collection
; next
->name
; next
++)
200 test_return_t collection_rc
= TEST_SUCCESS
;
206 if (collection_to_run
&& fnmatch(collection_to_run
, next
->name
, 0))
209 stats
.collection_total
++;
211 collection_rc
= world
.collection
.startup(world_ptr
);
213 if (collection_rc
!= TEST_SUCCESS
)
218 collection_rc
= world
.runner
->pre(next
->pre
, world_ptr
);
222 switch (collection_rc
)
225 fprintf(stderr
, "\n%s\n\n", next
->name
);
228 fprintf(stderr
, "\n%s [ failed ]\n\n", next
->name
);
229 stats
.collection_failed
++;
232 fprintf(stderr
, "\n%s [ failed ]\n\n", next
->name
);
233 stats
.collection_failed
++;
236 fprintf(stderr
, "\n%s [ skipping ]\n\n", next
->name
);
237 stats
.collection_skipped
++;
239 case TEST_MEMORY_ALLOCATION_FAILURE
:
240 case TEST_MAXIMUM_RETURN
:
247 for (x
= 0; run
->name
; run
++)
249 struct timeval start_time
, end_time
;
250 long int load_time
= 0;
252 if (wildcard
&& fnmatch(wildcard
, run
->name
, 0))
255 fprintf(stderr
, "Testing %s", run
->name
);
257 if (world
.test
.startup
)
259 world
.test
.startup(world_ptr
);
262 if (run
->requires_flush
&& world
.test
.flush
)
264 world
.test
.flush(world_ptr
);
267 if (world
.test
.pre_run
)
269 world
.test
.pre_run(world_ptr
);
276 if (next
->pre
&& world
.runner
->pre
)
278 return_code
= world
.runner
->pre(next
->pre
, world_ptr
);
280 if (return_code
!= TEST_SUCCESS
)
287 gettimeofday(&start_time
, NULL
);
288 return_code
= world
.runner
->run(run
->test_fn
, world_ptr
);
289 gettimeofday(&end_time
, NULL
);
290 load_time
= timedif(end_time
, start_time
);
293 if (next
->post
&& world
.runner
->post
)
295 (void) world
.runner
->post(next
->post
, world_ptr
);
300 if (world
.test
.post_run
)
302 world
.test
.post_run(world_ptr
);
307 fprintf(stderr
, "\t\t\t\t\t");
312 fprintf(stderr
, "%ld.%03ld ", load_time
/ 1000, load_time
% 1000);
319 push_failed_test(next
->name
, run
->name
);
330 case TEST_MEMORY_ALLOCATION_FAILURE
:
331 fprintf(stderr
, "Exhausted memory, quitting\n");
334 case TEST_MAXIMUM_RETURN
:
336 assert(0); // Coding error.
340 fprintf(stderr
, "[ %s ]\n", test_strerror(return_code
));
342 if (world
.test
.on_error
)
345 rc
= world
.test
.on_error(return_code
, world_ptr
);
347 if (rc
!= TEST_SUCCESS
)
351 // If we get a TEST_FATAL we move onto the next collection
352 if (return_code
== TEST_FATAL
)
358 if (next
->post
&& world
.runner
->post
)
360 (void) world
.runner
->post(next
->post
, world_ptr
);
363 if (! failed
&& ! skipped
)
365 stats
.collection_success
++;
369 world
.collection
.shutdown(world_ptr
);
372 if (stats
.collection_failed
|| stats
.collection_skipped
)
374 fprintf(stderr
, "Some test failures and/or skipped test occurred.\n\n");
381 fprintf(stderr
, "All tests completed successfully\n\n");
387 error
= world
.destroy(world_ptr
);
389 if (error
!= TEST_SUCCESS
)
391 fprintf(stderr
, "Failure during shutdown.\n");
392 stats
.failed
++; // We do this to make our exit code return EXIT_FAILURE
396 world_stats_print(&stats
);
398 return stats
.failed
== 0 ? 0 : 1;