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