burnin.cc 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /* Gearman server and library
  2. * Copyright (C) 2008 Brian Aker, Eric Day
  3. * All rights reserved.
  4. *
  5. * Use and distribution licensed under the BSD license. See
  6. * the COPYING file in the parent directory for full text.
  7. */
  8. #include <config.h>
  9. #include <libtest/test.hpp>
  10. using namespace libtest;
  11. #include <cassert>
  12. #include <cerrno>
  13. #include <cstdio>
  14. #include <cstdlib>
  15. #include <cstring>
  16. #include <libgearman/gearman.h>
  17. #include <libtest/test.hpp>
  18. #include <tests/start_worker.h>
  19. #include <tests/ports.h>
  20. #define DEFAULT_WORKER_NAME "burnin"
  21. struct client_test_st {
  22. gearman_client_st client;
  23. pid_t gearmand_pid;
  24. struct worker_handle_st *handle;
  25. client_test_st():
  26. gearmand_pid(-1),
  27. handle(NULL)
  28. { }
  29. };
  30. struct client_context_st {
  31. int latch;
  32. size_t min_size;
  33. size_t max_size;
  34. size_t num_tasks;
  35. size_t count;
  36. char *blob;
  37. client_context_st():
  38. latch(0),
  39. min_size(1024),
  40. max_size(1024 *2),
  41. num_tasks(20),
  42. count(2000),
  43. blob(NULL)
  44. { }
  45. };
  46. #ifndef __INTEL_COMPILER
  47. #pragma GCC diagnostic ignored "-Wold-style-cast"
  48. #endif
  49. static test_return_t burnin_test(void *object)
  50. {
  51. gearman_client_st *client= (gearman_client_st *)object;
  52. struct client_context_st *context= (struct client_context_st *)gearman_client_context(client);
  53. // This sketchy, don't do this in your own code.
  54. gearman_task_st *tasks= (gearman_task_st *)calloc(context->num_tasks, sizeof(gearman_task_st));
  55. test_true_got(tasks, strerror(errno));
  56. test_true_got(gearman_success(gearman_client_echo(client, test_literal_param("echo_test"))), gearman_client_error(client));
  57. do
  58. {
  59. for (uint32_t x= 0; x < context->num_tasks; x++)
  60. {
  61. size_t blob_size= 0;
  62. if (context->min_size == context->max_size)
  63. {
  64. blob_size= context->max_size;
  65. }
  66. else
  67. {
  68. blob_size= (size_t)rand();
  69. if (context->max_size > RAND_MAX)
  70. blob_size*= (size_t)(rand() + 1);
  71. blob_size= (blob_size % (context->max_size - context->min_size)) + context->min_size;
  72. }
  73. gearman_task_st *task_ptr;
  74. gearman_return_t ret;
  75. if (context->latch)
  76. {
  77. task_ptr= gearman_client_add_task_background(client, &(tasks[x]),
  78. NULL, DEFAULT_WORKER_NAME, NULL,
  79. (void *)context->blob, blob_size, &ret);
  80. }
  81. else
  82. {
  83. task_ptr= gearman_client_add_task(client, &(tasks[x]), NULL,
  84. DEFAULT_WORKER_NAME, NULL, (void *)context->blob, blob_size,
  85. &ret);
  86. }
  87. test_true_got(gearman_success(ret), gearman_client_error(client));
  88. test_truth(task_ptr);
  89. }
  90. gearman_return_t ret= gearman_client_run_tasks(client);
  91. for (uint32_t x= 0; x < context->num_tasks; x++)
  92. {
  93. test_compare(GEARMAN_TASK_STATE_FINISHED, tasks[x].state);
  94. test_compare(GEARMAN_SUCCESS, tasks[x].result_rc);
  95. }
  96. test_zero(client->new_tasks);
  97. test_true_got(gearman_success(ret), gearman_client_error(client));
  98. for (uint32_t x= 0; x < context->num_tasks; x++)
  99. {
  100. gearman_task_free(&(tasks[x]));
  101. }
  102. } while (context->count--);
  103. free(tasks);
  104. context->latch++;
  105. return TEST_SUCCESS;
  106. }
  107. static test_return_t setup(void *object)
  108. {
  109. gearman_client_st *client= (gearman_client_st *)object;
  110. struct client_context_st *context= new client_context_st;
  111. test_true_got(context, strerror(errno));
  112. context->blob= (char *)malloc(context->max_size);
  113. test_true_got(context->blob, strerror(errno));
  114. memset(context->blob, 'x', context->max_size);
  115. gearman_client_set_context(client, context);
  116. return TEST_SUCCESS;
  117. }
  118. static test_return_t cleanup(void *object)
  119. {
  120. gearman_client_st *client= (gearman_client_st *)object;
  121. struct client_context_st *context= (struct client_context_st *)gearman_client_context(client);
  122. free(context->blob);
  123. delete(context);
  124. return TEST_SUCCESS;
  125. }
  126. static void *worker_fn(gearman_job_st *, void *,
  127. size_t *result_size, gearman_return_t *ret_ptr)
  128. {
  129. *result_size= 0;
  130. *ret_ptr= GEARMAN_SUCCESS;
  131. return NULL;
  132. }
  133. static void *world_create(server_startup_st& servers, test_return_t& error)
  134. {
  135. /**
  136. * @TODO We cast this to char ** below, which is evil. We need to do the
  137. * right thing
  138. */
  139. const char *argv[1]= { "client_gearmand" };
  140. client_test_st *test= new client_test_st;
  141. if (not test)
  142. {
  143. error= TEST_MEMORY_ALLOCATION_FAILURE;
  144. return NULL;
  145. }
  146. /**
  147. We start up everything before we allocate so that we don't have to track memory in the forked process.
  148. */
  149. if (not server_startup(servers, "gearmand", BURNIN_TEST_PORT, 1, argv))
  150. {
  151. error= TEST_FAILURE;
  152. return NULL;
  153. }
  154. gearman_function_t func_arg= gearman_function_create_v1(worker_fn);
  155. test->handle= test_worker_start(BURNIN_TEST_PORT, NULL, DEFAULT_WORKER_NAME, func_arg, NULL, gearman_worker_options_t());
  156. if (not test->handle)
  157. {
  158. error= TEST_FAILURE;
  159. return NULL;
  160. }
  161. if (not gearman_client_create(&(test->client)))
  162. {
  163. error= TEST_FAILURE;
  164. return NULL;
  165. }
  166. if (gearman_failed(gearman_client_add_server(&(test->client), NULL, BURNIN_TEST_PORT)))
  167. {
  168. error= TEST_FAILURE;
  169. return NULL;
  170. }
  171. error= TEST_SUCCESS;
  172. return (void *)test;
  173. }
  174. static bool world_destroy(void *object)
  175. {
  176. client_test_st *test= (client_test_st *)object;
  177. gearman_client_free(&(test->client));
  178. delete test->handle;
  179. delete test;
  180. return TEST_SUCCESS;
  181. }
  182. test_st tests[] ={
  183. {"burnin", 0, burnin_test },
  184. // {"burnin_background", 0, burnin_test },
  185. {0, 0, 0}
  186. };
  187. collection_st collection[] ={
  188. {"burnin", setup, cleanup, tests},
  189. {0, 0, 0, 0}
  190. };
  191. typedef test_return_t (*libgearman_test_callback_fn)(gearman_client_st *);
  192. class GearmandRunner : public Runner {
  193. public:
  194. test_return_t run(test_callback_fn* func, void *object)
  195. {
  196. if (func)
  197. {
  198. libgearman_test_callback_fn actual= libgearman_test_callback_fn(func);
  199. client_test_st *container= (client_test_st*)object;
  200. return actual(&container->client);
  201. }
  202. return TEST_SUCCESS;
  203. }
  204. test_return_t pre(test_callback_fn* func, void *object)
  205. {
  206. if (func)
  207. {
  208. libgearman_test_callback_fn actual= libgearman_test_callback_fn(func);
  209. client_test_st *container= (client_test_st*)object;
  210. return actual(&container->client);
  211. }
  212. return TEST_SUCCESS;
  213. }
  214. test_return_t post(test_callback_fn* func, void *object)
  215. {
  216. if (func)
  217. {
  218. libgearman_test_callback_fn actual= libgearman_test_callback_fn(func);
  219. client_test_st *container= (client_test_st*)object;
  220. return actual(&container->client);
  221. }
  222. return TEST_SUCCESS;
  223. }
  224. };
  225. static GearmandRunner defualt_runner;
  226. void get_world(Framework *world)
  227. {
  228. world->collections= collection;
  229. world->_create= world_create;
  230. world->_destroy= world_destroy;
  231. world->set_runner(&defualt_runner);
  232. }