1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
5 * Copyright (C) 2011 Data Differential, http://datadifferential.com/
6 * Copyright (C) 2006-2009 Brian Aker All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following disclaimer
17 * in the documentation and/or other materials provided with the
20 * * The names of its contributors may not be used to endorse or
21 * promote products derived from this software without specific prior
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 #include "mem_config.h"
39 #include "libtest/test.hpp"
41 #if defined(HAVE_LIBUUID) && HAVE_LIBUUID
42 # include <uuid/uuid.h>
49 #include "libmemcached-1.0/memcached.h"
50 #include "libmemcached/is.h"
51 #include "libmemcached/server_instance.h"
53 #include "libhashkit-1.0/hashkit.h"
55 #include "libtest/memcached.hpp"
60 #include <semaphore.h>
63 #ifdef HAVE_SYS_TIME_H
64 # include <sys/time.h>
67 #include <sys/types.h>
73 #include "libtest/server.h"
75 #include "bin/generator.h"
77 #define SMALL_STRING_LEN 1024
79 #include "libtest/test.hpp"
81 using namespace libtest
;
83 #include "libmemcachedutil-1.0/util.h"
85 #include "tests/hash_results.h"
87 #include "tests/libmemcached-1.0/callback_counter.h"
88 #include "tests/libmemcached-1.0/fetch_all_results.h"
89 #include "tests/libmemcached-1.0/mem_functions.h"
90 #include "tests/libmemcached-1.0/setup_and_teardowns.h"
91 #include "tests/print.h"
92 #include "tests/debug.h"
93 #include "tests/memc.hpp"
95 #define UUID_STRING_MAXLENGTH 36
97 #include "tests/keys.hpp"
99 #include "libmemcached/instance.hpp"
102 test_return_t
mget_end(memcached_st
*memc
)
104 const char *keys
[]= { "foo", "foo2" };
105 size_t lengths
[]= { 3, 4 };
106 const char *values
[]= { "fjord", "41" };
109 for (size_t x
= 0; x
< test_array_length(keys
); x
++)
111 test_compare(MEMCACHED_SUCCESS
,
114 values
[x
], strlen(values
[x
]),
115 time_t(0), uint32_t(0)));
119 size_t string_length
;
122 // retrieve both via mget
123 test_compare(MEMCACHED_SUCCESS
,
126 test_array_length(keys
)));
128 char key
[MEMCACHED_MAX_KEY
];
130 memcached_return_t rc
;
132 // this should get both
133 for (size_t x
= 0; x
< test_array_length(keys
); x
++)
135 string
= memcached_fetch(memc
, key
, &key_length
, &string_length
,
137 test_compare(MEMCACHED_SUCCESS
, rc
);
144 test_compare(string_length
, strlen(values
[val
]));
145 test_true(strncmp(values
[val
], string
, string_length
) == 0);
149 // this should indicate end
150 string
= memcached_fetch(memc
, key
, &key_length
, &string_length
, &flags
, &rc
);
151 test_compare(MEMCACHED_END
, rc
);
155 test_compare(MEMCACHED_SUCCESS
,
156 memcached_mget(memc
, keys
, lengths
, 1));
158 string
= memcached_fetch(memc
, key
, &key_length
, &string_length
, &flags
, &rc
);
159 test_compare(key_length
, lengths
[0]);
160 test_true(strncmp(keys
[0], key
, key_length
) == 0);
161 test_compare(string_length
, strlen(values
[0]));
162 test_true(strncmp(values
[0], string
, string_length
) == 0);
163 test_compare(MEMCACHED_SUCCESS
, rc
);
166 // this should indicate end
167 string
= memcached_fetch(memc
, key
, &key_length
, &string_length
, &flags
, &rc
);
168 test_compare(MEMCACHED_END
, rc
);
174 test_return_t
mget_result_test(memcached_st
*memc
)
176 const char *keys
[]= {"fudge", "son", "food"};
177 size_t key_length
[]= {5, 3, 4};
179 memcached_result_st results_obj
;
180 memcached_result_st
*results
= memcached_result_create(memc
, &results_obj
);
182 test_true(&results_obj
== results
);
184 /* We need to empty the server before continueing test */
185 test_compare(MEMCACHED_SUCCESS
,
186 memcached_flush(memc
, 0));
188 test_compare(MEMCACHED_SUCCESS
,
189 memcached_mget(memc
, keys
, key_length
, 3));
191 memcached_return_t rc
;
192 while ((results
= memcached_fetch_result(memc
, &results_obj
, &rc
)))
197 while ((results
= memcached_fetch_result(memc
, &results_obj
, &rc
))) { test_true(false); /* We should never see a value returned */ };
199 test_compare(MEMCACHED_NOTFOUND
, rc
);
201 for (uint32_t x
= 0; x
< 3; x
++)
203 rc
= memcached_set(memc
, keys
[x
], key_length
[x
],
204 keys
[x
], key_length
[x
],
205 (time_t)50, (uint32_t)9);
206 test_true(rc
== MEMCACHED_SUCCESS
or rc
== MEMCACHED_BUFFERED
);
209 test_compare(MEMCACHED_SUCCESS
,
210 memcached_mget(memc
, keys
, key_length
, 3));
212 while ((results
= memcached_fetch_result(memc
, &results_obj
, &rc
)))
215 test_true(&results_obj
== results
);
216 test_compare(MEMCACHED_SUCCESS
, rc
);
217 test_memcmp(memcached_result_key_value(results
),
218 memcached_result_value(results
),
219 memcached_result_length(results
));
220 test_compare(memcached_result_key_length(results
), memcached_result_length(results
));
223 memcached_result_free(&results_obj
);
228 test_return_t
mget_result_alloc_test(memcached_st
*memc
)
230 const char *keys
[]= {"fudge", "son", "food"};
231 size_t key_length
[]= {5, 3, 4};
233 memcached_result_st
*results
;
235 /* We need to empty the server before continueing test */
236 test_compare(MEMCACHED_SUCCESS
,
237 memcached_flush(memc
, 0));
239 test_compare(MEMCACHED_SUCCESS
,
240 memcached_mget(memc
, keys
, key_length
, 3));
242 memcached_return_t rc
;
243 while ((results
= memcached_fetch_result(memc
, NULL
, &rc
)))
248 test_compare(MEMCACHED_NOTFOUND
, rc
);
250 for (uint32_t x
= 0; x
< 3; x
++)
252 rc
= memcached_set(memc
, keys
[x
], key_length
[x
],
253 keys
[x
], key_length
[x
],
254 (time_t)50, (uint32_t)9);
255 test_true(rc
== MEMCACHED_SUCCESS
or rc
== MEMCACHED_BUFFERED
);
258 test_compare(MEMCACHED_SUCCESS
,
259 memcached_mget(memc
, keys
, key_length
, 3));
262 while ((results
= memcached_fetch_result(memc
, NULL
, &rc
)))
265 test_compare(MEMCACHED_SUCCESS
, rc
);
266 test_compare(memcached_result_key_length(results
), memcached_result_length(results
));
267 test_memcmp(memcached_result_key_value(results
),
268 memcached_result_value(results
),
269 memcached_result_length(results
));
270 memcached_result_free(results
);
277 test_return_t
mget_result_function(memcached_st
*memc
)
279 const char *keys
[]= {"fudge", "son", "food"};
280 size_t key_length
[]= {5, 3, 4};
282 memcached_execute_fn callbacks
[1];
284 for (uint32_t x
= 0; x
< 3; x
++)
286 test_compare(return_value_based_on_buffering(memc
),
287 memcached_set(memc
, keys
[x
], key_length
[x
],
288 keys
[x
], key_length
[x
],
289 time_t(50), uint32_t(9)));
291 test_compare(MEMCACHED_SUCCESS
, memcached_flush_buffers(memc
));
292 memcached_quit(memc
);
294 test_compare(MEMCACHED_SUCCESS
,
295 memcached_mget(memc
, keys
, key_length
, 3));
297 callbacks
[0]= &callback_counter
;
300 test_compare(MEMCACHED_SUCCESS
,
301 memcached_fetch_execute(memc
, callbacks
, (void *)&counter
, 1));
303 test_compare(size_t(3), counter
);
308 test_return_t
mget_test(memcached_st
*memc
)
310 const char *keys
[]= {"fudge", "son", "food"};
311 size_t key_length
[]= {5, 3, 4};
313 char return_key
[MEMCACHED_MAX_KEY
];
314 size_t return_key_length
;
316 size_t return_value_length
;
318 test_compare(MEMCACHED_SUCCESS
,
319 memcached_mget(memc
, keys
, key_length
, 3));
322 memcached_return_t rc
;
323 while ((return_value
= memcached_fetch(memc
, return_key
, &return_key_length
,
324 &return_value_length
, &flags
, &rc
)))
326 test_true(return_value
);
328 test_false(return_value
);
329 test_zero(return_value_length
);
330 test_compare(MEMCACHED_NOTFOUND
, rc
);
332 for (uint32_t x
= 0; x
< 3; x
++)
334 rc
= memcached_set(memc
, keys
[x
], key_length
[x
],
335 keys
[x
], key_length
[x
],
336 (time_t)50, (uint32_t)9);
337 test_true(rc
== MEMCACHED_SUCCESS
or rc
== MEMCACHED_BUFFERED
);
339 test_compare(MEMCACHED_SUCCESS
,
340 memcached_mget(memc
, keys
, key_length
, 3));
343 while ((return_value
= memcached_fetch(memc
, return_key
, &return_key_length
,
344 &return_value_length
, &flags
, &rc
)))
346 test_true(return_value
);
347 test_compare(MEMCACHED_SUCCESS
, rc
);
348 if (not memc
->_namespace
)
350 test_compare(return_key_length
, return_value_length
);
351 test_memcmp(return_value
, return_key
, return_value_length
);
360 test_return_t
mget_execute(memcached_st
*original_memc
)
362 test_skip(true, memcached_behavior_get(original_memc
, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL
));
364 memcached_st
*memc
= create_single_instance_memcached(original_memc
, "--BINARY-PROTOCOL");
369 /* First add all of the items.. */
370 char blob
[1024] = {0};
372 for (size_t x
= 0; x
< keys
.size(); ++x
)
374 uint64_t query_id
= memcached_query_id(memc
);
375 memcached_return_t rc
= memcached_add(memc
,
376 keys
.key_at(x
), keys
.length_at(x
),
379 ASSERT_TRUE_(rc
== MEMCACHED_SUCCESS
or rc
== MEMCACHED_BUFFERED
, "Returned %s", memcached_strerror(NULL
, rc
));
380 test_compare(query_id
+1, memcached_query_id(memc
));
383 /* Try to get all of them with a large multiget */
385 memcached_execute_fn callbacks
[]= { &callback_counter
};
386 test_compare(MEMCACHED_SUCCESS
,
387 memcached_mget_execute(memc
,
388 keys
.keys_ptr(), keys
.lengths_ptr(),
389 keys
.size(), callbacks
, &counter
, 1));
392 uint64_t query_id
= memcached_query_id(memc
);
393 test_compare(MEMCACHED_SUCCESS
,
394 memcached_fetch_execute(memc
, callbacks
, (void *)&counter
, 1));
395 test_compare(query_id
, memcached_query_id(memc
));
397 /* Verify that we got all of the items */
398 test_compare(keys
.size(), counter
);
401 memcached_free(memc
);
408 test_return_t
memcached_fetch_result_NOT_FOUND(memcached_st
*memc
)
410 memcached_return_t rc
;
412 const char *key
= "not_found";
413 size_t key_length
= test_literal_param_size("not_found");
415 test_compare(MEMCACHED_SUCCESS
,
416 memcached_mget(memc
, &key
, &key_length
, 1));
418 memcached_result_st
*result
= memcached_fetch_result(memc
, NULL
, &rc
);
420 test_compare(MEMCACHED_NOTFOUND
, rc
);
422 memcached_result_free(result
);
428 Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
430 test_return_t
user_supplied_bug12(memcached_st
*memc
)
432 memcached_return_t rc
;
436 uint64_t number_value
;
438 value
= memcached_get(memc
, "autoincrement", strlen("autoincrement"),
439 &value_length
, &flags
, &rc
);
441 test_compare(MEMCACHED_NOTFOUND
, rc
);
443 rc
= memcached_increment(memc
, "autoincrement", strlen("autoincrement"),
446 /* The binary protocol will set the key if it doesn't exist */
447 if (memcached_behavior_get(memc
, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL
) == 1)
449 test_compare(MEMCACHED_SUCCESS
, rc
);
453 test_compare(MEMCACHED_NOTFOUND
, rc
);
456 test_compare(MEMCACHED_SUCCESS
,
457 memcached_set(memc
, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0));
459 value
= memcached_get(memc
, "autoincrement", strlen("autoincrement"), &value_length
, &flags
, &rc
);
463 test_compare(MEMCACHED_SUCCESS
,
464 memcached_increment(memc
, "autoincrement", strlen("autoincrement"), 1, &number_value
));
465 test_compare(2UL, number_value
);
471 Bug found where command total one more than MEMCACHED_MAX_BUFFER
472 set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
474 test_return_t
user_supplied_bug13(memcached_st
*memc
)
476 char key
[] = "key34567890";
478 char commandFirst
[]= "set key34567890 0 0 ";
479 char commandLast
[] = " \r\n"; /* first line of command sent to server */
480 size_t commandLength
;
482 commandLength
= strlen(commandFirst
) + strlen(commandLast
) + 4; /* 4 is number of characters in size, probably 8196 */
484 size_t overflowSize
= MEMCACHED_MAX_BUFFER
- commandLength
;
486 for (size_t testSize
= overflowSize
- 1; testSize
< overflowSize
+ 1; testSize
++)
488 char *overflow
= new (std::nothrow
) char[testSize
];
491 memset(overflow
, 'x', testSize
);
492 test_compare(MEMCACHED_SUCCESS
,
493 memcached_set(memc
, key
, strlen(key
),
494 overflow
, testSize
, 0, 0));
503 Test values of many different sizes
504 Bug found where command total one more than MEMCACHED_MAX_BUFFER
505 set key34567890 0 0 8169 \r\n
506 is sent followed by buffer of size 8169, followed by 8169
508 test_return_t
user_supplied_bug14(memcached_st
*memc
)
510 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_TCP_NODELAY
, true);
512 libtest::vchar_t value
;
513 value
.reserve(18000);
514 for (ptrdiff_t x
= 0; x
< 18000; x
++)
516 value
.push_back((char) (x
% 127));
519 for (size_t current_length
= 1; current_length
< value
.size(); current_length
++)
521 memcached_return_t rc
= memcached_set(memc
, test_literal_param("foo"),
522 &value
[0], current_length
,
523 (time_t)0, (uint32_t)0);
524 ASSERT_TRUE_(rc
== MEMCACHED_SUCCESS
or rc
== MEMCACHED_BUFFERED
, "Instead got %s", memcached_strerror(NULL
, rc
));
526 size_t string_length
;
528 char *string
= memcached_get(memc
, test_literal_param("foo"),
529 &string_length
, &flags
, &rc
);
531 test_compare(MEMCACHED_SUCCESS
, rc
);
532 test_compare(string_length
, current_length
);
534 snprintf(buffer
, sizeof(buffer
), "%u", uint32_t(string_length
));
535 test_memcmp(string
, &value
[0], string_length
);
547 test_return_t
user_supplied_bug19(memcached_st
*)
549 memcached_return_t res
;
551 memcached_st
*memc
= memcached(test_literal_param("--server=localhost:11311/?100 --server=localhost:11312/?100"));
553 const memcached_instance_st
* server
= memcached_server_by_key(memc
, "a", 1, &res
);
556 memcached_free(memc
);
561 /* CAS test from Andei */
562 test_return_t
user_supplied_bug20(memcached_st
*memc
)
564 const char *key
= "abc";
565 size_t key_len
= strlen("abc");
567 test_skip(MEMCACHED_SUCCESS
, memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_SUPPORT_CAS
, true));
569 test_compare(MEMCACHED_SUCCESS
,
571 test_literal_param("abc"),
572 test_literal_param("foobar"),
573 (time_t)0, (uint32_t)0));
575 test_compare(MEMCACHED_SUCCESS
,
576 memcached_mget(memc
, &key
, &key_len
, 1));
578 memcached_result_st result_obj
;
579 memcached_result_st
*result
= memcached_result_create(memc
, &result_obj
);
582 memcached_result_create(memc
, &result_obj
);
583 memcached_return_t status
;
584 result
= memcached_fetch_result(memc
, &result_obj
, &status
);
587 test_compare(MEMCACHED_SUCCESS
, status
);
589 memcached_result_free(result
);
594 /* Large mget() of missing keys with binary proto
596 * If many binary quiet commands (such as getq's in an mget) fill the output
597 * buffer and the server chooses not to respond, memcached_flush hangs. See
598 * http://lists.tangent.org/pipermail/libmemcached/2009-August/000918.html
601 /* sighandler_t function that always asserts false */
602 static __attribute__((noreturn
)) void fail(int)
608 test_return_t
_user_supplied_bug21(memcached_st
* memc
, size_t key_count
)
615 void (*oldalarm
)(int);
617 memcached_st
*memc_clone
= memcached_clone(NULL
, memc
);
618 test_true(memc_clone
);
620 /* only binproto uses getq for mget */
621 test_compare(MEMCACHED_SUCCESS
, memcached_behavior_set(memc_clone
, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL
, true));
623 /* empty the cache to ensure misses (hence non-responses) */
624 test_compare(MEMCACHED_SUCCESS
, memcached_flush(memc_clone
, 0));
626 keys_st
keys(key_count
);
628 oldalarm
= signal(SIGALRM
, fail
);
631 test_compare_got(MEMCACHED_SUCCESS
,
632 memcached_mget(memc_clone
, keys
.keys_ptr(), keys
.lengths_ptr(), keys
.size()),
633 memcached_last_error_message(memc_clone
));
636 signal(SIGALRM
, oldalarm
);
638 memcached_return_t rc
;
640 char return_key
[MEMCACHED_MAX_KEY
];
641 size_t return_key_length
;
643 size_t return_value_length
;
644 while ((return_value
= memcached_fetch(memc
, return_key
, &return_key_length
,
645 &return_value_length
, &flags
, &rc
)))
647 test_false(return_value
); // There are no keys to fetch, so the value should never be returned
649 test_compare(MEMCACHED_NOTFOUND
, rc
);
650 test_zero(return_value_length
);
651 test_zero(return_key_length
);
652 test_false(return_key
[0]);
653 test_false(return_value
);
655 memcached_free(memc_clone
);
661 test_return_t
user_supplied_bug21(memcached_st
*memc
)
663 test_skip(TEST_SUCCESS
, pre_binary(memc
));
665 /* should work as of r580 */
666 test_compare(TEST_SUCCESS
,
667 _user_supplied_bug21(memc
, 10));
669 /* should fail as of r580 */
670 test_compare(TEST_SUCCESS
,
671 _user_supplied_bug21(memc
, 1000));
676 test_return_t
comparison_operator_memcached_st_and__memcached_return_t_TEST(memcached_st
*)
680 memcached_st
*memc
= &memc_
;
682 ASSERT_EQ(memc
, MEMCACHED_SUCCESS
);
683 test_compare(memc
, MEMCACHED_SUCCESS
);
685 ASSERT_NEQ(memc
, MEMCACHED_FAILURE
);
691 static void my_free(const memcached_st
*ptr
, void *mem
, void *context
)
695 #ifdef HARD_MALLOC_TESTS
696 void *real_ptr
= (mem
== NULL
) ? mem
: (void*)((caddr_t
)mem
- 8);
704 static void *my_malloc(const memcached_st
*ptr
, const size_t size
, void *context
)
708 #ifdef HARD_MALLOC_TESTS
709 void *ret
= malloc(size
+ 8);
712 ret
= (void*)((caddr_t
)ret
+ 8);
715 void *ret
= malloc(size
);
720 memset(ret
, 0xff, size
);
727 static void *my_realloc(const memcached_st
*ptr
, void *mem
, const size_t size
, void *)
729 #ifdef HARD_MALLOC_TESTS
730 void *real_ptr
= (mem
== NULL
) ? NULL
: (void*)((caddr_t
)mem
- 8);
731 void *nmem
= realloc(real_ptr
, size
+ 8);
736 ret
= (void*)((caddr_t
)nmem
+ 8);
742 return realloc(mem
, size
);
747 static void *my_calloc(const memcached_st
*ptr
, size_t nelem
, const size_t size
, void *)
749 #ifdef HARD_MALLOC_TESTS
750 void *mem
= my_malloc(ptr
, nelem
* size
);
753 memset(mem
, 0, nelem
* size
);
759 return calloc(nelem
, size
);
763 #ifdef MEMCACHED_ENABLE_DEPRECATED
764 test_return_t
deprecated_set_memory_alloc(memcached_st
*memc
)
766 void *test_ptr
= NULL
;
769 memcached_malloc_fn malloc_cb
= (memcached_malloc_fn
)my_malloc
;
770 cb_ptr
= *(void **)&malloc_cb
;
771 memcached_return_t rc
;
773 test_compare(MEMCACHED_SUCCESS
,
774 memcached_callback_set(memc
, MEMCACHED_CALLBACK_MALLOC_FUNCTION
, cb_ptr
));
775 test_ptr
= memcached_callback_get(memc
, MEMCACHED_CALLBACK_MALLOC_FUNCTION
, &rc
);
776 test_compare(MEMCACHED_SUCCESS
, rc
);
777 test_true(test_ptr
== cb_ptr
);
781 memcached_realloc_fn realloc_cb
=
782 (memcached_realloc_fn
)my_realloc
;
783 cb_ptr
= *(void **)&realloc_cb
;
784 memcached_return_t rc
;
786 test_compare(MEMCACHED_SUCCESS
,
787 memcached_callback_set(memc
, MEMCACHED_CALLBACK_REALLOC_FUNCTION
, cb_ptr
));
788 test_ptr
= memcached_callback_get(memc
, MEMCACHED_CALLBACK_REALLOC_FUNCTION
, &rc
);
789 test_compare(MEMCACHED_SUCCESS
, rc
);
790 test_true(test_ptr
== cb_ptr
);
794 memcached_free_fn free_cb
=
795 (memcached_free_fn
)my_free
;
796 cb_ptr
= *(void **)&free_cb
;
797 memcached_return_t rc
;
799 test_compare(MEMCACHED_SUCCESS
,
800 memcached_callback_set(memc
, MEMCACHED_CALLBACK_FREE_FUNCTION
, cb_ptr
));
801 test_ptr
= memcached_callback_get(memc
, MEMCACHED_CALLBACK_FREE_FUNCTION
, &rc
);
802 test_compare(MEMCACHED_SUCCESS
, rc
);
803 test_true(test_ptr
== cb_ptr
);
811 test_return_t
set_memory_alloc(memcached_st
*memc
)
813 test_compare(MEMCACHED_INVALID_ARGUMENTS
,
814 memcached_set_memory_allocators(memc
, NULL
, my_free
,
815 my_realloc
, my_calloc
, NULL
));
817 test_compare(MEMCACHED_SUCCESS
,
818 memcached_set_memory_allocators(memc
, my_malloc
, my_free
,
819 my_realloc
, my_calloc
, NULL
));
821 memcached_malloc_fn mem_malloc
;
822 memcached_free_fn mem_free
;
823 memcached_realloc_fn mem_realloc
;
824 memcached_calloc_fn mem_calloc
;
825 memcached_get_memory_allocators(memc
, &mem_malloc
, &mem_free
,
826 &mem_realloc
, &mem_calloc
);
828 test_true(mem_malloc
== my_malloc
);
829 test_true(mem_realloc
== my_realloc
);
830 test_true(mem_calloc
== my_calloc
);
831 test_true(mem_free
== my_free
);
839 Test case adapted from John Gorman <johngorman2@gmail.com>
841 We are testing the error condition when we connect to a server via memcached_get()
842 but find that the server is not available.
844 test_return_t
memcached_get_MEMCACHED_ERRNO(memcached_st
*)
851 memcached_st
*tl_memc_h
= memcached(test_literal_param("--server=localhost:9898 --server=localhost:9899")); // This server should not exist
853 // See if memcached is reachable.
854 char *value
= memcached_get(tl_memc_h
,
855 test_literal_param(__func__
),
860 test_true(memcached_failed(rc
));
862 memcached_free(tl_memc_h
);
868 Test case adapted from John Gorman <johngorman2@gmail.com>
870 We are testing the error condition when we connect to a server via memcached_get_by_key()
871 but find that the server is not available.
873 test_return_t
memcached_get_by_key_MEMCACHED_ERRNO(memcached_st
*)
880 memcached_st
*tl_memc_h
= memcached_create(NULL
);
881 memcached_server_st
*servers
= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
882 memcached_server_push(tl_memc_h
, servers
);
883 memcached_server_list_free(servers
);
885 // See if memcached is reachable.
886 char *value
= memcached_get_by_key(tl_memc_h
,
887 test_literal_param(__func__
), // Key
888 test_literal_param(__func__
), // Value
893 test_true(memcached_failed(rc
));
895 memcached_free(tl_memc_h
);
900 /* Test memcached_server_get_last_disconnect
901 * For a working server set, shall be NULL
902 * For a set of non existing server, shall not be NULL
904 test_return_t
test_get_last_disconnect(memcached_st
*memc
)
906 memcached_return_t rc
;
907 const memcached_instance_st
* disconnected_server
;
909 /* With the working set of server */
910 const char *key
= "marmotte";
911 const char *value
= "milka";
913 memcached_reset_last_disconnected_server(memc
);
914 test_false(memc
->last_disconnected_server
);
915 rc
= memcached_set(memc
, key
, strlen(key
),
916 value
, strlen(value
),
917 (time_t)0, (uint32_t)0);
918 test_true(rc
== MEMCACHED_SUCCESS
|| rc
== MEMCACHED_BUFFERED
);
920 disconnected_server
= memcached_server_get_last_disconnect(memc
);
921 test_false(disconnected_server
);
923 /* With a non existing server */
925 memcached_server_st
*servers
;
927 const char *server_list
= "localhost:9";
929 servers
= memcached_servers_parse(server_list
);
931 mine
= memcached_create(NULL
);
932 rc
= memcached_server_push(mine
, servers
);
933 test_compare(MEMCACHED_SUCCESS
, rc
);
934 memcached_server_list_free(servers
);
937 rc
= memcached_set(mine
, key
, strlen(key
),
938 value
, strlen(value
),
939 (time_t)0, (uint32_t)0);
940 test_true(memcached_failed(rc
));
942 disconnected_server
= memcached_server_get_last_disconnect(mine
);
943 test_true_got(disconnected_server
, memcached_strerror(mine
, rc
));
944 test_compare(in_port_t(9), memcached_server_port(disconnected_server
));
945 test_false(strncmp(memcached_server_name(disconnected_server
),"localhost",9));
947 memcached_quit(mine
);
948 memcached_free(mine
);
953 test_return_t
test_multiple_get_last_disconnect(memcached_st
*)
955 const char *server_string
= "--server=localhost:8888 --server=localhost:8889 --server=localhost:8890 --server=localhost:8891 --server=localhost:8892";
958 test_compare(MEMCACHED_SUCCESS
,
959 libmemcached_check_configuration(server_string
, strlen(server_string
), buffer
, sizeof(buffer
)));
961 memcached_st
*memc
= memcached(server_string
, strlen(server_string
));
964 // We will just use the error strings as our keys
965 uint32_t counter
= 100;
968 for (int x
= int(MEMCACHED_SUCCESS
); x
< int(MEMCACHED_MAXIMUM_RETURN
); ++x
)
970 const char *msg
= memcached_strerror(memc
, memcached_return_t(x
));
971 memcached_return_t ret
= memcached_set(memc
, msg
, strlen(msg
), NULL
, 0, (time_t)0, (uint32_t)0);
972 test_true_got((ret
== MEMCACHED_CONNECTION_FAILURE
or ret
== MEMCACHED_SERVER_TEMPORARILY_DISABLED
), memcached_last_error_message(memc
));
974 const memcached_instance_st
* disconnected_server
= memcached_server_get_last_disconnect(memc
);
975 test_true(disconnected_server
);
976 test_strcmp("localhost", memcached_server_name(disconnected_server
));
977 test_true(memcached_server_port(disconnected_server
) >= 8888 and memcached_server_port(disconnected_server
) <= 8892);
981 memcached_reset_last_disconnected_server(memc
);
986 memcached_free(memc
);
992 * This test ensures that the failure counter isn't incremented during
993 * normal termination of the memcached instance.
995 test_return_t
wrong_failure_counter_test(memcached_st
*original_memc
)
997 memcached_st
* memc
= create_single_instance_memcached(original_memc
, NULL
);
999 /* Ensure that we are connected to the server by setting a value */
1000 memcached_return_t rc
= memcached_set(memc
,
1001 test_literal_param(__func__
), // Key
1002 test_literal_param(__func__
), // Value
1003 time_t(0), uint32_t(0));
1004 test_true(rc
== MEMCACHED_SUCCESS
or rc
== MEMCACHED_BUFFERED
);
1007 const memcached_instance_st
* instance
= memcached_server_instance_by_position(memc
, 0);
1009 /* The test is to see that the memcached_quit doesn't increase the
1010 * the server failure conter, so let's ensure that it is zero
1011 * before sending quit
1013 ((memcached_server_write_instance_st
)instance
)->server_failure_counter
= 0;
1015 memcached_quit(memc
);
1017 /* Verify that it memcached_quit didn't increment the failure counter
1018 * Please note that this isn't bullet proof, because an error could
1021 test_zero(instance
->server_failure_counter
);
1023 memcached_free(memc
);
1025 return TEST_SUCCESS
;
1029 * This tests ensures expected disconnections (for some behavior changes
1030 * for instance) do not wrongly increase failure counter
1032 test_return_t
wrong_failure_counter_two_test(memcached_st
*memc
)
1034 /* Set value to force connection to the server */
1035 const char *key
= "marmotte";
1036 const char *value
= "milka";
1038 test_compare_hint(MEMCACHED_SUCCESS
,
1039 memcached_set(memc
, key
, strlen(key
),
1040 value
, strlen(value
),
1041 (time_t)0, (uint32_t)0),
1042 memcached_last_error_message(memc
));
1045 /* put failure limit to 1 */
1046 test_compare(MEMCACHED_SUCCESS
,
1047 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT
, true));
1049 /* Put a retry timeout to effectively activate failure_limit effect */
1050 test_compare(MEMCACHED_SUCCESS
,
1051 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT
, 1));
1053 /* change behavior that triggers memcached_quit()*/
1054 test_compare(MEMCACHED_SUCCESS
,
1055 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_TCP_NODELAY
, true));
1058 /* Check if we still are connected */
1060 size_t string_length
;
1061 memcached_return rc
;
1062 char *string
= memcached_get(memc
, key
, strlen(key
),
1063 &string_length
, &flags
, &rc
);
1065 test_compare_got(MEMCACHED_SUCCESS
, rc
, memcached_strerror(NULL
, rc
));
1069 return TEST_SUCCESS
;
1073 #define regression_bug_655423_COUNT 6000
1074 test_return_t
regression_bug_655423(memcached_st
*memc
)
1076 memcached_st
*clone
= memcached_clone(NULL
, memc
);
1077 memc
= NULL
; // Just to make sure it is not used
1082 return TEST_SKIPPED
;
1085 test_skip(MEMCACHED_SUCCESS
, memcached_behavior_set(clone
, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL
, 1));
1086 test_skip(MEMCACHED_SUCCESS
, memcached_behavior_set(clone
, MEMCACHED_BEHAVIOR_SUPPORT_CAS
, 1));
1087 test_skip(MEMCACHED_SUCCESS
, memcached_behavior_set(clone
, MEMCACHED_BEHAVIOR_TCP_NODELAY
, 1));
1088 test_skip(MEMCACHED_SUCCESS
, memcached_behavior_set(clone
, MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH
, 1));
1090 memset(payload
, int('x'), sizeof(payload
));
1092 keys_st
keys(regression_bug_655423_COUNT
);
1094 for (size_t x
= 0; x
< keys
.size(); x
++)
1096 test_compare(MEMCACHED_SUCCESS
, memcached_set(clone
,
1099 payload
, sizeof(payload
), 0, 0));
1102 for (size_t x
= 0; x
< keys
.size(); x
++)
1104 size_t value_length
;
1105 memcached_return_t rc
;
1106 char *value
= memcached_get(clone
,
1109 &value_length
, NULL
, &rc
);
1111 if (rc
== MEMCACHED_NOTFOUND
)
1114 test_zero(value_length
);
1118 test_compare(MEMCACHED_SUCCESS
, rc
);
1120 test_compare(100LLU, value_length
);
1124 test_compare(MEMCACHED_SUCCESS
,
1125 memcached_mget(clone
,
1126 keys
.keys_ptr(), keys
.lengths_ptr(),
1130 memcached_result_st
*result
= NULL
;
1131 while ((result
= memcached_fetch_result(clone
, result
, NULL
)))
1133 test_compare(size_t(100), memcached_result_length(result
));
1137 test_true(count
> 100); // If we don't get back atleast this, something is up
1139 memcached_free(clone
);
1141 return TEST_SUCCESS
;
1145 * Test that ensures that buffered set to not trigger problems during io_flush
1147 #define regression_bug_490520_COUNT 200480
1148 test_return_t
regression_bug_490520(memcached_st
*original_memc
)
1150 memcached_st
* memc
= create_single_instance_memcached(original_memc
, NULL
);
1152 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_NO_BLOCK
,1);
1153 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS
,1);
1154 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_POLL_TIMEOUT
, 1000);
1155 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT
,1);
1156 memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT
, 3600);
1158 /* First add all of the items.. */
1159 char blob
[3333] = {0};
1160 for (uint32_t x
= 0; x
< regression_bug_490520_COUNT
; ++x
)
1163 int key_length
= snprintf(key
, sizeof(key
), "0200%u", x
);
1165 memcached_return rc
= memcached_set(memc
, key
, key_length
, blob
, sizeof(blob
), 0, 0);
1166 test_true_got(rc
== MEMCACHED_SUCCESS
or rc
== MEMCACHED_BUFFERED
, memcached_last_error_message(memc
));
1169 memcached_free(memc
);
1171 return TEST_SUCCESS
;
1174 test_return_t
regression_bug_1251482(memcached_st
*)
1176 test::Memc
memc("--server=localhost:5");
1178 memcached_behavior_set(&memc
, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT
, 0);
1180 for (size_t x
= 0; x
< 5; ++x
)
1182 size_t value_length
;
1183 memcached_return_t rc
;
1184 char *value
= memcached_get(&memc
,
1185 test_literal_param(__func__
),
1186 &value_length
, NULL
, &rc
);
1189 test_compare(0LLU, value_length
);
1191 test_ne_compare(MEMCACHED_SUCCESS
, rc
);
1193 test_compare(MEMCACHED_CONNECTION_FAILURE
, rc
);
1197 return TEST_SUCCESS
;
1200 test_return_t
regression_1009493_TEST(memcached_st
*)
1202 memcached_st
* memc
= memcached_create(NULL
);
1204 test_compare(MEMCACHED_SUCCESS
, memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_KETAMA
, true));
1206 memcached_st
* clone
= memcached_clone(NULL
, memc
);
1209 test_compare(memcached_behavior_get(memc
, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED
),
1210 memcached_behavior_get(clone
, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED
));
1212 memcached_free(memc
);
1213 memcached_free(clone
);
1215 return TEST_SUCCESS
;
1218 test_return_t
regression_994772_TEST(memcached_st
* memc
)
1220 test_skip(MEMCACHED_SUCCESS
, memcached_behavior_set(memc
, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL
, 1));
1222 test_compare(MEMCACHED_SUCCESS
,
1224 test_literal_param(__func__
), // Key
1225 test_literal_param(__func__
), // Value
1226 time_t(0), uint32_t(0)));
1228 const char *keys
[] = { __func__
};
1229 size_t key_length
[]= { strlen(__func__
) };
1230 test_compare(MEMCACHED_SUCCESS
,
1231 memcached_mget(memc
, keys
, key_length
, 1));
1233 memcached_return_t rc
;
1234 memcached_result_st
*results
= memcached_fetch_result(memc
, NULL
, &rc
);
1236 test_compare(MEMCACHED_SUCCESS
, rc
);
1238 test_strcmp(__func__
, memcached_result_value(results
));
1239 uint64_t cas_value
= memcached_result_cas(results
);
1240 test_true(cas_value
);
1242 char* take_value
= memcached_result_take_value(results
);
1243 test_strcmp(__func__
, take_value
);
1246 memcached_result_free(results
);
1248 // Bad cas value, sanity check
1249 test_true(cas_value
!= 9999);
1250 test_compare(MEMCACHED_END
,
1252 test_literal_param(__func__
), // Key
1253 test_literal_param(__FILE__
), // Value
1254 time_t(0), uint32_t(0), 9999));
1256 test_compare(MEMCACHED_SUCCESS
, memcached_set(memc
,
1257 "different", strlen("different"), // Key
1258 test_literal_param(__FILE__
), // Value
1259 time_t(0), uint32_t(0)));
1261 return TEST_SUCCESS
;