2 * Copyright (C) 2006-2009 Brian Aker
5 * Use and distribution licensed under the BSD license. See
6 * the COPYING file in the parent directory for full text.
13 Sample test application.
15 #include "libmemcached/common.h"
22 #include <sys/types.h>
27 #include "../clients/generator.h"
28 #include "../clients/execute.h"
31 #define INT64_MAX LONG_MAX
34 #define INT32_MAX INT_MAX
40 /* Number of items generated for tests */
41 #define GLOBAL_COUNT 100000
43 /* Number of times to run the test loop */
44 #define TEST_COUNTER 500000
45 static uint32_t global_count
;
47 static pairs_st
*global_pairs
;
48 static char *global_keys
[GLOBAL_COUNT
];
49 static size_t global_keys_length
[GLOBAL_COUNT
];
51 static test_return_t
cleanup_pairs(memcached_st
*memc
__attribute__((unused
)))
53 pairs_free(global_pairs
);
58 static test_return_t
generate_pairs(memcached_st
*memc
__attribute__((unused
)))
60 global_pairs
= pairs_generate(GLOBAL_COUNT
, 400);
61 global_count
= GLOBAL_COUNT
;
63 for (size_t x
= 0; x
< global_count
; x
++)
65 global_keys
[x
]= global_pairs
[x
].key
;
66 global_keys_length
[x
]= global_pairs
[x
].key_length
;
72 static test_return_t
drizzle(memcached_st
*memc
)
74 memcached_return_t rc
;
76 size_t return_value_length
;
80 for (size_t x
= 0; x
< TEST_COUNTER
; x
++)
85 test_bit
= (uint32_t)(random() % GLOBAL_COUNT
);
86 which
= (uint8_t)(random() % 2);
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
)
94 else if (rc
== MEMCACHED_NOTFOUND
)
99 WATCHPOINT_ASSERT(rc
);
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
,
109 if (rc
!= MEMCACHED_SUCCESS
&& rc
!= MEMCACHED_BUFFERED
)
111 WATCHPOINT_ERROR(rc
);
112 WATCHPOINT_ASSERT(0);
117 if (getenv("MEMCACHED_ATOM_BURIN_IN"))
123 static memcached_return_t
pre_nonblock(memcached_st
*memc
)
125 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_NO_BLOCK
, 0);
127 return MEMCACHED_SUCCESS
;
130 static memcached_return_t
pre_md5(memcached_st
*memc
)
132 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_HASH
, (uint64_t)MEMCACHED_HASH_MD5
);
134 return MEMCACHED_SUCCESS
;
137 static memcached_return_t
pre_hsieh(memcached_st
*memc
)
139 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_HASH
, (uint64_t)MEMCACHED_HASH_HSIEH
);
141 return MEMCACHED_SUCCESS
;
144 static memcached_return_t
enable_consistent(memcached_st
*memc
)
146 memcached_server_distribution_t value
= MEMCACHED_DISTRIBUTION_CONSISTENT
;
147 memcached_hash_t hash
;
148 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_DISTRIBUTION
, value
);
151 value
= (memcached_server_distribution_t
)memcached_behavior_get(memc
, MEMCACHED_BEHAVIOR_DISTRIBUTION
);
152 assert(value
== MEMCACHED_DISTRIBUTION_CONSISTENT
);
154 hash
= (memcached_hash_t
)memcached_behavior_get(memc
, MEMCACHED_BEHAVIOR_HASH
);
155 assert(hash
== MEMCACHED_HASH_HSIEH
);
158 return MEMCACHED_SUCCESS
;
162 Set the value, then quit to make sure it is flushed.
163 Come back in and test that add fails.
165 static test_return_t
add_test(memcached_st
*memc
)
167 memcached_return_t rc
;
168 const char *key
= "foo";
169 const char *value
= "when we sanitize";
170 unsigned long long setting_value
;
172 setting_value
= memcached_behavior_get(memc
, MEMCACHED_BEHAVIOR_NO_BLOCK
);
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);
183 /* Too many broken OS'es have broken loopback in async, so we can't be sure of the result */
186 test_truth(rc
== MEMCACHED_NOTSTORED
|| rc
== MEMCACHED_STORED
);
190 test_truth(rc
== MEMCACHED_NOTSTORED
);
197 * repeating add_tests many times
198 * may show a problem in timing
200 static test_return_t
many_adds(memcached_st
*memc
)
202 for (size_t x
= 0; x
< TEST_COUNTER
; x
++)
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
},
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
},
228 #define SERVERS_TO_CREATE 5
230 #include "libmemcached_world.h"
232 void get_world(world_st
*world
)
234 world
->collections
= collection
;
236 world
->create
= (test_callback_create_fn
)world_create
;
237 world
->destroy
= (test_callback_fn
)world_destroy
;
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
;
245 world
->collection
.startup
= (test_callback_fn
)world_container_startup
;
246 world
->collection
.shutdown
= (test_callback_fn
)world_container_shutdown
;
248 world
->runner
= &defualt_libmemcached_runner
;