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.
17 #include <libtest/test.hpp>
19 #include <libmemcached/memcached.h>
26 #include <sys/types.h>
30 #include <clients/generator.h>
31 #include <clients/execute.h>
33 #include <libtest/server.h>
35 #include <tests/debug.h>
37 #include "tests/libmemcached-1.0/generate.h"
39 using namespace libtest
;
41 /* Number of items generated for tests */
42 #define GLOBAL_COUNT 100000
44 /* Number of times to run the test loop */
45 #define TEST_COUNTER 500000
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_TEST(memcached_st
*)
53 pairs_free(global_pairs
);
58 static test_return_t
generate_pairs_TEST(memcached_st
*)
60 global_pairs
= pairs_generate(GLOBAL_COUNT
, 400);
62 for (ptrdiff_t x
= 0; x
< GLOBAL_COUNT
; x
++)
64 global_keys
[x
]= global_pairs
[x
].key
;
65 global_keys_length
[x
]= global_pairs
[x
].key_length
;
71 static test_return_t
drizzle_TEST(memcached_st
*memc
)
74 for (ptrdiff_t x
= 0; x
< TEST_COUNTER
; x
++)
76 memcached_return_t rc
;
78 uint32_t test_bit
= (uint32_t)(random() % GLOBAL_COUNT
);
79 uint8_t which
= (uint8_t)(random() % 2);
83 size_t return_value_length
;
85 char* return_value
= memcached_get(memc
, global_keys
[test_bit
], global_keys_length
[test_bit
],
86 &return_value_length
, &flags
, &rc
);
87 if (rc
== MEMCACHED_SUCCESS
&& return_value
)
91 else if (rc
== MEMCACHED_NOTFOUND
)
97 test_compare(MEMCACHED_SUCCESS
, rc
);
102 rc
= memcached_set(memc
, global_pairs
[test_bit
].key
,
103 global_pairs
[test_bit
].key_length
,
104 global_pairs
[test_bit
].value
,
105 global_pairs
[test_bit
].value_length
,
107 if (rc
!= MEMCACHED_SUCCESS
&& rc
!= MEMCACHED_BUFFERED
)
109 test_compare(MEMCACHED_SUCCESS
, rc
);
114 if (getenv("MEMCACHED_ATOM_BURIN_IN"))
122 static test_return_t
pre_nonblock(memcached_st
*memc
)
124 test_skip(MEMCACHED_SUCCESS
, memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_NO_BLOCK
, 0));
130 Set the value, then quit to make sure it is flushed.
131 Come back in and test that add fails.
133 static test_return_t
add_test(memcached_st
*memc
)
135 const char *key
= "foo";
136 const char *value
= "when we sanitize";
138 memcached_return_t rc
= memcached_set(memc
, key
, strlen(key
),
139 value
, strlen(value
),
140 time_t(0), uint32_t(0));
141 test_true_got(rc
== MEMCACHED_SUCCESS
or rc
== MEMCACHED_BUFFERED
, memcached_strerror(NULL
, rc
));
142 memcached_quit(memc
);
143 rc
= memcached_add(memc
, key
, strlen(key
),
144 value
, strlen(value
),
145 (time_t)0, (uint32_t)0);
147 if (rc
== MEMCACHED_CONNECTION_FAILURE
)
152 /* Too many broken OS'es have broken loopback in async, so we can't be sure of the result */
153 if (memcached_behavior_get(memc
, MEMCACHED_BEHAVIOR_NO_BLOCK
))
155 test_true(rc
== MEMCACHED_NOTSTORED
or rc
== MEMCACHED_STORED
);
159 test_compare_got(MEMCACHED_NOTSTORED
, rc
, memcached_strerror(NULL
, rc
));
166 * repeating add_tests many times
167 * may show a problem in timing
169 static test_return_t
many_adds(memcached_st
*memc
)
172 for (ptrdiff_t x
= 0; x
< TEST_COUNTER
; x
++)
174 test_compare_got(TEST_SUCCESS
, add_test(memc
), x
);
179 test_st smash_tests
[] ={
180 {"generate_pairs", true, (test_callback_fn
*)generate_pairs_TEST
},
181 {"drizzle", true, (test_callback_fn
*)drizzle_TEST
},
182 {"cleanup", true, (test_callback_fn
*)cleanup_pairs_TEST
},
183 {"many_adds", true, (test_callback_fn
*)many_adds
},
187 #define BENCHMARK_TEST_LOOP 20000
189 struct benchmark_state_st
193 memcached_st
*create
;
197 static test_return_t
memcached_create_benchmark(memcached_st
*)
199 benchmark_state
.create_init
= true;
201 for (ptrdiff_t x
= 0; x
< BENCHMARK_TEST_LOOP
; x
++)
203 memcached_st
*ptr
= memcached_create(&benchmark_state
.create
[x
]);
211 static test_return_t
memcached_clone_benchmark(memcached_st
*memc
)
213 benchmark_state
.clone_init
= true;
215 for (ptrdiff_t x
= 0; x
< BENCHMARK_TEST_LOOP
; x
++)
217 memcached_st
*ptr
= memcached_clone(&benchmark_state
.clone
[x
], memc
);
225 static test_return_t
pre_allocate(memcached_st
*)
227 memset(&benchmark_state
, 0, sizeof(benchmark_state
));
229 benchmark_state
.create
= (memcached_st
*)calloc(BENCHMARK_TEST_LOOP
, sizeof(memcached_st
));
230 test_true(benchmark_state
.create
);
231 benchmark_state
.clone
= (memcached_st
*)calloc(BENCHMARK_TEST_LOOP
, sizeof(memcached_st
));
232 test_true(benchmark_state
.clone
);
237 static test_return_t
post_allocate(memcached_st
*)
239 for (ptrdiff_t x
= 0; x
< BENCHMARK_TEST_LOOP
; x
++)
241 if (benchmark_state
.create_init
)
243 memcached_free(&benchmark_state
.create
[x
]);
246 if (benchmark_state
.clone_init
)
248 memcached_free(&benchmark_state
.clone
[x
]);
252 free(benchmark_state
.create
);
253 free(benchmark_state
.clone
);
259 test_st micro_tests
[] ={
260 {"memcached_create", 1, (test_callback_fn
*)memcached_create_benchmark
},
261 {"memcached_clone", 1, (test_callback_fn
*)memcached_clone_benchmark
},
266 collection_st collection
[] ={
267 {"smash", 0, 0, smash_tests
},
268 {"smash_nonblock", (test_callback_fn
*)pre_nonblock
, 0, smash_tests
},
269 {"micro-benchmark", (test_callback_fn
*)pre_allocate
, (test_callback_fn
*)post_allocate
, micro_tests
},
274 #include "tests/libmemcached_world.h"
276 void get_world(libtest::Framework
* world
)
278 world
->collections(collection
);
280 world
->create((test_callback_create_fn
*)world_create
);
281 world
->destroy((test_callback_destroy_fn
*)world_destroy
);
283 world
->set_runner(new LibmemcachedRunner
);