task.cc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
  2. *
  3. * Gearmand client and server library.
  4. *
  5. * Copyright (C) 2011-2013 Data Differential, http://datadifferential.com/
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions are
  10. * met:
  11. *
  12. * * Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * * Redistributions in binary form must reproduce the above
  16. * copyright notice, this list of conditions and the following disclaimer
  17. * in the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * * The names of its contributors may not be used to endorse or
  21. * promote products derived from this software without specific prior
  22. * written permission.
  23. *
  24. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  25. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  26. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  28. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  29. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  30. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  31. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  32. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  33. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  34. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35. *
  36. */
  37. #include "gear_config.h"
  38. #include <libtest/test.hpp>
  39. using namespace libtest;
  40. #include <libgearman-1.0/gearman.h>
  41. #include "libgearman/actions.hpp"
  42. #include "tests/task.h"
  43. #include "tests/workers/v2/call_exception.h"
  44. #include "tests/start_worker.h"
  45. #include "libgearman/client.hpp"
  46. #include "libgearman/worker.hpp"
  47. using namespace org::gearmand;
  48. #include <cassert>
  49. #include "libgearman/interface/task.hpp"
  50. #include <iostream>
  51. #include <memory>
  52. #ifndef __INTEL_COMPILER
  53. #pragma GCC diagnostic ignored "-Wold-style-cast"
  54. #endif
  55. test_return_t gearman_client_add_task_status_by_unique_NOT_FOUND_TEST(void *object)
  56. {
  57. gearman_client_st *client= (gearman_client_st *)object;
  58. const char *worker_function= (const char *)gearman_client_context(client);
  59. const char* unique_key= __func__;
  60. fatal_assert(worker_function);
  61. gearman_return_t ret;
  62. gearman_task_st* unique_task= gearman_client_add_task_status_by_unique(client,
  63. NULL, // context
  64. unique_key,
  65. &ret);
  66. ASSERT_EQ(GEARMAN_SUCCESS, ret);
  67. ASSERT_TRUE(unique_task);
  68. ASSERT_TRUE(gearman_task_unique(unique_task));
  69. ASSERT_EQ(strlen(unique_key), strlen(gearman_task_unique(unique_task)));
  70. libtest::dream(1, 0);
  71. test_false(gearman_task_is_running(unique_task));
  72. test_false(gearman_task_is_known(unique_task));
  73. gearman_task_free(unique_task);
  74. return TEST_SUCCESS;
  75. }
  76. test_return_t gearman_client_add_task_status_by_unique_TEST(void *object)
  77. {
  78. gearman_client_st *client= (gearman_client_st *)object;
  79. const char *worker_function= (const char *)gearman_client_context(client);
  80. const char* unique_key= __func__;
  81. fatal_assert(worker_function);
  82. gearman_return_t ret;
  83. gearman_task_st *task= gearman_client_add_task(client,
  84. NULL, // preallocated task
  85. NULL, // context
  86. worker_function, // function
  87. unique_key, // unique
  88. test_literal_param("sleep"), // workload
  89. &ret);
  90. ASSERT_EQ(GEARMAN_SUCCESS, ret);
  91. ASSERT_TRUE(task);
  92. ASSERT_TRUE(gearman_task_unique(task));
  93. ASSERT_EQ(strlen(unique_key), strlen(gearman_task_unique(task)));
  94. do
  95. {
  96. // just for async IO
  97. size_t limit= 10;
  98. do {
  99. if (--limit)
  100. {
  101. break;
  102. }
  103. ret= gearman_client_run_tasks(client);
  104. } while (gearman_continue(ret));
  105. if (limit)
  106. {
  107. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  108. }
  109. // If the task has been built to be freed, we won't have it to test
  110. if (gearman_client_has_option(client, GEARMAN_CLIENT_FREE_TASKS))
  111. {
  112. return TEST_SUCCESS;
  113. }
  114. } while (gearman_task_is_running(task));
  115. gearman_task_st* unique_task= gearman_client_add_task_status_by_unique(client,
  116. NULL, // context
  117. unique_key,
  118. &ret);
  119. ASSERT_EQ(GEARMAN_SUCCESS, ret);
  120. ASSERT_TRUE(unique_task);
  121. ASSERT_TRUE(gearman_task_unique(unique_task));
  122. ASSERT_EQ(strlen(unique_key), strlen(gearman_task_unique(unique_task)));
  123. gearman_task_free(unique_task);
  124. gearman_task_free(task);
  125. return TEST_SUCCESS;
  126. }
  127. test_return_t gearman_client_add_task_test(void *object)
  128. {
  129. SKIP_IF(HAVE_UUID_UUID_H != 1);
  130. gearman_client_st *client= (gearman_client_st *)object;
  131. const char *worker_function= (const char *)gearman_client_context(client);
  132. fatal_assert(worker_function);
  133. gearman_return_t ret;
  134. gearman_task_st *task= gearman_client_add_task(client,
  135. NULL, // preallocated task
  136. NULL, // context
  137. worker_function, // function
  138. NULL, // unique
  139. test_literal_param("dog"), // workload
  140. &ret);
  141. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  142. ASSERT_TRUE(task);
  143. ASSERT_TRUE(gearman_task_unique(task));
  144. ASSERT_EQ(size_t(GEARMAN_MAX_UUID_SIZE), strlen(gearman_task_unique(task)));
  145. do
  146. {
  147. // just for async IO
  148. do {
  149. ret= gearman_client_run_tasks(client);
  150. } while (gearman_continue(ret));
  151. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  152. // If the task has been built to be freed, we won't have it to test
  153. if (gearman_client_has_option(client, GEARMAN_CLIENT_FREE_TASKS))
  154. {
  155. return TEST_SUCCESS;
  156. }
  157. } while (gearman_task_is_running(task));
  158. gearman_task_free(task);
  159. return TEST_SUCCESS;
  160. }
  161. test_return_t gearman_client_add_task_test_fail(void *object)
  162. {
  163. gearman_client_st *client= (gearman_client_st *)object;
  164. const char *worker_function= (const char *)gearman_client_context(client);
  165. fatal_assert(worker_function);
  166. gearman_return_t ret;
  167. gearman_task_st *task= gearman_client_add_task(client, NULL, NULL,
  168. worker_function, NULL,
  169. test_literal_param("fail"),
  170. &ret);
  171. ASSERT_EQ(GEARMAN_SUCCESS,ret);
  172. ASSERT_TRUE(task);
  173. ASSERT_TRUE(task->impl()->client);
  174. do {
  175. ret= gearman_client_run_tasks(client);
  176. } while (gearman_continue(ret));
  177. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  178. // If the task has been free() then we can't check anything about it
  179. if (gearman_client_has_option(client, GEARMAN_CLIENT_FREE_TASKS))
  180. {
  181. return TEST_SUCCESS;
  182. }
  183. ASSERT_TRUE(task->impl()->client);
  184. ASSERT_EQ(gearman_task_return(task), GEARMAN_WORK_FAIL);
  185. ASSERT_TRUE(task->impl()->client);
  186. gearman_task_free(task);
  187. return TEST_SUCCESS;
  188. }
  189. test_return_t gearman_client_add_task_test_bad_workload(void *object)
  190. {
  191. gearman_client_st *client= (gearman_client_st *)object;
  192. const char *worker_function= (const char *)gearman_client_context(client);
  193. fatal_assert(worker_function);
  194. gearman_return_t ret;
  195. // We test for pointer with zero size
  196. gearman_task_st *task= gearman_client_add_task(client, NULL, NULL,
  197. worker_function, NULL, "fail", 0,
  198. &ret);
  199. ASSERT_EQ(ret, GEARMAN_INVALID_ARGUMENT);
  200. test_false(task);
  201. // We test for NULL with size
  202. task= gearman_client_add_task(client, NULL, NULL,
  203. worker_function, NULL, NULL, 5,
  204. &ret);
  205. ASSERT_EQ(ret, GEARMAN_INVALID_ARGUMENT);
  206. test_false(task);
  207. return TEST_SUCCESS;
  208. }
  209. static gearman_return_t gearman_exception_test_function(gearman_task_st *task)
  210. {
  211. bool *success= (bool *)gearman_task_context(task);
  212. if (not success)
  213. {
  214. return GEARMAN_WORK_FAIL;
  215. }
  216. *success= true;
  217. return GEARMAN_SUCCESS;
  218. }
  219. test_return_t gearman_client_add_task_exception(void *object)
  220. {
  221. gearman_client_st *client= (gearman_client_st *)object;
  222. const char *worker_function= (const char *)gearman_client_context(client);
  223. fatal_assert(worker_function);
  224. if (gearman_client_has_option(client, GEARMAN_CLIENT_FREE_TASKS))
  225. {
  226. return TEST_SKIPPED;
  227. }
  228. gearman_return_t ret;
  229. ASSERT_TRUE(gearman_client_set_server_option(client, test_literal_param("exceptions")));
  230. gearman_client_set_exception_fn(client, gearman_exception_test_function);
  231. bool exception_success= false;
  232. gearman_task_st *task= gearman_client_add_task(client, NULL, &exception_success,
  233. worker_function, NULL,
  234. test_literal_param("exception"),
  235. &ret);
  236. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  237. ASSERT_TRUE(task);
  238. do {
  239. ret= gearman_client_run_tasks(client);
  240. } while (gearman_continue(ret));
  241. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  242. ASSERT_TRUE(exception_success);
  243. gearman_client_set_exception_fn(client, NULL);
  244. // If the task has been free() then we can't check anything about it
  245. if (gearman_client_has_option(client, GEARMAN_CLIENT_FREE_TASKS))
  246. {
  247. return TEST_SUCCESS;
  248. }
  249. fatal_assert(client->impl()->task_list);
  250. gearman_task_free(task);
  251. return TEST_SUCCESS;
  252. }
  253. static gearman_return_t check_exception_function(gearman_task_st *task)
  254. {
  255. std::string *exception_str= (std::string *)gearman_task_context(task);
  256. if (exception_str == NULL)
  257. {
  258. Error << "Programmer error, null std::string passed";
  259. return GEARMAN_WORK_FAIL;
  260. }
  261. assert(task);
  262. #if 0
  263. exception_str->append(task->recv->arg[1], task->recv->arg_size[1]);
  264. #endif
  265. return GEARMAN_SUCCESS;
  266. }
  267. test_return_t gearman_client_add_task_check_exception_TEST(void*)
  268. {
  269. libgearman::Client client(libtest::default_port());
  270. if (gearman_client_has_option(&client, GEARMAN_CLIENT_FREE_TASKS))
  271. {
  272. return TEST_SKIPPED;
  273. }
  274. gearman_client_set_exception_fn(&client, check_exception_function);
  275. gearman_function_t func= gearman_function_create_v2(call_exception_WORKER);
  276. std::unique_ptr<worker_handle_st> call_exception_worker(test_worker_start(libtest::default_port(), NULL,
  277. __func__,
  278. func,
  279. NULL, gearman_worker_options_t()));
  280. std::string exception_string;
  281. gearman_return_t ret;
  282. gearman_task_st *task= gearman_client_add_task(&client, NULL, &exception_string,
  283. __func__, NULL,
  284. test_literal_param("exception test"),
  285. &ret);
  286. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  287. ASSERT_TRUE(task);
  288. do {
  289. ret= gearman_client_run_tasks(&client);
  290. } while (gearman_continue(ret));
  291. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  292. // This is a defect, from what I understand we should be passing along the
  293. // exception.
  294. #if 0
  295. ASSERT_TRUE(exception_string.compare("exception test") == 0);
  296. #endif
  297. // If the task has been free() then we can't check anything about it
  298. if (gearman_client_has_option(&client, GEARMAN_CLIENT_FREE_TASKS))
  299. {
  300. return TEST_SUCCESS;
  301. }
  302. fatal_assert(&client->impl()->task_list);
  303. gearman_task_free(task);
  304. return TEST_SUCCESS;
  305. }
  306. test_return_t gearman_client_add_task_background_test(void *object)
  307. {
  308. gearman_client_st *client= (gearman_client_st *)object;
  309. const char *worker_function= (const char *)gearman_client_context(client);
  310. fatal_assert(worker_function);
  311. gearman_return_t ret;
  312. gearman_task_st *task= gearman_client_add_task_background(client, NULL, NULL,
  313. worker_function, NULL, "dog", 3,
  314. &ret);
  315. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  316. ASSERT_TRUE(task);
  317. do
  318. {
  319. // just for async IO
  320. do {
  321. ret= gearman_client_run_tasks(client);
  322. } while (gearman_continue(ret));
  323. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  324. // If the task has been built to be freed, we won't have it to test
  325. if (gearman_client_has_option(client, GEARMAN_CLIENT_FREE_TASKS))
  326. {
  327. return TEST_SUCCESS;
  328. }
  329. } while (gearman_task_is_running(task));
  330. fatal_assert(client->impl()->task_list);
  331. gearman_task_free(task);
  332. return TEST_SUCCESS;
  333. }
  334. test_return_t gearman_client_add_task_high_background_test(void *object)
  335. {
  336. gearman_client_st *client= (gearman_client_st *)object;
  337. const char *worker_function= (const char *)gearman_client_context(client);
  338. fatal_assert(worker_function);
  339. gearman_return_t ret;
  340. gearman_task_st *task= gearman_client_add_task_high_background(client, NULL, NULL,
  341. worker_function, NULL, "dog", 3,
  342. &ret);
  343. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  344. ASSERT_TRUE(task);
  345. do
  346. {
  347. // just for async IO
  348. do {
  349. ret= gearman_client_run_tasks(client);
  350. } while (gearman_continue(ret));
  351. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  352. // If the task has been built to be freed, we won't have it to test
  353. if (gearman_client_has_option(client, GEARMAN_CLIENT_FREE_TASKS))
  354. {
  355. return TEST_SUCCESS;
  356. }
  357. } while (gearman_task_is_running(task));
  358. gearman_task_free(task);
  359. return TEST_SUCCESS;
  360. }
  361. test_return_t gearman_client_add_task_low_background_test(void *object)
  362. {
  363. gearman_client_st *client= (gearman_client_st *)object;
  364. const char *worker_function= (const char *)gearman_client_context(client);
  365. fatal_assert(worker_function);
  366. gearman_return_t ret;
  367. gearman_task_st *task= gearman_client_add_task_high_background(client, NULL, NULL,
  368. worker_function, NULL, "dog", 3,
  369. &ret);
  370. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  371. ASSERT_TRUE(task);
  372. do
  373. {
  374. // just for async IO
  375. do {
  376. ret= gearman_client_run_tasks(client);
  377. } while (gearman_continue(ret));
  378. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  379. // If the task has been built to be freed, we won't have it to test
  380. if (gearman_client_has_option(client, GEARMAN_CLIENT_FREE_TASKS))
  381. {
  382. return TEST_SUCCESS;
  383. }
  384. } while (gearman_task_is_running(task));
  385. if (not gearman_client_has_option(client, GEARMAN_CLIENT_FREE_TASKS))
  386. gearman_task_free(task);
  387. return TEST_SUCCESS;
  388. }
  389. static gearman_return_t gearman_warning_test_function(gearman_task_st *task)
  390. {
  391. bool *success= (bool *)gearman_task_context(task);
  392. if (not success)
  393. {
  394. return GEARMAN_WORK_FAIL;
  395. }
  396. *success= true;
  397. return GEARMAN_SUCCESS;
  398. }
  399. test_return_t gearman_client_add_task_warning(void *object)
  400. {
  401. gearman_client_st *client= (gearman_client_st *)object;
  402. const char *worker_function= (const char *)gearman_client_context(client);
  403. fatal_assert(worker_function);
  404. gearman_return_t ret;
  405. gearman_client_set_warning_fn(client, gearman_warning_test_function);
  406. bool warning_success= false;
  407. gearman_task_st *task= gearman_client_add_task(client, NULL, &warning_success,
  408. worker_function, NULL,
  409. test_literal_param("warning"),
  410. &ret);
  411. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  412. ASSERT_TRUE(task);
  413. ASSERT_EQ(GEARMAN_SUCCESS,
  414. gearman_client_run_tasks(client));
  415. ASSERT_TRUE(warning_success);
  416. gearman_client_set_warning_fn(client, NULL);
  417. if (not gearman_client_has_option(client, GEARMAN_CLIENT_FREE_TASKS))
  418. {
  419. gearman_task_free(task);
  420. }
  421. return TEST_SUCCESS;
  422. }
  423. test_return_t gearman_client_add_task_no_servers(void *)
  424. {
  425. gearman_client_st *client= gearman_client_create(NULL);
  426. ASSERT_TRUE(client);
  427. gearman_return_t ret;
  428. gearman_task_st *task= gearman_client_add_task(client, NULL, NULL,
  429. "does not exist", NULL,
  430. test_literal_param("dog"),
  431. &ret);
  432. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  433. ASSERT_TRUE(task);
  434. ASSERT_EQ(GEARMAN_NO_SERVERS,
  435. gearman_client_run_tasks(client));
  436. ASSERT_EQ(GEARMAN_NO_SERVERS,
  437. gearman_client_run_tasks(client));
  438. gearman_client_free(client);
  439. return TEST_SUCCESS;
  440. }
  441. test_return_t gearman_client_add_task_pause_test(void *object)
  442. {
  443. gearman_client_st *client= (gearman_client_st *)object;
  444. fatal_assert(client);
  445. const char *worker_function= (const char *)gearman_client_context(client);
  446. fatal_assert(worker_function);
  447. // Don't do this.
  448. gearman_actions_t pause_actions= gearman_actions_pause();
  449. client->impl()->actions= pause_actions;
  450. gearman_return_t ret;
  451. gearman_task_st *task= gearman_client_add_task(client, NULL, NULL,
  452. worker_function, NULL, "dog", 3,
  453. &ret);
  454. ASSERT_TRUE(client->impl()->actions.data_fn == pause_actions.data_fn);
  455. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  456. ASSERT_TRUE(task);
  457. ASSERT_TRUE(gearman_task_unique(task));
  458. ASSERT_EQ(size_t(GEARMAN_MAX_UUID_SIZE), strlen(gearman_task_unique(task)));
  459. do
  460. {
  461. // just for async IO
  462. uint32_t count= 0;
  463. do {
  464. count++;
  465. ASSERT_TRUE(client->impl()->actions.data_fn == pause_actions.data_fn);
  466. ret= gearman_client_run_tasks(client);
  467. ASSERT_TRUE(client->impl()->actions.data_fn == pause_actions.data_fn);
  468. } while (gearman_continue(ret));
  469. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  470. ASSERT_TRUE(count > 1);
  471. // If the task has been built to be freed, we won't have it to test
  472. if (gearman_client_has_option(client, GEARMAN_CLIENT_FREE_TASKS))
  473. {
  474. return TEST_SUCCESS;
  475. }
  476. } while (gearman_task_is_running(task));
  477. gearman_task_free(task);
  478. return TEST_SUCCESS;
  479. }
  480. struct _task_free_st {
  481. int64_t count;
  482. _task_free_st() :
  483. count(0)
  484. { }
  485. void add()
  486. {
  487. count++;
  488. }
  489. bool test()
  490. {
  491. return true;
  492. }
  493. void reset()
  494. {
  495. count= 0;
  496. }
  497. bool success()
  498. {
  499. if (count)
  500. return true;
  501. return false;
  502. }
  503. };
  504. static void test_task_free_fn(gearman_task_st *task, void *context)
  505. {
  506. fatal_assert(task);
  507. _task_free_st *foo= (_task_free_st *)context;
  508. fatal_assert(foo->test());
  509. foo->add();
  510. }
  511. test_return_t gearman_client_set_task_context_free_fn_test(void *object)
  512. {
  513. gearman_client_st *client= (gearman_client_st *)object;
  514. fatal_assert(client);
  515. const char *worker_function= (const char *)gearman_client_context(client);
  516. fatal_assert(worker_function);
  517. struct _task_free_st task_free_foo;
  518. gearman_client_set_task_context_free_fn(client, test_task_free_fn);
  519. gearman_return_t ret;
  520. gearman_task_st *task= gearman_client_add_task(client, NULL, NULL,
  521. worker_function, NULL, "dog", 3,
  522. &ret);
  523. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  524. ASSERT_TRUE(task);
  525. ASSERT_TRUE(gearman_task_unique(task));
  526. ASSERT_EQ(size_t(GEARMAN_MAX_UUID_SIZE), strlen(gearman_task_unique(task)));
  527. gearman_task_set_context(task, &task_free_foo);
  528. do
  529. {
  530. // just for async IO
  531. do {
  532. ret= gearman_client_run_tasks(client);
  533. } while (gearman_continue(ret));
  534. ASSERT_EQ(ret, GEARMAN_SUCCESS);
  535. // If the task has been built to be freed, we won't have it to test
  536. if (gearman_client_has_option(client, GEARMAN_CLIENT_FREE_TASKS))
  537. {
  538. ASSERT_TRUE(task_free_foo.success());
  539. return TEST_SUCCESS;
  540. }
  541. } while (gearman_task_is_running(task));
  542. gearman_task_free(task);
  543. ASSERT_TRUE(task_free_foo.success());
  544. return TEST_SUCCESS;
  545. }