round_robin.cc 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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 <cstdio>
  13. #include <cstdlib>
  14. #include <cstring>
  15. #include <memory>
  16. #include <unistd.h>
  17. #include <libgearman/gearman.h>
  18. #include <tests/ports.h>
  19. struct worker_test_st
  20. {
  21. gearman_worker_st worker;
  22. bool run_worker;
  23. worker_test_st() :
  24. worker(),
  25. run_worker(false)
  26. { }
  27. };
  28. #ifndef __INTEL_COMPILER
  29. #pragma GCC diagnostic ignored "-Wold-style-cast"
  30. #endif
  31. /* append test for worker */
  32. static void *append_function(gearman_job_st *job,
  33. void *context, size_t *result_size,
  34. gearman_return_t *ret_ptr)
  35. {
  36. /* this will will set the last char in the context (buffer) to the */
  37. /* first char of the work */
  38. char *buf = (char *)context;
  39. assert(buf);
  40. char *work = (char *)gearman_job_workload(job);
  41. buf += strlen(buf);
  42. *buf= *work;
  43. *result_size= 0;
  44. *ret_ptr= GEARMAN_SUCCESS;
  45. return NULL;
  46. }
  47. static test_return_t queue_add(void *object)
  48. {
  49. gearman_return_t rc;
  50. worker_test_st *test= (worker_test_st *)object;
  51. gearman_client_st client;
  52. gearman_client_st *client_ptr;
  53. char job_handle[GEARMAN_JOB_HANDLE_SIZE];
  54. uint8_t *value= (uint8_t *)strdup("0");
  55. size_t value_length= 1;
  56. test->run_worker= false;
  57. client_ptr= gearman_client_create(&client);
  58. test_truth(client_ptr);
  59. test_compare(GEARMAN_SUCCESS,
  60. gearman_client_add_server(&client, NULL, ROUND_ROBIN_WORKER_TEST_PORT));
  61. /* send strings "0", "1" ... "9" to alternating between 2 queues */
  62. /* queue1 = 1,3,5,7,9 */
  63. /* queue2 = 0,2,4,6,8 */
  64. for (uint32_t x= 0; x < 10; x++)
  65. {
  66. rc= gearman_client_do_background(&client, x % 2 ? "queue1" : "queue2", NULL,
  67. value, value_length, job_handle);
  68. test_truth(GEARMAN_SUCCESS == rc);
  69. *value = (uint8_t)(*value + 1);
  70. }
  71. gearman_client_free(&client);
  72. free(value);
  73. test->run_worker= true;
  74. return TEST_SUCCESS;
  75. }
  76. static test_return_t queue_worker(void *object)
  77. {
  78. worker_test_st *test= (worker_test_st *)object;
  79. test_truth(test);
  80. gearman_worker_st *worker= &(test->worker);
  81. test_truth(worker);
  82. char buffer[11];
  83. memset(buffer, 0, sizeof(buffer));
  84. test_truth(test->run_worker);
  85. test_compare_got(GEARMAN_SUCCESS,
  86. gearman_worker_add_function(worker, "queue1", 5, append_function, buffer),
  87. gearman_worker_error(worker));
  88. test_compare_got(GEARMAN_SUCCESS,
  89. gearman_worker_add_function(worker, "queue2", 5, append_function, buffer),
  90. gearman_worker_error(worker));
  91. for (uint32_t x= 0; x < 10; x++)
  92. {
  93. test_compare(GEARMAN_SUCCESS, gearman_worker_work(worker));
  94. }
  95. // expect buffer to be reassembled in a predictable round robin order
  96. test_strcmp("1032547698", buffer);
  97. return TEST_SUCCESS;
  98. }
  99. static void *world_create(server_startup_st& servers, test_return_t& error)
  100. {
  101. const char *argv[2]= { "test_gearmand", "--round-robin"};
  102. if (not server_startup(servers, "gearmand", ROUND_ROBIN_WORKER_TEST_PORT, 2, argv))
  103. {
  104. error= TEST_FAILURE;
  105. return NULL;
  106. }
  107. worker_test_st *test= new (std::nothrow) worker_test_st;;
  108. if (not test)
  109. {
  110. error= TEST_MEMORY_ALLOCATION_FAILURE;
  111. return NULL;
  112. }
  113. if (gearman_worker_create(&(test->worker)) == NULL)
  114. {
  115. error= TEST_FAILURE;
  116. return NULL;
  117. }
  118. if (gearman_failed(gearman_worker_add_server(&(test->worker), NULL, ROUND_ROBIN_WORKER_TEST_PORT)))
  119. {
  120. error= TEST_FAILURE;
  121. return NULL;
  122. }
  123. return test;
  124. }
  125. static bool world_destroy(void *object)
  126. {
  127. worker_test_st *test= (worker_test_st *)object;
  128. gearman_worker_free(&(test->worker));
  129. delete test;
  130. return TEST_SUCCESS;
  131. }
  132. test_st tests[] ={
  133. {"add", 0, queue_add },
  134. {"worker", 0, queue_worker },
  135. {0, 0, 0}
  136. };
  137. collection_st collection[] ={
  138. {"round_robin", 0, 0, tests},
  139. {0, 0, 0, 0}
  140. };
  141. void get_world(Framework *world)
  142. {
  143. world->collections= collection;
  144. world->_create= world_create;
  145. world->_destroy= world_destroy;
  146. }