3d58960e9b4feb838fbc22534e19f95a91759950
[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 "libmemcached/common.h"
16
17 #include <assert.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <sys/time.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <time.h>
26 #include "server.h"
27 #include "../clients/generator.h"
28 #include "../clients/execute.h"
29
30 #ifndef INT64_MAX
31 #define INT64_MAX LONG_MAX
32 #endif
33 #ifndef INT32_MAX
34 #define INT32_MAX INT_MAX
35 #endif
36
37
38 #include "test.h"
39
40 /* Number of items generated for tests */
41 #define GLOBAL_COUNT 100000
42
43 /* Number of times to run the test loop */
44 #define TEST_COUNTER 500000
45 static uint32_t global_count;
46
47 static pairs_st *global_pairs;
48 static char *global_keys[GLOBAL_COUNT];
49 static size_t global_keys_length[GLOBAL_COUNT];
50
51 static test_return_t cleanup_pairs(memcached_st *memc __attribute__((unused)))
52 {
53 pairs_free(global_pairs);
54
55 return 0;
56 }
57
58 static test_return_t generate_pairs(memcached_st *memc __attribute__((unused)))
59 {
60 global_pairs= pairs_generate(GLOBAL_COUNT, 400);
61 global_count= GLOBAL_COUNT;
62
63 for (size_t x= 0; x < global_count; x++)
64 {
65 global_keys[x]= global_pairs[x].key;
66 global_keys_length[x]= global_pairs[x].key_length;
67 }
68
69 return 0;
70 }
71
72 static test_return_t drizzle(memcached_st *memc)
73 {
74 memcached_return_t rc;
75 char *return_value;
76 size_t return_value_length;
77 uint32_t flags;
78
79 infinite:
80 for (size_t x= 0; x < TEST_COUNTER; x++)
81 {
82 uint32_t test_bit;
83 uint8_t which;
84
85 test_bit= (uint32_t)(random() % GLOBAL_COUNT);
86 which= (uint8_t)(random() % 2);
87
88 if (which == 0)
89 {
90 return_value= memcached_get(memc, global_keys[test_bit], global_keys_length[test_bit],
91 &return_value_length, &flags, &rc);
92 if (rc == MEMCACHED_SUCCESS && return_value)
93 free(return_value);
94 else if (rc == MEMCACHED_NOTFOUND)
95 continue;
96 else
97 {
98 WATCHPOINT_ERROR(rc);
99 WATCHPOINT_ASSERT(rc);
100 }
101 }
102 else
103 {
104 rc= memcached_set(memc, global_pairs[test_bit].key,
105 global_pairs[test_bit].key_length,
106 global_pairs[test_bit].value,
107 global_pairs[test_bit].value_length,
108 0, 0);
109 if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED)
110 {
111 WATCHPOINT_ERROR(rc);
112 WATCHPOINT_ASSERT(0);
113 }
114 }
115 }
116
117 if (getenv("MEMCACHED_ATOM_BURIN_IN"))
118 goto infinite;
119
120 return 0;
121 }
122
123 static memcached_return_t pre_nonblock(memcached_st *memc)
124 {
125 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
126
127 return MEMCACHED_SUCCESS;
128 }
129
130 static memcached_return_t pre_md5(memcached_st *memc)
131 {
132 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
133
134 return MEMCACHED_SUCCESS;
135 }
136
137 static memcached_return_t pre_hsieh(memcached_st *memc)
138 {
139 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
140
141 return MEMCACHED_SUCCESS;
142 }
143
144 static memcached_return_t enable_consistent(memcached_st *memc)
145 {
146 memcached_server_distribution_t value= MEMCACHED_DISTRIBUTION_CONSISTENT;
147 memcached_hash_t hash;
148 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
149 pre_hsieh(memc);
150
151 value= (memcached_server_distribution_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
152 assert(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
153
154 hash= (memcached_hash_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
155 assert(hash == MEMCACHED_HASH_HSIEH);
156
157
158 return MEMCACHED_SUCCESS;
159 }
160
161 /*
162 Set the value, then quit to make sure it is flushed.
163 Come back in and test that add fails.
164 */
165 static test_return_t add_test(memcached_st *memc)
166 {
167 memcached_return_t rc;
168 const char *key= "foo";
169 const char *value= "when we sanitize";
170 unsigned long long setting_value;
171
172 setting_value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
173
174 rc= memcached_set(memc, key, strlen(key),
175 value, strlen(value),
176 (time_t)0, (uint32_t)0);
177 test_truth(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
178 memcached_quit(memc);
179 rc= memcached_add(memc, key, strlen(key),
180 value, strlen(value),
181 (time_t)0, (uint32_t)0);
182
183 /* Too many broken OS'es have broken loopback in async, so we can't be sure of the result */
184 if (setting_value)
185 {
186 test_truth(rc == MEMCACHED_NOTSTORED || rc == MEMCACHED_STORED);
187 }
188 else
189 {
190 test_truth(rc == MEMCACHED_NOTSTORED);
191 }
192
193 return 0;
194 }
195
196 /*
197 * repeating add_tests many times
198 * may show a problem in timing
199 */
200 static test_return_t many_adds(memcached_st *memc)
201 {
202 for (size_t x= 0; x < TEST_COUNTER; x++)
203 {
204 add_test(memc);
205 }
206 return 0;
207 }
208
209 test_st smash_tests[] ={
210 {"generate_pairs", 1, (test_callback_fn)generate_pairs },
211 {"drizzle", 1, (test_callback_fn)drizzle },
212 {"cleanup", 1, (test_callback_fn)cleanup_pairs },
213 {"many_adds", 1, (test_callback_fn)many_adds },
214 {0, 0, 0}
215 };
216
217
218 collection_st collection[] ={
219 {"smash", 0, 0, smash_tests},
220 {"smash_hsieh", (test_callback_fn)pre_hsieh, 0, smash_tests},
221 {"smash_hsieh_consistent", (test_callback_fn)enable_consistent, 0, smash_tests},
222 {"smash_md5", (test_callback_fn)pre_md5, 0, smash_tests},
223 {"smash_nonblock", (test_callback_fn)pre_nonblock, 0, smash_tests},
224 {0, 0, 0, 0}
225 };
226
227
228 #define SERVERS_TO_CREATE 5
229
230 #include "libmemcached_world.h"
231
232 void get_world(world_st *world)
233 {
234 world->collections= collection;
235
236 world->create= (test_callback_create_fn)world_create;
237 world->destroy= (test_callback_fn)world_destroy;
238
239 world->test.startup= (test_callback_fn)world_test_startup;
240 world->test.flush= (test_callback_fn)world_flush;
241 world->test.pre_run= (test_callback_fn)world_pre_run;
242 world->test.post_run= (test_callback_fn)world_post_run;
243 world->test.on_error= (test_callback_error_fn)world_on_error;
244
245 world->collection.startup= (test_callback_fn)world_container_startup;
246 world->collection.shutdown= (test_callback_fn)world_container_shutdown;
247
248 world->runner= &defualt_libmemcached_runner;
249 }