From 7551ea615b5f6cfaa390f7d24dca2fa388943ddb Mon Sep 17 00:00:00 2001 From: Brian Aker Date: Fri, 27 May 2011 14:18:02 -0700 Subject: [PATCH] Additional test to test for failure on get replication. --- docs/memcached_flush.rst | 8 +++--- libmemcached/get.cc | 57 +++++++++++++++++++++++++++------------- tests/mem_functions.cc | 1 + tests/replication.cc | 38 +++++++++++++++++++++++++++ tests/replication.h | 3 +++ 5 files changed, 85 insertions(+), 22 deletions(-) diff --git a/docs/memcached_flush.rst b/docs/memcached_flush.rst index c38ad499..42453b35 100644 --- a/docs/memcached_flush.rst +++ b/docs/memcached_flush.rst @@ -24,7 +24,7 @@ DESCRIPTION ----------- -memcached_flush() is used to wipe clean the contents of memcached(1) servers. +:c:func::`memcached_flush()` is used to wipe clean the contents of memcached(1) servers. It will either do this immediately or expire the content based on the expiration time passed to the method (a value of zero causes an immediate flush). The operation is not atomic to multiple servers, just atomic to a @@ -37,9 +37,9 @@ RETURN ------ -A value of type \ ``memcached_return_t``\ is returned -On success that value will be \ ``MEMCACHED_SUCCESS``\ . -Use memcached_strerror() to translate this value to a printable string. +A value of type :c:type:`memcached_return_t` is returned +On success that value will be :c:type:`MEMCACHED_SUCCESS`. +Use :c:type:`memcached_strerror()` to translate this value to a printable string. ---- diff --git a/libmemcached/get.cc b/libmemcached/get.cc index 29d01bc8..d0b01b33 100644 --- a/libmemcached/get.cc +++ b/libmemcached/get.cc @@ -1,15 +1,42 @@ -/* LibMemcached - * Copyright (C) 2006-2009 Brian Aker - * All rights reserved. +/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: + * + * Libmemcached library * - * Use and distribution licensed under the BSD license. See - * the COPYING file in the parent directory for full text. + * Copyright (C) 2011 Data Differential, http://datadifferential.com/ + * Copyright (C) 2006-2009 Brian Aker All rights reserved. * - * Summary: Get functions for libmemcached + * 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. * */ -#include "common.h" +#include "libmemcached/common.h" +#include /* What happens if no servers exist? @@ -66,10 +93,9 @@ char *memcached_get_by_key(memcached_st *ptr, { if (ptr->get_key_failure && *error == MEMCACHED_NOTFOUND) { - memcached_return_t rc; memcached_result_reset(&ptr->result); - rc= ptr->get_key_failure(ptr, key, key_length, &ptr->result); + memcached_return_t rc= ptr->get_key_failure(ptr, key, key_length, &ptr->result); /* On all failure drop to returning NULL */ if (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED) @@ -516,8 +542,6 @@ static memcached_return_t replication_binary_mget(memcached_st *ptr, for (uint32_t x= 0; x < number_of_keys; ++x) { - memcached_server_write_instance_st instance; - if (hash[x] == memcached_server_count(ptr)) continue; /* Already successfully sent */ @@ -533,12 +557,12 @@ static memcached_return_t replication_binary_mget(memcached_st *ptr, if (dead_servers[server]) continue; - instance= memcached_server_instance_fetch(ptr, server); + memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, server); if (memcached_server_response_count(instance) == 0) { rc= memcached_connect(instance); - if (rc != MEMCACHED_SUCCESS) + if (memcached_failed(rc)) { memcached_io_reset(instance); dead_servers[server]= true; @@ -607,11 +631,8 @@ static memcached_return_t binary_mget_by_key(memcached_st *ptr, } else { - uint32_t* hash; - bool* dead_servers; - - hash= static_cast(libmemcached_malloc(ptr, sizeof(uint32_t) * number_of_keys)); - dead_servers= static_cast(libmemcached_calloc(ptr, memcached_server_count(ptr), sizeof(bool))); + uint32_t* hash= static_cast(libmemcached_malloc(ptr, sizeof(uint32_t) * number_of_keys)); + bool* dead_servers= static_cast(libmemcached_calloc(ptr, memcached_server_count(ptr), sizeof(bool))); if (hash == NULL || dead_servers == NULL) { diff --git a/tests/mem_functions.cc b/tests/mem_functions.cc index 14141a0b..dfa1584f 100644 --- a/tests/mem_functions.cc +++ b/tests/mem_functions.cc @@ -6116,6 +6116,7 @@ test_st replication_tests[]= { {"mget", 0, (test_callback_fn)replication_mget_test }, {"delete", 0, (test_callback_fn)replication_delete_test }, {"rand_mget", 0, (test_callback_fn)replication_randomize_mget_test }, + {"fail", 0, (test_callback_fn)replication_randomize_mget_fail_test }, {0, 0, (test_callback_fn)0} }; diff --git a/tests/replication.cc b/tests/replication.cc index 3034c6a4..92d68066 100644 --- a/tests/replication.cc +++ b/tests/replication.cc @@ -294,3 +294,41 @@ test_return_t replication_delete_test(memcached_st *memc) return TEST_SUCCESS; } + +test_return_t replication_randomize_mget_fail_test(memcached_st *memc) +{ + memcached_st *memc_clone= memcached_clone(NULL, memc); + memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 3); + + for (int x= int(MEMCACHED_SUCCESS); x < int(MEMCACHED_MAXIMUM_RETURN); ++x) + { + const char *key= memcached_strerror(NULL, memcached_return_t(x)); + memcached_return_t rc= memcached_set(memc, + key, strlen(key), + key, strlen(key), 0, 0); + test_true(rc == MEMCACHED_SUCCESS); + } + + memcached_flush_buffers(memc); + + // We need to now cause a failure in one server, never do this in your own + // code. + close(memc_clone->servers[1].fd); + memc_clone->servers[1].port= 1; + memc_clone->servers[1].address_info_next= NULL; + + for (int x= int(MEMCACHED_SUCCESS); x < int(MEMCACHED_MAXIMUM_RETURN); ++x) + { + const char *key= memcached_strerror(NULL, memcached_return_t(x)); + memcached_return_t rc; + uint32_t flags; + size_t value_length; + char *value= memcached_get(memc_clone, key, strlen(key), &value_length, &flags, &rc); + test_true(rc == MEMCACHED_SUCCESS); + test_compare(strlen(key), value_length); + test_strcmp(key, value); + free(value); + } + memcached_free(memc_clone); + return TEST_SUCCESS; +} diff --git a/tests/replication.h b/tests/replication.h index d7eba14a..980be828 100644 --- a/tests/replication.h +++ b/tests/replication.h @@ -56,6 +56,9 @@ test_return_t replication_delete_test(memcached_st *memc); LIBTEST_INTERNAL_API test_return_t replication_randomize_mget_test(memcached_st *memc); +LIBTEST_INTERNAL_API +test_return_t replication_randomize_mget_fail_test(memcached_st *memc); + #ifdef __cplusplus } #endif -- 2.30.2