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