From: Brian Aker Date: Sat, 20 Aug 2011 07:01:20 +0000 (-0700) Subject: This patch creates a couple of tests around how autoeject works. X-Git-Tag: 0.52~13 X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=b1e692afdbd3823e57c649fe82e073f3b0743ada;p=m6w6%2Flibmemcached This patch creates a couple of tests around how autoeject works. --- diff --git a/libmemcached/constants.h b/libmemcached/constants.h index 7a84b9a8..106aec49 100644 --- a/libmemcached/constants.h +++ b/libmemcached/constants.h @@ -54,7 +54,7 @@ #define MEMCACHED_EXPIRATION_NOT_ADD 0xffffffffU #define MEMCACHED_VERSION_STRING_LENGTH 24 #define MEMCACHED_MAXIMUM_INTEGER_DISPLAY_LENGTH 20 -#define MEMCACHED_SERVER_FAILURE_LIMIT 2 +#define MEMCACHED_SERVER_FAILURE_LIMIT 5 #define MEMCACHED_SERVER_FAILURE_RETRY_TIMEOUT 2 diff --git a/libmemcached/server.cc b/libmemcached/server.cc index 022dda4f..ed360ee3 100644 --- a/libmemcached/server.cc +++ b/libmemcached/server.cc @@ -53,6 +53,7 @@ static inline void _server_init(memcached_server_st *self, memcached_st *root, self->fd= -1; self->io_bytes_sent= 0; self->server_failure_counter= 0; + self->server_failure_counter_query_id= 0; self->weight= weight ? weight : 1; // 1 is the default weight value WATCHPOINT_SET(self->io_wait_count.read= 0); WATCHPOINT_SET(self->io_wait_count.write= 0); diff --git a/libmemcached/server.h b/libmemcached/server.h index e6f3a30a..3afb5202 100644 --- a/libmemcached/server.h +++ b/libmemcached/server.h @@ -63,6 +63,7 @@ struct memcached_server_st { memcached_socket_t fd; uint32_t io_bytes_sent; /* # bytes sent since last read */ uint32_t server_failure_counter; + uint64_t server_failure_counter_query_id; uint32_t weight; uint32_t version; enum memcached_server_state_t state; diff --git a/libmemcached/server.hpp b/libmemcached/server.hpp index 320da115..8cfcbdba 100644 --- a/libmemcached/server.hpp +++ b/libmemcached/server.hpp @@ -93,7 +93,11 @@ static inline void memcached_mark_server_for_timeout(memcached_server_write_inst } server->state= MEMCACHED_SERVER_STATE_IN_TIMEOUT; - server->server_failure_counter++; + if (server->server_failure_counter_query_id != server->root->query_id) + { + server->server_failure_counter++; + server->server_failure_counter_query_id= server->root->query_id; + } set_last_disconnected_host(server); } } diff --git a/libtest/include.am b/libtest/include.am index d7394fd0..044ca4f8 100644 --- a/libtest/include.am +++ b/libtest/include.am @@ -69,6 +69,7 @@ noinst_HEADERS+= \ libtest/libtool.hpp \ libtest/memcached.h \ libtest/runner.h \ + libtest/port.h \ libtest/server.h \ libtest/server_container.h \ libtest/signal.h \ @@ -88,6 +89,7 @@ libtest_libtest_la_SOURCES= \ libtest/killpid.cc \ libtest/libtool.cc \ libtest/runner.cc \ + libtest/port.cc \ libtest/server.cc \ libtest/server_container.cc \ libtest/signal.cc \ diff --git a/libtest/port.cc b/libtest/port.cc new file mode 100644 index 00000000..9bd7717f --- /dev/null +++ b/libtest/port.cc @@ -0,0 +1,73 @@ +/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: + * + * libtest + * + * Copyright (C) 2011 Data Differential, http://datadifferential.com/ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#ifndef __INTEL_COMPILER +#pragma GCC diagnostic ignored "-Wold-style-cast" +#endif + +using namespace libtest; + +static in_port_t global_port= 0; +static in_port_t global_max_port= 0; + +in_port_t default_port() +{ + return global_port; +} + +void set_default_port(in_port_t port) +{ + global_port= port; +} + +in_port_t max_port() +{ + return global_max_port; +} + +void set_max_port(in_port_t port) +{ + if (port > global_max_port) + { + global_max_port= port; + } + + global_max_port= port; +} diff --git a/libtest/port.h b/libtest/port.h new file mode 100644 index 00000000..63b29929 --- /dev/null +++ b/libtest/port.h @@ -0,0 +1,39 @@ +/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: + * + * libtest + * + * Copyright (C) 2011 Data Differential, http://datadifferential.com/ + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +/* + Structures for generic tests. +*/ + +#pragma once + +LIBTEST_API +in_port_t default_port(); + +LIBTEST_API +void set_default_port(in_port_t port); + +LIBTEST_API +in_port_t max_port(); + +LIBTEST_API +void set_max_port(in_port_t port); diff --git a/libtest/server_container.cc b/libtest/server_container.cc index bba1240c..684303a2 100644 --- a/libtest/server_container.cc +++ b/libtest/server_container.cc @@ -147,6 +147,8 @@ bool server_startup(server_startup_st& construct, const std::string& server_type Outn(); (void)try_port; + set_max_port(try_port); + // Look to see if we are being provided ports to use { char variable_buffer[1024]; diff --git a/libtest/test.cc b/libtest/test.cc index 5c43e40b..89e7c071 100644 --- a/libtest/test.cc +++ b/libtest/test.cc @@ -44,19 +44,8 @@ using namespace libtest; -static in_port_t global_port= 0; static char global_socket[1024]; -in_port_t default_port() -{ - return global_port; -} - -void set_default_port(in_port_t port) -{ - global_port= port; -} - const char *default_socket() { assert(global_socket[0]); diff --git a/libtest/test.hpp b/libtest/test.hpp index a10aa30d..047dd8ce 100644 --- a/libtest/test.hpp +++ b/libtest/test.hpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include diff --git a/tests/failure.cc b/tests/failure.cc index 185f9c71..c616a262 100644 --- a/tests/failure.cc +++ b/tests/failure.cc @@ -71,6 +71,22 @@ static test_return_t shutdown_servers(memcached_st *memc) return TEST_SUCCESS; } +static test_return_t add_shutdown_servers(memcached_st *memc) +{ + while (memcached_server_count(memc) < 2) + { + const char *argv[1]= { "add_shutdown_server" }; + in_port_t port= max_port() +1; + test_true(global_framework->servers().start_socket_server("memcached", port, 1, argv)); + test_compare(MEMCACHED_SUCCESS, memcached_server_add(memc, "localhost", port)); + } + + // Disable a single server, just the first + global_framework->servers().shutdown(0); + + return TEST_SUCCESS; +} + static test_return_t restart_servers(memcached_st *) { // Restart the servers @@ -142,6 +158,29 @@ static test_return_t MEMCACHED_SERVER_TEMPORARILY_DISABLED_to_success_TEST(memca return TEST_SUCCESS; } +static test_return_t MEMCACHED_SERVER_MARKED_DEAD_TEST(memcached_st *memc) +{ + test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 30)); + test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS, true)); + + memcached_return_t ret; + do { + ret= memcached_set(memc, + test_literal_param("foo"), + NULL, 0, time_t(0), uint32_t(0)); + } while (ret == MEMCACHED_SUCCESS or ret == MEMCACHED_CONNECTION_FAILURE); + test_compare(MEMCACHED_SERVER_TEMPORARILY_DISABLED, ret); + + do { + sleep(3); + ret= memcached_set(memc, test_literal_param("foo"), NULL, 0, time_t(0), uint32_t(0)); + } while (ret == MEMCACHED_SERVER_TEMPORARILY_DISABLED or ret == MEMCACHED_SUCCESS); + + test_compare_got(MEMCACHED_SERVER_MARKED_DEAD, ret, memcached_last_error_message(memc)); + + return TEST_SUCCESS; +} + test_st cull_TESTS[] ={ { "cull servers", true, (test_callback_fn*)cull_TEST }, { 0, 0, 0 } @@ -153,9 +192,15 @@ test_st server_temporarily_disabled_TESTS[] ={ { 0, 0, 0 } }; +test_st server_permanently_disabled_TESTS[] ={ + { "memcached_set(MEMCACHED_SERVER_MARKED_DEAD)", true, (test_callback_fn*)MEMCACHED_SERVER_MARKED_DEAD_TEST }, + { 0, 0, 0 } +}; + collection_st collection[] ={ { "cull", (test_callback_fn*)shutdown_servers, (test_callback_fn*)restart_servers, cull_TESTS }, { "server failed", (test_callback_fn*)shutdown_servers, (test_callback_fn*)restart_servers, server_temporarily_disabled_TESTS }, + { "server eject", (test_callback_fn*)add_shutdown_servers, (test_callback_fn*)restart_servers, server_permanently_disabled_TESTS }, { 0, 0, 0, 0 } };