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
9 #include "gear_config.h"
10 #include <libtest/test.hpp>
11
12 using namespace libtest;
13
14 #include <cassert>
15 #include <cerrno>
16 #include <cstdio>
17 #include <cstdlib>
18 #include <cstring>
19
20 #include <libgearman/gearman.h>
21
22 #include <libtest/test.hpp>
23
24 #include "libgearman/client.hpp"
25 using namespace org::gearmand;
26
27 #include <tests/start_worker.h>
28
29 #define DEFAULT_WORKER_NAME "burnin"
30
worker_fn(gearman_job_st *,void *)31 static gearman_return_t worker_fn(gearman_job_st*, void*)
32 {
33 return GEARMAN_SUCCESS;
34 }
35
36 struct client_test_st {
37 libgearman::Client _client;
38 worker_handle_st *handle;
39
client_test_stclient_test_st40 client_test_st():
41 _client(libtest::default_port()),
42 handle(NULL)
43 {
44 gearman_function_t func_arg= gearman_function_create(worker_fn);
45 handle= test_worker_start(libtest::default_port(), NULL, DEFAULT_WORKER_NAME, func_arg, NULL, gearman_worker_options_t());
46 }
47
~client_test_stclient_test_st48 ~client_test_st()
49 {
50 delete handle;
51 }
52
clientclient_test_st53 gearman_client_st* client()
54 {
55 return &_client;
56 }
57 };
58
59 struct client_context_st {
60 int latch;
61 size_t min_size;
62 size_t max_size;
63 size_t num_tasks;
64 size_t count;
65 char *blob;
66
client_context_stclient_context_st67 client_context_st():
68 latch(0),
69 min_size(1024),
70 max_size(1024 *2),
71 num_tasks(20),
72 count(2000),
73 blob(NULL)
74 { }
75
~client_context_stclient_context_st76 ~client_context_st()
77 {
78 if (blob)
79 {
80 free(blob);
81 }
82 }
83 };
84
85 #ifndef __INTEL_COMPILER
86 #pragma GCC diagnostic ignored "-Wold-style-cast"
87 #endif
88
89 static client_test_st *test_client_context= NULL;
burnin_TEST(void *)90 static test_return_t burnin_TEST(void*)
91 {
92 gearman_client_st *client= test_client_context->client();
93 fatal_assert(client);
94
95 client_context_st *context= (client_context_st *)gearman_client_context(client);
96 fatal_assert(context);
97
98 // This sketchy, don't do this in your own code.
99 test_true(context->num_tasks > 0);
100 std::vector<gearman_task_st> tasks;
101 try {
102 tasks.resize(context->num_tasks);
103 }
104 catch (...)
105 { }
106 ASSERT_EQ(tasks.size(), context->num_tasks);
107
108 ASSERT_EQ(gearman_client_echo(client, test_literal_param("echo_test")), GEARMAN_SUCCESS);
109
110 do
111 {
112 for (uint32_t x= 0; x < context->num_tasks; x++)
113 {
114 size_t blob_size= 0;
115
116 if (context->min_size == context->max_size)
117 {
118 blob_size= context->max_size;
119 }
120 else
121 {
122 blob_size= (size_t)rand();
123
124 if (context->max_size > RAND_MAX)
125 {
126 blob_size*= (size_t)(rand() + 1);
127 }
128
129 blob_size= (blob_size % (context->max_size - context->min_size)) + context->min_size;
130 }
131
132 gearman_task_st *task_ptr;
133 gearman_return_t ret;
134 if (context->latch)
135 {
136 task_ptr= gearman_client_add_task_background(client, &(tasks[x]),
137 NULL, DEFAULT_WORKER_NAME, NULL,
138 (void *)context->blob, blob_size, &ret);
139 }
140 else
141 {
142 task_ptr= gearman_client_add_task(client, &(tasks[x]), NULL,
143 DEFAULT_WORKER_NAME, NULL, (void *)context->blob, blob_size,
144 &ret);
145 }
146
147 ASSERT_EQ(ret, GEARMAN_SUCCESS);
148 test_truth(task_ptr);
149 }
150
151 gearman_return_t ret= gearman_client_run_tasks(client);
152 for (uint32_t x= 0; x < context->num_tasks; x++)
153 {
154 ASSERT_EQ(GEARMAN_TASK_STATE_FINISHED, tasks[x].state);
155 ASSERT_EQ(GEARMAN_SUCCESS, tasks[x].result_rc);
156 }
157 test_zero(client->new_tasks);
158
159 ASSERT_EQ(ret, GEARMAN_SUCCESS);
160
161 for (uint32_t x= 0; x < context->num_tasks; x++)
162 {
163 gearman_task_free(&(tasks[x]));
164 }
165 } while (context->count--);
166
167 context->latch++;
168
169 return TEST_SUCCESS;
170 }
171
burnin_setup(void *)172 static test_return_t burnin_setup(void*)
173 {
174 test_client_context= new client_test_st;
175 client_context_st *context= new client_context_st;
176
177 context->blob= (char *)malloc(context->max_size);
178 test_true(context->blob);
179 memset(context->blob, 'x', context->max_size);
180
181 gearman_client_set_context(test_client_context->client(), context);
182
183 return TEST_SUCCESS;
184 }
185
burnin_cleanup(void *)186 static test_return_t burnin_cleanup(void*)
187 {
188 client_context_st *context= (struct client_context_st *)gearman_client_context(test_client_context->client());
189
190 delete context;
191 delete test_client_context;
192 test_client_context= NULL;
193
194 return TEST_SUCCESS;
195 }
196
197 /*********************** World functions **************************************/
198
world_create(server_startup_st & servers,test_return_t & error)199 static void *world_create(server_startup_st& servers, test_return_t& error)
200 {
201 if (server_startup(servers, "gearmand", libtest::default_port(), NULL) == false)
202 {
203 error= TEST_SKIPPED;
204 return NULL;
205 }
206
207 worker_handles_st *handle= new worker_handles_st;
208 if (handle == NULL)
209 {
210 error= TEST_FAILURE;
211 return NULL;
212 }
213
214 return handle;
215 }
216
world_destroy(void * object)217 static bool world_destroy(void *object)
218 {
219 worker_handles_st *handles= (worker_handles_st *)object;
220 delete handles;
221
222 return TEST_SUCCESS;
223 }
224
225 test_st burnin_TESTS[] ={
226 {"burnin", 0, burnin_TEST },
227 {0, 0, 0}
228 };
229
230 collection_st collection[] ={
231 {"burnin", burnin_setup, burnin_cleanup, burnin_TESTS },
232 {0, 0, 0, 0}
233 };
234
get_world(libtest::Framework * world)235 void get_world(libtest::Framework *world)
236 {
237 world->collections(collection);
238 world->create(world_create);
239 world->destroy(world_destroy);
240 }
241