a7e49c91c119259ff98359b4e3736835442a6c9c
[awesomized/libmemcached] / tests / atomsmasher.c
1 /* LibMemcached
2 * Copyright (C) 2006-2009 Brian Aker
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 * Summary:
9 *
10 */
11
12 /*
13 Sample test application.
14 */
15 #include "config.h"
16
17 #include "libmemcached/memcached.h"
18 #include "libmemcached/watchpoint.h"
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stdint.h>
23 #include <string.h>
24 #include <sys/time.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
28 #include <time.h>
29 #include "server.h"
30 #include "../clients/generator.h"
31 #include "../clients/execute.h"
32
33 #include "test.h"
34
35 /* Number of items generated for tests */
36 #define GLOBAL_COUNT 100000
37
38 /* Number of times to run the test loop */
39 #define TEST_COUNTER 500000
40 static uint32_t global_count;
41
42 static pairs_st *global_pairs;
43 static char *global_keys[GLOBAL_COUNT];
44 static size_t global_keys_length[GLOBAL_COUNT];
45
46 static test_return_t cleanup_pairs(memcached_st *memc __attribute__((unused)))
47 {
48 pairs_free(global_pairs);
49
50 return 0;
51 }
52
53 static test_return_t generate_pairs(memcached_st *memc __attribute__((unused)))
54 {
55 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
56 global_count= GLOBAL_COUNT;
57
58 for (size_t x= 0; x < global_count; x++)
59 {
60 global_keys[x]= global_pairs[x].key;
61 global_keys_length[x]= global_pairs[x].key_length;
62 }
63
64 return 0;
65 }
66
67 static test_return_t drizzle(memcached_st *memc)
68 {
69 memcached_return_t rc;
70 char *return_value;
71 size_t return_value_length;
72 uint32_t flags;
73
74 infinite:
75 for (size_t x= 0; x < TEST_COUNTER; x++)
76 {
77 uint32_t test_bit;
78 uint8_t which;
79
80 test_bit= (uint32_t)(random() % GLOBAL_COUNT);
81 which= (uint8_t)(random() % 2);
82
83 if (which == 0)
84 {
85 return_value= memcached_get(memc, global_keys[test_bit], global_keys_length[test_bit],
86 &return_value_length, &flags, &rc);
87 if (rc == MEMCACHED_SUCCESS && return_value)
88 {
89 free(return_value);
90 }
91 else if (rc == MEMCACHED_NOTFOUND)
92 {
93 continue;
94 }
95 else
96 {
97 WATCHPOINT_ERROR(rc);
98 WATCHPOINT_ASSERT(rc);
99 }
100 }
101 else
102 {
103 rc= memcached_set(memc, global_pairs[test_bit].key,
104 global_pairs[test_bit].key_length,
105 global_pairs[test_bit].value,
106 global_pairs[test_bit].value_length,
107 0, 0);
108 if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED)
109 {
110 WATCHPOINT_ERROR(rc);
111 WATCHPOINT_ASSERT(0);
112 }
113 }
114 }
115
116 if (getenv("MEMCACHED_ATOM_BURIN_IN"))
117 goto infinite;
118
119 return TEST_SUCCESS;
120 }
121
122 static test_return_t pre_nonblock(memcached_st *memc)
123 {
124 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
125
126 return TEST_SUCCESS;
127 }
128
129 /*
130 Set the value, then quit to make sure it is flushed.
131 Come back in and test that add fails.
132 */
133 static test_return_t add_test(memcached_st *memc)
134 {
135 memcached_return_t rc;
136 const char *key= "foo";
137 const char *value= "when we sanitize";
138 unsigned long long setting_value;
139
140 setting_value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
141
142 rc= memcached_set(memc, key, strlen(key),
143 value, strlen(value),
144 (time_t)0, (uint32_t)0);
145 test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
146 memcached_quit(memc);
147 rc= memcached_add(memc, key, strlen(key),
148 value, strlen(value),
149 (time_t)0, (uint32_t)0);
150
151 /* Too many broken OS'es have broken loopback in async, so we can't be sure of the result */
152 if (setting_value)
153 {
154 test_true(rc == MEMCACHED_NOTSTORED || rc == MEMCACHED_STORED);
155 }
156 else
157 {
158 test_true(rc == MEMCACHED_NOTSTORED);
159 }
160
161 return 0;
162 }
163
164 /*
165 * repeating add_tests many times
166 * may show a problem in timing
167 */
168 static test_return_t many_adds(memcached_st *memc)
169 {
170 for (size_t x= 0; x < TEST_COUNTER; x++)
171 {
172 add_test(memc);
173 }
174 return 0;
175 }
176
177 test_st smash_tests[] ={
178 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
179 {"drizzle", 1, (test_callback_fn)drizzle },
180 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
181 {"many_adds", 1, (test_callback_fn)many_adds },
182 {0, 0, 0}
183 };
184
185 #define BENCHMARK_TEST_LOOP 20000
186
187 struct benchmark_state_st
188 {
189 bool create_init;
190 bool clone_init;
191 memcached_st *create;
192 memcached_st *clone;
193 } benchmark_state;
194
195 static test_return_t memcached_create_benchmark(memcached_st *memc __attribute__((unused)))
196 {
197 benchmark_state.create_init= true;
198
199 for (size_t x= 0; x < BENCHMARK_TEST_LOOP; x++)
200 {
201 memcached_st *ptr;
202 ptr= memcached_create(&benchmark_state.create[x]);
203
204 test_true(ptr);
205 }
206
207 return TEST_SUCCESS;
208 }
209
210 static test_return_t memcached_clone_benchmark(memcached_st *memc)
211 {
212 benchmark_state.clone_init= true;
213
214 for (size_t x= 0; x < BENCHMARK_TEST_LOOP; x++)
215 {
216 memcached_st *ptr;
217 ptr= memcached_clone(&benchmark_state.clone[x], memc);
218
219 test_true(ptr);
220 }
221
222 return TEST_SUCCESS;
223 }
224
225 static test_return_t pre_allocate(memcached_st *memc __attribute__((unused)))
226 {
227 memset(&benchmark_state, 0, sizeof(benchmark_state));
228
229 benchmark_state.create= (memcached_st *)calloc(BENCHMARK_TEST_LOOP, sizeof(memcached_st));
230 test_true(benchmark_state.create);
231 benchmark_state.clone= (memcached_st *)calloc(BENCHMARK_TEST_LOOP, sizeof(memcached_st));
232 test_true(benchmark_state.clone);
233
234 return TEST_SUCCESS;
235 }
236
237 static test_return_t post_allocate(memcached_st *memc __attribute__((unused)))
238 {
239 for (size_t x= 0; x < BENCHMARK_TEST_LOOP; x++)
240 {
241 if (benchmark_state.create_init)
242 memcached_free(&benchmark_state.create[x]);
243
244 if (benchmark_state.clone_init)
245 memcached_free(&benchmark_state.clone[x]);
246 }
247
248 free(benchmark_state.create);
249 free(benchmark_state.clone);
250
251 return TEST_SUCCESS;
252 }
253
254
255 test_st micro_tests[] ={
256 {"memcached_create", 1, (test_callback_fn)memcached_create_benchmark },
257 {"memcached_clone", 1, (test_callback_fn)memcached_clone_benchmark },
258 {0, 0, 0}
259 };
260
261
262 collection_st collection[] ={
263 {"smash", 0, 0, smash_tests},
264 {"smash_nonblock", (test_callback_fn)pre_nonblock, 0, smash_tests},
265 {"micro-benchmark", (test_callback_fn)pre_allocate, (test_callback_fn)post_allocate, micro_tests},
266 {0, 0, 0, 0}
267 };
268
269
270 #define SERVERS_TO_CREATE 5
271
272 #include "libmemcached_world.h"
273
274 void get_world(world_st *world)
275 {
276 world->collections= collection;
277
278 world->create= (test_callback_create_fn)world_create;
279 world->destroy= (test_callback_fn)world_destroy;
280
281 world->test.startup= (test_callback_fn)world_test_startup;
282 world->test.flush= (test_callback_fn)world_flush;
283 world->test.pre_run= (test_callback_fn)world_pre_run;
284 world->test.post_run= (test_callback_fn)world_post_run;
285 world->test.on_error= (test_callback_error_fn)world_on_error;
286
287 world->collection.startup= (test_callback_fn)world_container_startup;
288 world->collection.shutdown= (test_callback_fn)world_container_shutdown;
289
290 world->runner= &defualt_libmemcached_runner;
291 }