From 08f36a77850ee38a5e6eacba23bd252a7678b788 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Mon, 19 Oct 2020 12:18:48 +0200 Subject: [PATCH] testing: ++ --- CMake/_Include.cmake | 4 +- src/libmemcached/connect.cc | 24 +- src/mem_config.h.in | 4 +- test/tests/memcached/behavior.cpp | 44 ++- .../memcached/regression/lp_000-421-108.cpp | 31 ++ test/tests/memcached/simple.cpp | 15 + test/tests/memcached/stat.cpp | 7 + test/tests/memcached/value_flags.cpp | 2 +- tests/libmemcached-1.0/mem_functions.cc | 325 ------------------ 9 files changed, 113 insertions(+), 343 deletions(-) create mode 100644 test/tests/memcached/regression/lp_000-421-108.cpp diff --git a/CMake/_Include.cmake b/CMake/_Include.cmake index 420a9723..a1bd2e49 100644 --- a/CMake/_Include.cmake +++ b/CMake/_Include.cmake @@ -113,8 +113,8 @@ check_decl(htonll arpa/inet.h) check_decl(MSG_DONTWAIT sys/socket.h) check_decl(MSG_MORE sys/socket.h) check_decl(MSG_NOSIGNAL sys/socket.h) -check_decl(rcvtimeo sys/socket.h) -check_decl(sndtimeo sys/socket.h) +check_decl(SO_RCVTIMEO sys/socket.h) +check_decl(SO_SNDTIMEO sys/socket.h) check_decl(setenv stdlib.h) check_decl(strerror string.h) check_decl(strerror_r string.h) diff --git a/src/libmemcached/connect.cc b/src/libmemcached/connect.cc index 4c4b1dff..37972bc9 100644 --- a/src/libmemcached/connect.cc +++ b/src/libmemcached/connect.cc @@ -1,5 +1,5 @@ /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * + * * Libmemcached library * * Copyright (C) 2011 Data Differential, http://datadifferential.com/ @@ -40,11 +40,11 @@ #include -#ifndef SOCK_CLOEXEC +#ifndef SOCK_CLOEXEC # define SOCK_CLOEXEC 0 #endif -#ifndef SOCK_NONBLOCK +#ifndef SOCK_NONBLOCK # define SOCK_NONBLOCK 0 #endif @@ -136,7 +136,7 @@ static memcached_return_t connect_poll(memcached_instance_st* server, const int assert (number_of == 1); if (fds[0].revents & POLLERR or - fds[0].revents & POLLHUP or + fds[0].revents & POLLHUP or fds[0].revents & POLLNVAL) { int err; @@ -191,7 +191,7 @@ static memcached_return_t set_hostinfo(memcached_instance_st* server) int length= snprintf(str_port, MEMCACHED_NI_MAXSERV, "%u", uint32_t(server->port())); if (length >= MEMCACHED_NI_MAXSERV or length <= 0 or errno != 0) { - return memcached_set_error(*server, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, + return memcached_set_error(*server, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, memcached_literal_param("snprintf(NI_MAXSERV)")); } @@ -298,15 +298,15 @@ static bool set_socket_options(memcached_instance_st* server) { int flags; do - { + { flags= fcntl(server->fd, F_GETFD, 0); } while (flags == -1 and (errno == EINTR or errno == EAGAIN)); if (flags != -1) - { + { int rval; do - { + { rval= fcntl (server->fd, F_SETFD, flags | FD_CLOEXEC); } while (rval == -1 && (errno == EINTR or errno == EAGAIN)); // we currently ignore the case where rval is -1 @@ -320,7 +320,7 @@ static bool set_socket_options(memcached_instance_st* server) return true; } -#ifdef HAVE_SNDTIMEO +#ifdef HAVE_SO_SNDTIMEO if (server->root->snd_timeout > 0) { struct timeval waittime; @@ -335,7 +335,7 @@ static bool set_socket_options(memcached_instance_st* server) } #endif -#ifdef HAVE_RCVTIMEO +#ifdef HAVE_SO_RCVTIMEO if (server->root->rcv_timeout > 0) { struct timeval waittime; @@ -660,7 +660,7 @@ static memcached_return_t backoff_handling(memcached_instance_st* server, bool& struct timeval curr_time; bool _gettime_success= (gettimeofday(&curr_time, NULL) == 0); - /* + /* If we hit server_failure_limit then something is completely wrong about the server. 1) If autoeject is enabled we do that. @@ -669,7 +669,7 @@ static memcached_return_t backoff_handling(memcached_instance_st* server, bool& if (server->server_failure_counter >= server->root->server_failure_limit) { /* - We just auto_eject if we hit this point + We just auto_eject if we hit this point */ if (_is_auto_eject_host(server->root)) { diff --git a/src/mem_config.h.in b/src/mem_config.h.in index 2048e991..7601a3dd 100644 --- a/src/mem_config.h.in +++ b/src/mem_config.h.in @@ -36,11 +36,11 @@ #cmakedefine HAVE_MURMUR_HASH 1 #cmakedefine HAVE_NETDB_H 1 #cmakedefine HAVE_POLL_H 1 -#cmakedefine HAVE_RCVTIMEO 1 #cmakedefine HAVE_SASL_SASL_H 1 #cmakedefine HAVE_SETENV 1 #cmakedefine HAVE_SHARED_ENABLED 1 -#cmakedefine HAVE_SNDTIMEO 1 +#cmakedefine HAVE_SO_RCVTIMEO 1 +#cmakedefine HAVE_SO_SNDTIMEO 1 #cmakedefine HAVE_STDDEF_H 1 #cmakedefine HAVE_STDLIB_H 1 #cmakedefine HAVE_STRERROR 1 diff --git a/test/tests/memcached/behavior.cpp b/test/tests/memcached/behavior.cpp index 1ee58370..3cfef229 100644 --- a/test/tests/memcached/behavior.cpp +++ b/test/tests/memcached/behavior.cpp @@ -1 +1,43 @@ -#warning TODO +#include "test/lib/common.hpp" +#include "test/lib/MemcachedCluster.hpp" + +static memcached_return_t callback_counter(const memcached_st *, memcached_result_st *, void *context) { + auto *counter = reinterpret_cast(context); + *counter = *counter + 1; + + return MEMCACHED_SUCCESS; +} + +TEST_CASE("memcached_behavior") { + auto test = MemcachedCluster::network(); + auto memc = &test.memc; + + SECTION("IO_KEY_PREFETCH") { + test.enableBinaryProto(); + constexpr int NUM_KEYS = 2048; + + // use batches of 64 keys + REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH, 64)); + + array str; + array chr; + array len; + + for (auto i = 0; i < NUM_KEYS; ++i) { + str[i] = to_string(i); + chr[i] = str[i].data(); + len[i] = str[i].length(); + REQUIRE_SUCCESS(memcached_set(memc, chr[i], len[i], chr[i], len[i], 0, 0)); + } + + memcached_quit(memc); + + size_t counter = 0; + memcached_execute_fn cb[] = {&callback_counter}; + REQUIRE_SUCCESS(memcached_mget_execute(memc, chr.data(), len.data(), NUM_KEYS, cb, &counter, 1)); + auto q_id = memcached_query_id(memc); + REQUIRE_SUCCESS(memcached_fetch_execute(memc, cb, &counter, 1)); + REQUIRE(counter == NUM_KEYS); + REQUIRE(q_id == memcached_query_id(memc)); + } +} diff --git a/test/tests/memcached/regression/lp_000-421-108.cpp b/test/tests/memcached/regression/lp_000-421-108.cpp new file mode 100644 index 00000000..4e6cabc6 --- /dev/null +++ b/test/tests/memcached/regression/lp_000-421-108.cpp @@ -0,0 +1,31 @@ +#include "test/lib/common.hpp" +#include "test/lib/MemcachedCluster.hpp" + +TEST_CASE("memcached_regression_lp421108") { + MemcachedCluster test; + auto memc = &test.memc; + + memcached_return_t rc; + auto memc_stat = memcached_stat(memc, NULL, &rc); + REQUIRE_SUCCESS(rc); + + // stat_get_value used memcmp + + Malloced bytes_str(memcached_stat_get_value(memc, memc_stat, "bytes", &rc)); + REQUIRE_SUCCESS(rc); + REQUIRE(*bytes_str); + + Malloced bytes_read_str(memcached_stat_get_value(memc, memc_stat,"bytes_read", &rc)); + REQUIRE_SUCCESS(rc); + REQUIRE(*bytes_read_str); + + Malloced bytes_written_str(memcached_stat_get_value(memc, memc_stat, "bytes_written", &rc)); + REQUIRE_SUCCESS(rc); + REQUIRE(*bytes_written_str); + + REQUIRE(strcmp(*bytes_str, *bytes_read_str)); + REQUIRE(strcmp(*bytes_str, *bytes_written_str)); + REQUIRE(strcmp(*bytes_read_str, *bytes_written_str)); + + memcached_stat_free(nullptr, memc_stat); +} diff --git a/test/tests/memcached/simple.cpp b/test/tests/memcached/simple.cpp index 779084b6..19f1ff02 100644 --- a/test/tests/memcached/simple.cpp +++ b/test/tests/memcached/simple.cpp @@ -59,5 +59,20 @@ TEST_CASE("memcached_simple") { REQUIRE_SUCCESS(memcached_replace(memc, S(__func__), S("replaced"), 0, 0)); } + + DYNAMIC_SECTION("not found (buffered=" << buffered << ",binary=" << binary << ")") { + memcached_return_t rc; + Malloced val(memcached_get(memc, S("not-found"), nullptr, nullptr, &rc)); + REQUIRE_RC(MEMCACHED_NOTFOUND, rc); + REQUIRE_FALSE(*val); + + val = memcached_get_by_key(memc, S("not-found"), S("not-found"), nullptr, nullptr, &rc); + REQUIRE_RC(MEMCACHED_NOTFOUND, rc); + REQUIRE_FALSE(*val); + } + + DYNAMIC_SECTION("verbosity (buffered=" << buffered << ",binary=" << binary << ")") { + REQUIRE_SUCCESS(memcached_verbosity(memc, 0)); + } } } diff --git a/test/tests/memcached/stat.cpp b/test/tests/memcached/stat.cpp index c07a0d1e..f22de55c 100644 --- a/test/tests/memcached/stat.cpp +++ b/test/tests/memcached/stat.cpp @@ -11,6 +11,10 @@ static memcached_return_t item_counter(const memcached_instance_st *, const char return MEMCACHED_SUCCESS; } +static memcached_return_t stat_null(const memcached_instance_st *, const char *, size_t, const char *, size_t, void *) { + return MEMCACHED_SUCCESS; +} + TEST_CASE("memcached_stat") { MemcachedCluster test; auto memc = &test.memc; @@ -31,6 +35,9 @@ TEST_CASE("memcached_stat") { size_t count = 0; REQUIRE_SUCCESS(memcached_stat_execute(memc, nullptr, item_counter, &count)); REQUIRE(count == 64); + + auto arg = GENERATE(as(), "slabs", "items", "sizes"); + REQUIRE_SUCCESS(memcached_stat_execute(memc, arg.c_str(), stat_null, nullptr)); } SECTION("servername") { diff --git a/test/tests/memcached/value_flags.cpp b/test/tests/memcached/value_flags.cpp index e148b1d3..b7b31d24 100644 --- a/test/tests/memcached/value_flags.cpp +++ b/test/tests/memcached/value_flags.cpp @@ -8,7 +8,7 @@ TEST_CASE("memcached_value_flags") { auto blob = make_unique(size); SECTION("set & get flags") { - uint32_t flag = GENERATE(123, 456, 789); + uint32_t flag = GENERATE(123, 456, 789, UINT32_MAX); REQUIRE_SUCCESS(memcached_set(memc, S(__func__), blob.get(), size, 0, flag)); diff --git a/tests/libmemcached-1.0/mem_functions.cc b/tests/libmemcached-1.0/mem_functions.cc index 189f60f2..041cd6d0 100644 --- a/tests/libmemcached-1.0/mem_functions.cc +++ b/tests/libmemcached-1.0/mem_functions.cc @@ -399,53 +399,7 @@ test_return_t mget_execute(memcached_st *original_memc) return TEST_SUCCESS; } -test_return_t MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH_TEST(memcached_st *original_memc) -{ - test_skip(true, memcached_behavior_get(original_memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)); - - memcached_st *memc= create_single_instance_memcached(original_memc, "--BINARY-PROTOCOL"); - test_true(memc); - - test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH, 8)); - - keys_st keys(20480); - /* First add all of the items.. */ - char blob[1024] = {0}; - - for (size_t x= 0; x < keys.size(); ++x) - { - uint64_t query_id= memcached_query_id(memc); - memcached_return_t rc= memcached_add(memc, - keys.key_at(x), keys.length_at(x), - blob, sizeof(blob), - 0, 0); - test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED); - test_compare(query_id +1, memcached_query_id(memc)); - } - - /* Try to get all of them with a large multiget */ - size_t counter= 0; - memcached_execute_fn callbacks[]= { &callback_counter }; - test_compare(MEMCACHED_SUCCESS, - memcached_mget_execute(memc, - keys.keys_ptr(), keys.lengths_ptr(), - keys.size(), callbacks, &counter, 1)); - - { - uint64_t query_id= memcached_query_id(memc); - test_compare(MEMCACHED_SUCCESS, - memcached_fetch_execute(memc, callbacks, (void *)&counter, 1)); - test_compare(query_id, memcached_query_id(memc)); - - /* Verify that we got all of the items */ - test_compare(keys.size(), counter); - } - - memcached_free(memc); - - return TEST_SUCCESS; -} test_return_t memcached_fetch_result_NOT_FOUND(memcached_st *memc) { @@ -582,89 +536,6 @@ test_return_t user_supplied_bug14(memcached_st *memc) return TEST_SUCCESS; } -/* - Look for zero length value problems -*/ -test_return_t user_supplied_bug15(memcached_st *memc) -{ - for (uint32_t x= 0; x < 2; x++) - { - memcached_return_t rc= memcached_set(memc, test_literal_param("mykey"), - NULL, 0, - (time_t)0, (uint32_t)0); - - test_compare(MEMCACHED_SUCCESS, rc); - - size_t length; - uint32_t flags; - char *value= memcached_get(memc, test_literal_param("mykey"), - &length, &flags, &rc); - - test_compare(MEMCACHED_SUCCESS, rc); - test_false(value); - test_zero(length); - test_zero(flags); - - value= memcached_get(memc, test_literal_param("mykey"), - &length, &flags, &rc); - - test_compare(MEMCACHED_SUCCESS, rc); - test_null(value); - test_zero(length); - test_zero(flags); - } - - return TEST_SUCCESS; -} - -/* Check the return sizes on FLAGS to make sure it stores 32bit unsigned values correctly */ -test_return_t user_supplied_bug16(memcached_st *memc) -{ - test_compare(MEMCACHED_SUCCESS, memcached_set(memc, test_literal_param("mykey"), - NULL, 0, - (time_t)0, UINT32_MAX)); - - - size_t length; - uint32_t flags; - memcached_return_t rc; - char *value= memcached_get(memc, test_literal_param("mykey"), - &length, &flags, &rc); - - test_compare(MEMCACHED_SUCCESS, rc); - test_null(value); - test_zero(length); - test_compare(flags, UINT32_MAX); - - return TEST_SUCCESS; -} - -#if !defined(__sun) && !defined(__OpenBSD__) -/* Check the validity of chinese key*/ -test_return_t user_supplied_bug17(memcached_st *memc) -{ - const char *key= "豆瓣"; - const char *value="我们在炎热抑郁的夏天无法停止豆瓣"; - memcached_return_t rc= memcached_set(memc, key, strlen(key), - value, strlen(value), - (time_t)0, 0); - - test_compare(MEMCACHED_SUCCESS, rc); - - size_t length; - uint32_t flags; - char *value2= memcached_get(memc, key, strlen(key), - &length, &flags, &rc); - - test_compare(length, strlen(value)); - test_compare(MEMCACHED_SUCCESS, rc); - test_memcmp(value, value2, length); - free(value2); - - return TEST_SUCCESS; -} -#endif - /* From Andrei on IRC */ @@ -812,34 +683,6 @@ test_return_t comparison_operator_memcached_st_and__memcached_return_t_TEST(memc return TEST_SUCCESS; } -test_return_t result_static(memcached_st *memc) -{ - memcached_result_st result; - memcached_result_st *result_ptr= memcached_result_create(memc, &result); - test_false(result.options.is_allocated); - test_true(memcached_is_initialized(&result)); - test_true(result_ptr); - test_true(result_ptr == &result); - - memcached_result_free(&result); - - test_false(result.options.is_allocated); - test_false(memcached_is_initialized(&result)); - - return TEST_SUCCESS; -} - -test_return_t result_alloc(memcached_st *memc) -{ - memcached_result_st *result_ptr= memcached_result_create(memc, NULL); - test_true(result_ptr); - test_true(result_ptr->options.is_allocated); - test_true(memcached_is_initialized(result_ptr)); - memcached_result_free(result_ptr); - - return TEST_SUCCESS; -} - static void my_free(const memcached_st *ptr, void *mem, void *context) { @@ -986,56 +829,7 @@ test_return_t set_memory_alloc(memcached_st *memc) return TEST_SUCCESS; } -test_return_t MEMCACHED_BEHAVIOR_POLL_TIMEOUT_test(memcached_st *memc) -{ - const uint64_t timeout= 100; // Not using, just checking that it sets - - memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout); - test_compare(timeout, memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT)); - - return TEST_SUCCESS; -} - -test_return_t analyzer_test(memcached_st *memc) -{ - memcached_analysis_st *report; - memcached_return_t rc; - - memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc); - test_compare(MEMCACHED_SUCCESS, rc); - test_true(memc_stat); - - report= memcached_analyze(memc, memc_stat, &rc); - test_compare(MEMCACHED_SUCCESS, rc); - test_true(report); - - free(report); - memcached_stat_free(NULL, memc_stat); - - return TEST_SUCCESS; -} - -test_return_t hsieh_avaibility_test (memcached_st *memc) -{ - test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_HSIEH)); - - test_compare(MEMCACHED_SUCCESS, - memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, - (uint64_t)MEMCACHED_HASH_HSIEH)); - - return TEST_SUCCESS; -} - -test_return_t murmur_avaibility_test (memcached_st *memc) -{ - test_skip(true, libhashkit_has_algorithm(HASHKIT_HASH_MURMUR)); - - test_compare(MEMCACHED_SUCCESS, - memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR)); - - return TEST_SUCCESS; -} /* Test case adapted from John Gorman @@ -1066,27 +860,6 @@ test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *) return TEST_SUCCESS; } -/* - We connect to a server which exists, but search for a key that does not exist. -*/ -test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc) -{ - size_t len; - uint32_t flags; - memcached_return rc; - - // See if memcached is reachable. - char *value= memcached_get(memc, - test_literal_param(__func__), - &len, &flags, &rc); - - test_false(value); - test_zero(len); - test_compare(MEMCACHED_NOTFOUND, rc); - - return TEST_SUCCESS; -} - /* Test case adapted from John Gorman @@ -1120,64 +893,6 @@ test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *) return TEST_SUCCESS; } -/* - We connect to a server which exists, but search for a key that does not exist. -*/ -test_return_t memcached_get_by_key_MEMCACHED_NOTFOUND(memcached_st *memc) -{ - size_t len; - uint32_t flags; - memcached_return rc; - - // See if memcached is reachable. - char *value= memcached_get_by_key(memc, - test_literal_param(__func__), // Key - test_literal_param(__func__), // Value - &len, &flags, &rc); - - test_false(value); - test_zero(len); - test_compare(MEMCACHED_NOTFOUND, rc); - - return TEST_SUCCESS; -} - -test_return_t regression_bug_421108(memcached_st *memc) -{ - memcached_return_t rc; - memcached_stat_st *memc_stat= memcached_stat(memc, NULL, &rc); - test_compare(MEMCACHED_SUCCESS, rc); - - char *bytes_str= memcached_stat_get_value(memc, memc_stat, "bytes", &rc); - test_compare(MEMCACHED_SUCCESS, rc); - test_true(bytes_str); - char *bytes_read_str= memcached_stat_get_value(memc, memc_stat, - "bytes_read", &rc); - test_compare(MEMCACHED_SUCCESS, rc); - test_true(bytes_read_str); - - char *bytes_written_str= memcached_stat_get_value(memc, memc_stat, - "bytes_written", &rc); - test_compare(MEMCACHED_SUCCESS, rc); - test_true(bytes_written_str); - - unsigned long long bytes= strtoull(bytes_str, 0, 10); - unsigned long long bytes_read= strtoull(bytes_read_str, 0, 10); - unsigned long long bytes_written= strtoull(bytes_written_str, 0, 10); - - test_true(bytes != bytes_read); - test_true(bytes != bytes_written); - - /* Release allocated resources */ - free(bytes_str); - free(bytes_read_str); - free(bytes_written_str); - memcached_stat_free(NULL, memc_stat); - - return TEST_SUCCESS; -} - - /* Test memcached_server_get_last_disconnect * For a working server set, shall be NULL * For a set of non existing server, shall not be NULL @@ -1269,46 +984,6 @@ test_return_t test_multiple_get_last_disconnect(memcached_st *) return TEST_SUCCESS; } -test_return_t test_verbosity(memcached_st *memc) -{ - test_compare(MEMCACHED_SUCCESS, memcached_verbosity(memc, 0)); - - return TEST_SUCCESS; -} - - -static memcached_return_t stat_printer(const memcached_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; -} - -test_return_t memcached_stat_execute_test(memcached_st *memc) -{ - memcached_return_t rc= memcached_stat_execute(memc, NULL, stat_printer, NULL); - test_compare(MEMCACHED_SUCCESS, rc); - - test_compare(MEMCACHED_SUCCESS, - memcached_stat_execute(memc, "slabs", stat_printer, NULL)); - - test_compare(MEMCACHED_SUCCESS, - memcached_stat_execute(memc, "items", stat_printer, NULL)); - - test_compare(MEMCACHED_SUCCESS, - memcached_stat_execute(memc, "sizes", stat_printer, NULL)); - - return TEST_SUCCESS; -} - /* * This test ensures that the failure counter isn't incremented during * normal termination of the memcached instance. -- 2.30.2