worker_test.cc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835
  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 <assert.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <unistd.h>
  17. #define GEARMAN_CORE
  18. #include <libgearman/gearman.h>
  19. #include <libgearman/connection.hpp>
  20. #include "libgearman/packet.hpp"
  21. #include "libgearman/universal.hpp"
  22. #include "libtest/test.h"
  23. #include "libtest/server.h"
  24. #define WORKER_TEST_PORT 32125
  25. struct worker_test_st
  26. {
  27. pid_t gearmand_pid;
  28. gearman_worker_st *_worker;
  29. gearman_worker_st *worker()
  30. {
  31. return _worker;
  32. }
  33. worker_test_st() :
  34. gearmand_pid(-1)
  35. {
  36. _worker= gearman_worker_create(NULL);
  37. }
  38. ~worker_test_st()
  39. {
  40. gearman_worker_free(_worker);
  41. }
  42. };
  43. static test_return_t init_test(void *)
  44. {
  45. gearman_worker_st worker;
  46. test_truth(gearman_worker_create(&worker));
  47. gearman_worker_free(&worker);
  48. return TEST_SUCCESS;
  49. }
  50. static test_return_t allocation_test(void *)
  51. {
  52. gearman_worker_st *worker;
  53. test_truth(worker= gearman_worker_create(NULL));
  54. gearman_worker_free(worker);
  55. return TEST_SUCCESS;
  56. }
  57. #ifndef __INTEL_COMPILER
  58. #pragma GCC diagnostic ignored "-Wold-style-cast"
  59. #endif
  60. static test_return_t clone_test(void *object)
  61. {
  62. gearman_worker_st *from= (gearman_worker_st *)object;
  63. gearman_worker_st *worker;
  64. test_truth(worker= gearman_worker_clone(NULL, NULL));
  65. test_truth(worker->options.allocated);
  66. gearman_worker_free(worker);
  67. test_truth(worker= gearman_worker_clone(NULL, from));
  68. gearman_worker_free(worker);
  69. return TEST_SUCCESS;
  70. }
  71. static test_return_t option_test(void *)
  72. {
  73. gearman_worker_st *gear;
  74. gearman_worker_options_t default_options;
  75. gear= gearman_worker_create(NULL);
  76. test_truth(gear);
  77. { // Initial Allocated, no changes
  78. test_truth(gear->options.allocated);
  79. test_false(gear->options.non_blocking);
  80. test_truth(gear->options.packet_init);
  81. test_false(gear->options.change);
  82. test_false(gear->options.grab_uniq);
  83. test_false(gear->options.timeout_return);
  84. }
  85. /* Set up for default options */
  86. default_options= gearman_worker_options(gear);
  87. /*
  88. We take the basic options, and push
  89. them back in. See if we change anything.
  90. */
  91. gearman_worker_set_options(gear, default_options);
  92. { // Initial Allocated, no changes
  93. test_truth(gear->options.allocated);
  94. test_false(gear->options.non_blocking);
  95. test_truth(gear->options.packet_init);
  96. test_false(gear->options.change);
  97. test_false(gear->options.grab_uniq);
  98. test_false(gear->options.timeout_return);
  99. }
  100. /*
  101. We will trying to modify non-mutable options (which should not be allowed)
  102. */
  103. {
  104. gearman_worker_remove_options(gear, GEARMAN_WORKER_ALLOCATED);
  105. { // Initial Allocated, no changes
  106. test_truth(gear->options.allocated);
  107. test_false(gear->options.non_blocking);
  108. test_truth(gear->options.packet_init);
  109. test_false(gear->options.change);
  110. test_false(gear->options.grab_uniq);
  111. test_false(gear->options.timeout_return);
  112. }
  113. gearman_worker_remove_options(gear, GEARMAN_WORKER_PACKET_INIT);
  114. { // Initial Allocated, no changes
  115. test_truth(gear->options.allocated);
  116. test_false(gear->options.non_blocking);
  117. test_truth(gear->options.packet_init);
  118. test_false(gear->options.change);
  119. test_false(gear->options.grab_uniq);
  120. test_false(gear->options.timeout_return);
  121. }
  122. }
  123. /*
  124. We will test modifying GEARMAN_WORKER_NON_BLOCKING in several manners.
  125. */
  126. {
  127. gearman_worker_remove_options(gear, GEARMAN_WORKER_NON_BLOCKING);
  128. { // GEARMAN_WORKER_NON_BLOCKING set to default, by default.
  129. test_truth(gear->options.allocated);
  130. test_false(gear->options.non_blocking);
  131. test_truth(gear->options.packet_init);
  132. test_false(gear->options.change);
  133. test_false(gear->options.grab_uniq);
  134. test_false(gear->options.timeout_return);
  135. }
  136. gearman_worker_add_options(gear, GEARMAN_WORKER_NON_BLOCKING);
  137. { // GEARMAN_WORKER_NON_BLOCKING set to default, by default.
  138. test_truth(gear->options.allocated);
  139. test_truth(gear->options.non_blocking);
  140. test_truth(gear->options.packet_init);
  141. test_false(gear->options.change);
  142. test_false(gear->options.grab_uniq);
  143. test_false(gear->options.timeout_return);
  144. }
  145. gearman_worker_set_options(gear, GEARMAN_WORKER_NON_BLOCKING);
  146. { // GEARMAN_WORKER_NON_BLOCKING set to default, by default.
  147. test_truth(gear->options.allocated);
  148. test_truth(gear->options.non_blocking);
  149. test_truth(gear->options.packet_init);
  150. test_false(gear->options.change);
  151. test_false(gear->options.grab_uniq);
  152. test_false(gear->options.timeout_return);
  153. }
  154. gearman_worker_set_options(gear, GEARMAN_WORKER_GRAB_UNIQ);
  155. { // Everything is now set to false except GEARMAN_WORKER_GRAB_UNIQ, and non-mutable options
  156. test_truth(gear->options.allocated);
  157. test_false(gear->options.non_blocking);
  158. test_truth(gear->options.packet_init);
  159. test_false(gear->options.change);
  160. test_truth(gear->options.grab_uniq);
  161. test_false(gear->options.timeout_return);
  162. }
  163. /*
  164. Reset options to default. Then add an option, and then add more options. Make sure
  165. the options are all additive.
  166. */
  167. {
  168. gearman_worker_set_options(gear, default_options);
  169. { // See if we return to defaults
  170. test_truth(gear->options.allocated);
  171. test_false(gear->options.non_blocking);
  172. test_truth(gear->options.packet_init);
  173. test_false(gear->options.change);
  174. test_false(gear->options.grab_uniq);
  175. test_false(gear->options.timeout_return);
  176. }
  177. gearman_worker_add_options(gear, GEARMAN_WORKER_TIMEOUT_RETURN);
  178. { // All defaults, except timeout_return
  179. test_truth(gear->options.allocated);
  180. test_false(gear->options.non_blocking);
  181. test_truth(gear->options.packet_init);
  182. test_false(gear->options.change);
  183. test_false(gear->options.grab_uniq);
  184. test_truth(gear->options.timeout_return);
  185. }
  186. gearman_worker_add_options(gear, (gearman_worker_options_t)(GEARMAN_WORKER_NON_BLOCKING|GEARMAN_WORKER_GRAB_UNIQ));
  187. { // GEARMAN_WORKER_NON_BLOCKING set to default, by default.
  188. test_truth(gear->options.allocated);
  189. test_truth(gear->options.non_blocking);
  190. test_truth(gear->options.packet_init);
  191. test_false(gear->options.change);
  192. test_truth(gear->options.grab_uniq);
  193. test_truth(gear->options.timeout_return);
  194. }
  195. }
  196. /*
  197. Add an option, and then replace with that option plus a new option.
  198. */
  199. {
  200. gearman_worker_set_options(gear, default_options);
  201. { // See if we return to defaults
  202. test_truth(gear->options.allocated);
  203. test_false(gear->options.non_blocking);
  204. test_truth(gear->options.packet_init);
  205. test_false(gear->options.change);
  206. test_false(gear->options.grab_uniq);
  207. test_false(gear->options.timeout_return);
  208. }
  209. gearman_worker_add_options(gear, GEARMAN_WORKER_TIMEOUT_RETURN);
  210. { // All defaults, except timeout_return
  211. test_truth(gear->options.allocated);
  212. test_false(gear->options.non_blocking);
  213. test_truth(gear->options.packet_init);
  214. test_false(gear->options.change);
  215. test_false(gear->options.grab_uniq);
  216. test_truth(gear->options.timeout_return);
  217. }
  218. gearman_worker_add_options(gear, (gearman_worker_options_t)(GEARMAN_WORKER_TIMEOUT_RETURN|GEARMAN_WORKER_GRAB_UNIQ));
  219. { // GEARMAN_WORKER_NON_BLOCKING set to default, by default.
  220. test_truth(gear->options.allocated);
  221. test_false(gear->options.non_blocking);
  222. test_truth(gear->options.packet_init);
  223. test_false(gear->options.change);
  224. test_truth(gear->options.grab_uniq);
  225. test_truth(gear->options.timeout_return);
  226. }
  227. }
  228. }
  229. gearman_worker_free(gear);
  230. return TEST_SUCCESS;
  231. }
  232. static test_return_t echo_test(void *object)
  233. {
  234. gearman_worker_st *worker= (gearman_worker_st *)object;
  235. assert(worker);
  236. test_true_got(gearman_success(gearman_worker_echo(worker, gearman_literal_param("This is my echo test"))), gearman_worker_error(worker));
  237. return TEST_SUCCESS;
  238. }
  239. static test_return_t echo_multi_test(void *object)
  240. {
  241. gearman_worker_st *worker= (gearman_worker_st *)object;
  242. assert(worker);
  243. const char *value[]= {
  244. "This is my echo test",
  245. "This land is my land",
  246. "This land is your land",
  247. "We the people",
  248. "in order to form a more perfect union",
  249. "establish justice",
  250. NULL
  251. };
  252. const char **ptr= value;
  253. while (*ptr)
  254. {
  255. test_true_got(gearman_success(gearman_worker_echo(worker, gearman_c_str_param(*ptr))), gearman_worker_error(worker));
  256. ptr++;
  257. }
  258. return TEST_SUCCESS;
  259. }
  260. static test_return_t echo_max_test(void *object)
  261. {
  262. gearman_worker_st *worker= (gearman_worker_st *)object;
  263. assert(worker);
  264. test_compare(GEARMAN_ARGUMENT_TOO_LARGE, gearman_worker_echo(worker, "This is my echo test", SIZE_MAX));
  265. return TEST_SUCCESS;
  266. }
  267. static test_return_t abandoned_worker_test(void *)
  268. {
  269. gearman_job_handle_t job_handle;
  270. const void *args[2];
  271. size_t args_size[2];
  272. {
  273. gearman_client_st *client= gearman_client_create(NULL);
  274. test_truth(client);
  275. gearman_client_add_server(client, NULL, WORKER_TEST_PORT);
  276. test_true_got(gearman_success(gearman_client_do_background(client, "abandoned_worker", NULL, NULL, 0, job_handle)), gearman_client_error(client));
  277. gearman_client_free(client);
  278. }
  279. /* Now take job with one worker. */
  280. gearman_universal_st universal;
  281. gearman_universal_initialize(universal);
  282. gearman_connection_st *worker1;
  283. test_truth(worker1= gearman_connection_create(universal, NULL));
  284. worker1->set_host(NULL, WORKER_TEST_PORT);
  285. gearman_packet_st packet;
  286. args[0]= "abandoned_worker";
  287. args_size[0]= strlen("abandoned_worker");
  288. test_truth(gearman_success(gearman_packet_create_args(universal, packet, GEARMAN_MAGIC_REQUEST,
  289. GEARMAN_COMMAND_CAN_DO,
  290. args, args_size, 1)));
  291. test_true_got(gearman_success(worker1->send(packet, true)), gearman_universal_error(universal));
  292. gearman_packet_free(&packet);
  293. gearman_return_t ret;
  294. test_true_got(gearman_success(ret= gearman_packet_create_args(universal, packet, GEARMAN_MAGIC_REQUEST,
  295. GEARMAN_COMMAND_GRAB_JOB,
  296. NULL, NULL, 0)), gearman_strerror(ret));
  297. test_true_got(gearman_success(ret= worker1->send(packet, true)), gearman_strerror(ret));
  298. gearman_packet_free(&packet);
  299. worker1->receiving(packet, ret, false);
  300. test_truth(not (ret != GEARMAN_SUCCESS || packet.command != GEARMAN_COMMAND_JOB_ASSIGN));
  301. test_strcmp(job_handle, packet.arg[0]); // unexepcted job
  302. gearman_packet_free(&packet);
  303. gearman_connection_st *worker2;
  304. test_truth(worker2= gearman_connection_create(universal, NULL));
  305. worker2->set_host(NULL, WORKER_TEST_PORT);
  306. args[0]= "abandoned_worker";
  307. args_size[0]= strlen("abandoned_worker");
  308. test_true_got(gearman_success(ret= gearman_packet_create_args(universal, packet, GEARMAN_MAGIC_REQUEST,
  309. GEARMAN_COMMAND_CAN_DO,
  310. args, args_size, 1)), gearman_strerror(ret));
  311. test_true_got(gearman_success(ret= worker2->send(packet, true)), gearman_strerror(ret));
  312. gearman_packet_free(&packet);
  313. args[0]= job_handle;
  314. args_size[0]= strlen(job_handle) + 1;
  315. args[1]= "test";
  316. args_size[1]= 4;
  317. test_true_got(gearman_success(ret= gearman_packet_create_args(universal, packet, GEARMAN_MAGIC_REQUEST,
  318. GEARMAN_COMMAND_WORK_COMPLETE,
  319. args, args_size, 2)), gearman_strerror(ret));
  320. test_true_got(gearman_success(ret= worker2->send(packet, true)), gearman_strerror(ret));
  321. gearman_packet_free(&packet);
  322. gearman_universal_set_timeout(universal, 1000);
  323. worker2->receiving(packet, ret, false);
  324. test_truth(not (ret != GEARMAN_SUCCESS or packet.command != GEARMAN_COMMAND_ERROR));
  325. delete worker1;
  326. delete worker2;
  327. gearman_packet_free(&packet);
  328. gearman_universal_free(universal);
  329. return TEST_SUCCESS;
  330. }
  331. static void *no_unique_worker(gearman_job_st *job,
  332. void *, size_t *size,
  333. gearman_return_t *ret_ptr)
  334. {
  335. if (gearman_job_unique(job) and strlen(gearman_job_unique(job)))
  336. {
  337. *ret_ptr= GEARMAN_WORK_FAIL;
  338. }
  339. else
  340. {
  341. *ret_ptr= GEARMAN_SUCCESS;
  342. }
  343. *size= 0;
  344. return NULL;
  345. }
  346. static void *check_unique_worker(gearman_job_st *job,
  347. void *context, size_t *size,
  348. gearman_return_t *ret_ptr)
  349. {
  350. if (gearman_job_unique(job))
  351. {
  352. size_t length= strlen(gearman_job_unique(job));
  353. if (length == gearman_job_workload_size(job))
  354. {
  355. if (not memcmp(gearman_job_unique(job), gearman_job_workload(job),length))
  356. {
  357. bool *success= (bool *)context;
  358. if (success)
  359. *success= true;
  360. *ret_ptr= GEARMAN_SUCCESS;
  361. *size= length;
  362. return strdup((char*)gearman_job_unique(job));
  363. }
  364. }
  365. }
  366. *size= 0;
  367. *ret_ptr= GEARMAN_WORK_FAIL;
  368. return NULL;
  369. }
  370. static void *fail_worker(gearman_job_st *,
  371. void *, size_t *size,
  372. gearman_return_t *ret_ptr)
  373. {
  374. *ret_ptr= GEARMAN_WORK_FAIL;
  375. *size= 0;
  376. return NULL;
  377. }
  378. static test_return_t gearman_worker_add_function_test(void *object)
  379. {
  380. gearman_worker_st *worker= (gearman_worker_st *)object;
  381. const char *function_name= "fail_worker";
  382. test_true_got(gearman_success(gearman_worker_add_function(worker, function_name,0, fail_worker, NULL)), gearman_worker_error(worker));
  383. test_truth(gearman_worker_function_exist(worker, gearman_c_str_param(function_name)));
  384. test_true_got(gearman_success(gearman_worker_unregister(worker, function_name)), gearman_worker_error(worker));
  385. bool found= gearman_worker_function_exist(worker, function_name, strlen(function_name));
  386. test_false(found);
  387. /* Make sure we have removed it */
  388. test_true_got(GEARMAN_NO_REGISTERED_FUNCTION == gearman_worker_unregister(worker, function_name), gearman_worker_error(worker));
  389. return TEST_SUCCESS;
  390. }
  391. static test_return_t gearman_worker_add_function_multi_test(void *object)
  392. {
  393. gearman_worker_st *worker= (gearman_worker_st *)object;
  394. const char *function_name_ext= "fail_worker";
  395. for (uint32_t x= 0; x < 100; x++)
  396. {
  397. char buffer[1024];
  398. snprintf(buffer, 1024, "%u%s", x, function_name_ext);
  399. test_true_got(gearman_success(gearman_worker_add_function(worker, buffer, 0, fail_worker, NULL)), gearman_worker_error(worker));
  400. }
  401. for (uint32_t x= 0; x < 100; x++)
  402. {
  403. char buffer[1024];
  404. snprintf(buffer, 1024, "%u%s", x, function_name_ext);
  405. test_true_got(gearman_success(gearman_worker_unregister(worker, buffer)), gearman_worker_error(worker));
  406. }
  407. for (uint32_t x= 0; x < 100; x++)
  408. {
  409. char buffer[1024];
  410. snprintf(buffer, 1024, "%u%s", x, function_name_ext);
  411. test_true_got(GEARMAN_NO_REGISTERED_FUNCTION == gearman_worker_unregister(worker, buffer), gearman_worker_error(worker));
  412. }
  413. return TEST_SUCCESS;
  414. }
  415. static test_return_t gearman_worker_unregister_all_test(void *object)
  416. {
  417. gearman_worker_st *worker= (gearman_worker_st *)object;
  418. const char *function_name_ext= "fail_worker";
  419. for (uint32_t x= 0; x < 100; x++)
  420. {
  421. char buffer[1024];
  422. snprintf(buffer, sizeof(buffer), "%u%s", x, function_name_ext);
  423. gearman_return_t rc= gearman_worker_add_function(worker,
  424. buffer,
  425. 0, fail_worker, NULL);
  426. test_true_got(gearman_success(rc), gearman_strerror(rc));
  427. }
  428. test_truth(gearman_success(gearman_worker_unregister_all(worker)));
  429. for (uint32_t x= 0; x < 100; x++)
  430. {
  431. char buffer[1024];
  432. snprintf(buffer, sizeof(buffer), "%u%s", x, function_name_ext);
  433. gearman_return_t rc= gearman_worker_unregister(worker, buffer);
  434. test_true_got(rc == GEARMAN_NO_REGISTERED_FUNCTION, gearman_strerror(rc));
  435. }
  436. test_true_got(GEARMAN_NO_REGISTERED_FUNCTIONS == gearman_worker_unregister_all(worker), gearman_worker_error(worker));
  437. return TEST_SUCCESS;
  438. }
  439. static test_return_t gearman_worker_work_with_test(void *object)
  440. {
  441. gearman_worker_st *worker= (gearman_worker_st *)object;
  442. const char *function_name= "fail_worker";
  443. gearman_return_t rc;
  444. rc= gearman_worker_add_function(worker,
  445. function_name,
  446. 0, fail_worker, NULL);
  447. test_true_got(rc == GEARMAN_SUCCESS, gearman_strerror(rc));
  448. gearman_worker_set_timeout(worker, 2);
  449. rc= gearman_worker_work(worker);
  450. test_true_got(rc == GEARMAN_TIMEOUT, gearman_strerror(rc));
  451. /* Make sure we have remove worker function */
  452. rc= gearman_worker_unregister(worker, function_name);
  453. test_true_got(rc == GEARMAN_SUCCESS, gearman_strerror(rc));
  454. return TEST_SUCCESS;
  455. }
  456. static test_return_t gearman_worker_context_test(void *object)
  457. {
  458. gearman_worker_st *worker= (gearman_worker_st *)object;
  459. test_truth(worker);
  460. test_false(gearman_worker_context(worker));
  461. int value= 5;
  462. gearman_worker_set_context(worker, &value);
  463. int *ptr= (int *)gearman_worker_context(worker);
  464. test_truth(ptr == &value);
  465. test_truth(*ptr == value);
  466. gearman_worker_set_context(worker, NULL);
  467. return TEST_SUCCESS;
  468. }
  469. static test_return_t gearman_worker_remove_options_GEARMAN_WORKER_GRAB_UNIQ(void *object)
  470. {
  471. gearman_worker_st *worker= (gearman_worker_st *)object;
  472. const char *function_name= "_test_worker";
  473. const char *unique_name= "fooman";
  474. gearman_return_t rc;
  475. test_true_got(gearman_success(rc= gearman_worker_add_function(worker,
  476. function_name,
  477. 0,
  478. no_unique_worker, NULL)), gearman_strerror(rc));
  479. {
  480. gearman_client_st *client;
  481. test_truth(client= gearman_client_create(NULL));
  482. gearman_client_add_server(client, NULL, WORKER_TEST_PORT);
  483. test_true_got(gearman_success(gearman_client_do_background(client, function_name, unique_name, gearman_c_str_param(unique_name), NULL)), gearman_client_error(client));
  484. gearman_client_free(client);
  485. }
  486. test_false(worker->options.grab_uniq);
  487. gearman_worker_add_options(worker, GEARMAN_WORKER_GRAB_UNIQ);
  488. test_truth(worker->options.grab_uniq);
  489. gearman_worker_remove_options(worker, GEARMAN_WORKER_GRAB_UNIQ);
  490. test_false(worker->options.grab_uniq);
  491. gearman_job_st *job= gearman_worker_grab_job(worker, NULL, &rc);
  492. test_true_got(gearman_success(rc), gearman_strerror(rc));
  493. test_truth(job);
  494. size_t size= 0;
  495. void *result= no_unique_worker(job, NULL, &size, &rc);
  496. test_true_got(gearman_success(rc), gearman_strerror(rc));
  497. test_false(result);
  498. test_false(size);
  499. return TEST_SUCCESS;
  500. }
  501. static test_return_t gearman_worker_add_options_GEARMAN_WORKER_GRAB_UNIQ(void *object)
  502. {
  503. gearman_worker_st *worker= (gearman_worker_st *)object;
  504. const char *function_name= "_test_worker";
  505. const char *unique_name= "fooman";
  506. gearman_return_t rc;
  507. test_true_got(gearman_success(rc= gearman_worker_add_function(worker,
  508. function_name,
  509. 0,
  510. check_unique_worker, NULL)), gearman_strerror(rc));
  511. {
  512. gearman_client_st *client;
  513. test_truth(client= gearman_client_create(NULL));
  514. gearman_client_add_server(client, NULL, WORKER_TEST_PORT);
  515. test_true_got(gearman_success(gearman_client_do_background(client, function_name, unique_name, gearman_c_str_param(unique_name), NULL)), gearman_client_error(client));
  516. gearman_client_free(client);
  517. }
  518. test_false(worker->options.grab_uniq);
  519. gearman_worker_add_options(worker, GEARMAN_WORKER_GRAB_UNIQ);
  520. test_truth(worker->options.grab_uniq);
  521. gearman_job_st *job= gearman_worker_grab_job(worker, NULL, &rc);
  522. test_true_got(gearman_success(rc), gearman_strerror(rc));
  523. test_truth(job);
  524. size_t size= 0;
  525. void *result= check_unique_worker(job, NULL, &size, &rc);
  526. test_true_got(gearman_success(rc), gearman_strerror(rc));
  527. test_truth(result);
  528. test_truth(size);
  529. free(result);
  530. return TEST_SUCCESS;
  531. }
  532. static test_return_t gearman_worker_add_options_GEARMAN_WORKER_GRAB_UNIQ_worker_work(void *object)
  533. {
  534. gearman_worker_st *worker= (gearman_worker_st *)object;
  535. const char *function_name= "_test_worker";
  536. const char *unique_name= "fooman";
  537. gearman_return_t rc;
  538. bool success= false;
  539. test_true_got(gearman_success(rc= gearman_worker_add_function(worker,
  540. function_name,
  541. 0,
  542. check_unique_worker, &success)), gearman_strerror(rc));
  543. {
  544. gearman_client_st *client;
  545. test_truth(client= gearman_client_create(NULL));
  546. gearman_client_add_server(client, NULL, WORKER_TEST_PORT);
  547. test_true_got(gearman_success(gearman_client_do_background(client, function_name, unique_name, gearman_c_str_param(unique_name), NULL)), gearman_client_error(client));
  548. gearman_client_free(client);
  549. }
  550. test_false(worker->options.grab_uniq);
  551. gearman_worker_add_options(worker, GEARMAN_WORKER_GRAB_UNIQ);
  552. test_truth(worker->options.grab_uniq);
  553. test_true_got(gearman_success(rc= gearman_worker_work(worker)), gearman_strerror(rc));
  554. test_truth(success);
  555. return TEST_SUCCESS;
  556. }
  557. static test_return_t gearman_worker_failover_test(void *object)
  558. {
  559. gearman_worker_st *worker= (gearman_worker_st *)object;
  560. gearman_return_t rc;
  561. test_true_got(gearman_success(rc= gearman_worker_add_server(worker, NULL, WORKER_TEST_PORT)), gearman_strerror(rc));
  562. test_true_got(gearman_success(rc= gearman_worker_add_server(worker, NULL, WORKER_TEST_PORT +1)), gearman_strerror(rc));
  563. const char *function_name= "fail_worker";
  564. test_true_got(gearman_success(rc= gearman_worker_add_function(worker,
  565. function_name,
  566. 0, fail_worker, NULL)), gearman_strerror(rc));
  567. gearman_worker_set_timeout(worker, 2);
  568. rc= gearman_worker_work(worker);
  569. test_true_got(rc == GEARMAN_TIMEOUT, gearman_strerror(rc));
  570. /* Make sure we have remove worker function */
  571. test_true_got(gearman_success(rc= gearman_worker_unregister(worker, function_name)) , gearman_strerror(rc));
  572. return TEST_SUCCESS;
  573. }
  574. /*********************** World functions **************************************/
  575. static void *world_create(test_return_t *error)
  576. {
  577. pid_t gearmand_pid;
  578. gearmand_pid= test_gearmand_start(WORKER_TEST_PORT, 0, NULL);
  579. if (gearmand_pid == -1)
  580. {
  581. *error= TEST_FAILURE;
  582. return NULL;
  583. }
  584. worker_test_st *test= new worker_test_st;
  585. if (not test)
  586. {
  587. *error= TEST_MEMORY_ALLOCATION_FAILURE;
  588. return NULL;
  589. }
  590. test->gearmand_pid= gearmand_pid;
  591. if (gearman_worker_add_server(test->worker(), NULL, WORKER_TEST_PORT) != GEARMAN_SUCCESS)
  592. {
  593. *error= TEST_FAILURE;
  594. return NULL;
  595. }
  596. *error= TEST_SUCCESS;
  597. return (void *)test;
  598. }
  599. static test_return_t world_destroy(void *object)
  600. {
  601. worker_test_st *test= (worker_test_st *)object;
  602. test_gearmand_stop(test->gearmand_pid);
  603. delete test;
  604. return TEST_SUCCESS;
  605. }
  606. test_st tests[] ={
  607. {"init", 0, init_test },
  608. {"allocation", 0, allocation_test },
  609. {"clone", 0, clone_test },
  610. {"echo", 0, echo_test },
  611. {"echo_multi", 0, echo_multi_test },
  612. {"options", 0, option_test },
  613. {"gearman_worker_add_function()", 0, gearman_worker_add_function_test },
  614. {"gearman_worker_add_function() multi", 0, gearman_worker_add_function_multi_test },
  615. {"gearman_worker_unregister_all()", 0, gearman_worker_unregister_all_test },
  616. {"gearman_worker_work() with timout", 0, gearman_worker_work_with_test },
  617. {"gearman_worker_context", 0, gearman_worker_context_test },
  618. {"gearman_worker_failover", 0, gearman_worker_failover_test },
  619. {"gearman_worker_remove_options(GEARMAN_WORKER_GRAB_UNIQ)", 0, gearman_worker_remove_options_GEARMAN_WORKER_GRAB_UNIQ },
  620. {"gearman_worker_add_options(GEARMAN_WORKER_GRAB_UNIQ)", 0, gearman_worker_add_options_GEARMAN_WORKER_GRAB_UNIQ },
  621. {"gearman_worker_add_options(GEARMAN_WORKER_GRAB_UNIQ) worker_work()", 0, gearman_worker_add_options_GEARMAN_WORKER_GRAB_UNIQ_worker_work },
  622. {"echo_max", 0, echo_max_test },
  623. {"abandoned_worker", 0, abandoned_worker_test },
  624. {0, 0, 0}
  625. };
  626. collection_st collection[] ={
  627. {"worker", 0, 0, tests},
  628. {0, 0, 0, 0}
  629. };
  630. typedef test_return_t (*libgearman_test_prepost_callback_fn)(worker_test_st *);
  631. typedef test_return_t (*libgearman_test_callback_fn)(gearman_worker_st *);
  632. static test_return_t _runner_prepost_default(libgearman_test_prepost_callback_fn func, worker_test_st *container)
  633. {
  634. if (func)
  635. {
  636. return func(container);
  637. }
  638. return TEST_SUCCESS;
  639. }
  640. static test_return_t _runner_default(libgearman_test_callback_fn func, worker_test_st *container)
  641. {
  642. if (func)
  643. {
  644. test_return_t rc;
  645. if (container->worker())
  646. {
  647. gearman_worker_st *worker= gearman_worker_clone(NULL, container->worker());
  648. test_truth(worker);
  649. rc= func(worker);
  650. gearman_worker_free(worker);
  651. }
  652. else
  653. {
  654. rc= func(container->worker());
  655. }
  656. return rc;
  657. }
  658. return TEST_SUCCESS;
  659. }
  660. static world_runner_st runner= {
  661. (test_callback_runner_fn)_runner_prepost_default,
  662. (test_callback_runner_fn)_runner_default,
  663. (test_callback_runner_fn)_runner_prepost_default
  664. };
  665. void get_world(world_st *world)
  666. {
  667. world->collections= collection;
  668. world->create= world_create;
  669. world->destroy= world_destroy;
  670. world->runner= &runner;
  671. }