X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=tests%2Flibmemcached-1.0%2Fpool.cc;h=457cf962ea62413f4abd40802a63ad8a370002da;hb=5bb059e5a357331f91fde818f703f0a0aae14a42;hp=f6214e0d3b5b5f103de029d2d9f35d9bc7b2b1bf;hpb=9169cee9ec0f231b3117a0d5a7840d2067f29610;p=awesomized%2Flibmemcached diff --git a/tests/libmemcached-1.0/pool.cc b/tests/libmemcached-1.0/pool.cc index f6214e0d..457cf962 100644 --- a/tests/libmemcached-1.0/pool.cc +++ b/tests/libmemcached-1.0/pool.cc @@ -35,7 +35,7 @@ * */ -#include +#include #include using namespace libtest; @@ -47,10 +47,16 @@ using namespace libtest; #include -#include -#include +#include +#include +#include #include +#include +#include + +#include "libmemcached/instance.hpp" + #ifndef __INTEL_COMPILER #pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif @@ -58,20 +64,19 @@ using namespace libtest; test_return_t memcached_pool_test(memcached_st *) { - memcached_return_t rc; const char *config_string= "--SERVER=host10.example.com --SERVER=host11.example.com --SERVER=host10.example.com --POOL-MIN=10 --POOL-MAX=32"; char buffer[2048]; - rc= libmemcached_check_configuration(config_string, sizeof(config_string) -1, buffer, sizeof(buffer)); - test_true_got(rc != MEMCACHED_SUCCESS, buffer); + test_compare(libmemcached_check_configuration(config_string, sizeof(config_string) -1, buffer, sizeof(buffer)), MEMCACHED_PARSE_ERROR); memcached_pool_st* pool= memcached_pool(config_string, strlen(config_string)); - test_true_got(pool, strerror(errno)); + test_true(pool); + memcached_return_t rc; memcached_st *memc= memcached_pool_pop(pool, false, &rc); - test_true(rc == MEMCACHED_SUCCESS); + test_compare(rc, MEMCACHED_SUCCESS); test_true(memc); /* @@ -186,7 +191,7 @@ test_return_t connection_pool2_test(memcached_st *memc) test_compare(MEMCACHED_SUCCESS, rc); } - test_compare(UINT64_C(9999), memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK)); + test_compare(uint64_t(9999), memcached_behavior_get(mmc[1], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK)); test_compare(MEMCACHED_SUCCESS, memcached_pool_release(pool, mmc[1])); test_compare(MEMCACHED_SUCCESS, memcached_pool_release(pool, mmc[0])); @@ -197,7 +202,7 @@ test_return_t connection_pool2_test(memcached_st *memc) test_compare(MEMCACHED_SUCCESS, rc); } - test_compare(UINT64_C(9999), memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK)); + test_compare(uint64_t(9999), memcached_behavior_get(mmc[0], MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK)); test_compare(MEMCACHED_SUCCESS, memcached_pool_release(pool, mmc[0])); test_true(memcached_pool_destroy(pool) == memc); @@ -235,14 +240,10 @@ struct test_pool_context_st { } }; -static void* connection_release(void *arg) +static __attribute__((noreturn)) void* connection_release(void *arg) { test_pool_context_st *resource= static_cast(arg); - assert(resource); - if (resource == NULL) - { - abort(); - } + FATAL_IF(resource == NULL); // Release all of the memc we are holding resource->rc= memcached_pool_release(resource->pool, resource->mmc); @@ -320,3 +321,177 @@ test_return_t connection_pool3_test(memcached_st *memc) return TEST_SUCCESS; } + +static memcached_st * create_single_instance_memcached(const memcached_st *original_memc, const char *options) +{ + /* + If no options are given, copy over at least the binary flag. + */ + char options_buffer[1024]= { 0 }; + if (options == NULL) + { + if (memcached_is_binary(original_memc)) + { + snprintf(options_buffer, sizeof(options_buffer), "--BINARY"); + } + } + + /* + * I only want to hit _one_ server so I know the number of requests I'm + * sending in the pipeline. + */ + const memcached_instance_st * instance= memcached_server_instance_by_position(original_memc, 0); + + char server_string[1024]; + int server_string_length; + if (instance->type == MEMCACHED_CONNECTION_UNIX_SOCKET) + { + if (options) + { + server_string_length= snprintf(server_string, sizeof(server_string), "--SOCKET=\"%s\" %s", + memcached_server_name(instance), options); + } + else + { + server_string_length= snprintf(server_string, sizeof(server_string), "--SOCKET=\"%s\"", + memcached_server_name(instance)); + } + } + else + { + if (options) + { + server_string_length= snprintf(server_string, sizeof(server_string), "--server=%s:%d %s", + memcached_server_name(instance), int(memcached_server_port(instance)), + options); + } + else + { + server_string_length= snprintf(server_string, sizeof(server_string), "--server=%s:%d", + memcached_server_name(instance), int(memcached_server_port(instance))); + } + } + + if (server_string_length <= 0) + { + return NULL; + } + + char errror_buffer[1024]; + if (memcached_failed(libmemcached_check_configuration(server_string, server_string_length, errror_buffer, sizeof(errror_buffer)))) + { + Error << "Failed to parse (" << server_string << ") " << errror_buffer; + return NULL; + } + + return memcached(server_string, server_string_length); +} + +pthread_mutex_t mutex= PTHREAD_MUTEX_INITIALIZER; +static bool _running= false; + +static void set_running(const bool arg) +{ + int error; + FATAL_IF_((error= pthread_mutex_lock(&mutex)) != 0, strerror(error)); + + _running= arg; + + FATAL_IF_((error= pthread_mutex_unlock(&mutex)) != 0, strerror(error)); +} + +static bool running() +{ + int error; + bool ret; + + FATAL_IF_((error= pthread_mutex_lock(&mutex)) != 0, strerror(error)); + + ret= _running; + + FATAL_IF_((error= pthread_mutex_unlock(&mutex)) != 0, strerror(error)); + + return ret; +} + +static void *worker_thread(void *ctx) +{ + memcached_pool_st *pool= (memcached_pool_st *)ctx; + + while (running()) + { + memcached_return_t rc; + memcached_st *mc= memcached_pool_pop(pool, true, &rc); + + if (mc == NULL) + { + Error << "failed to fetch a connection from the pool" << memcached_strerror(NULL, rc); + dream(1, 0); + continue; + } + + rc= memcached_set(mc, "test:kv", 7, "value", 5, 600, 0); + if (memcached_failed(rc)) + { + Out << "failed memcached_set()"; + } + + rc= memcached_pool_push(pool, mc); + if (memcached_failed(rc)) + { + Error << "failed to release a connection to the pool" << memcached_strerror(NULL, rc); + } + } + + return NULL; +} + +#define NUM_THREADS 20 +test_return_t regression_bug_962815(memcached_st *memc) +{ + pthread_t pid[NUM_THREADS]; + + test_false(running()); + + memcached_st *master = create_single_instance_memcached(memc, 0); + test_true(master); + + memcached_pool_st *pool= memcached_pool_create(master, 5, 10); + + test_true(pool); + + set_running(true); + + for (size_t x=0; x < NUM_THREADS; x++) + { + test_compare(0, pthread_create(&pid[x], NULL, worker_thread, (void*)pool)); + } + + { + pollfd fds[1]; + memset(fds, 0, sizeof(pollfd)); + fds[0].fd= -1; //STDIN_FILENO; + fds[0].events= POLLIN; + fds[0].revents= 0; + + int active_fd; + if ((active_fd= poll(fds, 1, 5000)) == -1) + { + Error << "poll() failed with:" << strerror(errno); + } + test_zero(active_fd); + + set_running(false); + } + + for (size_t x=0; x < NUM_THREADS; x++) + { + test_compare(0, pthread_join(pid[x], NULL)); + } + + memcached_pool_destroy(pool); + + memcached_free(master); + + return TEST_SUCCESS; +}