Additional test to test for failure on get replication.
authorBrian Aker <brian@tangent.org>
Fri, 27 May 2011 21:18:02 +0000 (14:18 -0700)
committerBrian Aker <brian@tangent.org>
Fri, 27 May 2011 21:18:02 +0000 (14:18 -0700)
docs/memcached_flush.rst
libmemcached/get.cc
tests/mem_functions.cc
tests/replication.cc
tests/replication.h

index c38ad499896b7087c2249322a04c84af30132eb9..42453b355c6ad79b0b96ba221ce2ce83bb6e4803 100644 (file)
@@ -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.
 
 
 ----
index 29d01bc8c293d6d2a844b541af67e871a7f4fafb..d0b01b336dedaee19471e5628298792f255131d5 100644 (file)
@@ -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 <iostream>
 
 /*
   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<uint32_t*>(libmemcached_malloc(ptr, sizeof(uint32_t) * number_of_keys));
-    dead_servers= static_cast<bool*>(libmemcached_calloc(ptr, memcached_server_count(ptr), sizeof(bool)));
+    uint32_t* hash= static_cast<uint32_t*>(libmemcached_malloc(ptr, sizeof(uint32_t) * number_of_keys));
+    bool* dead_servers= static_cast<bool*>(libmemcached_calloc(ptr, memcached_server_count(ptr), sizeof(bool)));
 
     if (hash == NULL || dead_servers == NULL)
     {
index 14141a0b4e95ac0da50eed997541ef972139838b..dfa1584f69cab4d8defcb65a52ac9f3dccc6c626 100644 (file)
@@ -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}
 };
 
index 3034c6a44c1cdeca36dd5861b925e43832828e51..92d68066626add88befe75171eec4895349f7544 100644 (file)
@@ -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;
+}
index d7eba14aac24fcff8623d83f5889c833ec4a005e..980be82880e46715e118f8a2560acbd91d5f9318 100644 (file)
@@ -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