burnin.cc 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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. #if defined(NDEBUG)
  10. # undef NDEBUG
  11. #endif
  12. #include <cassert>
  13. #include <cerrno>
  14. #include <cstdio>
  15. #include <cstdlib>
  16. #include <cstring>
  17. #include <iostream>
  18. #include <libgearman/gearman.h>
  19. #include <libtest/test.h>
  20. #include <libtest/server.h>
  21. #include <libtest/worker.h>
  22. #define CLIENT_TEST_PORT 32143
  23. #define DEFAULT_WORKER_NAME "burnin"
  24. struct client_test_st {
  25. gearman_client_st client;
  26. pid_t gearmand_pid;
  27. struct worker_handle_st *handle;
  28. client_test_st():
  29. gearmand_pid(-1),
  30. handle(NULL)
  31. { }
  32. };
  33. struct client_context_st {
  34. int latch;
  35. size_t min_size;
  36. size_t max_size;
  37. size_t num_tasks;
  38. size_t count;
  39. char *blob;
  40. client_context_st():
  41. latch(0),
  42. min_size(1024),
  43. max_size(1024 *2),
  44. num_tasks(10),
  45. count(0), // 1000
  46. blob(NULL)
  47. { }
  48. };
  49. void *world_create(test_return_t *error);
  50. test_return_t world_destroy(void *object);
  51. static gearman_return_t _complete(gearman_task_st *task)
  52. {
  53. std::cerr << "Completed " << gearman_task_job_handle(task) << std::endl;
  54. return GEARMAN_SUCCESS;
  55. }
  56. #ifndef __INTEL_COMPILER
  57. #pragma GCC diagnostic ignored "-Wold-style-cast"
  58. #endif
  59. static test_return_t burnin_test(void *object)
  60. {
  61. gearman_client_st *client= (gearman_client_st *)object;
  62. struct client_context_st *context= (struct client_context_st *)gearman_client_context(client);
  63. // This sketchy, don't do this in your own code.
  64. gearman_task_st *tasks= (gearman_task_st *)calloc(context->num_tasks, sizeof(gearman_task_st));
  65. test_true_got(tasks, strerror(errno));
  66. gearman_client_set_complete_fn(client, _complete);
  67. test_true_got(gearman_success(gearman_client_echo(client, gearman_literal_param("echo_test"))), gearman_client_error(client));
  68. do
  69. {
  70. for (uint32_t x= 0; x < context->num_tasks; x++)
  71. {
  72. size_t blob_size= 0;
  73. if (context->min_size == context->max_size)
  74. {
  75. blob_size= context->max_size;
  76. }
  77. else
  78. {
  79. blob_size= (size_t)rand();
  80. if (context->max_size > RAND_MAX)
  81. blob_size*= (size_t)(rand() + 1);
  82. blob_size= (blob_size % (context->max_size - context->min_size)) + context->min_size;
  83. }
  84. gearman_task_st *task_ptr;
  85. gearman_return_t ret;
  86. if (context->latch)
  87. {
  88. task_ptr= gearman_client_add_task_background(client, &(tasks[x]),
  89. NULL, DEFAULT_WORKER_NAME, NULL,
  90. (void *)context->blob, blob_size, &ret);
  91. }
  92. else
  93. {
  94. task_ptr= gearman_client_add_task(client, &(tasks[x]), NULL,
  95. DEFAULT_WORKER_NAME, NULL, (void *)context->blob, blob_size,
  96. &ret);
  97. }
  98. test_true_got(gearman_success(ret), gearman_client_error(client));
  99. test_truth(task_ptr);
  100. std::cerr << "Added job " << x << std::endl;
  101. }
  102. gearman_client_set_timeout(client, 4000);
  103. gearman_return_t ret= gearman_client_run_tasks(client);
  104. for (uint32_t x= 0; x < context->num_tasks; x++)
  105. {
  106. std::cerr << gearman_strerror(gearman_task_error(&tasks[x])) << std::endl;
  107. }
  108. std::cerr << "run tasks left " << client->new_tasks << std::endl;
  109. test_true_got(gearman_success(ret), gearman_client_error(client));
  110. for (uint32_t x= 0; x < context->num_tasks; x++)
  111. {
  112. gearman_task_free(&(tasks[x]));
  113. }
  114. } while (context->count--);
  115. free(tasks);
  116. context->latch++;
  117. return TEST_SUCCESS;
  118. }
  119. static test_return_t setup(void *object)
  120. {
  121. gearman_client_st *client= (gearman_client_st *)object;
  122. struct client_context_st *context= new client_context_st;
  123. test_true_got(context, strerror(errno));
  124. context->blob= (char *)malloc(context->max_size);
  125. test_true_got(context->blob, strerror(errno));
  126. memset(context->blob, 'x', context->max_size);
  127. gearman_client_set_context(client, context);
  128. return TEST_SUCCESS;
  129. }
  130. static test_return_t cleanup(void *object)
  131. {
  132. gearman_client_st *client= (gearman_client_st *)object;
  133. struct client_context_st *context= (struct client_context_st *)gearman_client_context(client);
  134. free(context->blob);
  135. delete(context);
  136. return TEST_SUCCESS;
  137. }
  138. static void *worker_fn(gearman_job_st *, void *,
  139. size_t *result_size, gearman_return_t *ret_ptr)
  140. {
  141. result_size= 0;
  142. *ret_ptr= GEARMAN_SUCCESS;
  143. return NULL;
  144. }
  145. void *world_create(test_return_t *error)
  146. {
  147. pid_t gearmand_pid;
  148. /**
  149. * @TODO We cast this to char ** below, which is evil. We need to do the
  150. * right thing
  151. */
  152. const char *argv[1]= { "client_gearmand" };
  153. client_test_st *test= new client_test_st;
  154. if (not test)
  155. {
  156. *error= TEST_MEMORY_ALLOCATION_FAILURE;
  157. return NULL;
  158. }
  159. /**
  160. We start up everything before we allocate so that we don't have to track memory in the forked process.
  161. */
  162. test->gearmand_pid= gearmand_pid= test_gearmand_start(CLIENT_TEST_PORT, 1, argv);
  163. if (test->gearmand_pid == -1)
  164. {
  165. *error= TEST_FAILURE;
  166. return NULL;
  167. }
  168. test->handle= test_worker_start(CLIENT_TEST_PORT, DEFAULT_WORKER_NAME, worker_fn, NULL, gearman_worker_options_t());
  169. if (not test->handle)
  170. {
  171. *error= TEST_FAILURE;
  172. return NULL;
  173. }
  174. if (not gearman_client_create(&(test->client)))
  175. {
  176. *error= TEST_FAILURE;
  177. return NULL;
  178. }
  179. if (gearman_failed(gearman_client_add_server(&(test->client), NULL, CLIENT_TEST_PORT)))
  180. {
  181. *error= TEST_FAILURE;
  182. return NULL;
  183. }
  184. *error= TEST_SUCCESS;
  185. return (void *)test;
  186. }
  187. test_return_t world_destroy(void *object)
  188. {
  189. client_test_st *test= (client_test_st *)object;
  190. gearman_client_free(&(test->client));
  191. test_gearmand_stop(test->gearmand_pid);
  192. test_worker_stop(test->handle);
  193. delete test;
  194. return TEST_SUCCESS;
  195. }
  196. test_st tests[] ={
  197. {"burnin", 0, burnin_test },
  198. // {"burnin_background", 0, burnin_test },
  199. {0, 0, 0}
  200. };
  201. collection_st collection[] ={
  202. {"burnin", setup, cleanup, tests},
  203. {0, 0, 0, 0}
  204. };
  205. typedef test_return_t (*libgearman_test_callback_fn)(gearman_client_st *);
  206. static test_return_t _runner_default(libgearman_test_callback_fn func, client_test_st *container)
  207. {
  208. if (func)
  209. {
  210. return func(&container->client);
  211. }
  212. else
  213. {
  214. return TEST_SUCCESS;
  215. }
  216. }
  217. static world_runner_st runner= {
  218. (test_callback_runner_fn)_runner_default,
  219. (test_callback_runner_fn)_runner_default,
  220. (test_callback_runner_fn)_runner_default
  221. };
  222. void get_world(world_st *world)
  223. {
  224. world->collections= collection;
  225. world->create= world_create;
  226. world->destroy= world_destroy;
  227. world->runner= &runner;
  228. }