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