X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=tests%2Fmem_functions.c;h=91cb2b2347187e78105d32ffaead02daed626727;hb=4cd075fbd0fab78e393c1559db340a221196a006;hp=3872ee387768a8372324b160e7e8db39fa71e780;hpb=727bb52db1af1d405c76df285001938eafb67d0a;p=m6w6%2Flibmemcached diff --git a/tests/mem_functions.c b/tests/mem_functions.c index 3872ee38..91cb2b23 100644 --- a/tests/mem_functions.c +++ b/tests/mem_functions.c @@ -1,19 +1,50 @@ -/* libMemcached Functions Test - * Copyright (C) 2006-2009 Brian Aker - * All rights reserved. +/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: + * + * Libmemcached library + * + * Copyright (C) 2011 Data Differential, http://datadifferential.com/ + * Copyright (C) 2006-2009 Brian Aker All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * The names of its contributors may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Use and distribution licensed under the BSD license. See - * the COPYING file in the parent directory for full text. */ + /* Sample test application. */ -#include "libmemcached/common.h" +#include "config.h" #include #include +#include #include #include #include @@ -22,19 +53,27 @@ #include #include #include -#include "server.h" + +#include "libmemcached/common.h" + +#include + #include "clients/generator.h" #include "clients/execute.h" -#ifndef INT64_MAX -#define INT64_MAX LONG_MAX -#endif -#ifndef INT32_MAX -#define INT32_MAX INT_MAX -#endif +#define SMALL_STRING_LEN 1024 +#include +#include "tests/deprecated.h" +#include "tests/parser.h" +#include "tests/pool.h" +#include "tests/string.h" +#include "tests/replication.h" +#include "tests/basic.h" +#include "tests/error_conditions.h" +#include "tests/print.h" +#include "tests/virtual_buckets.h" -#include "test.h" #ifdef HAVE_LIBMEMCACHEDUTIL #include @@ -56,9 +95,10 @@ static size_t global_keys_length[GLOBAL_COUNT]; static test_return_t pre_binary(memcached_st *memc); -static test_return_t init_test(memcached_st *not_used __attribute__((unused))) +static test_return_t init_test(memcached_st *not_used) { memcached_st memc; + (void)not_used; (void)memcached_create(&memc); memcached_free(&memc); @@ -66,45 +106,48 @@ static test_return_t init_test(memcached_st *not_used __attribute__((unused))) return TEST_SUCCESS; } -static test_return_t server_list_null_test(memcached_st *ptr __attribute__((unused))) -{ - memcached_server_st *server_list; - memcached_return_t rc; - - server_list= memcached_server_list_append_with_weight(NULL, NULL, 0, 0, NULL); - test_true(server_list == NULL); - - server_list= memcached_server_list_append_with_weight(NULL, "localhost", 0, 0, NULL); - test_true(server_list == NULL); - - server_list= memcached_server_list_append_with_weight(NULL, NULL, 0, 0, &rc); - test_true(server_list == NULL); - - return TEST_SUCCESS; -} - #define TEST_PORT_COUNT 7 in_port_t test_ports[TEST_PORT_COUNT]; -static memcached_return_t server_display_function(const memcached_st *ptr __attribute__((unused)), +static memcached_return_t server_display_function(const memcached_st *ptr, const memcached_server_st *server, void *context) { /* Do Nothing */ size_t bigger= *((size_t *)(context)); + (void)ptr; assert(bigger <= memcached_server_port(server)); *((size_t *)(context))= memcached_server_port(server); return MEMCACHED_SUCCESS; } -static test_return_t server_sort_test(memcached_st *ptr __attribute__((unused))) +static memcached_return_t dump_server_information(const memcached_st *ptr, + const memcached_server_st *instance, + void *context) +{ + /* Do Nothing */ + FILE *stream= (FILE *)context; + (void)ptr; + + fprintf(stream, "Memcached Server: %s %u Version %u.%u.%u\n", + memcached_server_name(instance), + memcached_server_port(instance), + instance->major_version, + instance->minor_version, + instance->micro_version); + + return MEMCACHED_SUCCESS; +} + +static test_return_t server_sort_test(memcached_st *ptr) { size_t bigger= 0; /* Prime the value for the test_true in server_display_function */ memcached_return_t rc; memcached_server_fn callbacks[1]; memcached_st *local_memc; + (void)ptr; local_memc= memcached_create(NULL); test_true(local_memc); @@ -130,13 +173,14 @@ static test_return_t server_sort_test(memcached_st *ptr __attribute__((unused))) return TEST_SUCCESS; } -static test_return_t server_sort2_test(memcached_st *ptr __attribute__((unused))) +static test_return_t server_sort2_test(memcached_st *ptr) { size_t bigger= 0; /* Prime the value for the test_true in server_display_function */ memcached_return_t rc; memcached_server_fn callbacks[1]; memcached_st *local_memc; memcached_server_instance_st instance; + (void)ptr; local_memc= memcached_create(NULL); test_true(local_memc); @@ -166,36 +210,15 @@ static test_return_t server_sort2_test(memcached_st *ptr __attribute__((unused)) return TEST_SUCCESS; } -static memcached_return_t server_print_callback(const memcached_st *ptr __attribute__((unused)), - const memcached_server_st *server, - void *context __attribute__((unused))) +static test_return_t memcached_server_remove_test(memcached_st *ptr) { - (void)server; // Just in case we aren't printing. - -#if 0 - fprintf(stderr, "%s(%d)", memcached_server_name(server), memcached_server_port(server)); -#endif + const char *server_string= "--server=localhost:4444 --server=localhost:4445 --server=localhost:4446 --server=localhost:4447 --server=localhost --server=memcache1.memcache.bk.sapo.pt:11211 --server=memcache1.memcache.bk.sapo.pt:11212 --server=memcache1.memcache.bk.sapo.pt:11213 --server=memcache1.memcache.bk.sapo.pt:11214 --server=memcache2.memcache.bk.sapo.pt:11211 --server=memcache2.memcache.bk.sapo.pt:11212 --server=memcache2.memcache.bk.sapo.pt:11213 --server=memcache2.memcache.bk.sapo.pt:11214"; + (void)ptr; - return MEMCACHED_SUCCESS; -} + memcached_st *memc= memcached(server_string, strlen(server_string)); + test_true(memc); -static test_return_t memcached_server_remove_test(memcached_st *ptr __attribute__((unused))) -{ - memcached_return_t rc; - memcached_st local_memc; - memcached_st *memc; - memcached_server_st *servers; memcached_server_fn callbacks[1]; - - const char *server_string= "localhost:4444, localhost:4445, localhost:4446, localhost:4447, localhost, memcache1.memcache.bk.sapo.pt:11211, memcache1.memcache.bk.sapo.pt:11212, memcache1.memcache.bk.sapo.pt:11213, memcache1.memcache.bk.sapo.pt:11214, memcache2.memcache.bk.sapo.pt:11211, memcache2.memcache.bk.sapo.pt:11212, memcache2.memcache.bk.sapo.pt:11213, memcache2.memcache.bk.sapo.pt:11214"; - - memc= memcached_create(&local_memc); - - servers= memcached_servers_parse(server_string); - - rc= memcached_server_push(memc, servers); - memcached_server_list_free(servers); - callbacks[0]= server_print_callback; memcached_server_cursor(memc, callbacks, NULL, 1); @@ -204,26 +227,33 @@ static test_return_t memcached_server_remove_test(memcached_st *ptr __attribute_ return TEST_SUCCESS; } -static memcached_return_t server_display_unsort_function(const memcached_st *ptr __attribute__((unused)), +static memcached_return_t server_display_unsort_function(const memcached_st *ptr, const memcached_server_st *server, void *context) { /* Do Nothing */ uint32_t x= *((uint32_t *)(context)); + (void)ptr; + + if (! (test_ports[x] == server->port)) + { + fprintf(stderr, "%lu -> %lu\n", (unsigned long)test_ports[x], (unsigned long)server->port); + return MEMCACHED_FAILURE; + } - assert(test_ports[x] == server->port); *((uint32_t *)(context))= ++x; return MEMCACHED_SUCCESS; } -static test_return_t server_unsort_test(memcached_st *ptr __attribute__((unused))) +static test_return_t server_unsort_test(memcached_st *ptr) { size_t counter= 0; /* Prime the value for the test_true in server_display_function */ size_t bigger= 0; /* Prime the value for the test_true in server_display_function */ memcached_return_t rc; memcached_server_fn callbacks[1]; memcached_st *local_memc; + (void)ptr; local_memc= memcached_create(NULL); test_true(local_memc); @@ -253,8 +283,9 @@ static test_return_t server_unsort_test(memcached_st *ptr __attribute__((unused) return TEST_SUCCESS; } -static test_return_t allocation_test(memcached_st *not_used __attribute__((unused))) +static test_return_t allocation_test(memcached_st *not_used) { + (void)not_used; memcached_st *memc; memc= memcached_create(NULL); test_true(memc); @@ -292,13 +323,11 @@ static test_return_t clone_test(memcached_st *memc) { // Test all of the flags test_true(memc_clone->flags.no_block == memc->flags.no_block); test_true(memc_clone->flags.tcp_nodelay == memc->flags.tcp_nodelay); - test_true(memc_clone->flags.reuse_memory == memc->flags.reuse_memory); - test_true(memc_clone->flags.use_cache_lookups == memc->flags.use_cache_lookups); test_true(memc_clone->flags.support_cas == memc->flags.support_cas); test_true(memc_clone->flags.buffer_requests == memc->flags.buffer_requests); test_true(memc_clone->flags.use_sort_hosts == memc->flags.use_sort_hosts); test_true(memc_clone->flags.verify_key == memc->flags.verify_key); - test_true(memc_clone->flags.ketama_weighted == memc->flags.ketama_weighted); + test_true(memc_clone->ketama.weighted == memc->ketama.weighted); test_true(memc_clone->flags.binary_protocol == memc->flags.binary_protocol); test_true(memc_clone->flags.hash_with_prefix_key == memc->flags.hash_with_prefix_key); test_true(memc_clone->flags.no_reply == memc->flags.no_reply); @@ -308,7 +337,6 @@ static test_return_t clone_test(memcached_st *memc) } test_true(memc_clone->get_key_failure == memc->get_key_failure); test_true(hashkit_compare(&memc_clone->hashkit, &memc->hashkit)); - test_true(hashkit_compare(&memc_clone->distribution_hashkit, &memc->distribution_hashkit)); test_true(memc_clone->io_bytes_watermark == memc->io_bytes_watermark); test_true(memc_clone->io_msg_watermark == memc->io_msg_watermark); test_true(memc_clone->io_key_prefetch == memc->io_key_prefetch); @@ -382,10 +410,10 @@ static test_return_t error_test(memcached_st *memc) 2300930706U, 2943759320U, 674306647U, 2400528935U, 54481931U, 4186304426U, 1741088401U, 2979625118U, 4159057246U, 3425930182U, 2593724503U, 1868899624U, - 1769812374U, 2302537950U, 1110330676U }; + 1769812374U, 2302537950U, 1110330676U, 3365377466U, + 1336171666U, 3021258493U, 3365377466U }; // You have updated the memcache_error messages but not updated docs/tests. - test_true(MEMCACHED_MAXIMUM_RETURN == 43); for (rc= MEMCACHED_SUCCESS; rc < MEMCACHED_MAXIMUM_RETURN; rc++) { uint32_t hash_val; @@ -399,6 +427,7 @@ static test_return_t error_test(memcached_st *memc) } test_true(values[rc] == hash_val); } + test_true(MEMCACHED_MAXIMUM_RETURN == 46); return TEST_SUCCESS; } @@ -682,7 +711,6 @@ static test_return_t add_test(memcached_st *memc) */ static test_return_t add_wrapper(memcached_st *memc) { - unsigned int x; unsigned int max= 10000; #ifdef __sun max= 10; @@ -691,7 +719,7 @@ static test_return_t add_wrapper(memcached_st *memc) max= 10; #endif - for (x= 0; x < max; x++) + for (uint32_t x= 0; x < max; x++) add_test(memc); return TEST_SUCCESS; @@ -738,16 +766,19 @@ static test_return_t flush_test(memcached_st *memc) { memcached_return_t rc; + uint64_t query_id= memcached_query_id(memc); rc= memcached_flush(memc, 0); - test_true(rc == MEMCACHED_SUCCESS); + test_compare(rc, MEMCACHED_SUCCESS); + test_compare(query_id +1, memcached_query_id(memc)); return TEST_SUCCESS; } -static memcached_return_t server_function(const memcached_st *ptr __attribute__((unused)), - const memcached_server_st *server __attribute__((unused)), - void *context __attribute__((unused))) +static memcached_return_t server_function(const memcached_st *ptr, + const memcached_server_st *server, + void *context) { + (void)ptr; (void)server; (void)context; /* Do Nothing */ return MEMCACHED_SUCCESS; @@ -755,8 +786,8 @@ static memcached_return_t server_function(const memcached_st *ptr __attribute__ static test_return_t memcached_server_cursor_test(memcached_st *memc) { - char context[8]; - strcpy(context, "foo bad"); + char context[10]; + strncpy(context, "foo bad", sizeof(context)); memcached_server_fn callbacks[1]; callbacks[0]= server_function; @@ -776,18 +807,23 @@ static test_return_t bad_key_test(memcached_st *memc) size_t max_keylen= 0xffff; // Just skip if we are in binary mode. + uint64_t query_id= memcached_query_id(memc); if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)) return TEST_SKIPPED; + test_compare(query_id, memcached_query_id(memc)); // We should not increase the query_id for memcached_behavior_get() memc_clone= memcached_clone(NULL, memc); test_true(memc_clone); + query_id= memcached_query_id(memc_clone); rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set); test_true(rc == MEMCACHED_SUCCESS); + test_compare(query_id, memcached_query_id(memc_clone)); // We should not increase the query_id for memcached_behavior_set() /* All keys are valid in the binary protocol (except for length) */ if (memcached_behavior_get(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 0) { + query_id= memcached_query_id(memc_clone); string= memcached_get(memc_clone, key, strlen(key), &string_length, &flags, &rc); test_true(rc == MEMCACHED_BAD_KEY_PROVIDED); @@ -795,7 +831,9 @@ static test_return_t bad_key_test(memcached_st *memc) test_true(!string); set= 0; + query_id= memcached_query_id(memc_clone); rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set); + test_compare(query_id, memcached_query_id(memc_clone)); // We should not increase the query_id for memcached_behavior_set() test_true(rc == MEMCACHED_SUCCESS); string= memcached_get(memc_clone, key, strlen(key), &string_length, &flags, &rc); @@ -807,14 +845,20 @@ static test_return_t bad_key_test(memcached_st *memc) const char *keys[] = { "GoodKey", "Bad Key", "NotMine" }; size_t key_lengths[] = { 7, 7, 7 }; set= 1; + query_id= memcached_query_id(memc_clone); rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set); test_true(rc == MEMCACHED_SUCCESS); + test_compare(query_id, memcached_query_id(memc_clone)); + query_id= memcached_query_id(memc_clone); rc= memcached_mget(memc_clone, keys, key_lengths, 3); test_true(rc == MEMCACHED_BAD_KEY_PROVIDED); + test_compare(query_id +1, memcached_query_id(memc_clone)); + query_id= memcached_query_id(memc_clone); rc= memcached_mget_by_key(memc_clone, "foo daddy", 9, keys, key_lengths, 1); test_true(rc == MEMCACHED_BAD_KEY_PROVIDED); + test_compare(query_id +1, memcached_query_id(memc_clone)); max_keylen= 250; @@ -825,7 +869,7 @@ static test_return_t bad_key_test(memcached_st *memc) rc= memcached_callback_set(memc_clone, MEMCACHED_CALLBACK_PREFIX_KEY, NULL); test_true(rc == MEMCACHED_SUCCESS); - char *longkey= malloc(max_keylen + 1); + char *longkey= (char *)malloc(max_keylen + 1); if (longkey != NULL) { memset(longkey, 'a', max_keylen + 1); @@ -861,12 +905,12 @@ static test_return_t bad_key_test(memcached_st *memc) } #define READ_THROUGH_VALUE "set for me" -static memcached_return_t read_through_trigger(memcached_st *memc __attribute__((unused)), - char *key __attribute__((unused)), - size_t key_length __attribute__((unused)), +static memcached_return_t read_through_trigger(memcached_st *memc, + char *key, + size_t key_length, memcached_result_st *result) { - + (void)memc;(void)key;(void)key_length; return memcached_result_set_value(result, READ_THROUGH_VALUE, strlen(READ_THROUGH_VALUE)); } @@ -909,10 +953,11 @@ static test_return_t read_through(memcached_st *memc) return TEST_SUCCESS; } -static memcached_return_t delete_trigger(memcached_st *ptr __attribute__((unused)), +static memcached_return_t delete_trigger(memcached_st *ptr, const char *key, - size_t key_length __attribute__((unused))) + size_t key_length) { + (void)ptr;(void)key_length; assert(key); return MEMCACHED_SUCCESS; @@ -939,8 +984,10 @@ static test_return_t get_test(memcached_st *memc) size_t string_length; uint32_t flags; + uint64_t query_id= memcached_query_id(memc); rc= memcached_delete(memc, key, strlen(key), (time_t)0); test_true(rc == MEMCACHED_BUFFERED || rc == MEMCACHED_NOTFOUND); + test_compare(query_id +1, memcached_query_id(memc)); string= memcached_get(memc, key, strlen(key), &string_length, &flags, &rc); @@ -961,18 +1008,22 @@ static test_return_t get_test2(memcached_st *memc) size_t string_length; uint32_t flags; + uint64_t query_id= memcached_query_id(memc); rc= memcached_set(memc, key, strlen(key), value, strlen(value), (time_t)0, (uint32_t)0); test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED); + test_compare(query_id +1, memcached_query_id(memc)); + query_id= memcached_query_id(memc); string= memcached_get(memc, key, strlen(key), &string_length, &flags, &rc); + test_compare(query_id +1, memcached_query_id(memc)); test_true(string); test_true(rc == MEMCACHED_SUCCESS); test_true(string_length == strlen(value)); - test_true(!memcmp(string, value, string_length)); + test_memcmp(string, value, string_length); free(string); @@ -1003,25 +1054,26 @@ static test_return_t set_test3(memcached_st *memc) memcached_return_t rc; char *value; size_t value_length= 8191; - unsigned int x; value = (char*)malloc(value_length); test_true(value); - for (x= 0; x < value_length; x++) + for (uint32_t x= 0; x < value_length; x++) value[x] = (char) (x % 127); /* The dump test relies on there being at least 32 items in memcached */ - for (x= 0; x < 32; x++) + for (uint32_t x= 0; x < 32; x++) { char key[16]; - sprintf(key, "foo%u", x); + snprintf(key, sizeof(key), "foo%u", x); + uint64_t query_id= memcached_query_id(memc); rc= memcached_set(memc, key, strlen(key), value, value_length, (time_t)0, (uint32_t)0); test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED); + test_compare(query_id +1, memcached_query_id(memc)); } free(value); @@ -1560,10 +1612,11 @@ static test_return_t mget_result_alloc_test(memcached_st *memc) } /* Count the results */ -static memcached_return_t callback_counter(const memcached_st *ptr __attribute__((unused)), - memcached_result_st *result __attribute__((unused)), +static memcached_return_t callback_counter(const memcached_st *ptr, + memcached_result_st *result, void *context) { + (void)ptr; (void)result; size_t *counter= (size_t *)context; *counter= *counter + 1; @@ -1685,11 +1738,13 @@ static test_return_t mget_execute(memcached_st *memc) { char k[251]; - key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x); + key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x); keys[x]= strdup(k); test_true(keys[x] != NULL); + uint64_t query_id= memcached_query_id(memc); rc= memcached_add(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0); test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED); + test_compare(query_id +1, memcached_query_id(memc)); } /* Try to get all of them with a large multiget */ @@ -1701,8 +1756,10 @@ static test_return_t mget_execute(memcached_st *memc) if (rc == MEMCACHED_SUCCESS) { test_true(binary); + uint64_t query_id= memcached_query_id(memc); rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1); test_true(rc == MEMCACHED_END); + test_compare(query_id, memcached_query_id(memc)); /* Verify that we got all of the items */ test_true(counter == max_keys); @@ -1790,9 +1847,10 @@ static test_return_t get_stats_keys(memcached_st *memc) return TEST_SUCCESS; } -static test_return_t version_string_test(memcached_st *memc __attribute__((unused))) +static test_return_t version_string_test(memcached_st *memc) { const char *version_string; + (void)memc; version_string= memcached_lib_version(); @@ -1860,13 +1918,15 @@ static test_return_t add_host_test(memcached_st *memc) return TEST_SUCCESS; } -static memcached_return_t clone_test_callback(memcached_st *parent __attribute__((unused)), memcached_st *memc_clone __attribute__((unused))) +static memcached_return_t clone_test_callback(memcached_st *parent, memcached_st *memc_clone) { + (void)parent;(void)memc_clone; return MEMCACHED_SUCCESS; } -static memcached_return_t cleanup_test_callback(memcached_st *ptr __attribute__((unused))) +static memcached_return_t cleanup_test_callback(memcached_st *ptr) { + (void)ptr; return MEMCACHED_SUCCESS; } @@ -1972,21 +2032,15 @@ static test_return_t MEMCACHED_BEHAVIOR_CORK_test(memcached_st *memc) { memcached_return_t rc; bool set= true; - bool value; rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, set); - test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED); + test_true(rc == MEMCACHED_DEPRECATED); - value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CORK); - - if (rc == MEMCACHED_SUCCESS) - { - test_true((bool)value == set); - } - else - { - test_false((bool)value == set); - } + // Platform dependent +#if 0 + bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CORK); + test_false(value); +#endif return TEST_SUCCESS; } @@ -2039,7 +2093,7 @@ static test_return_t MEMCACHED_BEHAVIOR_TCP_KEEPIDLE_test(memcached_st *memc) return TEST_SUCCESS; } -static test_return_t fetch_all_results(memcached_st *memc) +static test_return_t fetch_all_results(memcached_st *memc, size_t *keys_returned) { memcached_return_t rc= MEMCACHED_SUCCESS; char return_key[MEMCACHED_MAX_KEY]; @@ -2048,15 +2102,20 @@ static test_return_t fetch_all_results(memcached_st *memc) size_t return_value_length; uint32_t flags; + *keys_returned= 0; + while ((return_value= memcached_fetch(memc, return_key, &return_key_length, &return_value_length, &flags, &rc))) { test_true(return_value); test_true(rc == MEMCACHED_SUCCESS); free(return_value); + *keys_returned= *keys_returned +1; } - return ((rc == MEMCACHED_END) || (rc == MEMCACHED_SUCCESS)) ? TEST_SUCCESS : TEST_FAILURE; + test_true_got(rc == MEMCACHED_END || rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc)); + + return TEST_SUCCESS; } /* Test case provided by Cal Haldenbrand */ @@ -2194,7 +2253,8 @@ static test_return_t user_supplied_bug3(memcached_st *memc) rc= memcached_mget(memc, (const char **)keys, key_lengths, KEY_COUNT); test_true(rc == MEMCACHED_SUCCESS); - test_true(fetch_all_results(memc) == TEST_SUCCESS); + size_t keys_returned; + test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS); for (x= 0; x < KEY_COUNT; x++) free(keys[x]); @@ -2222,7 +2282,7 @@ static test_return_t user_supplied_bug4(memcached_st *memc) /* We need to empty the server before continueing test */ rc= memcached_flush(memc, 0); - test_true(rc == MEMCACHED_NO_SERVERS); + test_compare(rc, MEMCACHED_NO_SERVERS); rc= memcached_mget(memc, keys, key_length, 3); test_true(rc == MEMCACHED_NO_SERVERS); @@ -2232,7 +2292,7 @@ static test_return_t user_supplied_bug4(memcached_st *memc) { test_true(return_value); } - test_true(!return_value); + test_false(return_value); test_true(return_value_length == 0); test_true(rc == MEMCACHED_NO_SERVERS); @@ -2254,7 +2314,7 @@ static test_return_t user_supplied_bug4(memcached_st *memc) test_true(return_value); test_true(rc == MEMCACHED_SUCCESS); test_true(return_key_length == return_value_length); - test_true(!memcmp(return_value, return_key, return_value_length)); + test_memcmp(return_value, return_key, return_value_length); free(return_value); x++; } @@ -2386,7 +2446,7 @@ static test_return_t user_supplied_bug6(memcached_st *memc) return TEST_SUCCESS; } -static test_return_t user_supplied_bug8(memcached_st *memc __attribute__((unused))) +static test_return_t user_supplied_bug8(memcached_st *memc) { memcached_return_t rc; memcached_st *mine; @@ -2395,6 +2455,7 @@ static test_return_t user_supplied_bug8(memcached_st *memc __attribute__((unused memcached_server_st *servers; const char *server_list= "memcache1.memcache.bk.sapo.pt:11211, memcache1.memcache.bk.sapo.pt:11212, memcache1.memcache.bk.sapo.pt:11213, memcache1.memcache.bk.sapo.pt:11214, memcache2.memcache.bk.sapo.pt:11211, memcache2.memcache.bk.sapo.pt:11212, memcache2.memcache.bk.sapo.pt:11213, memcache2.memcache.bk.sapo.pt:11214"; + (void)memc; servers= memcached_servers_parse(server_list); test_true(servers); @@ -2783,7 +2844,7 @@ static test_return_t user_supplied_bug16(memcached_st *memc) return TEST_SUCCESS; } -#ifndef __sun +#if !defined(__sun) && !defined(__OpenBSD__) /* Check the validity of chinese key*/ static test_return_t user_supplied_bug17(memcached_st *memc) { @@ -2911,7 +2972,7 @@ static test_return_t user_supplied_bug18(memcached_st *trash) /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets * us test the boundary wraparound. */ - test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index); + test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index); /* verify the standard ketama set. */ for (x= 0; x < 99; x++) @@ -2939,14 +3000,20 @@ static test_return_t user_supplied_bug18(memcached_st *trash) */ /* sighandler_t function that always asserts false */ -static void fail(int unused __attribute__((unused))) +static void fail(int unused) { + (void)unused; assert(0); } static test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count) { +#ifdef WIN32 + (void)memc; + (void)key_count; + return TEST_SKIPPED; +#else memcached_return_t rc; unsigned int x; char **keys; @@ -2985,7 +3052,8 @@ static test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count) alarm(0); signal(SIGALRM, oldalarm); - test_true(fetch_all_results(memc) == TEST_SUCCESS); + size_t keys_returned; + test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS); for (x= 0; x < key_count; x++) free(keys[x]); @@ -2995,6 +3063,7 @@ static test_return_t _user_supplied_bug21(memcached_st* memc, size_t key_count) memcached_free(memc_clone); return TEST_SUCCESS; +#endif } static test_return_t user_supplied_bug21(memcached_st *memc) @@ -3064,7 +3133,7 @@ static test_return_t auto_eject_hosts(memcached_st *trash) instance= memcached_server_instance_by_position(memc, 2); ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) + 15; - memc->next_distribution_rebuild= time(NULL) - 1; + memc->ketama.next_distribution_rebuild= time(NULL) - 1; /* This would not work if there were only two hosts. @@ -3078,7 +3147,7 @@ static test_return_t auto_eject_hosts(memcached_st *trash) /* and re-added when it's back. */ ((memcached_server_write_instance_st)instance)->next_retry = time(NULL) - 1; - memc->next_distribution_rebuild= time(NULL) - 1; + memc->ketama.next_distribution_rebuild= time(NULL) - 1; memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, memc->distribution); for (size_t x= 0; x < 99; x++) @@ -3139,12 +3208,14 @@ static test_return_t output_ketama_weighted_keys(memcached_st *trash) for (int x= 0; x < 10000; x++) { char key[10]; - sprintf(key, "%d", x); + snprintf(key, sizeof(key), "%d", x); uint32_t server_idx = memcached_generate_hash(memc, key, strlen(key)); char *hostname = memc->hosts[server_idx].hostname; in_port_t port = memc->hosts[server_idx].port; fprintf(fp, "key %s is on host /%s:%u\n", key, hostname, port); + memcached_server_instance_st instance= + memcached_server_instance_by_position(memc, host_index); } fclose(fp); #endif @@ -3187,127 +3258,17 @@ static test_return_t result_alloc(memcached_st *memc) return TEST_SUCCESS; } -static test_return_t string_static_null(memcached_st *memc) -{ - memcached_string_st string; - memcached_string_st *string_ptr; - - string_ptr= memcached_string_create(memc, &string, 0); - test_true(string.options.is_initialized == true); - test_true(string_ptr); - - /* The following two better be the same! */ - test_true(memcached_is_allocated(string_ptr) == false); - test_true(memcached_is_allocated(&string) == false); - test_true(&string == string_ptr); - - test_true(string.options.is_initialized == true); - test_true(memcached_is_initialized(&string) == true); - memcached_string_free(&string); - test_true(memcached_is_initialized(&string) == false); - - return TEST_SUCCESS; -} - -static test_return_t string_alloc_null(memcached_st *memc) -{ - memcached_string_st *string; - - string= memcached_string_create(memc, NULL, 0); - test_true(string); - test_true(memcached_is_allocated(string) == true); - test_true(memcached_is_initialized(string) == true); - memcached_string_free(string); - - return TEST_SUCCESS; -} - -static test_return_t string_alloc_with_size(memcached_st *memc) -{ - memcached_string_st *string; - - string= memcached_string_create(memc, NULL, 1024); - test_true(string); - test_true(memcached_is_allocated(string) == true); - test_true(memcached_is_initialized(string) == true); - memcached_string_free(string); - - return TEST_SUCCESS; -} - -static test_return_t string_alloc_with_size_toobig(memcached_st *memc) -{ - memcached_string_st *string; - - string= memcached_string_create(memc, NULL, SIZE_MAX); - test_true(string == NULL); - - return TEST_SUCCESS; -} - -static test_return_t string_alloc_append(memcached_st *memc) -{ - unsigned int x; - char buffer[SMALL_STRING_LEN]; - memcached_string_st *string; - - /* Ring the bell! */ - memset(buffer, 6, SMALL_STRING_LEN); - - string= memcached_string_create(memc, NULL, 100); - test_true(string); - test_true(memcached_is_allocated(string) == true); - test_true(memcached_is_initialized(string) == true); - - for (x= 0; x < 1024; x++) - { - memcached_return_t rc; - rc= memcached_string_append(string, buffer, SMALL_STRING_LEN); - test_true(rc == MEMCACHED_SUCCESS); - } - test_true(memcached_is_allocated(string) == true); - memcached_string_free(string); - - return TEST_SUCCESS; -} - -static test_return_t string_alloc_append_toobig(memcached_st *memc) -{ - memcached_return_t rc; - unsigned int x; - char buffer[SMALL_STRING_LEN]; - memcached_string_st *string; - - /* Ring the bell! */ - memset(buffer, 6, SMALL_STRING_LEN); - - string= memcached_string_create(memc, NULL, 100); - test_true(string); - test_true(memcached_is_allocated(string) == true); - test_true(memcached_is_initialized(string) == true); - - for (x= 0; x < 1024; x++) - { - rc= memcached_string_append(string, buffer, SMALL_STRING_LEN); - test_true(rc == MEMCACHED_SUCCESS); - } - rc= memcached_string_append(string, buffer, SIZE_MAX); - test_true(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE); - test_true(memcached_is_allocated(string) == true); - memcached_string_free(string); - - return TEST_SUCCESS; -} - -static test_return_t cleanup_pairs(memcached_st *memc __attribute__((unused))) +static test_return_t cleanup_pairs(memcached_st *memc) { + (void)memc; pairs_free(global_pairs); return TEST_SUCCESS; } -static test_return_t generate_pairs(memcached_st *memc __attribute__((unused))) +static test_return_t generate_pairs(memcached_st *memc) { + (void)memc; global_pairs= pairs_generate(GLOBAL_COUNT, 400); global_count= GLOBAL_COUNT; @@ -3320,8 +3281,9 @@ static test_return_t generate_pairs(memcached_st *memc __attribute__((unused))) return TEST_SUCCESS; } -static test_return_t generate_large_pairs(memcached_st *memc __attribute__((unused))) +static test_return_t generate_large_pairs(memcached_st *memc) { + (void)memc; global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10); global_count= GLOBAL2_COUNT; @@ -3336,7 +3298,9 @@ static test_return_t generate_large_pairs(memcached_st *memc __attribute__((unus static test_return_t generate_data(memcached_st *memc) { - execute_set(memc, global_pairs, global_count); + unsigned int check_execute= execute_set(memc, global_pairs, global_count); + + test_true(check_execute == global_count); return TEST_SUCCESS; } @@ -3346,7 +3310,9 @@ static test_return_t generate_data_with_stats(memcached_st *memc) memcached_stat_st *stat_p; memcached_return_t rc; uint32_t host_index= 0; - execute_set(memc, global_pairs, global_count); + unsigned int check_execute= execute_set(memc, global_pairs, global_count); + + test_true(check_execute == global_count); //TODO: hosts used size stats stat_p= memcached_stat(memc, NULL, &rc); @@ -3442,9 +3408,22 @@ static test_return_t mget_read(memcached_st *memc) { memcached_return_t rc; + if (! libmemcached_util_version_check(memc, 1, 4, 4)) + return TEST_SKIPPED; + rc= memcached_mget(memc, global_keys, global_keys_length, global_count); - test_true(rc == MEMCACHED_SUCCESS); - test_true(fetch_all_results(memc) == TEST_SUCCESS); + + test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc)); + + // Go fetch the keys and test to see if all of them were returned + { + size_t keys_returned; + test_true(fetch_all_results(memc, &keys_returned) == TEST_SUCCESS); + char buffer[30]; + snprintf(buffer, sizeof(buffer), "%lu", (unsigned long)keys_returned); + test_true_got(global_count == keys_returned, buffer); + } + return TEST_SUCCESS; } @@ -3453,8 +3432,13 @@ static test_return_t mget_read_result(memcached_st *memc) { memcached_return_t rc; + if (! libmemcached_util_version_check(memc, 1, 4, 4)) + return TEST_SKIPPED; + rc= memcached_mget(memc, global_keys, global_keys_length, global_count); - test_true(rc == MEMCACHED_SUCCESS); + + test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc)); + /* Turn this into a help function */ { memcached_result_st results_obj; @@ -3480,8 +3464,12 @@ static test_return_t mget_read_function(memcached_st *memc) size_t counter; memcached_execute_fn callbacks[1]; + if (! libmemcached_util_version_check(memc, 1, 4, 4)) + return TEST_SKIPPED; + rc= memcached_mget(memc, global_keys, global_keys_length, global_count); - test_true(rc == MEMCACHED_SUCCESS); + + test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc)); callbacks[0]= &callback_counter; counter= 0; @@ -3529,7 +3517,7 @@ static test_return_t add_host_test1(memcached_st *memc) { char buffer[SMALL_STRING_LEN]; - snprintf(buffer, SMALL_STRING_LEN, "%zu.example.com", 400+x); + snprintf(buffer, SMALL_STRING_LEN, "%lu.example.com", (unsigned long)(400 +x)); servers= memcached_server_list_append_with_weight(servers, buffer, 401, 0, &rc); test_true(rc == MEMCACHED_SUCCESS); @@ -3590,7 +3578,6 @@ static test_return_t pre_nonblock_binary(memcached_st *memc) { memcached_return_t rc= MEMCACHED_FAILURE; memcached_st *memc_clone; - memcached_server_instance_st instance; memc_clone= memcached_clone(NULL, memc); test_true(memc_clone); @@ -3598,9 +3585,7 @@ static test_return_t pre_nonblock_binary(memcached_st *memc) // will not toggle protocol on an connection. memcached_version(memc_clone); - instance= memcached_server_instance_by_position(memc_clone, 0); - - if (instance->major_version >= 1 && instance->minor_version > 2) + if (libmemcached_util_version_check(memc_clone, 1, 4, 4)) { memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0); rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1); @@ -3619,9 +3604,13 @@ static test_return_t pre_nonblock_binary(memcached_st *memc) static test_return_t pre_murmur(memcached_st *memc) { +#ifdef HAVE_MURMUR_HASH memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR); - return TEST_SUCCESS; +#else + (void) memc; + return TEST_SKIPPED; +#endif } static test_return_t pre_jenkins(memcached_st *memc) @@ -3725,26 +3714,14 @@ static test_return_t pre_behavior_ketama_weighted(memcached_st *memc) static test_return_t pre_binary(memcached_st *memc) { memcached_return_t rc= MEMCACHED_FAILURE; - memcached_st *memc_clone; - memcached_server_instance_st instance; - - memc_clone= memcached_clone(NULL, memc); - test_true(memc_clone); - // The memcached_version needs to be done on a clone, because the server - // will not toggle protocol on an connection. - memcached_version(memc_clone); - instance= memcached_server_instance_by_position(memc_clone, 0); - - if (instance->major_version >= 1 && instance->minor_version > 2) + if (libmemcached_util_version_check(memc, 1, 4, 4)) { rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1); test_true(rc == MEMCACHED_SUCCESS); test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1); } - memcached_free(memc_clone); - return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED; } @@ -3810,9 +3787,10 @@ static test_return_t pre_replication_noblock(memcached_st *memc) } -static void my_free(const memcached_st *ptr __attribute__((unused)), void *mem, void *context) +static void my_free(const memcached_st *ptr, void *mem, void *context) { - (void) context; + (void)context; + (void)ptr; #ifdef HARD_MALLOC_TESTS void *real_ptr= (mem == NULL) ? mem : (void*)((caddr_t)mem - 8); free(real_ptr); @@ -3822,9 +3800,10 @@ static void my_free(const memcached_st *ptr __attribute__((unused)), void *mem, } -static void *my_malloc(const memcached_st *ptr __attribute__((unused)), const size_t size, void *context) +static void *my_malloc(const memcached_st *ptr, const size_t size, void *context) { (void)context; + (void)ptr; #ifdef HARD_MALLOC_TESTS void *ret= malloc(size + 8); if (ret != NULL) @@ -3844,7 +3823,7 @@ static void *my_malloc(const memcached_st *ptr __attribute__((unused)), const si } -static void *my_realloc(const memcached_st *ptr __attribute__((unused)), void *mem, const size_t size, void *context) +static void *my_realloc(const memcached_st *ptr, void *mem, const size_t size, void *context) { (void)context; #ifdef HARD_MALLOC_TESTS @@ -3859,12 +3838,13 @@ static void *my_realloc(const memcached_st *ptr __attribute__((unused)), void *m return ret; #else + (void)ptr; return realloc(mem, size); #endif } -static void *my_calloc(const memcached_st *ptr __attribute__((unused)), size_t nelem, const size_t size, void *context) +static void *my_calloc(const memcached_st *ptr, size_t nelem, const size_t size, void *context) { (void)context; #ifdef HARD_MALLOC_TESTS @@ -3876,6 +3856,7 @@ static void *my_calloc(const memcached_st *ptr __attribute__((unused)), size_t n return mem; #else + (void)ptr; return calloc(nelem, size); #endif } @@ -3893,9 +3874,10 @@ static test_return_t set_prefix(memcached_st *memc) /* Test a clean set */ rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *)key); - test_true(rc == MEMCACHED_SUCCESS); + test_true_got(rc == MEMCACHED_SUCCESS, memcached_last_error_message(memc)); value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc); + test_true(value); test_true(memcmp(value, key, 4) == 0); test_true(rc == MEMCACHED_SUCCESS); @@ -3904,6 +3886,7 @@ static test_return_t set_prefix(memcached_st *memc) test_true(rc == MEMCACHED_SUCCESS); value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc); + test_false(value); test_true(rc == MEMCACHED_FAILURE); /* Now setup for main test */ @@ -3911,6 +3894,7 @@ static test_return_t set_prefix(memcached_st *memc) test_true(rc == MEMCACHED_SUCCESS); value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc); + test_true(value); test_true(rc == MEMCACHED_SUCCESS); test_true(memcmp(value, key, 4) == 0); @@ -3923,18 +3907,19 @@ static test_return_t set_prefix(memcached_st *memc) test_true(rc == MEMCACHED_SUCCESS); value= memcached_callback_get(memc, MEMCACHED_CALLBACK_PREFIX_KEY, &rc); + test_false(value); test_true(rc == MEMCACHED_FAILURE); test_true(value == NULL); /* Test a long key for failure */ /* TODO, extend test to determine based on setting, what result should be */ - strcpy(long_key, "Thisismorethentheallottednumberofcharacters"); + strncpy(long_key, "Thisismorethentheallottednumberofcharacters", sizeof(long_key)); rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key); //test_true(rc == MEMCACHED_BAD_KEY_PROVIDED); test_true(rc == MEMCACHED_SUCCESS); /* Now test a key with spaces (which will fail from long key, since bad key is not set) */ - strcpy(long_key, "This is more then the allotted number of characters"); + strncpy(long_key, "This is more then the allotted number of characters", sizeof(long_key)); rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key); test_true(rc == MEMCACHED_BAD_KEY_PROVIDED); @@ -3942,7 +3927,7 @@ static test_return_t set_prefix(memcached_st *memc) rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY, 1); test_true(rc == MEMCACHED_SUCCESS); - strcpy(long_key, "dog cat"); + strncpy(long_key, "dog cat", sizeof(long_key)); rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_PREFIX_KEY, long_key); test_true(rc == MEMCACHED_BAD_KEY_PROVIDED); } @@ -4070,13 +4055,7 @@ static test_return_t enable_cas(memcached_st *memc) { unsigned int set= 1; - memcached_server_instance_st instance= - memcached_server_instance_by_position(memc, 0); - - memcached_version(memc); - - if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4)) - || instance->minor_version > 2) + if (libmemcached_util_version_check(memc, 1, 2, 4)) { memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set); @@ -4095,7 +4074,9 @@ static test_return_t check_for_1_2_3(memcached_st *memc) if ((instance->major_version >= 1 && (instance->minor_version == 2 && instance->micro_version >= 4)) || instance->minor_version > 2) + { return TEST_SUCCESS; + } return TEST_SKIPPED; } @@ -4164,7 +4145,11 @@ static test_return_t noreply_test(memcached_st *memc) for (size_t x= 0; x < 100; ++x) { char key[10]; - size_t len= (size_t)sprintf(key, "%zu", x); + int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x); + test_false((size_t)check_length >= sizeof(key) || check_length < 0); + + size_t len= (size_t)check_length; + switch (count) { case 0: @@ -4212,7 +4197,11 @@ static test_return_t noreply_test(memcached_st *memc) { char key[10]; - size_t len= (size_t)sprintf(key, "%zu", x); + int check_length= (size_t)snprintf(key, sizeof(key), "%lu", (unsigned long)x); + + test_false((size_t)check_length >= sizeof(key) || check_length < 0); + + size_t len= (size_t)check_length; size_t length; uint32_t flags; char* value=memcached_get(memc, key, strlen(key), @@ -4298,11 +4287,12 @@ static test_return_t analyzer_test(memcached_st *memc) } /* Count the objects */ -static memcached_return_t callback_dump_counter(const memcached_st *ptr __attribute__((unused)), - const char *key __attribute__((unused)), - size_t key_length __attribute__((unused)), +static memcached_return_t callback_dump_counter(const memcached_st *ptr, + const char *key, + size_t key_length, void *context) { + (void)ptr; (void)key; (void)key_length; size_t *counter= (size_t *)context; *counter= *counter + 1; @@ -4345,24 +4335,28 @@ static void* connection_release(void *arg) } *resource= arg; usleep(250); + // Release all of the memc we are holding assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS); return arg; } +#define POOL_SIZE 10 static test_return_t connection_pool_test(memcached_st *memc) { - memcached_pool_st* pool= memcached_pool_create(memc, 5, 10); + memcached_pool_st* pool= memcached_pool_create(memc, 5, POOL_SIZE); test_true(pool != NULL); - memcached_st* mmc[10]; + memcached_st *mmc[POOL_SIZE]; memcached_return_t rc; - for (size_t x= 0; x < 10; ++x) + // Fill up our array that we will store the memc that are in the pool + for (size_t x= 0; x < POOL_SIZE; ++x) { mmc[x]= memcached_pool_pop(pool, false, &rc); test_true(mmc[x] != NULL); test_true(rc == MEMCACHED_SUCCESS); } + // All memc should be gone test_true(memcached_pool_pop(pool, false, &rc) == NULL); test_true(rc == MEMCACHED_SUCCESS); @@ -4371,11 +4365,12 @@ static test_return_t connection_pool_test(memcached_st *memc) memcached_pool_st* pool; memcached_st* mmc; } item= { .pool = pool, .mmc = mmc[9] }; + pthread_create(&tid, NULL, connection_release, &item); mmc[9]= memcached_pool_pop(pool, true, &rc); test_true(rc == MEMCACHED_SUCCESS); pthread_join(tid, NULL); - test_true(mmc[9] == item.mmc); + test_true(mmc[9]); const char *key= "key"; size_t keylen= strlen(key); @@ -4383,7 +4378,7 @@ static test_return_t connection_pool_test(memcached_st *memc) rc= memcached_set(mmc[0], key, keylen, "0", 1, 0, 0); test_true(rc == MEMCACHED_SUCCESS); - for (size_t x= 0; x < 10; ++x) + for (size_t x= 0; x < POOL_SIZE; ++x) { uint64_t number_value; rc= memcached_increment(mmc[x], key, keylen, 1, &number_value); @@ -4392,7 +4387,7 @@ static test_return_t connection_pool_test(memcached_st *memc) } // Release them.. - for (size_t x= 0; x < 10; ++x) + for (size_t x= 0; x < POOL_SIZE; ++x) { test_true(memcached_pool_push(pool, mmc[x]) == MEMCACHED_SUCCESS); } @@ -4419,265 +4414,82 @@ static test_return_t connection_pool_test(memcached_st *memc) test_true(memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == 9999); test_true(memcached_pool_push(pool, mmc[0]) == MEMCACHED_SUCCESS); - test_true(memcached_pool_destroy(pool) == memc); + return TEST_SUCCESS; } -#endif -static test_return_t replication_set_test(memcached_st *memc) +static test_return_t util_version_test(memcached_st *memc) { - memcached_return_t rc; - memcached_st *memc_clone= memcached_clone(NULL, memc); - memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0); + bool if_successful; - rc= memcached_set(memc, "bubba", 5, "0", 1, 0, 0); - test_true(rc == MEMCACHED_SUCCESS); + if_successful= libmemcached_util_version_check(memc, 0, 0, 0); + test_true(if_successful == true); - /* - ** We are using the quiet commands to store the replicas, so we need - ** to ensure that all of them are processed before we can continue. - ** In the test we go directly from storing the object to trying to - ** receive the object from all of the different servers, so we - ** could end up in a race condition (the memcached server hasn't yet - ** processed the quiet command from the replication set when it process - ** the request from the other client (created by the clone)). As a - ** workaround for that we call memcached_quit to send the quit command - ** to the server and wait for the response ;-) If you use the test code - ** as an example for your own code, please note that you shouldn't need - ** to do this ;-) - */ - memcached_quit(memc); + if_successful= libmemcached_util_version_check(memc, 9, 9, 9); - /* - ** "bubba" should now be stored on all of our servers. We don't have an - ** easy to use API to address each individual server, so I'll just iterate - ** through a bunch of "master keys" and I should most likely hit all of the - ** servers... - */ - for (int x= 'a'; x <= 'z'; ++x) + // We expect failure + if (if_successful) { - char key[2]= { [0]= (char)x }; - size_t len; - uint32_t flags; - char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5, - &len, &flags, &rc); - test_true(rc == MEMCACHED_SUCCESS); - test_true(val != NULL); - free(val); + fprintf(stderr, "\n----------------------------------------------------------------------\n"); + fprintf(stderr, "\nDumping Server Information\n\n"); + memcached_server_fn callbacks[1]; + + callbacks[0]= dump_server_information; + memcached_server_cursor(memc, callbacks, (void *)stderr, 1); + fprintf(stderr, "\n----------------------------------------------------------------------\n"); } + test_true(if_successful == false); - memcached_free(memc_clone); + memcached_server_instance_st instance= + memcached_server_instance_by_position(memc, 0); - return TEST_SUCCESS; -} + memcached_version(memc); -static test_return_t replication_get_test(memcached_st *memc) -{ - memcached_return_t rc; + // We only use one binary when we test, so this should be just fine. + if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version); + test_true(if_successful == true); - /* - * Don't do the following in your code. I am abusing the internal details - * within the library, and this is not a supported interface. - * This is to verify correct behavior in the library - */ - for (uint32_t host= 0; host < memcached_server_count(memc); ++host) - { - memcached_st *memc_clone= memcached_clone(NULL, memc); - memcached_server_instance_st instance= - memcached_server_instance_by_position(memc_clone, host); + if (instance->micro_version > 0) + if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version -1)); + else if (instance->minor_version > 0) + if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version - 1), instance->micro_version); + else if (instance->major_version > 0) + if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version -1), instance->minor_version, instance->micro_version); - ((memcached_server_write_instance_st)instance)->port= 0; + test_true(if_successful == true); - for (int x= 'a'; x <= 'z'; ++x) - { - char key[2]= { [0]= (char)x }; - size_t len; - uint32_t flags; - char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5, - &len, &flags, &rc); - test_true(rc == MEMCACHED_SUCCESS); - test_true(val != NULL); - free(val); - } + if (instance->micro_version > 0) + if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, (uint8_t)(instance->micro_version +1)); + else if (instance->minor_version > 0) + if_successful= libmemcached_util_version_check(memc, instance->major_version, (uint8_t)(instance->minor_version +1), instance->micro_version); + else if (instance->major_version > 0) + if_successful= libmemcached_util_version_check(memc, (uint8_t)(instance->major_version +1), instance->minor_version, instance->micro_version); - memcached_free(memc_clone); - } + test_true(if_successful == false); return TEST_SUCCESS; } -static test_return_t replication_mget_test(memcached_st *memc) +static test_return_t ping_test(memcached_st *memc) { memcached_return_t rc; - memcached_st *memc_clone= memcached_clone(NULL, memc); - memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0); + memcached_server_instance_st instance= + memcached_server_instance_by_position(memc, 0); - const char *keys[]= { "bubba", "key1", "key2", "key3" }; - size_t len[]= { 5, 4, 4, 4 }; + // Test both the version that returns a code, and the one that does not. + test_true(libmemcached_util_ping(memcached_server_name(instance), + memcached_server_port(instance), NULL)); - for (size_t x= 0; x< 4; ++x) - { - rc= memcached_set(memc, keys[x], len[x], "0", 1, 0, 0); - test_true(rc == MEMCACHED_SUCCESS); - } + test_true(libmemcached_util_ping(memcached_server_name(instance), + memcached_server_port(instance), &rc)); - /* - ** We are using the quiet commands to store the replicas, so we need - ** to ensure that all of them are processed before we can continue. - ** In the test we go directly from storing the object to trying to - ** receive the object from all of the different servers, so we - ** could end up in a race condition (the memcached server hasn't yet - ** processed the quiet command from the replication set when it process - ** the request from the other client (created by the clone)). As a - ** workaround for that we call memcached_quit to send the quit command - ** to the server and wait for the response ;-) If you use the test code - ** as an example for your own code, please note that you shouldn't need - ** to do this ;-) - */ - memcached_quit(memc); - - /* - * Don't do the following in your code. I am abusing the internal details - * within the library, and this is not a supported interface. - * This is to verify correct behavior in the library - */ - memcached_result_st result_obj; - for (uint32_t host= 0; host < memc_clone->number_of_hosts; host++) - { - memcached_st *new_clone= memcached_clone(NULL, memc); - memcached_server_instance_st instance= - memcached_server_instance_by_position(new_clone, host); - ((memcached_server_write_instance_st)instance)->port= 0; - - for (int x= 'a'; x <= 'z'; ++x) - { - char key[2]= { [0]= (char)x, [1]= 0 }; - - rc= memcached_mget_by_key(new_clone, key, 1, keys, len, 4); - test_true(rc == MEMCACHED_SUCCESS); - - memcached_result_st *results= memcached_result_create(new_clone, &result_obj); - test_true(results); - - int hits= 0; - while ((results= memcached_fetch_result(new_clone, &result_obj, &rc)) != NULL) - { - hits++; - } - test_true(hits == 4); - memcached_result_free(&result_obj); - } - - memcached_free(new_clone); - } - - memcached_free(memc_clone); - - return TEST_SUCCESS; -} - -static test_return_t replication_randomize_mget_test(memcached_st *memc) -{ - memcached_result_st result_obj; - memcached_return_t rc; - memcached_st *memc_clone= memcached_clone(NULL, memc); - memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 3); - memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, 1); - - const char *keys[]= { "key1", "key2", "key3", "key4", "key5", "key6", "key7" }; - size_t len[]= { 4, 4, 4, 4, 4, 4, 4 }; - - for (size_t x= 0; x< 7; ++x) - { - rc= memcached_set(memc, keys[x], len[x], "1", 1, 0, 0); - test_true(rc == MEMCACHED_SUCCESS); - } - - memcached_quit(memc); - - for (size_t x= 0; x< 7; ++x) - { - const char key[2]= { [0]= (const char)x }; - - rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 7); - test_true(rc == MEMCACHED_SUCCESS); - - memcached_result_st *results= memcached_result_create(memc_clone, &result_obj); - test_true(results); + test_true(rc == MEMCACHED_SUCCESS); - int hits= 0; - while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL) - { - ++hits; - } - test_true(hits == 7); - memcached_result_free(&result_obj); - } - memcached_free(memc_clone); return TEST_SUCCESS; } +#endif -static test_return_t replication_delete_test(memcached_st *memc) -{ - memcached_return_t rc; - memcached_st *memc_clone= memcached_clone(NULL, memc); - /* Delete the items from all of the servers except 1 */ - uint64_t repl= memcached_behavior_get(memc, - MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS); - memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, --repl); - - const char *keys[]= { "bubba", "key1", "key2", "key3" }; - size_t len[]= { 5, 4, 4, 4 }; - - for (size_t x= 0; x< 4; ++x) - { - rc= memcached_delete_by_key(memc, keys[0], len[0], keys[x], len[x], 0); - test_true(rc == MEMCACHED_SUCCESS); - } - - /* - * Don't do the following in your code. I am abusing the internal details - * within the library, and this is not a supported interface. - * This is to verify correct behavior in the library - */ - uint32_t hash= memcached_generate_hash(memc, keys[0], len[0]); - for (uint32_t x= 0; x < (repl + 1); ++x) - { - memcached_server_instance_st instance= - memcached_server_instance_by_position(memc_clone, x); - - ((memcached_server_write_instance_st)instance)->port= 0; - if (++hash == memc_clone->number_of_hosts) - hash= 0; - } - - memcached_result_st result_obj; - for (uint32_t host= 0; host < memc_clone->number_of_hosts; ++host) - { - for (size_t x= 'a'; x <= 'z'; ++x) - { - const char key[2]= { [0]= (const char)x }; - - rc= memcached_mget_by_key(memc_clone, key, 1, keys, len, 4); - test_true(rc == MEMCACHED_SUCCESS); - - memcached_result_st *results= memcached_result_create(memc_clone, &result_obj); - test_true(results); - - int hits= 0; - while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL) - { - ++hits; - } - test_true(hits == 4); - memcached_result_free(&result_obj); - } - } - memcached_free(memc_clone); - - return TEST_SUCCESS; -} #if 0 static test_return_t hash_sanity_test (memcached_st *memc) @@ -4704,7 +4516,7 @@ static test_return_t hash_sanity_test (memcached_st *memc) static test_return_t hsieh_avaibility_test (memcached_st *memc) { - memcached_return_t expected_rc= MEMCACHED_FAILURE; + memcached_return_t expected_rc= MEMCACHED_INVALID_ARGUMENTS; #ifdef HAVE_HSIEH_HASH expected_rc= MEMCACHED_SUCCESS; #endif @@ -4715,10 +4527,24 @@ static test_return_t hsieh_avaibility_test (memcached_st *memc) return TEST_SUCCESS; } -static test_return_t one_at_a_time_run (memcached_st *memc __attribute__((unused))) +static test_return_t murmur_avaibility_test (memcached_st *memc) +{ + memcached_return_t expected_rc= MEMCACHED_INVALID_ARGUMENTS; +#ifdef HAVE_MURMUR_HASH + expected_rc= MEMCACHED_SUCCESS; +#endif + memcached_return_t rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, + (uint64_t)MEMCACHED_HASH_MURMUR); + test_true(rc == expected_rc); + + return TEST_SUCCESS; +} + +static test_return_t one_at_a_time_run (memcached_st *memc) { uint32_t x; const char **ptr; + (void)memc; for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) { @@ -4731,10 +4557,11 @@ static test_return_t one_at_a_time_run (memcached_st *memc __attribute__((unused return TEST_SUCCESS; } -static test_return_t md5_run (memcached_st *memc __attribute__((unused))) +static test_return_t md5_run (memcached_st *memc) { uint32_t x; const char **ptr; + (void)memc; for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) { @@ -4747,10 +4574,11 @@ static test_return_t md5_run (memcached_st *memc __attribute__((unused))) return TEST_SUCCESS; } -static test_return_t crc_run (memcached_st *memc __attribute__((unused))) +static test_return_t crc_run (memcached_st *memc) { uint32_t x; const char **ptr; + (void)memc; for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) { @@ -4763,10 +4591,11 @@ static test_return_t crc_run (memcached_st *memc __attribute__((unused))) return TEST_SUCCESS; } -static test_return_t fnv1_64_run (memcached_st *memc __attribute__((unused))) +static test_return_t fnv1_64_run (memcached_st *memc) { uint32_t x; const char **ptr; + (void)memc; for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) { @@ -4779,10 +4608,11 @@ static test_return_t fnv1_64_run (memcached_st *memc __attribute__((unused))) return TEST_SUCCESS; } -static test_return_t fnv1a_64_run (memcached_st *memc __attribute__((unused))) +static test_return_t fnv1a_64_run (memcached_st *memc) { uint32_t x; const char **ptr; + (void)memc; for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) { @@ -4795,11 +4625,11 @@ static test_return_t fnv1a_64_run (memcached_st *memc __attribute__((unused))) return TEST_SUCCESS; } -static test_return_t fnv1_32_run (memcached_st *memc __attribute__((unused))) +static test_return_t fnv1_32_run (memcached_st *memc) { uint32_t x; const char **ptr; - + (void)memc; for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) { @@ -4812,10 +4642,11 @@ static test_return_t fnv1_32_run (memcached_st *memc __attribute__((unused))) return TEST_SUCCESS; } -static test_return_t fnv1a_32_run (memcached_st *memc __attribute__((unused))) +static test_return_t fnv1a_32_run (memcached_st *memc) { uint32_t x; const char **ptr; + (void)memc; for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) { @@ -4828,10 +4659,11 @@ static test_return_t fnv1a_32_run (memcached_st *memc __attribute__((unused))) return TEST_SUCCESS; } -static test_return_t hsieh_run (memcached_st *memc __attribute__((unused))) +static test_return_t hsieh_run (memcached_st *memc) { uint32_t x; const char **ptr; + (void)memc; for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) { @@ -4844,13 +4676,15 @@ static test_return_t hsieh_run (memcached_st *memc __attribute__((unused))) return TEST_SUCCESS; } -static test_return_t murmur_run (memcached_st *memc __attribute__((unused))) +static test_return_t murmur_run (memcached_st *memc) { #ifdef WORDS_BIGENDIAN + (void)murmur_values; return TEST_SKIPPED; #else uint32_t x; const char **ptr; + (void)memc; for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) { @@ -4864,11 +4698,11 @@ static test_return_t murmur_run (memcached_st *memc __attribute__((unused))) #endif } -static test_return_t jenkins_run (memcached_st *memc __attribute__((unused))) +static test_return_t jenkins_run (memcached_st *memc) { uint32_t x; const char **ptr; - + (void)memc; for (ptr= list_to_hash, x= 0; *ptr; ptr++, x++) { @@ -4963,12 +4797,12 @@ static test_return_t memcached_get_hashkit_test (memcached_st *memc) } /* - Test case adapted from John Gorman + Test case adapted from John Gorman - We are testing the error condition when we connect to a server via memcached_get() + We are testing the error condition when we connect to a server via memcached_get() but find that the server is not available. */ -static test_return_t memcached_get_MEMCACHED_SOME_ERRORS(memcached_st *memc) +static test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *memc) { (void)memc; memcached_st *tl_memc_h; @@ -4982,26 +4816,23 @@ static test_return_t memcached_get_MEMCACHED_SOME_ERRORS(memcached_st *memc) // Create a handle. tl_memc_h= memcached_create(NULL); - servers= memcached_servers_parse("localhost:9898"); // This server should not exist + servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist memcached_server_push(tl_memc_h, servers); memcached_server_list_free(servers); // See if memcached is reachable. value= memcached_get(tl_memc_h, key, strlen(key), &len, &flags, &rc); - if (value) - { - free(value); - test_true(value); // Pointer won't be zero so this is fine. - } - + test_false(value); test_true(len == 0); - test_true(rc == MEMCACHED_SOME_ERRORS); + test_false(rc == MEMCACHED_SUCCESS); + + memcached_free(tl_memc_h); return TEST_SUCCESS; } -/* +/* We connect to a server which exists, but search for a key that does not exist. */ static test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc) @@ -5015,12 +4846,64 @@ static test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc) // See if memcached is reachable. value= memcached_get(memc, key, strlen(key), &len, &flags, &rc); - if (value) - { - free(value); - test_true(value); // Pointer won't be zero so this is fine. - } + test_false(value); + test_true(len == 0); + test_true(rc == MEMCACHED_NOTFOUND); + return TEST_SUCCESS; +} + +/* + Test case adapted from John Gorman + + We are testing the error condition when we connect to a server via memcached_get_by_key() + but find that the server is not available. +*/ +static test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *memc) +{ + (void)memc; + memcached_st *tl_memc_h; + memcached_server_st *servers; + + const char *key= "MemcachedLives"; + size_t len; + uint32_t flags; + memcached_return rc; + char *value; + + // Create a handle. + tl_memc_h= memcached_create(NULL); + servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist + memcached_server_push(tl_memc_h, servers); + memcached_server_list_free(servers); + + // See if memcached is reachable. + value= memcached_get_by_key(tl_memc_h, key, strlen(key), key, strlen(key), &len, &flags, &rc); + + test_false(value); + test_true(len == 0); + test_false(rc == MEMCACHED_SUCCESS); + + memcached_free(tl_memc_h); + + return TEST_SUCCESS; +} + +/* + We connect to a server which exists, but search for a key that does not exist. +*/ +static test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc) +{ + const char *key= "MemcachedKeyNotEXIST"; + size_t len; + uint32_t flags; + memcached_return rc; + char *value; + + // See if memcached is reachable. + value= memcached_get_by_key(memc, key, strlen(key), key, strlen(key), &len, &flags, &rc); + + test_false(value); test_true(len == 0); test_true(rc == MEMCACHED_NOTFOUND); @@ -5069,7 +4952,7 @@ static test_return_t ketama_compatibility_libmemcached(memcached_st *trash) /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets * us test the boundary wraparound. */ - test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index); + test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index); /* verify the standard ketama set. */ for (x= 0; x < 99; x++) @@ -5092,7 +4975,6 @@ static test_return_t ketama_compatibility_spymemcached(memcached_st *trash) { memcached_return_t rc; uint64_t value; - int x; memcached_server_st *server_pool; memcached_st *memc; @@ -5111,6 +4993,7 @@ static test_return_t ketama_compatibility_spymemcached(memcached_st *trash) test_true(memcached_behavior_get_distribution(memc) == MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA_SPY); server_pool = memcached_servers_parse("10.0.1.1:11211 600,10.0.1.2:11211 300,10.0.1.3:11211 200,10.0.1.4:11211 350,10.0.1.5:11211 1000,10.0.1.6:11211 800,10.0.1.7:11211 950,10.0.1.8:11211 100"); + assert(server_pool); memcached_server_push(memc, server_pool); /* verify that the server list was parsed okay. */ @@ -5128,10 +5011,10 @@ static test_return_t ketama_compatibility_spymemcached(memcached_st *trash) /* VDEAAAAA hashes to fffcd1b5, after the last continuum point, and lets * us test the boundary wraparound. */ - test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->continuum[0].index); + test_true(memcached_generate_hash(memc, (char *)"VDEAAAAA", 8) == memc->ketama.continuum[0].index); /* verify the standard ketama set. */ - for (x= 0; x < 99; x++) + for (uint32_t x= 0; x < 99; x++) { uint32_t server_idx= memcached_generate_hash(memc, ketama_test_cases_spy[x].key, strlen(ketama_test_cases_spy[x].key)); @@ -5202,7 +5085,7 @@ static test_return_t regression_bug_434843(memcached_st *memc) { char k[251]; - key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x); + key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x); keys[x]= strdup(k); test_true(keys[x] != NULL); } @@ -5343,7 +5226,7 @@ static test_return_t regression_bug_447342(memcached_st *memc) memcached_server_instance_st instance_one; memcached_server_instance_st instance_two; - if (memcached_server_count(memc) < 3 || pre_replication(memc) != MEMCACHED_SUCCESS) + if (memcached_server_count(memc) < 3 || pre_replication(memc) != TEST_SUCCESS) return TEST_SKIPPED; memcached_return_t rc; @@ -5359,7 +5242,7 @@ static test_return_t regression_bug_447342(memcached_st *memc) { char k[251]; - key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x); + key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x); keys[x]= strdup(k); test_true(keys[x] != NULL); rc= memcached_set(memc, k, key_length[x], k, key_length[x], 0, 0); @@ -5471,47 +5354,47 @@ static test_return_t regression_bug_463297(memcached_st *memc) (instance->major_version == 1 && instance->minor_version > 2)) { - /* Binary protocol doesn't support deferred delete */ - memcached_st *bin_clone= memcached_clone(NULL, memc); - test_true(bin_clone != NULL); - test_true(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS); - test_true(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS); - memcached_free(bin_clone); + /* Binary protocol doesn't support deferred delete */ + memcached_st *bin_clone= memcached_clone(NULL, memc); + test_true(bin_clone != NULL); + test_true(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS); + test_true(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS); + memcached_free(bin_clone); - memcached_quit(memc_clone); + memcached_quit(memc_clone); - /* If we know the server version, deferred delete should fail - * with invalid arguments */ - test_true(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS); + /* If we know the server version, deferred delete should fail + * with invalid arguments */ + test_true(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS); - /* If we don't know the server version, we should get a protocol error */ - memcached_return_t rc= memcached_delete(memc, "foo", 3, 1); + /* If we don't know the server version, we should get a protocol error */ + memcached_return_t rc= memcached_delete(memc, "foo", 3, 1); - /* but there is a bug in some of the memcached servers (1.4) that treats - * the counter as noreply so it doesn't send the proper error message - */ - test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR); + /* but there is a bug in some of the memcached servers (1.4) that treats + * the counter as noreply so it doesn't send the proper error message + */ + test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc)); - /* And buffered mode should be disabled and we should get protocol error */ - test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS); - rc= memcached_delete(memc, "foo", 3, 1); - test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR); + /* And buffered mode should be disabled and we should get protocol error */ + test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS); + rc= memcached_delete(memc, "foo", 3, 1); + test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc)); - /* Same goes for noreply... */ - test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS); - rc= memcached_delete(memc, "foo", 3, 1); - test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR); + /* Same goes for noreply... */ + test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS); + rc= memcached_delete(memc, "foo", 3, 1); + test_true_got(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR || rc == MEMCACHED_INVALID_ARGUMENTS, memcached_strerror(NULL, rc)); - /* but a normal request should go through (and be buffered) */ - test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED); - test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS); + /* but a normal request should go through (and be buffered) */ + test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED); + test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS); - test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS); - /* unbuffered noreply should be success */ - test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS); - /* unbuffered with reply should be not found... */ - test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS); - test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND); + test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS); + /* unbuffered noreply should be success */ + test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS); + /* unbuffered with reply should be not found... */ + test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS); + test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND); } memcached_free(memc_clone); @@ -5624,7 +5507,7 @@ static test_return_t test_cull_servers(memcached_st *memc) uint32_t count = memcached_server_count(memc); // Do not do this in your code, it is not supported. - memc->servers[1].state.is_dead= true; + memc->servers[1].options.is_dead= true; memc->state.is_time_for_rebuild= true; uint32_t new_count= memcached_server_count(memc); @@ -5637,6 +5520,39 @@ static test_return_t test_cull_servers(memcached_st *memc) return TEST_SUCCESS; } + +static memcached_return_t stat_printer(memcached_server_instance_st server, + const char *key, size_t key_length, + const char *value, size_t value_length, + void *context) +{ + (void)server; + (void)context; + (void)key; + (void)key_length; + (void)value; + (void)value_length; + + return MEMCACHED_SUCCESS; +} + +static test_return_t memcached_stat_execute_test(memcached_st *memc) +{ + memcached_return_t rc= memcached_stat_execute(memc, NULL, stat_printer, NULL); + test_true(rc == MEMCACHED_SUCCESS); + + rc= memcached_stat_execute(memc, "slabs", stat_printer, NULL); + test_true(rc == MEMCACHED_SUCCESS); + + rc= memcached_stat_execute(memc, "items", stat_printer, NULL); + test_true(rc == MEMCACHED_SUCCESS); + + rc= memcached_stat_execute(memc, "sizes", stat_printer, NULL); + test_true(rc == MEMCACHED_SUCCESS); + + return TEST_SUCCESS; +} + /* * This test ensures that the failure counter isn't incremented during * normal termination of the memcached instance. @@ -5686,6 +5602,56 @@ static test_return_t wrong_failure_counter_test(memcached_st *memc) return TEST_SUCCESS; } +/* + * This tests ensures expected disconnections (for some behavior changes + * for instance) do not wrongly increase failure counter + */ +static test_return_t wrong_failure_counter_two_test(memcached_st *memc) +{ + memcached_return rc; + + memcached_st *memc_clone; + memc_clone= memcached_clone(NULL, memc); + test_true(memc_clone); + + /* Set value to force connection to the server */ + const char *key= "marmotte"; + const char *value= "milka"; + char *string = NULL; + size_t string_length; + uint32_t flags; + + rc= memcached_set(memc_clone, key, strlen(key), + value, strlen(value), + (time_t)0, (uint32_t)0); + test_true_got(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc)); + + + /* put failure limit to 1 */ + rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 1); + assert(rc == MEMCACHED_SUCCESS); + + /* Put a retry timeout to effectively activate failure_limit effect */ + rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1); + assert(rc == MEMCACHED_SUCCESS); + + /* change behavior that triggers memcached_quit()*/ + rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1); + assert(rc == MEMCACHED_SUCCESS); + + + /* Check if we still are connected */ + string= memcached_get(memc_clone, key, strlen(key), + &string_length, &flags, &rc); + + test_true_got(rc == MEMCACHED_SUCCESS, memcached_strerror(NULL, rc)); + test_true(string); + free(string); + memcached_free(memc_clone); + + return TEST_SUCCESS; +} + @@ -5723,7 +5689,7 @@ static test_return_t regression_bug_490486(memcached_st *memc) for (size_t x= 0; x < max_keys; ++x) { char k[251]; - key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%zu", x); + key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x); keys[x]= strdup(k); assert(keys[x] != NULL); rc= memcached_set(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0); @@ -5795,6 +5761,48 @@ static test_return_t regression_bug_490486(memcached_st *memc) return TEST_SUCCESS; } +static test_return_t regression_bug_583031(memcached_st *unused) +{ + (void)unused; + + memcached_st *memc= memcached_create(NULL); + assert(memc); + memcached_server_add(memc, "10.2.3.4", 11211); + + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 1000); + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 1000); + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SND_TIMEOUT, 1000); + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 1000); + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000); + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT, 3); + + memcached_return_t rc; + size_t length; + uint32_t flags; + + (void)memcached_get(memc, "dsf", 3, &length, &flags, &rc); + + test_true_got(rc == MEMCACHED_TIMEOUT || rc == MEMCACHED_ERRNO || rc == MEMCACHED_FAILURE, memcached_strerror(memc, rc)); + + memcached_free(memc); + + return TEST_SUCCESS; +} + +static test_return_t regression_bug_581030(memcached_st *unused) +{ + (void)unused; + +#ifndef DEBUG + memcached_stat_st *local_stat= memcached_stat(NULL, NULL, NULL); + test_false(local_stat); + + memcached_stat_free(NULL, NULL); +#endif + + return TEST_SUCCESS; +} + static void memcached_die(memcached_st* mc, memcached_return error, const char* what, uint32_t it) { fprintf(stderr, "Iteration #%u: ", it); @@ -5823,7 +5831,7 @@ static test_return_t regression_bug_(memcached_st *memc) return TEST_SKIPPED; } - for (uint32_t x= 0; x < TEST_CONSTANT_CREATION; x++) + for (uint32_t x= 0; x < TEST_CONSTANT_CREATION; x++) { memcached_st* mc= memcached_create(NULL); memcached_return rc; @@ -5853,7 +5861,7 @@ static test_return_t regression_bug_(memcached_st *memc) if (rc == MEMCACHED_SUCCESS) { - if (x > 0) + if (x > 0) { size_t get_value_len; char *get_value; @@ -5941,6 +5949,7 @@ static test_return_t sasl_auth_test(memcached_st *memc) /* Clean the server before beginning testing */ test_st tests[] ={ + {"util_version", 1, (test_callback_fn)util_version_test }, {"flush", 0, (test_callback_fn)flush_test }, {"init", 0, (test_callback_fn)init_test }, {"allocation", 0, (test_callback_fn)allocation_test }, @@ -5993,13 +6002,14 @@ test_st tests[] ={ {"delete_through", 1, (test_callback_fn)delete_through }, {"noreply", 1, (test_callback_fn)noreply_test}, {"analyzer", 1, (test_callback_fn)analyzer_test}, -#ifdef HAVE_LIBMEMCACHEDUTIL {"connectionpool", 1, (test_callback_fn)connection_pool_test }, -#endif + {"memcached_pool_test", 1, (test_callback_fn)memcached_pool_test }, + {"ping", 1, (test_callback_fn)ping_test }, {"test_get_last_disconnect", 1, (test_callback_fn)test_get_last_disconnect}, {"verbosity", 1, (test_callback_fn)test_verbosity}, {"test_server_failure", 1, (test_callback_fn)test_server_failure}, {"cull_servers", 1, (test_callback_fn)test_cull_servers}, + {"memcached_stat_execute", 1, (test_callback_fn)memcached_stat_execute_test}, {0, 0, 0} }; @@ -6011,6 +6021,16 @@ test_st behavior_tests[] ={ {0, 0, 0} }; +test_st basic_tests[] ={ + {"init", 1, (test_callback_fn)basic_init_test}, + {"clone", 1, (test_callback_fn)basic_clone_test}, + {"reset", 1, (test_callback_fn)basic_reset_stack_test}, + {"reset heap", 1, (test_callback_fn)basic_reset_heap_test}, + {"reset stack clone", 1, (test_callback_fn)basic_reset_stack_clone_test}, + {"reset heap clone", 1, (test_callback_fn)basic_reset_heap_clone_test}, + {0, 0, 0} +}; + test_st regression_binary_vs_block[] ={ {"block add", 1, (test_callback_fn)block_add_regression}, {"binary add", 1, (test_callback_fn)binary_add_regression}, @@ -6029,6 +6049,7 @@ test_st string_tests[] ={ {"string alloc with malloc failure", 0, (test_callback_fn)string_alloc_with_size_toobig }, {"string append", 0, (test_callback_fn)string_alloc_append }, {"string append failure (too big)", 0, (test_callback_fn)string_alloc_append_toobig }, + {"string_alloc_append_multiple", 0, (test_callback_fn)string_alloc_append_multiple }, {0, 0, (test_callback_fn)0} }; @@ -6064,7 +6085,7 @@ test_st user_tests[] ={ {"user_supplied_bug14", 1, (test_callback_fn)user_supplied_bug14 }, {"user_supplied_bug15", 1, (test_callback_fn)user_supplied_bug15 }, {"user_supplied_bug16", 1, (test_callback_fn)user_supplied_bug16 }, -#ifndef __sun +#if !defined(__sun) && !defined(__OpenBSD__) /* ** It seems to be something weird with the character sets.. ** value_fetch is unable to parse the value line (iscntrl "fails"), so I @@ -6079,6 +6100,7 @@ test_st user_tests[] ={ {"user_supplied_bug20", 1, (test_callback_fn)user_supplied_bug20 }, {"user_supplied_bug21", 1, (test_callback_fn)user_supplied_bug21 }, {"wrong_failure_counter_test", 1, (test_callback_fn)wrong_failure_counter_test}, + {"wrong_failure_counter_two_test", 1, (test_callback_fn)wrong_failure_counter_two_test}, {0, 0, (test_callback_fn)0} }; @@ -6106,7 +6128,10 @@ test_st regression_tests[]= { {"lp:447342", 1, (test_callback_fn)regression_bug_447342 }, {"lp:463297", 1, (test_callback_fn)regression_bug_463297 }, {"lp:490486", 1, (test_callback_fn)regression_bug_490486 }, + {"lp:583031", 1, (test_callback_fn)regression_bug_583031 }, {"lp:?", 1, (test_callback_fn)regression_bug_ }, + {"lp:728286", 1, (test_callback_fn)regression_bug_728286 }, + {"lp:581030", 1, (test_callback_fn)regression_bug_581030 }, {0, 0, (test_callback_fn)0} }; @@ -6161,6 +6186,11 @@ test_st hsieh_availability[] ={ {0, 0, (test_callback_fn)0} }; +test_st murmur_availability[] ={ + {"murmur_avaibility_test", 0, (test_callback_fn)murmur_avaibility_test}, + {0, 0, (test_callback_fn)0} +}; + #if 0 test_st hash_sanity[] ={ {"hash sanity", 0, (test_callback_fn)hash_sanity_test}, @@ -6190,8 +6220,35 @@ test_st hash_tests[] ={ }; test_st error_conditions[] ={ - {"memcached_get_MEMCACHED_SOME_ERRORS", 0, (test_callback_fn)memcached_get_MEMCACHED_SOME_ERRORS }, - {"memcached_get_MEMCACHED_NOTFOUND", 0, (test_callback_fn)memcached_get_MEMCACHED_NOTFOUND }, + {"memcached_get(MEMCACHED_ERRNO)", 0, (test_callback_fn)memcached_get_MEMCACHED_ERRNO }, + {"memcached_get(MEMCACHED_NOTFOUND)", 0, (test_callback_fn)memcached_get_MEMCACHED_NOTFOUND }, + {"memcached_get_by_key(MEMCACHED_ERRNO)", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_ERRNO }, + {"memcached_get_by_key(MEMCACHED_NOTFOUND)", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_NOTFOUND }, + {"memcached_get_by_key(MEMCACHED_NOTFOUND)", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_NOTFOUND }, + {"memcached_increment(MEMCACHED_NO_SERVERS)", 0, (test_callback_fn)memcached_increment_MEMCACHED_NO_SERVERS }, + {0, 0, (test_callback_fn)0} +}; + + +test_st parser_tests[] ={ + {"behavior", 0, (test_callback_fn)behavior_parser_test }, + {"boolean_options", 0, (test_callback_fn)parser_boolean_options_test }, + {"configure_file", 0, (test_callback_fn)memcached_create_with_options_with_filename }, + {"distribtions", 0, (test_callback_fn)parser_distribution_test }, + {"hash", 0, (test_callback_fn)parser_hash_test }, + {"libmemcached_check_configuration", 0, (test_callback_fn)libmemcached_check_configuration_test }, + {"libmemcached_check_configuration_with_filename", 0, (test_callback_fn)libmemcached_check_configuration_with_filename_test }, + {"number_options", 0, (test_callback_fn)parser_number_options_test }, + {"randomly generated options", 0, (test_callback_fn)random_statement_build_test }, + {"prefix_key", 0, (test_callback_fn)parser_key_prefix_test }, + {"server", 0, (test_callback_fn)server_test }, + {"bad server strings", 0, (test_callback_fn)servers_bad_test }, + {"server with weights", 0, (test_callback_fn)server_with_weight_test }, + {0, 0, (test_callback_fn)0} +}; + +test_st virtual_bucket_tests[] ={ + {"basic", 0, (test_callback_fn)virtual_back_map }, {0, 0, (test_callback_fn)0} }; @@ -6199,7 +6256,9 @@ collection_st collection[] ={ #if 0 {"hash_sanity", 0, 0, hash_sanity}, #endif + {"basic", 0, 0, basic_tests}, {"hsieh_availability", 0, 0, hsieh_availability}, + {"murmur_availability", 0, 0, murmur_availability}, {"block", 0, 0, tests}, {"binary", (test_callback_fn)pre_binary, 0, tests}, {"nonblock", (test_callback_fn)pre_nonblock, 0, tests}, @@ -6256,12 +6315,12 @@ collection_st collection[] ={ {"behaviors", 0, 0, behavior_tests}, {"regression_binary_vs_block", (test_callback_fn)key_setup, (test_callback_fn)key_teardown, regression_binary_vs_block}, {"error_conditions", 0, 0, error_conditions}, + {"parser", 0, 0, parser_tests}, + {"virtual buckets", 0, 0, virtual_bucket_tests}, {0, 0, 0, 0} }; -#define SERVERS_TO_CREATE 5 - -#include "libmemcached_world.h" +#include "tests/libmemcached_world.h" void get_world(world_st *world) {