From a6874b396cec9cacc3e424585d904bc36c7439be Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 7 Oct 2020 13:17:39 +0200 Subject: [PATCH 01/16] testing: touch --- test/lib/common.hpp | 6 ++++ test/tests/bin/memtouch.cpp | 64 ++++++++++++++++++++++++++++++++++ test/tests/memcached/touch.cpp | 48 +++++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 test/tests/bin/memtouch.cpp create mode 100644 test/tests/memcached/touch.cpp diff --git a/test/lib/common.hpp b/test/lib/common.hpp index 517b4263..b5ef3525 100644 --- a/test/lib/common.hpp +++ b/test/lib/common.hpp @@ -113,6 +113,12 @@ public: Malloced(T *ptr_) : ptr{ptr_} {} + Malloced &operator=(T *ptr_) { + if (ptr) + free(ptr); + ptr = ptr_; + return *this; + } ~Malloced() { if(ptr) free(ptr); diff --git a/test/tests/bin/memtouch.cpp b/test/tests/bin/memtouch.cpp new file mode 100644 index 00000000..35da7dc9 --- /dev/null +++ b/test/tests/bin/memtouch.cpp @@ -0,0 +1,64 @@ +#include "test/lib/common.hpp" +#include "test/lib/Shell.hpp" +#include "test/lib/Server.hpp" +#include "test/lib/Retry.hpp" +#include "test/lib/ReturnMatcher.hpp" + +using Catch::Matchers::Contains; + +TEST_CASE("bin/memtouch") { + Shell sh{string{TESTING_ROOT "/../src/bin"}}; + + SECTION("no servers provided") { + string output; + REQUIRE_FALSE(sh.run("memtouch", output)); + REQUIRE(output == "No Servers provided\n"); + } + + SECTION("--help") { + string output; + REQUIRE(sh.run("memtouch --help", output)); + REQUIRE_THAT(output, Contains("memtouch")); + REQUIRE_THAT(output, Contains("v1")); + REQUIRE_THAT(output, Contains("help")); + REQUIRE_THAT(output, Contains("version")); + REQUIRE_THAT(output, Contains("option")); + REQUIRE_THAT(output, Contains("--")); + REQUIRE_THAT(output, Contains("=")); + } + + SECTION("with server") { + Server server{MEMCACHED_BINARY, {"-p", random_port_string}}; + MemcachedPtr memc; + LoneReturnMatcher test{*memc}; + + REQUIRE(server.ensureListening()); + auto port = get(server.getSocketOrPort()); + auto comm = "memtouch --servers=localhost:" + to_string(port) + " "; + + REQUIRE_SUCCESS(memcached_server_add(*memc, "localhost", port)); + + SECTION("found") { + REQUIRE_SUCCESS(memcached_set(*memc, S("memtouch"), S("memtouch-SET"), 0, 0)); + + string output; + REQUIRE(sh.run(comm + "memtouch", output)); + REQUIRE(output.empty()); + } + + SECTION("not found") { + memcached_delete(*memc, S("memtouch"), 0); + + string output; + REQUIRE_FALSE(sh.run(comm + "memtouch", output)); + REQUIRE(output.empty()); + } + + SECTION("expires") { + REQUIRE_SUCCESS(memcached_set(*memc, S("memtouch"), S("memtouch"), 60, 0)); + REQUIRE_SUCCESS(memcached_exist(*memc, S("memtouch"))); + REQUIRE(sh.run(comm + "--expire=" + to_string(time(nullptr) - 2) + " memtouch")); + REQUIRE_RC(MEMCACHED_NOTFOUND, memcached_exist(*memc, S("memtouch"))); + } + } +} diff --git a/test/tests/memcached/touch.cpp b/test/tests/memcached/touch.cpp new file mode 100644 index 00000000..982236b5 --- /dev/null +++ b/test/tests/memcached/touch.cpp @@ -0,0 +1,48 @@ +#include "test/lib/common.hpp" +#include "test/lib/MemcachedCluster.hpp" + +TEST_CASE("memcached_touch") { + auto test = MemcachedCluster::mixed(); + auto memc = &test.memc; + memcached_return_t rc; + auto binary = GENERATE(0, 1); + + test.enableBinaryProto(binary); + + DYNAMIC_SECTION("touch binary=" << binary) { + REQUIRE_FALSE(memcached_get(memc, S(__func__), nullptr, nullptr, &rc)); + REQUIRE_RC(MEMCACHED_NOTFOUND, rc); + + REQUIRE_SUCCESS(memcached_set(memc, S(__func__), S(__func__), 2, 0)); + + Malloced val(memcached_get(memc, S(__func__), nullptr, nullptr, &rc)); + REQUIRE_SUCCESS(rc); + REQUIRE(*val); + + REQUIRE_SUCCESS(memcached_touch(memc, S(__func__), 60)); + val = memcached_get(memc, S(__func__), nullptr, nullptr, &rc); + REQUIRE_SUCCESS(rc); + REQUIRE(*val); + + REQUIRE_SUCCESS(memcached_touch(memc, S(__func__), time(nullptr) - 2)); + val = memcached_get(memc, S(__func__), nullptr, nullptr, &rc); + REQUIRE_RC(MEMCACHED_NOTFOUND, rc); + REQUIRE_FALSE(*val); + } + + DYNAMIC_SECTION("touch_by_key binary=" << binary) { + REQUIRE_RC(MEMCACHED_NOTFOUND, memcached_touch_by_key(memc, S(__func__), S(__func__), 60)); + REQUIRE_SUCCESS(memcached_set_by_key(memc, S(__func__), S(__func__), S(__func__), 2, 0)); + + Malloced val(memcached_get_by_key(memc, S(__func__), S(__func__), nullptr, nullptr, &rc)); + REQUIRE_SUCCESS(rc); + REQUIRE(*val); + + REQUIRE_SUCCESS(memcached_touch_by_key(memc, S(__func__), S(__func__), time(nullptr) - 2)); + val = memcached_get_by_key(memc, S(__func__), S(__func__), nullptr, nullptr, &rc); + REQUIRE_RC(MEMCACHED_NOTFOUND, rc); + REQUIRE_FALSE(*val); + + REQUIRE_RC(MEMCACHED_NOTFOUND, memcached_touch_by_key(memc, S(__func__), S(__func__), 60)); + } +} -- 2.30.2 From cf5fafcbbfd88990693baaa8b10838fd36598f5f Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 7 Oct 2020 13:51:43 +0200 Subject: [PATCH 02/16] travis: add arm64 build --- .github/workflows/cmake-build-ci.gen | 1 + .github/workflows/cmake-build-ci.yml | 1 + .travis.yml | 43 ++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 .travis.yml diff --git a/.github/workflows/cmake-build-ci.gen b/.github/workflows/cmake-build-ci.gen index 6f7c48a1..0d1e1be0 100755 --- a/.github/workflows/cmake-build-ci.gen +++ b/.github/workflows/cmake-build-ci.gen @@ -190,6 +190,7 @@ on: push: paths-ignore: - "docs/**" + - ".travis.yml" branches-ignore: - gh-pages - catch diff --git a/.github/workflows/cmake-build-ci.yml b/.github/workflows/cmake-build-ci.yml index e2de43d1..492c4d53 100644 --- a/.github/workflows/cmake-build-ci.yml +++ b/.github/workflows/cmake-build-ci.yml @@ -4,6 +4,7 @@ on: push: paths-ignore: - "docs/**" + - ".travis.yml" branches-ignore: - gh-pages - catch diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..ff23b34d --- /dev/null +++ b/.travis.yml @@ -0,0 +1,43 @@ +os: linux +dist: focal +arch: arm64 +language: cpp + +addons: + apt: + packages: + - libevent-dev + - libsasl2-dev + +env: + - CMAKE_BUILD_TYPE=Debug BUILD_TESTING=true ENABLE_SASL=true + +install: + - | + git clone --depth 1 -b 1.6.7 https://github.com/memcached/memcached + cd memcached + ./autogen.sh + CFLAGS="-O2 -pipe" ./configure \ + --prefix=/opt \ + --disable-coverage \ + --disable-docs \ + --disable-dependency-tracking \ + --enable-sasl \ + --enable-sasl-pwdb \ + ; + make -j2 + make install + cd .. + +before_script: + - mkdir build + +script: + - cd build + - cmake -DMEMCACHED_BINARY=/opt/bin/memcached .. + - make -j2 VERBOSE=1 + - make test VERBOSE=1 + - make install DESTDIR=. + +after_failure: + - cat Testing/Temporary/LastTest.log || true -- 2.30.2 From fe7194f7d6348559fc9219d9899c9633c9de77f2 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 7 Oct 2020 15:53:00 +0200 Subject: [PATCH 03/16] testing: udp flag must be set prior adding servers --- test/lib/MemcachedCluster.cpp | 22 +++++++++++++--------- test/lib/MemcachedCluster.hpp | 9 ++++++--- test/tests/memcached/udp.cpp | 17 ----------------- 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/test/lib/MemcachedCluster.cpp b/test/lib/MemcachedCluster.cpp index bb164e5d..06e2c7f1 100644 --- a/test/lib/MemcachedCluster.cpp +++ b/test/lib/MemcachedCluster.cpp @@ -29,6 +29,11 @@ void MemcachedCluster::init() { } REQUIRE(memcached_create(&memc)); + + for (const auto &[behavior, value] : to_set) { + REQUIRE(MEMCACHED_SUCCESS == memcached_behavior_set(&memc, behavior, value)); + } + for (const auto &server : cluster.getServers()) { auto target = server.getSocketOrPort(); if (holds_alternative(target)) { @@ -59,8 +64,9 @@ MemcachedCluster::MemcachedCluster() init(); } -MemcachedCluster::MemcachedCluster(Cluster &&cluster_) +MemcachedCluster::MemcachedCluster(Cluster &&cluster_, behaviors_t to_set_) : cluster{move(cluster_)} +, to_set{move(to_set_)} { init(); } @@ -103,7 +109,9 @@ MemcachedCluster MemcachedCluster::udp() { Server::arg_pair_t{"-U", random_socket_or_port_string}, Server::arg_t{"-v"} } - }}}; + }}, { + {MEMCACHED_BEHAVIOR_USE_UDP, 1} + }}; } #if LIBMEMCACHED_WITH_SASL_SUPPORT @@ -114,8 +122,9 @@ MemcachedCluster MemcachedCluster::sasl() { Server::arg_pair_t{"-p", random_socket_or_port_string}, Server::arg_t{"-S"} } - }}}; - mc.enableBinaryProto(); + }}, { + {MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1}, + }}; REQUIRE(MEMCACHED_SUCCESS == memcached_set_sasl_auth_data(&mc.memc, "memcached", "memcached")); return mc; @@ -137,11 +146,6 @@ void MemcachedCluster::enableReplication() { MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, memcached_server_count(&memc) - 1)); } -void MemcachedCluster::enableUdp(bool enable) { - REQUIRE(MEMCACHED_SUCCESS == memcached_behavior_set(&memc, - MEMCACHED_BEHAVIOR_USE_UDP, enable)); -} - void MemcachedCluster::killOneServer() { const auto &servers = cluster.getServers(); const auto &victim = servers[random_num(0UL, servers.size() - 1)]; diff --git a/test/lib/MemcachedCluster.hpp b/test/lib/MemcachedCluster.hpp index 5dbe5c2c..0a4dcb6b 100644 --- a/test/lib/MemcachedCluster.hpp +++ b/test/lib/MemcachedCluster.hpp @@ -7,19 +7,21 @@ class MemcachedCluster { public: + using behavior_t = pair; + using behaviors_t = vector; + Cluster cluster; memcached_st memc{empty_memc}; ReturnMatcher returns{&memc}; MemcachedCluster(); - explicit - MemcachedCluster(Cluster &&cluster); + explicit MemcachedCluster(Cluster &&cluster, behaviors_t to_set = {}); ~MemcachedCluster(); MemcachedCluster(const MemcachedCluster &) = delete; MemcachedCluster &operator=(const MemcachedCluster &) = delete; - MemcachedCluster(MemcachedCluster &&mc);; + MemcachedCluster(MemcachedCluster &&mc); MemcachedCluster &operator=(MemcachedCluster &&mc); void enableBinaryProto(bool enable = true); @@ -40,6 +42,7 @@ public: void killOneServer(); private: + behaviors_t to_set; static const memcached_st empty_memc; void init(); diff --git a/test/tests/memcached/udp.cpp b/test/tests/memcached/udp.cpp index 85e44126..ad242145 100644 --- a/test/tests/memcached/udp.cpp +++ b/test/tests/memcached/udp.cpp @@ -9,23 +9,6 @@ TEST_CASE("memcached_udp") { auto test = MemcachedCluster::udp(); auto memc = &test.memc; - SECTION("sets reply flag") { - // FIXME: bad internals test - REQUIRE(memc->flags.reply); - REQUIRE_FALSE(memc->flags.use_udp); - REQUIRE_FALSE(memc->flags.use_udp == memc->flags.reply); - test.enableUdp(); - REQUIRE_FALSE(memc->flags.reply); - REQUIRE(memc->flags.use_udp); - REQUIRE_FALSE(memc->flags.use_udp == memc->flags.reply); - test.enableUdp(false); - REQUIRE(memc->flags.reply); - REQUIRE_FALSE(memc->flags.use_udp); - REQUIRE_FALSE(memc->flags.use_udp == memc->flags.reply); - } - - test.enableUdp(); - SECTION("compat") { memcached_return_t rc; REQUIRE_RC(MEMCACHED_INVALID_ARGUMENTS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true)); -- 2.30.2 From 8d1c71d47768dc77183ddc36e412599cf5cf9a28 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 7 Oct 2020 16:10:44 +0200 Subject: [PATCH 04/16] testing: re-enable udp test on mac [travis skip] --- test/tests/memcached/udp.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/tests/memcached/udp.cpp b/test/tests/memcached/udp.cpp index ad242145..f832e75f 100644 --- a/test/tests/memcached/udp.cpp +++ b/test/tests/memcached/udp.cpp @@ -2,10 +2,6 @@ #include "test/lib/MemcachedCluster.hpp" TEST_CASE("memcached_udp") { -#ifdef __APPLE__ - WARN("skip: memcached crashes"); - SUCCEED(); -#else auto test = MemcachedCluster::udp(); auto memc = &test.memc; @@ -76,5 +72,4 @@ TEST_CASE("memcached_udp") { } } } -#endif } -- 2.30.2 From 2224115a3a7017166591a9c628827771dd82e36d Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Mon, 12 Oct 2020 19:24:25 +0200 Subject: [PATCH 05/16] testing: freebsd on cirrus --- .cirrus.yml | 51 ++++++++++++++++++++++++++ .github/workflows/cmake-build-ci.gen | 1 + .github/workflows/cmake-build-ci.yml | 1 + CMake/EnableDtrace.cmake | 55 ++++++++++++++++++++++++++++ CMake/_Include.cmake | 16 +++++++- src/bin/common/CMakeLists.txt | 2 +- src/libmemcached/CMakeLists.txt | 33 ++++++----------- src/libmemcached/assert.hpp | 4 +- src/libmemcached/backtrace.cc | 20 ++++------ src/libmemcachedutil/CMakeLists.txt | 1 + src/mem_config.h.in | 10 +++-- test/lib/Server.cpp | 3 +- test/lib/random.hpp | 8 ++-- test/tests/bin/memcp.cpp | 6 ++- test/tests/bin/memdump.cpp | 6 ++- test/tests/bin/memflush.cpp | 6 ++- test/tests/bin/memping.cpp | 6 ++- test/tests/bin/memrm.cpp | 6 ++- test/tests/bin/memstat.cpp | 6 ++- test/tests/memcached/util.cpp | 2 +- 20 files changed, 190 insertions(+), 53 deletions(-) create mode 100644 .cirrus.yml create mode 100644 CMake/EnableDtrace.cmake diff --git a/.cirrus.yml b/.cirrus.yml new file mode 100644 index 00000000..c7fe30bc --- /dev/null +++ b/.cirrus.yml @@ -0,0 +1,51 @@ +env: + CMAKE_BUILD_TYPE: Debug + BUILD_TESTING: "ON" + ENABLE_SASL: "ON" + ENABLE_HASH_HSIEH: "ON" + ENABLE_DTRACE: "ON" + VERBOSE: "ON" + MEMCACHED_BINARY: "/usr/local/bin/memcached" + +task: + name: Freebsd + env: + ports: RELEASE_12_1_0 + freebsd_instance: + image_family: freebsd-12-1 + dependencies_script: | + pkg update + pkg upgrade -y + pkg install -y \ + autotools \ + bison \ + cmake \ + cyrus-sasl \ + flex \ + libevent \ + pkgconf \ + subversion \ + sudo + memcached_script: | + svn co https://svn.freebsd.org/ports/tags/${ports}/databases/memcached memcached + svn co https://svn.freebsd.org/ports/tags/${ports}/Mk /usr/ports/Mk + svn co https://svn.freebsd.org/ports/tags/${ports}/Templates /usr/ports/Templates + cd memcached + echo bin/memcached > pkg-plist + make all install SASLPWDB_CONFIGURE_ENABLE=sasl-pwdb OPTIONS_SET="SASL SASLPWDB" OPTIONS_DEFINE="SASL SASLPWDB" + cd .. + prepare_script: | + mkdir build + chown nobody build + chsh -s /bin/sh nobody + configure_script: | + sudo -E -u nobody cmake -S . -B build + build_script: | + sudo -E -u nobody make -C build -j2 all + test_script: | + sudo -E -u nobody make -C build -j2 test/fast + install_script: | + sudo -E -u nobody make -C build install DESTDIR=/tmp + on_failure: + failed_script: | + cat build/Testing/Temporary/LastTest.log || true diff --git a/.github/workflows/cmake-build-ci.gen b/.github/workflows/cmake-build-ci.gen index 0d1e1be0..c6bd81fb 100755 --- a/.github/workflows/cmake-build-ci.gen +++ b/.github/workflows/cmake-build-ci.gen @@ -191,6 +191,7 @@ on: paths-ignore: - "docs/**" - ".travis.yml" + - ".cirrus.yml" branches-ignore: - gh-pages - catch diff --git a/.github/workflows/cmake-build-ci.yml b/.github/workflows/cmake-build-ci.yml index 492c4d53..3209d0ad 100644 --- a/.github/workflows/cmake-build-ci.yml +++ b/.github/workflows/cmake-build-ci.yml @@ -5,6 +5,7 @@ on: paths-ignore: - "docs/**" - ".travis.yml" + - ".cirrus.yml" branches-ignore: - gh-pages - catch diff --git a/CMake/EnableDtrace.cmake b/CMake/EnableDtrace.cmake new file mode 100644 index 00000000..184a327a --- /dev/null +++ b/CMake/EnableDtrace.cmake @@ -0,0 +1,55 @@ +function(enable_dtrace_for TARGET PROBES_D PROBES_H) + if(HAVE_DTRACE AND NOT CMAKE_CROSSCOMPILING) + target_sources(${TARGET} PRIVATE ${PROBES_H}) + add_custom_command( + OUTPUT + ${PROBES_H} + MAIN_DEPENDENCY + ${PROBES_D} + COMMAND + ${DTRACE_EXECUTABLE} + ARGS + -x nolibs -h + -s ${CMAKE_CURRENT_SOURCE_DIR}/${PROBES_D} + -o ${PROBES_H} + ) + if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") + add_custom_command( + OUTPUT + ${TARGET}_probes.o + MAIN_DEPENDENCY + ${PROBES_H} + COMMAND + ${DTRACE_EXECUTABLE} + ARGS + -x nolibs -G + -s ${CMAKE_CURRENT_SOURCE_DIR}/${PROBES_D} + -o ${TARGET}_probes.o + ) + target_sources(${TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_probes.o) + set_source_files_properties(${TARGET}_probes.o PROPERTIES + GENERATED true + EXTERNAL_OBJECT true) + else() # not Linux + set(PROBES_C ${TARGET}_probes.cc) + file(GENERATE + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PROBES_C} + CONTENT "#include \"${PROBES_H}\"" + ) + add_custom_command( + TARGET ${TARGET} + PRE_LINK + DEPENDS + ${PROBES_H} + COMMAND + rm -f ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TARGET}.dir/${PROBES_C}.o + COMMAND + ${DTRACE_EXECUTABLE} -x nolibs -G + -s ${CMAKE_CURRENT_SOURCE_DIR}/${PROBES_D} + -o ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TARGET}.dir/${PROBES_C}.o + ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TARGET}.dir/*.o + ) + target_sources(${TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/${PROBES_C}) + endif() + endif() +endfunction() diff --git a/CMake/_Include.cmake b/CMake/_Include.cmake index a6b5463c..67fe16bf 100644 --- a/CMake/_Include.cmake +++ b/CMake/_Include.cmake @@ -6,6 +6,12 @@ endif() include(GNUInstallDirs) include(CMakePackageConfigHelpers) +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "FreeBSD") + find_program(PKGCONF pkgconf) + if(PKGCONF) + set(PKG_CONFIG_EXECUTABLE ${PKGCONF}) + endif() +endif() find_package(PkgConfig) set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) @@ -34,6 +40,7 @@ if(ENABLE_MEMASLAP) endif() ## dtrace +include(EnableDtrace) if(ENABLE_DTRACE) find_package(DTrace) if(DTRACE_EXECUTABLE) @@ -69,10 +76,10 @@ endif() # system checks +check_header(alloca.h) check_header(arpa/inet.h) check_header(dlfcn.h) check_header(errno.h) -check_header(execinfo.h) check_header(fcntl.h) check_header(io.h) check_header(limits.h) @@ -103,8 +110,13 @@ check_decl(setenv stdlib.h) check_decl(strerror string.h) check_decl(strerror_r string.h) check_compiles(HAVE_STRERROR_R_CHAR_P "char x, y = *strerror_r(0,&x,1);" string.h) + check_decl(abi::__cxa_demangle cxxabi.h) -set(HAVE_GCC_ABI_DEMANGLE ${HAVE_ABI____CXA_DEMANGLE}) + +find_package(Backtrace) +if(Backtrace_FOUND) + set(HAVE_BACKTRACE 1) +endif() check_type(in_port_t netinet/in.h) diff --git a/src/bin/common/CMakeLists.txt b/src/bin/common/CMakeLists.txt index c452049a..d1fd699e 100644 --- a/src/bin/common/CMakeLists.txt +++ b/src/bin/common/CMakeLists.txt @@ -1,6 +1,6 @@ add_library(libclient_common STATIC utilities.cc generator.cc execute.cc) add_library(client_common ALIAS libclient_common) -target_link_libraries(libclient_common PRIVATE libmemcachedinternal) +target_link_libraries(libclient_common PUBLIC libmemcachedinternal) target_include_directories(libclient_common PUBLIC . ${CMAKE_SOURCE_DIR}/include diff --git a/src/libmemcached/CMakeLists.txt b/src/libmemcached/CMakeLists.txt index a029ac58..819a98f7 100644 --- a/src/libmemcached/CMakeLists.txt +++ b/src/libmemcached/CMakeLists.txt @@ -2,7 +2,7 @@ find_package(FLEX) find_package(BISON 2.3) -if(${BISON_VERSION} VERSION_GREATER_EQUAL 3.0) +if("${BISON_VERSION}" VERSION_GREATER_EQUAL 3.0) set(BISON_WARNINGS -Wno-deprecated) endif() @@ -18,27 +18,10 @@ flex_target(CSL_SCANNER csl/scanner.l ${CMAKE_CURRENT_BINARY_DIR}/csl/scanner.cc set_source_files_properties(${FLEX_CSL_SCANNER_OUTPUTS} PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) add_flex_bison_dependency(CSL_SCANNER CSL_PARSER) -if(HAVE_DTRACE) - add_custom_command( - OUTPUT dtrace_probes.h - COMMAND ${DTRACE_EXECUTABLE} - ARGS -h -o dtrace_probes.h -s ${CMAKE_CURRENT_SOURCE_DIR}/libmemcached_probes.d - MAIN_DEPENDENCY libmemcached_probes.d - ) - add_custom_command( - OUTPUT libmemcached_probes.o - COMMAND ${DTRACE_EXECUTABLE} - ARGS -o libmemcached_probes.o -G -s ${CMAKE_CURRENT_SOURCE_DIR}/libmemcached_probes.d - MAIN_DEPENDENCY dtrace_probes.h - ) - set(DTRACE_GENERATED_OUTPUT libmemcached_probes.o) -endif() - set(LIBMEMCACHED_SOURCES csl/context.cc ${BISON_CSL_PARSER_OUTPUTS} ${FLEX_CSL_SCANNER_OUTPUTS} - ${DTRACE_GENERATED_OUTPUT} allocators.cc analyze.cc array.c @@ -97,17 +80,20 @@ set_target_properties(libmemcached PROPERTIES SOVERSION ${LIBMEMCACHED_SO_VERSION} VERSION v${LIBMEMCACHED_VERSION}) target_compile_definitions(libmemcached PRIVATE -DBUILDING_LIBMEMCACHED) -target_link_libraries(libmemcached PUBLIC libhashkit Threads::Threads ${LIBSASL_LIBRARIES} ${CMAKE_DL_LIBS}) -target_include_directories(libmemcached PRIVATE ${LIBSASL_INCLUDEDIR}) +target_link_libraries(libmemcached PUBLIC libhashkit Threads::Threads ${LIBSASL_LIBRARIES} ${CMAKE_DL_LIBS} ${Backtrace_LIBRARIES}) +target_include_directories(libmemcached PRIVATE ${Backtrace_INCLUDE_DIR}) target_include_directories(libmemcached PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_BINARY_DIR}/src ${CMAKE_BINARY_DIR}) +target_include_directories(libmemcached PUBLIC ${LIBSASL_INCLUDEDIR}) target_include_directories(libmemcached PUBLIC $ $ $) +enable_dtrace_for(libmemcached libmemcached_probes.d dtrace_probes.h) + install(TARGETS libmemcached EXPORT libmemcached-targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) export(EXPORT libmemcached-targets NAMESPACE libmemcached::) @@ -126,17 +112,20 @@ add_library(libmemcachedinternal STATIC add_library(memcachedinternal ALIAS libmemcachedinternal) set_target_properties(libmemcachedinternal PROPERTIES LIBRARY_OUTPUT_NAME memcachedinternal) target_compile_definitions(libmemcachedinternal PRIVATE -DBUILDING_LIBMEMCACHEDINTERNAL) -target_link_libraries(libmemcachedinternal PUBLIC libhashkit Threads::Threads ${LIBSASL_LIBRARIES} ${CMAKE_DL_LIBS}) -target_include_directories(libmemcachedinternal PRIVATE ${LIBSASL_INCLUDEDIR}) +target_link_libraries(libmemcachedinternal PUBLIC libhashkit Threads::Threads ${LIBSASL_LIBRARIES} ${CMAKE_DL_LIBS} ${Backtrace_LIBRARIES}) +target_include_directories(libmemcachedinternal PRIVATE ${Backtrace_INCLUDE_DIR}) target_include_directories(libmemcachedinternal PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_BINARY_DIR}/src ${CMAKE_BINARY_DIR}) +target_include_directories(libmemcachedinternal PUBLIC ${LIBSASL_INCLUDEDIR}) target_include_directories(libmemcachedinternal PUBLIC $ $ $) +enable_dtrace_for(libmemcachedinternal libmemcached_probes.d dtrace_probes.h) + # let libmemcached depend on libmemcachedinternal to ensure that they do not # compete for the same generated dependencies add_dependencies(libmemcached libmemcachedinternal) diff --git a/src/libmemcached/assert.hpp b/src/libmemcached/assert.hpp index a1526bab..de2283a7 100644 --- a/src/libmemcached/assert.hpp +++ b/src/libmemcached/assert.hpp @@ -1,5 +1,5 @@ /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * + * * libmcachedd client library. * * Copyright (C) 2011-2013 Data Differential, http://datadifferential.com/ @@ -50,7 +50,7 @@ # ifdef _WIN32 # include -# else +# elif HAVE_ALLOCA_H # include # endif diff --git a/src/libmemcached/backtrace.cc b/src/libmemcached/backtrace.cc index e171fbeb..8017f7a2 100644 --- a/src/libmemcached/backtrace.cc +++ b/src/libmemcached/backtrace.cc @@ -1,5 +1,5 @@ /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * + * * Libmemcached client library. * * Copyright (C) 2012 Data Differential, http://datadifferential.com/ @@ -43,13 +43,11 @@ #include #include -#if defined(HAVE_SHARED_ENABLED) && HAVE_SHARED_ENABLED +#if HAVE_BACKTRACE -#ifdef HAVE_EXECINFO_H -#include -#endif +#include BACKTRACE_HEADER -#ifdef HAVE_GCC_ABI_DEMANGLE +#if HAVE_ABI____CXA_DEMANGLE # include # define USE_DEMANGLE 1 #else @@ -58,13 +56,12 @@ #ifdef HAVE_DLFCN_H # include -#endif +#endif const int MAX_DEPTH= 50; void custom_backtrace(void) { -#ifdef HAVE_EXECINFO_H void *backtrace_buffer[MAX_DEPTH +1]; int stack_frames= backtrace(backtrace_buffer, MAX_DEPTH); @@ -73,7 +70,7 @@ void custom_backtrace(void) char **symbollist= backtrace_symbols(backtrace_buffer, stack_frames); if (symbollist) { - for (int x= 0; x < stack_frames; x++) + for (int x= 0; x < stack_frames; x++) { bool was_demangled= false; @@ -119,13 +116,12 @@ void custom_backtrace(void) ::free(symbollist); } } -#endif // HAVE_EXECINFO_H } -#else // HAVE_SHARED_ENABLED +#else // HAVE_BACKTRACE void custom_backtrace(void) { fprintf(stderr, "Backtrace null function called\n"); } -#endif // AX_ENABLE_BACKTRACE +#endif // HAVE_BACKTRACE diff --git a/src/libmemcachedutil/CMakeLists.txt b/src/libmemcachedutil/CMakeLists.txt index c1110b47..7e2a6e67 100644 --- a/src/libmemcachedutil/CMakeLists.txt +++ b/src/libmemcachedutil/CMakeLists.txt @@ -25,6 +25,7 @@ target_include_directories(libmemcachedutil PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_BINARY_DIR}/src ${CMAKE_BINARY_DIR}) +target_include_directories(libmemcachedutil PUBLIC ${LIBSASL_INCLUDEDIR}) target_include_directories(libmemcachedutil PUBLIC $ $ diff --git a/src/mem_config.h.in b/src/mem_config.h.in index 1d1d3d29..9609ab40 100644 --- a/src/mem_config.h.in +++ b/src/mem_config.h.in @@ -8,11 +8,13 @@ #cmakedefine HAVE_C_STDATOMIC 1 #cmakedefine HAVE_CXX_STDATOMIC 1 +#cmakedefine HAVE_ABI____CXA_DEMANGLE 1 +#cmakedefine HAVE_BACKTRACE 1 +#cmakedefine HAVE_ALLOCA_H 1 #cmakedefine HAVE_ARPA_INET_H 1 #cmakedefine HAVE_DLFCN_H 1 #cmakedefine HAVE_DTRACE 1 #cmakedefine HAVE_ERRNO_H 1 -#cmakedefine HAVE_EXECINFO_H 1 #cmakedefine HAVE_FCNTL 1 #cmakedefine HAVE_FCNTL_H 1 #cmakedefine HAVE_FNV64_HASH 1 @@ -54,8 +56,6 @@ #cmakedefine HAVE_WINSOCK2_H 1 #cmakedefine HAVE_WS2TCPIP_H 1 -#cmakedefine HAVE_ABI____CXA_DEMANGLE 1 -#cmakedefine HAVE_GCC_ABI_DEMANGLE 1 #cmakedefine HAVE_CINTTYPES 1 #cmakedefine HAVE_CSTDINT 1 @@ -69,4 +69,8 @@ # include #endif +#if HAVE_BACKTRACE +# define BACKTRACE_HEADER <@Backtrace_HEADER@> +#endif + #define HAVE_LIBMEMCACHED 1 diff --git a/test/lib/Server.cpp b/test/lib/Server.cpp index af6e41ba..2744f3e1 100644 --- a/test/lib/Server.cpp +++ b/test/lib/Server.cpp @@ -67,7 +67,8 @@ vector Server::createArgv() { vector arr; pushArg(arr, binary); - //pushArg(arr, "-v"); + pushArg(arr, "-u"); + pushArg(arr, "nobody"); for (auto it = args.cbegin(); it != args.cend(); ++it) { if (holds_alternative(*it)) { diff --git a/test/lib/random.hpp b/test/lib/random.hpp index 18e518c3..1984e89c 100644 --- a/test/lib/random.hpp +++ b/test/lib/random.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -17,9 +18,10 @@ enable_if_t, T> random_num(T min, T max) { using rnd = mt19937; using dst = uniform_int_distribution; - auto time = duration_cast(system_clock::now().time_since_epoch()); - auto seed = static_cast(time.count() % numeric_limits::max()); - auto rgen = rnd{seed}; + static auto time = duration_cast(system_clock::now().time_since_epoch()); + static auto seed = static_cast(time.count() % numeric_limits::max()); + static auto rgen = rnd{seed}; + return dst(min, max)(rgen); } diff --git a/test/tests/bin/memcp.cpp b/test/tests/bin/memcp.cpp index ef234cbe..83fe9749 100644 --- a/test/tests/bin/memcp.cpp +++ b/test/tests/bin/memcp.cpp @@ -63,7 +63,11 @@ TEST_CASE("bin/memcp") { string output; REQUIRE_FALSE(sh.run(comm + temp.getFn(), output)); - REQUIRE_THAT(output, Contains("CONNECTION FAILURE")); + REQUIRE_THAT(output, + Contains("CONNECTION FAILURE") + || Contains("SERVER HAS FAILED") + || Contains("SYSTEM ERROR") + || Contains("TIMEOUT OCCURRED")); } SECTION("file not found") { diff --git a/test/tests/bin/memdump.cpp b/test/tests/bin/memdump.cpp index b2caa3d1..e16f5e3e 100644 --- a/test/tests/bin/memdump.cpp +++ b/test/tests/bin/memdump.cpp @@ -56,7 +56,11 @@ TEST_CASE("bin/memdump") { string output; REQUIRE_FALSE(sh.run(comm + "-v", output)); - REQUIRE_THAT(output, Contains("CONNECTION FAILURE") || Contains("SERVER HAS FAILED")); + REQUIRE_THAT(output, + Contains("CONNECTION FAILURE") + || Contains("SERVER HAS FAILED") + || Contains("SYSTEM ERROR") + || Contains("TIMEOUT OCCURRED")); } SECTION("empty") { diff --git a/test/tests/bin/memflush.cpp b/test/tests/bin/memflush.cpp index 45246fa0..b512b8e2 100644 --- a/test/tests/bin/memflush.cpp +++ b/test/tests/bin/memflush.cpp @@ -62,7 +62,11 @@ TEST_CASE("bin/memflush") { string output; REQUIRE_FALSE(sh.run(comm, output)); - REQUIRE_THAT(output, Contains("CONNECTION FAILURE") || Contains("SERVER HAS FAILED")); + REQUIRE_THAT(output, + Contains("CONNECTION FAILURE") + || Contains("SERVER HAS FAILED") + || Contains("SYSTEM ERROR") + || Contains("TIMEOUT OCCURRED")); } } } diff --git a/test/tests/bin/memping.cpp b/test/tests/bin/memping.cpp index ab56fa12..bd6b6ced 100644 --- a/test/tests/bin/memping.cpp +++ b/test/tests/bin/memping.cpp @@ -49,7 +49,11 @@ TEST_CASE("bin/memping") { string output; REQUIRE_FALSE(sh.run(comm, output)); - REQUIRE_THAT(output, Contains("CONNECTION FAILURE") || Contains("SERVER HAS FAILED")); + REQUIRE_THAT(output, + Contains("CONNECTION FAILURE") + || Contains("SERVER HAS FAILED") + || Contains("SYSTEM ERROR") + || Contains("TIMEOUT OCCURRED")); } } } diff --git a/test/tests/bin/memrm.cpp b/test/tests/bin/memrm.cpp index b4a7fd01..d6a9f7d4 100644 --- a/test/tests/bin/memrm.cpp +++ b/test/tests/bin/memrm.cpp @@ -69,7 +69,11 @@ TEST_CASE("bin/memrm") { string output; REQUIRE_FALSE(sh.run(comm + " -v key2", output)); - REQUIRE_THAT(output, Contains("CONNECTION FAILURE") || Contains("SERVER HAS FAILED")); + REQUIRE_THAT(output, + Contains("CONNECTION FAILURE") + || Contains("SERVER HAS FAILED") + || Contains("SYSTEM ERROR") + || Contains("TIMEOUT OCCURRED")); } } } diff --git a/test/tests/bin/memstat.cpp b/test/tests/bin/memstat.cpp index 87db31d4..431d1ce7 100644 --- a/test/tests/bin/memstat.cpp +++ b/test/tests/bin/memstat.cpp @@ -64,7 +64,11 @@ TEST_CASE("bin/memstat") { string output; REQUIRE_FALSE(sh.run(comm + "--analyze", output)); - REQUIRE_THAT(output, Contains("CONNECTION FAILURE") || Contains("SERVER HAS FAILED")); + REQUIRE_THAT(output, + Contains("CONNECTION FAILURE") + || Contains("SERVER HAS FAILED") + || Contains("SYSTEM ERROR") + || Contains("TIMEOUT OCCURRED")); } } } diff --git a/test/tests/memcached/util.cpp b/test/tests/memcached/util.cpp index ae91ffa4..35a76b7e 100644 --- a/test/tests/memcached/util.cpp +++ b/test/tests/memcached/util.cpp @@ -53,7 +53,7 @@ TEST_CASE("memcached_util") { } REQUIRE(-1 == libmemcached_util_getpid("localhost", 1, &rc)); - REQUIRE_RC(MEMCACHED_CONNECTION_FAILURE, rc); + REQUIRE(memcached_fatal(rc)); } SECTION("ping") { -- 2.30.2 From 52f96be72d2f18994d6133c4410c263133270f0e Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 13 Oct 2020 08:42:17 +0200 Subject: [PATCH 06/16] fix warning --- src/libmemcached/hosts.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libmemcached/hosts.cc b/src/libmemcached/hosts.cc index 630a52d0..ab58c922 100644 --- a/src/libmemcached/hosts.cc +++ b/src/libmemcached/hosts.cc @@ -1,5 +1,5 @@ /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * + * * Libmemcached library * * Copyright (C) 2011 Data Differential, http://datadifferential.com/ @@ -264,7 +264,7 @@ static memcached_return_t update_continuum(Memcached *ptr) if (size_t(sort_host_length) >= sizeof(sort_host) or sort_host_length < 0) { - return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, + return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, memcached_literal_param("snprintf(sizeof(sort_host))")); } @@ -317,7 +317,7 @@ static memcached_return_t update_continuum(Memcached *ptr) if (size_t(sort_host_length) >= sizeof(sort_host) or sort_host_length < 0) { - return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, + return memcached_set_error(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, memcached_literal_param("snprintf(sizeof(sort_host)))")); } @@ -359,7 +359,7 @@ static memcached_return_t update_continuum(Memcached *ptr) return MEMCACHED_SUCCESS; } -static memcached_return_t server_add(Memcached *memc, +static memcached_return_t server_add(Memcached *memc, const memcached_string_t& hostname, in_port_t port, uint32_t weight, @@ -441,7 +441,7 @@ memcached_return_t memcached_server_push(memcached_st *shell, const memcached_se WATCHPOINT_ASSERT(instance); memcached_string_t hostname= { memcached_string_make_from_cstr(list[x].hostname) }; - if (__instance_create_with(ptr, instance, + if (__instance_create_with(ptr, instance, hostname, list[x].port, list[x].weight, list[x].type) == NULL) { @@ -494,7 +494,7 @@ memcached_return_t memcached_instance_push(memcached_st *ptr, const struct memca WATCHPOINT_ASSERT(instance); memcached_string_t hostname= { memcached_string_make_from_cstr(list[x]._hostname) }; - if (__instance_create_with(ptr, instance, + if (__instance_create_with(ptr, instance, hostname, list[x].port(), list[x].weight, list[x].type) == NULL) { -- 2.30.2 From 04e64c9f685ccf00e11238b0e19dc722f8630233 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 13 Oct 2020 08:43:12 +0200 Subject: [PATCH 07/16] fix warning (double promotion) --- src/libmemcached/hosts.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libmemcached/hosts.cc b/src/libmemcached/hosts.cc index ab58c922..b8292b2b 100644 --- a/src/libmemcached/hosts.cc +++ b/src/libmemcached/hosts.cc @@ -232,7 +232,7 @@ static memcached_return_t update_continuum(Memcached *ptr) if (memcached_is_weighted_ketama(ptr)) { float pct= (float)list[host_index].weight / (float)total_weight; - pointer_per_server= (uint32_t) ((::floor((float) (pct * MEMCACHED_POINTS_PER_SERVER_KETAMA / 4 * (float)live_servers + 0.0000000001))) * 4); + pointer_per_server= (uint32_t) ((::floor((float) (pct * MEMCACHED_POINTS_PER_SERVER_KETAMA / 4 * (float)live_servers + 0.0000000001F))) * 4); pointer_per_hash= 4; if (0 && DEBUG) { -- 2.30.2 From 03ba544b4ef8a00bd4d51dfde1ed2bfb477096dc Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 13 Oct 2020 08:43:44 +0200 Subject: [PATCH 08/16] testing: parser --- test/lib/env.hpp | 17 +++++ test/setup.cpp | 16 ++--- test/tests/memcached/parser.cpp | 34 ++++++++++ tests/parser.cc | 107 -------------------------------- 4 files changed, 56 insertions(+), 118 deletions(-) create mode 100644 test/lib/env.hpp create mode 100644 test/tests/memcached/parser.cpp delete mode 100644 tests/parser.cc diff --git a/test/lib/env.hpp b/test/lib/env.hpp new file mode 100644 index 00000000..814e2a15 --- /dev/null +++ b/test/lib/env.hpp @@ -0,0 +1,17 @@ +#include "mem_config.h" + +#include + +#if HAVE_SETENV +# define SET_ENV_EX(n, k, v, overwrite) setenv(k, v, (overwrite)) +#else // !HAVE_SETENV +# define SET_ENV_EX(n, k, v, overwrite) do { \ + static char n ## _env[] = k "=" v; \ + if ((overwrite) || !getenv(k)) { \ + putenv(n ## _env); \ + } \ +} while(false) +#endif + +#define SET_ENV(symbolic_name, literal_env_var, literal_env_val) \ + SET_ENV_EX(symbolic_name, literal_env_var, literal_env_val, true) diff --git a/test/setup.cpp b/test/setup.cpp index 1f4c9a47..493b591f 100644 --- a/test/setup.cpp +++ b/test/setup.cpp @@ -1,17 +1,11 @@ #include "mem_config.h" +#include "test/lib/env.hpp" #include #include #include #include #include #include -#include - -#if HAVE_SETENV -# define SET_ENV(n, k, v) setenv(k, v, 0) -#else // !HAVE_SETENV -# define SET_ENV(n, k, v) static char n ## _env[] = k "=" v; putenv(n ## _env) -#endif static void sigchld(int, siginfo_t *si, void *) { switch (si->si_code) { @@ -64,19 +58,19 @@ static inline void setup_asan(char **argv) { const auto set = getenv("ASAN_OPTIONS"); if (!set || !*set) { - SET_ENV(asan, "ASAN_OPTIONS", ASAN_OPTIONS); + SET_ENV_EX(asan, "ASAN_OPTIONS", ASAN_OPTIONS, 0); execvp(argv[0], argv); perror("exec()"); } } #else -# define setup_asan(a) +# define setup_asan(a) (void) a #endif #if LIBMEMCACHED_WITH_SASL_SUPPORT static inline void setup_sasl() { - SET_ENV(sasl_pwdb, "MEMCACHED_SASL_PWDB", LIBMEMCACHED_WITH_SASL_PWDB); - SET_ENV(sasl_conf, "SASL_CONF_PATH", LIBMEMCACHED_WITH_SASL_CONF); + SET_ENV_EX(sasl_pwdb, "MEMCACHED_SASL_PWDB", LIBMEMCACHED_WITH_SASL_PWDB, 0); + SET_ENV_EX(sasl_conf, "SASL_CONF_PATH", LIBMEMCACHED_WITH_SASL_CONF, 0); } #else # define setup_sasl() diff --git a/test/tests/memcached/parser.cpp b/test/tests/memcached/parser.cpp new file mode 100644 index 00000000..ca7fa400 --- /dev/null +++ b/test/tests/memcached/parser.cpp @@ -0,0 +1,34 @@ +#include "test/lib/common.hpp" +#include "test/lib/env.hpp" + +TEST_CASE("memcached_parser") { + SECTION("fail: null string") { + REQUIRE_FALSE(memcached(nullptr, 123)); + } + SECTION("fail: zero length") { + REQUIRE_FALSE(memcached("123", 0)); + } + SECTION("success: localhost") { + auto mc = memcached(S("--server=localhost")); + REQUIRE(mc); + memcached_free(mc); + } + SECTION("env") { + SECTION("success: localhost") { + SET_ENV(success_localhost, "LIBMEMCACHED", "--server=localhost"); + auto mc = memcached(nullptr, 0); + REQUIRE(mc); + memcached_free(mc); + } + SECTION("success: empty string") { + SET_ENV(success_empty_string, "LIBMEMCACHED", ""); + auto mc = memcached(nullptr, 0); + REQUIRE(mc); + memcached_free(mc); + } + SECTION("fail: extra quotes") { + SET_ENV(fail_extra_quotes, "LIBMEMCACHED", "\"--server=localhost\""); + REQUIRE_FALSE(memcached(nullptr, 0)); + } + } +} diff --git a/tests/parser.cc b/tests/parser.cc deleted file mode 100644 index 5e164a3b..00000000 --- a/tests/parser.cc +++ /dev/null @@ -1,107 +0,0 @@ -/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * - * Libmemcached library - * - * Copyright (C) 2012 Data Differential, http://datadifferential.com/ - * - * 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 "mem_config.h" - -/* - C++ interface test -*/ -#include "libmemcached-1.0/memcached.hpp" -#include "libtest/test.hpp" - -using namespace libtest; - -static test_return_t memcached_NULL_string_TEST(void*) -{ - test_null(memcached(NULL, 75)); - return TEST_SUCCESS; -} - -static test_return_t memcached_zero_string_length_TEST(void*) -{ - test_null(memcached("value", 0)); - return TEST_SUCCESS; -} - -static test_return_t putenv_localhost_quoted_TEST(void*) -{ - test_zero(setenv("LIBMEMCACHED", "\"--server=localhost\"", 1)); - test_null(memcached(NULL, 0)); - - return TEST_SUCCESS; -} - -static test_return_t putenv_NULL_TEST(void*) -{ - test_zero(setenv("LIBMEMCACHED", "", 1)); - memcached_st *memc= memcached(NULL, 0); - test_true(memc); - - memcached_free(memc); - - return TEST_SUCCESS; -} - -static test_return_t putenv_localhost_TEST(void*) -{ - test_zero(setenv("LIBMEMCACHED", "--server=localhost", 1)); - memcached_st *memc= memcached(NULL, 0); - test_true(memc); - - memcached_free(memc); - - return TEST_SUCCESS; -} - -test_st memcached_TESTS[] ={ - {"memcached(NULL, 75)", false, (test_callback_fn*)memcached_NULL_string_TEST }, - {"memcached(\"value\", 0)", false, (test_callback_fn*)memcached_zero_string_length_TEST }, - {"putenv(LIBMEMCACHED=--server=localhost)", false, (test_callback_fn*)putenv_localhost_TEST }, - {"putenv(LIBMEMCACHED)", false, (test_callback_fn*)putenv_NULL_TEST }, - {"putenv(LIBMEMCACHED=--server=\"localhost\")", false, (test_callback_fn*)putenv_localhost_quoted_TEST }, - {0, 0, 0} -}; - -collection_st collection[] ={ - {"memcached()", 0, 0, memcached_TESTS}, - {0, 0, 0, 0} -}; - -void get_world(libtest::Framework* world) -{ - world->collections(collection); -} - -- 2.30.2 From 89d42d1063873a0ffd7e618253ff94c9d2b653ec Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 13 Oct 2020 11:54:18 +0200 Subject: [PATCH 09/16] fix include --- test/setup.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/setup.cpp b/test/setup.cpp index 493b591f..9591a356 100644 --- a/test/setup.cpp +++ b/test/setup.cpp @@ -6,6 +6,7 @@ #include #include #include +#include static void sigchld(int, siginfo_t *si, void *) { switch (si->si_code) { -- 2.30.2 From 2dd79b61ec7944b82ec6b576cc081603ec526049 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 13 Oct 2020 11:56:03 +0200 Subject: [PATCH 10/16] testing: parser --- test/fixtures/parser.hpp | 200 ++++++++ test/lib/env.hpp | 2 + test/tests/memcached/parser.cpp | 17 + tests/libmemcached-1.0/parser.cc | 782 ------------------------------- tests/libmemcached-1.0/parser.h | 118 ----- 5 files changed, 219 insertions(+), 900 deletions(-) create mode 100644 test/fixtures/parser.hpp delete mode 100644 tests/libmemcached-1.0/parser.cc delete mode 100644 tests/libmemcached-1.0/parser.h diff --git a/test/fixtures/parser.hpp b/test/fixtures/parser.hpp new file mode 100644 index 00000000..2c72302d --- /dev/null +++ b/test/fixtures/parser.hpp @@ -0,0 +1,200 @@ +#pragma once + +#include +#include +#include + +using namespace std; + +struct c_string { + const char *c_str; + size_t size; + + c_string(const char *s, size_t l) noexcept + : c_str{s} + , size{l} + {} + bool operator ==(const c_string &cs) const noexcept { + return !strcmp(c_str, cs.c_str); + } + bool operator ==(const char *p) const noexcept { + return !strcmp(c_str, p); + } +}; + +static c_string null_c_string{nullptr, 0}; + +struct test_case { + using setting_key_t = variant; + using setting_t = pair; + using result_t = variant; + c_string option; + result_t result; + + test_case(c_string o, c_string r) noexcept + : option{o} + , result{r} + {} + test_case(const char *os, size_t ol, const char *rs, size_t rl) noexcept + : option{os, ol} + , result{c_string{rs, rl}} + {} + test_case(const char *os, size_t ol, memcached_behavior_t b, uint64_t v) noexcept + : option{os, ol} + , result{setting_t{b, v}} + {} + test_case(const char *os, size_t ol, memcached_flag_t f, uint64_t v) noexcept + : option{os, ol} + , result{setting_t{f, v}} + {} +}; + +#define test_count(tca) (sizeof(tca)/sizeof(tca[0])) + +struct test_group { + using check_func = function; + const char *name; + check_func check; + test_case *tests; + size_t ntests; + + test_group(const char *name_, check_func check_, test_case *tests_, size_t ntests_) noexcept + : name{name_} + , check{move(check_)} + , tests{tests_} + , ntests{ntests_} + {} +}; + +static test_case host_string_tests[] = { + {S("--server=localhost"), S("localhost")}, + {S("--server=10.0.2.1"), S("10.0.2.1")}, + {S("--server=example.com"), S("example.com")}, + {S("--server=localhost:30"), S("localhost")}, + {S("--server=10.0.2.1:20"), S("10.0.2.1")}, + {S("--server=example.com:1024"), S("example.com")}, + {S("--server=10.0.2.1:30/?40"), S("10.0.2.1")}, + {S("--server=example.com:1024/?30"), S("example.com")}, + {S("--server=10.0.2.1/?20"), S("10.0.2.1")}, + {S("--server=example.com/?10"), S("example.com")}, +}; + +static test_group test_host_strings{ + "host strings", + [](memcached_st *memc, const test_case::result_t &result) { + auto instance = memcached_server_instance_by_position(memc, 0); + REQUIRE(instance); + REQUIRE(get(result) == memcached_server_name(instance)); + }, + host_string_tests, + test_count(host_string_tests) +}; + +static test_case bad_host_string_tests[] = { + {{S("-servers=localhost:11221,localhost:11222,localhost:11223,localhost:11224,localhost:11225")}, null_c_string}, + {{S("-- servers=a.example.com:81,localhost:82,b.example.com")}, null_c_string}, + {{S("--servers=localhost:+80")}, null_c_string}, + // all of the following should not fail IMO + {{S("--servers=localhost.com.")}, null_c_string}, + {{S("--server=localhost.com.")}, null_c_string}, + {{S("--server=localhost.com.:80")}, null_c_string}, +}; + +static test_group test_bad_host_strings{ + "bad host strings", + [](memcached_st *memc, const test_case::result_t &) { + REQUIRE_FALSE(memc); + }, + bad_host_string_tests, + test_count(bad_host_string_tests) +}; + +static test_case behavior_tests[] = { + {S("--CONNECT-TIMEOUT=456"), MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 456}, + {S("--IO-BYTES-WATERMARK=456"), MEMCACHED_BEHAVIOR_IO_BYTES_WATERMARK, 456}, + {S("--IO-KEY-PREFETCH=456"), MEMCACHED_BEHAVIOR_IO_KEY_PREFETCH, 456}, + {S("--IO-MSG-WATERMARK=456"), MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 456}, + {S("--NUMBER-OF-REPLICAS=456"), MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 456}, + {S("--POLL-TIMEOUT=456"), MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 456}, + {S("--RCV-TIMEOUT=456"), MEMCACHED_BEHAVIOR_RCV_TIMEOUT, 456}, + {S("--REMOVE-FAILED-SERVERS=3"), MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, 1}, + {S("--RETRY-TIMEOUT=456"), MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 456}, + {S("--SND-TIMEOUT=456"), MEMCACHED_BEHAVIOR_SND_TIMEOUT, 456}, + {S("--SOCKET-RECV-SIZE=456"), MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, 456}, + {S("--SOCKET-SEND-SIZE=456"), MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, 456}, + {S("--BINARY-PROTOCOL"), MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1}, + {S("--BUFFER-REQUESTS"), MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1}, + {S("--NOREPLY"), MEMCACHED_BEHAVIOR_NOREPLY, 1}, + {S("--RANDOMIZE-REPLICA-READ"), MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, 1}, + {S("--SORT-HOSTS"), MEMCACHED_BEHAVIOR_SORT_HOSTS, 1}, + {S("--SUPPORT-CAS"), MEMCACHED_BEHAVIOR_SUPPORT_CAS, 1}, + {S("--TCP-NODELAY"), MEMCACHED_BEHAVIOR_TCP_NODELAY, 1}, + {S("--TCP-KEEPALIVE"), MEMCACHED_BEHAVIOR_TCP_KEEPALIVE, 1}, + {S("--TCP-KEEPIDLE"), MEMCACHED_BEHAVIOR_TCP_KEEPIDLE, 1}, + {S("--USE-UDP"), MEMCACHED_BEHAVIOR_USE_UDP, 1}, + {S("--VERIFY-KEY"), MEMCACHED_BEHAVIOR_VERIFY_KEY, 1}, + {S("--DISTRIBUTION=consistent"), MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT}, + {S("--DISTRIBUTION=consistent,CRC"), MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT}, + {S("--DISTRIBUTION=consistent,MD5"), MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT}, + {S("--DISTRIBUTION=consistent,JENKINS"), MEMCACHED_BEHAVIOR_KETAMA_HASH, MEMCACHED_HASH_JENKINS}, + {S("--DISTRIBUTION=random"), MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_RANDOM}, + {S("--DISTRIBUTION=modula"), MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_MODULA}, + {S("--HASH=CRC"), MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_CRC}, + {S("--HASH=FNV1A_32"), MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_FNV1A_32}, + {S("--HASH=FNV1_32"), MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_FNV1_32}, + {S("--HASH=JENKINS"), MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_JENKINS}, + {S("--HASH=MD5"), MEMCACHED_BEHAVIOR_HASH, MEMCACHED_HASH_MD5}, + +}; + +static test_group test_behaviors{ + "behaviors", + [](memcached_st *memc, const test_case::result_t &result) { + auto setting = get(result); + REQUIRE(memc); + REQUIRE(setting.second == + memcached_behavior_get(memc, get(setting.first))); + }, + behavior_tests, + test_count(behavior_tests) +}; + +static test_case flag_tests[] = { + {S("--FETCH-VERSION"), MEMCACHED_FLAG_IS_FETCHING_VERSION, 1}, + {S("--HASH-WITH-NAMESPACE"), MEMCACHED_FLAG_HASH_WITH_NAMESPACE, 1}, +}; + +static test_group test_flags{ + "flags", + [](memcached_st *memc, const test_case::result_t &result) { + auto setting = get(result); + REQUIRE(memc); + REQUIRE(setting.second == memcached_flag(*memc, get(setting.first))); + }, + flag_tests, + test_count(flag_tests) +}; + +static test_case namespace_tests[] = { + {S("--NAMESPACE=foo"), S("foo")}, + {S("--NAMESPACE=\"foo\""), S("foo")}, + {S("--NAMESPACE=\"The quick brown fox jumps over the lazy dog\""), S("The quick brown fox jumps over the lazy dog")}, +}; + +static test_group test_namespace{ + "namespace", + [](memcached_st *memc, const test_case::result_t &result) { + auto ns = get(result); + REQUIRE(memc); + REQUIRE(ns == memcached_get_namespace(*memc)); + }, + namespace_tests, + test_count(namespace_tests) +}; + +static test_group tests[] = { + test_host_strings, + test_bad_host_strings, + test_behaviors, + test_flags, +}; diff --git a/test/lib/env.hpp b/test/lib/env.hpp index 814e2a15..105fef5d 100644 --- a/test/lib/env.hpp +++ b/test/lib/env.hpp @@ -1,3 +1,5 @@ +#pragma once + #include "mem_config.h" #include diff --git a/test/tests/memcached/parser.cpp b/test/tests/memcached/parser.cpp index ca7fa400..20fbed41 100644 --- a/test/tests/memcached/parser.cpp +++ b/test/tests/memcached/parser.cpp @@ -1,6 +1,9 @@ #include "test/lib/common.hpp" #include "test/lib/env.hpp" +#include "libmemcached/common.h" +#include "test/fixtures/parser.hpp" + TEST_CASE("memcached_parser") { SECTION("fail: null string") { REQUIRE_FALSE(memcached(nullptr, 123)); @@ -31,4 +34,18 @@ TEST_CASE("memcached_parser") { REQUIRE_FALSE(memcached(nullptr, 0)); } } + + SECTION("fixtures") { + for (const auto &test : tests) { + DYNAMIC_SECTION(test.name) { + for (size_t i = 0; i < test.ntests; ++i) { + auto &tc = test.tests[i]; + DYNAMIC_SECTION(tc.option.c_str) { + MemcachedPtr memc(memcached(tc.option.c_str, tc.option.size)); + test.check(*memc, tc.result); + } + } + } + } + } } diff --git a/tests/libmemcached-1.0/parser.cc b/tests/libmemcached-1.0/parser.cc deleted file mode 100644 index b5204a83..00000000 --- a/tests/libmemcached-1.0/parser.cc +++ /dev/null @@ -1,782 +0,0 @@ -/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * - * Libmemcached Client and Server - * - * Copyright (C) 2011 Data Differential, http://datadifferential.com/ - * All rights reserved. - * - * 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 "mem_config.h" -#include "libtest/test.hpp" - -using namespace libtest; - -#include -#include -#include - -#include "libmemcached-1.0/memcached.h" -#include "libmemcachedutil-1.0/util.h" - -#include "tests/libmemcached-1.0/parser.h" -#include "tests/print.h" -#include "libmemcached/instance.hpp" - -enum scanner_type_t -{ - NIL, - UNSIGNED, - SIGNED, - ARRAY -}; - - -struct scanner_string_st { - const char *c_str; - size_t size; -}; - -static inline scanner_string_st scanner_string(const char *arg, size_t arg_size) -{ - scanner_string_st local= { arg, arg_size }; - return local; -} - -#define make_scanner_string(X) scanner_string((X), static_cast(sizeof(X) - 1)) - -static struct scanner_string_st scanner_string_null= { 0, 0}; - -struct scanner_variable_t { - enum scanner_type_t type; - struct scanner_string_st option; - struct scanner_string_st result; - test_return_t (*check_func)(memcached_st *memc, const scanner_string_st &hostname); -}; - -// Check and make sure the first host is what we expect it to be -static test_return_t __check_host(memcached_st *memc, const scanner_string_st &hostname) -{ - const memcached_instance_st * instance= - memcached_server_instance_by_position(memc, 0); - - test_true(instance); - - const char *first_hostname = memcached_server_name(instance); - test_true(first_hostname); - test_strcmp(first_hostname, hostname.c_str); - - return TEST_SUCCESS; -} - -// Check and make sure the prefix_key is what we expect it to be -static test_return_t __check_namespace(memcached_st *, const scanner_string_st &) -{ -#if 0 - const char *_namespace = memcached_get_namespace(memc); - test_true(_namespace); - test_strcmp(_namespace, arg.c_str); -#endif - - return TEST_SUCCESS; -} - -static test_return_t __check_IO_MSG_WATERMARK(memcached_st *memc, const scanner_string_st &value) -{ - uint64_t value_number; - - value_number= atoll(value.c_str); - - test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK) == value_number); - return TEST_SUCCESS; -} - -static test_return_t __check_REMOVE_FAILED_SERVERS(memcached_st *memc, const scanner_string_st &) -{ - test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS)); - return TEST_SUCCESS; -} - -static test_return_t __check_NOREPLY(memcached_st *memc, const scanner_string_st &) -{ - test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NOREPLY)); - return TEST_SUCCESS; -} - -static test_return_t __check_VERIFY_KEY(memcached_st *memc, const scanner_string_st &) -{ - test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_VERIFY_KEY)); - return TEST_SUCCESS; -} - -static test_return_t __check_distribution_RANDOM(memcached_st *memc, const scanner_string_st &) -{ - test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION) == MEMCACHED_DISTRIBUTION_RANDOM); - return TEST_SUCCESS; -} - -scanner_variable_t test_server_strings[]= { - { ARRAY, make_scanner_string("--server=localhost"), make_scanner_string("localhost"), __check_host }, - { ARRAY, make_scanner_string("--server=10.0.2.1"), make_scanner_string("10.0.2.1"), __check_host }, - { ARRAY, make_scanner_string("--server=example.com"), make_scanner_string("example.com"), __check_host }, - { ARRAY, make_scanner_string("--server=localhost:30"), make_scanner_string("localhost"), __check_host }, - { ARRAY, make_scanner_string("--server=10.0.2.1:20"), make_scanner_string("10.0.2.1"), __check_host }, - { ARRAY, make_scanner_string("--server=example.com:1024"), make_scanner_string("example.com"), __check_host }, - { NIL, scanner_string_null, scanner_string_null, NULL } -}; - -scanner_variable_t test_server_strings_with_weights[]= { - { ARRAY, make_scanner_string("--server=10.0.2.1:30/?40"), make_scanner_string("10.0.2.1"), __check_host }, - { ARRAY, make_scanner_string("--server=example.com:1024/?30"), make_scanner_string("example.com"), __check_host }, - { ARRAY, make_scanner_string("--server=10.0.2.1/?20"), make_scanner_string("10.0.2.1"), __check_host }, - { ARRAY, make_scanner_string("--server=example.com/?10"), make_scanner_string("example.com"), __check_host }, - { NIL, scanner_string_null, scanner_string_null, NULL } -}; - -scanner_variable_t bad_test_strings[]= { - { ARRAY, make_scanner_string("-servers=localhost:11221,localhost:11222,localhost:11223,localhost:11224,localhost:11225"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("-- servers=a.example.com:81,localhost:82,b.example.com"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--servers=localhost:+80"), scanner_string_null, NULL}, - { ARRAY, make_scanner_string("--servers=localhost.com."), scanner_string_null, NULL}, - { ARRAY, make_scanner_string("--server=localhost.com."), scanner_string_null, NULL}, - { ARRAY, make_scanner_string("--server=localhost.com.:80"), scanner_string_null, NULL}, - { NIL, scanner_string_null, scanner_string_null, NULL} -}; - -scanner_variable_t test_number_options[]= { - { ARRAY, make_scanner_string("--CONNECT-TIMEOUT=456"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--IO-BYTES-WATERMARK=456"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--IO-KEY-PREFETCH=456"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--IO-MSG-WATERMARK=456"), make_scanner_string("456"), __check_IO_MSG_WATERMARK }, - { ARRAY, make_scanner_string("--NUMBER-OF-REPLICAS=456"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--POLL-TIMEOUT=456"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--RCV-TIMEOUT=456"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--REMOVE-FAILED-SERVERS=3"), scanner_string_null, __check_REMOVE_FAILED_SERVERS }, - { ARRAY, make_scanner_string("--RETRY-TIMEOUT=456"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--SND-TIMEOUT=456"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--SOCKET-RECV-SIZE=456"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--SOCKET-SEND-SIZE=456"), scanner_string_null, NULL }, - { NIL, scanner_string_null, scanner_string_null, NULL} -}; - -scanner_variable_t test_boolean_options[]= { - { ARRAY, make_scanner_string("--FETCH-VERSION"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--BINARY-PROTOCOL"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--BUFFER-REQUESTS"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--HASH-WITH-NAMESPACE"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--NOREPLY"), scanner_string_null, __check_NOREPLY }, - { ARRAY, make_scanner_string("--RANDOMIZE-REPLICA-READ"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--SORT-HOSTS"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--SUPPORT-CAS"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--TCP-NODELAY"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--TCP-KEEPALIVE"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--TCP-KEEPIDLE"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--USE-UDP"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--VERIFY-KEY"), scanner_string_null, __check_VERIFY_KEY }, - { NIL, scanner_string_null, scanner_string_null, NULL} -}; - -scanner_variable_t namespace_strings[]= { - { ARRAY, make_scanner_string("--NAMESPACE=foo"), make_scanner_string("foo"), __check_namespace }, - { ARRAY, make_scanner_string("--NAMESPACE=\"foo\""), make_scanner_string("foo"), __check_namespace }, - { ARRAY, make_scanner_string("--NAMESPACE=\"This_is_a_very_long_key\""), make_scanner_string("This_is_a_very_long_key"), __check_namespace }, - { NIL, scanner_string_null, scanner_string_null, NULL} -}; - -scanner_variable_t distribution_strings[]= { - { ARRAY, make_scanner_string("--DISTRIBUTION=consistent"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--DISTRIBUTION=consistent,CRC"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--DISTRIBUTION=consistent,MD5"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--DISTRIBUTION=random"), scanner_string_null, __check_distribution_RANDOM }, - { ARRAY, make_scanner_string("--DISTRIBUTION=modula"), scanner_string_null, NULL }, - { NIL, scanner_string_null, scanner_string_null, NULL} -}; - -scanner_variable_t hash_strings[]= { - { ARRAY, make_scanner_string("--HASH=CRC"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--HASH=FNV1A_32"), scanner_string_null, NULL }, - { ARRAY, make_scanner_string("--HASH=FNV1_32"), scanner_string_null, NULL }, -#if 0 - { ARRAY, make_scanner_string("--HASH=JENKINS"), scanner_string_null, NULL }, -#endif - { ARRAY, make_scanner_string("--HASH=MD5"), scanner_string_null, NULL }, - { NIL, scanner_string_null, scanner_string_null, NULL} -}; - - -static test_return_t _test_option(scanner_variable_t *scanner, bool test_true_opt= true) -{ - for (scanner_variable_t *ptr= scanner; ptr->type != NIL; ptr++) - { - memcached_st *memc= memcached(ptr->option.c_str, ptr->option.size); - - // The case that it should have parsed, but it didn't. We will inspect for - // an error with libmemcached_check_configuration() - if (memc == NULL and test_true_opt) - { - char buffer[2048]; - bool success= libmemcached_check_configuration(ptr->option.c_str, ptr->option.size, buffer, sizeof(buffer)); - - std::string temp(buffer); - temp+= " with option string:"; - temp+= ptr->option.c_str; - test_true_got(success, temp.c_str()); - Error << "Failed for " << temp; - - return TEST_FAILURE; // The line above should fail since memc should be null - } - - if (test_true_opt) - { - if (ptr->check_func) - { - test_return_t test_rc= (*ptr->check_func)(memc, ptr->result); - if (test_rc != TEST_SUCCESS) - { - memcached_free(memc); - return test_rc; - } - } - - memcached_free(memc); - } - else - { - test_false_with(memc, ptr->option.c_str); - } - } - - return TEST_SUCCESS; -} - -test_return_t server_test(memcached_st *) -{ - return _test_option(test_server_strings); -} - -test_return_t server_with_weight_test(memcached_st *) -{ - return _test_option(test_server_strings_with_weights); -} - -test_return_t servers_bad_test(memcached_st *) -{ - test_return_t rc; - if ((rc= _test_option(bad_test_strings, false)) != TEST_SUCCESS) - { - return rc; - } - - return TEST_SUCCESS; -} - -test_return_t parser_number_options_test(memcached_st*) -{ - return _test_option(test_number_options); -} - -test_return_t parser_boolean_options_test(memcached_st*) -{ - return _test_option(test_boolean_options); -} - -test_return_t behavior_parser_test(memcached_st*) -{ - return TEST_SUCCESS; -} - -test_return_t parser_hash_test(memcached_st*) -{ - return _test_option(hash_strings); -} - -test_return_t parser_distribution_test(memcached_st*) -{ - return _test_option(distribution_strings); -} - -test_return_t parser_key_prefix_test(memcached_st*) -{ - return _test_option(distribution_strings); -} - -test_return_t test_namespace_keyword(memcached_st*) -{ - return _test_option(namespace_strings); -} - -#define SUPPORT_EXAMPLE_CNF "support/example.cnf" - -test_return_t memcached_create_with_options_with_filename(memcached_st*) -{ - test_skip(0, access(SUPPORT_EXAMPLE_CNF, R_OK)); - - memcached_st *memc_ptr= memcached(test_literal_param("--CONFIGURE-FILE=\"support/example.cnf\"")); - test_true_got(memc_ptr, "memcached() failed"); - memcached_free(memc_ptr); - - return TEST_SUCCESS; -} - -test_return_t libmemcached_check_configuration_with_filename_test(memcached_st*) -{ - test_skip(0, access(SUPPORT_EXAMPLE_CNF, R_OK)); - - char buffer[BUFSIZ]; - - test_compare_hint(MEMCACHED_SUCCESS, - libmemcached_check_configuration(test_literal_param("--CONFIGURE-FILE=\"support/example.cnf\""), buffer, sizeof(buffer)), - buffer); - - test_compare_hint(MEMCACHED_PARSE_ERROR, - libmemcached_check_configuration(test_literal_param("--CONFIGURE-FILE=support/example.cnf"), buffer, sizeof(buffer)), - buffer); - - test_compare_hint(MEMCACHED_ERRNO, - libmemcached_check_configuration(test_literal_param("--CONFIGURE-FILE=\"bad-path/example.cnf\""), buffer, sizeof(buffer)), - buffer) ; - - return TEST_SUCCESS; -} - -test_return_t libmemcached_check_configuration_test(memcached_st*) -{ - char buffer[BUFSIZ]; - test_compare(MEMCACHED_SUCCESS, - libmemcached_check_configuration(test_literal_param("--server=localhost"), buffer, sizeof(buffer))); - - test_compare_hint(MEMCACHED_PARSE_ERROR, - libmemcached_check_configuration(test_literal_param("--dude=localhost"), buffer, sizeof(buffer)), - buffer); - - return TEST_SUCCESS; -} - -test_return_t memcached_create_with_options_test(memcached_st*) -{ - { - memcached_st *memc_ptr; - memc_ptr= memcached(test_literal_param("--server=localhost")); - test_true_got(memc_ptr, memcached_last_error_message(memc_ptr)); - memcached_free(memc_ptr); - } - - { - memcached_st *memc_ptr= memcached(test_literal_param("--dude=localhost")); - test_false_with(memc_ptr, memcached_last_error_message(memc_ptr)); - } - - return TEST_SUCCESS; -} - -test_return_t test_include_keyword(memcached_st*) -{ - test_skip(0, access(SUPPORT_EXAMPLE_CNF, R_OK)); - - char buffer[BUFSIZ]; - test_compare(MEMCACHED_SUCCESS, - libmemcached_check_configuration(test_literal_param("INCLUDE \"support/example.cnf\""), buffer, sizeof(buffer))); - - return TEST_SUCCESS; -} - -test_return_t test_end_keyword(memcached_st*) -{ - char buffer[BUFSIZ]; - test_compare(MEMCACHED_SUCCESS, - libmemcached_check_configuration(test_literal_param("--server=localhost END bad keywords"), buffer, sizeof(buffer))); - - return TEST_SUCCESS; -} - -test_return_t test_reset_keyword(memcached_st*) -{ - char buffer[BUFSIZ]; - test_compare(MEMCACHED_SUCCESS, - libmemcached_check_configuration(test_literal_param("--server=localhost reset --server=bad.com"), buffer, sizeof(buffer))); - - return TEST_SUCCESS; -} - -test_return_t test_error_keyword(memcached_st*) -{ - char buffer[BUFSIZ]; - memcached_return_t rc; - rc= libmemcached_check_configuration(test_literal_param("--server=localhost ERROR --server=bad.com"), buffer, sizeof(buffer)); - test_true_got(rc != MEMCACHED_SUCCESS, buffer); - - return TEST_SUCCESS; -} - -#define RANDOM_STRINGS 1000 -test_return_t random_statement_build_test(memcached_st*) -{ - std::vector option_list; - - for (scanner_variable_t *ptr= test_server_strings; ptr->type != NIL; ptr++) - option_list.push_back(&ptr->option); - - for (scanner_variable_t *ptr= test_number_options; ptr->type != NIL; ptr++) - option_list.push_back(&ptr->option); - - for (scanner_variable_t *ptr= test_boolean_options; ptr->type != NIL; ptr++) - option_list.push_back(&ptr->option); - - for (scanner_variable_t *ptr= namespace_strings; ptr->type != NIL; ptr++) - option_list.push_back(&ptr->option); - - for (scanner_variable_t *ptr= distribution_strings; ptr->type != NIL; ptr++) - option_list.push_back(&ptr->option); - - for (scanner_variable_t *ptr= hash_strings; ptr->type != NIL; ptr++) - option_list.push_back(&ptr->option); - - std::vector used_list; - used_list.resize(option_list.size()); - - struct used_options_st { - bool has_hash; - bool has_namespace; - bool has_distribution; - bool has_buffer_requests; - bool has_udp; - bool has_binary; - bool has_verify_key; - - used_options_st() : - has_hash(false), - has_namespace(false), - has_distribution(false), - has_buffer_requests(false), - has_udp(false), - has_binary(false), - has_verify_key(false) - { - } - } used_options; - - for (uint32_t x= 0; x < RANDOM_STRINGS; x++) - { - std::string random_options; - - uint32_t number_of= random() % uint32_t(option_list.size()); - for (uint32_t options= 0; options < number_of; options++) - { - size_t option_list_position= random() % option_list.size(); - - if (used_list[option_list_position]) - { - continue; - } - used_list[option_list_position]= true; - - std::string random_string= option_list[option_list_position]->c_str; - - if (random_string.compare(0, test_literal_compare_param("--HASH")) == 0) - { - if (used_options.has_hash) - { - continue; - } - - if (used_options.has_distribution) - { - continue; - } - used_options.has_hash= true; - } - - if (random_string.compare(0, test_literal_compare_param("--NAMESPACE")) == 0) - { - if (used_options.has_namespace) - { - continue; - } - used_options.has_namespace= true; - } - - if (random_string.compare(0, test_literal_compare_param("--USE-UDP")) == 0) - { - if (used_options.has_udp) - { - continue; - } - used_options.has_udp= true; - - if (used_options.has_buffer_requests) - { - continue; - } - } - - if (random_string.compare(0, test_literal_compare_param("--BUFFER-REQUESTS")) == 0) - { - if (used_options.has_buffer_requests) - { - continue; - } - used_options.has_buffer_requests= true; - - if (used_options.has_udp) - { - continue; - } - } - - if (random_string.compare(0, test_literal_compare_param("--BINARY-PROTOCOL")) == 0) - { - if (used_options.has_binary) - { - continue; - } - used_options.has_binary= true; - - if (used_options.has_verify_key) - { - continue; - } - } - - if (random_string.compare(0, test_literal_compare_param("--VERIFY-KEY")) == 0) - { - if (used_options.has_verify_key) - { - continue; - } - used_options.has_verify_key= true; - - if (used_options.has_binary) - { - continue; - } - } - - if (random_string.compare(0, test_literal_compare_param("--DISTRIBUTION")) == 0) - { - if (used_options.has_distribution) - { - continue; - } - - if (used_options.has_hash) - { - continue; - } - used_options.has_distribution= true; - } - - random_options+= random_string; - random_options+= " "; - } - - if (random_options.size() <= 1) - { - continue; - } - - random_options.resize(random_options.size() -1); - - char buffer[BUFSIZ]; - memcached_return_t rc= libmemcached_check_configuration(random_options.c_str(), random_options.size(), buffer, sizeof(buffer)); - if (memcached_failed(rc)) - { - Error << "libmemcached_check_configuration(" << random_options << ") : " << buffer; - return TEST_FAILURE; - } - } - - return TEST_SUCCESS; -} - -static memcached_return_t dump_server_information(const memcached_st *, - const memcached_instance_st * instance, - void *) -{ - if (strcmp(memcached_server_name(instance), "localhost")) - { - fatal_assert(not memcached_server_name(instance)); - return MEMCACHED_FAILURE; - } - - if (memcached_server_port(instance) < 8888 or memcached_server_port(instance) > 8892) - { - fatal_assert(not memcached_server_port(instance)); - return MEMCACHED_FAILURE; - } - - if (instance->weight > 5 or instance->weight < 2) - { - fatal_assert(not instance->weight); - return MEMCACHED_FAILURE; - } - - return MEMCACHED_SUCCESS; -} - -test_return_t test_hostname_port_weight(memcached_st *) -{ - const char *server_string= "--server=localhost:8888/?2 --server=localhost:8889/?3 --server=localhost:8890/?4 --server=localhost:8891/?5 --server=localhost:8892/?3"; - char buffer[BUFSIZ]; - - test_compare_got(MEMCACHED_SUCCESS, - libmemcached_check_configuration(server_string, strlen(server_string), buffer, sizeof(buffer)), buffer); - - memcached_st *memc= memcached(server_string, strlen(server_string)); - test_true(memc); - - memcached_server_fn callbacks[]= { dump_server_information }; - test_true(memcached_success(memcached_server_cursor(memc, callbacks, NULL, 1))); - - memcached_free(memc); - - return TEST_SUCCESS; -} - -struct socket_weight_t { - const char *socket; - size_t weight; - const char* type; -}; - -static memcached_return_t dump_socket_information(const memcached_st *, - const memcached_instance_st * instance, - void *context) -{ - socket_weight_t *check= (socket_weight_t *)context; - - if (strcmp(memcached_server_type(instance), check->type) == 0) - { - if (strcmp(memcached_server_name(instance), check->socket) == 0) - { - if (instance->weight == check->weight) - { - return MEMCACHED_SUCCESS; - } - else - { - Error << instance->weight << " != " << check->weight; - } - } - else - { - Error << "'" << memcached_server_name(instance) << "'" << " != " << "'" << check->socket << "'"; - } - } - else - { - Error << "'" << memcached_server_type(instance) << "'" << " != " << "'" << check->type << "'"; - } - - return MEMCACHED_FAILURE; -} - -test_return_t test_parse_socket(memcached_st *) -{ - char buffer[BUFSIZ]; - - memcached_server_fn callbacks[]= { dump_socket_information }; - { - test_compare_got(MEMCACHED_SUCCESS, - libmemcached_check_configuration(test_literal_param("--socket=\"/tmp/foo\""), buffer, sizeof(buffer)), - buffer); - - memcached_st *memc= memcached(test_literal_param("--socket=\"/tmp/foo\"")); - test_true(memc); - socket_weight_t check= { "/tmp/foo", 1, "SOCKET"}; - test_compare(MEMCACHED_SUCCESS, - memcached_server_cursor(memc, callbacks, &check, 1)); - memcached_free(memc); - } - - { - test_compare_got(MEMCACHED_SUCCESS, - libmemcached_check_configuration(test_literal_param("--socket=\"/tmp/foo\"/?23"), buffer, sizeof(buffer)), - buffer); - - memcached_st *memc= memcached(test_literal_param("--socket=\"/tmp/foo\"/?23")); - test_true(memc); - socket_weight_t check= { "/tmp/foo", 23, "SOCKET"}; - test_compare(MEMCACHED_SUCCESS, - memcached_server_cursor(memc, callbacks, &check, 1)); - memcached_free(memc); - } - - return TEST_SUCCESS; -} - -/* - By setting the timeout value to zero, we force poll() to return immediatly. -*/ -test_return_t regression_bug_71231153_connect(memcached_st *) -{ - { // Test the connect-timeout, on a bad host we should get MEMCACHED_CONNECTION_FAILURE - memcached_st *memc= memcached(test_literal_param("--SERVER=10.0.2.252 --CONNECT-TIMEOUT=0")); - test_true(memc); - test_zero(memc->connect_timeout); - test_compare(MEMCACHED_DEFAULT_TIMEOUT, memc->poll_timeout); - - memcached_return_t rc; - size_t value_len; - char *value= memcached_get(memc, test_literal_param("test"), &value_len, NULL, &rc); - test_false(value); - test_zero(value_len); - test_compare_got(MEMCACHED_TIMEOUT, rc, memcached_last_error_message(memc)); - - memcached_free(memc); - } - - return TEST_SUCCESS; -} - -test_return_t regression_bug_71231153_poll(memcached_st *) -{ - { // Test the poll timeout, on a bad host we should get MEMCACHED_CONNECTION_FAILURE - memcached_st *memc= memcached(test_literal_param("--SERVER=10.0.2.252 --POLL-TIMEOUT=0")); - test_true(memc); - test_compare(MEMCACHED_DEFAULT_CONNECT_TIMEOUT, memc->connect_timeout); - test_zero(memc->poll_timeout); - - memcached_return_t rc; - size_t value_len; - char *value= memcached_get(memc, test_literal_param("test"), &value_len, NULL, &rc); - test_false(value); - test_zero(value_len); -#ifdef __APPLE__ - test_compare_got(MEMCACHED_CONNECTION_FAILURE, rc, memcached_last_error_message(memc)); -#else - test_compare_got(MEMCACHED_TIMEOUT, rc, memcached_last_error_message(memc)); -#endif - - memcached_free(memc); - } - - return TEST_SUCCESS; -} diff --git a/tests/libmemcached-1.0/parser.h b/tests/libmemcached-1.0/parser.h deleted file mode 100644 index a58bba21..00000000 --- a/tests/libmemcached-1.0/parser.h +++ /dev/null @@ -1,118 +0,0 @@ -/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * - * Libmemcached - * - * Copyright (C) 2011 Data Differential, http://datadifferential.com/ - * All rights reserved. - * - * 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. - * - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -test_return_t memcached_NULL_string_TEST(memcached_st*); -test_return_t memcached_zero_string_length_TEST(memcached_st*); - -LIBTEST_LOCAL -test_return_t server_test(memcached_st *memc); - -LIBTEST_LOCAL -test_return_t servers_bad_test(memcached_st *memc); - -LIBTEST_LOCAL -test_return_t behavior_parser_test(memcached_st*); - -LIBTEST_LOCAL -test_return_t parser_number_options_test(memcached_st*); - -LIBTEST_LOCAL -test_return_t parser_distribution_test(memcached_st*); - -LIBTEST_LOCAL -test_return_t parser_hash_test(memcached_st*); - -LIBTEST_LOCAL -test_return_t parser_boolean_options_test(memcached_st*); - -LIBTEST_LOCAL -test_return_t parser_key_prefix_test(memcached_st*); - -LIBTEST_LOCAL - test_return_t libmemcached_check_configuration_test(memcached_st*); - -LIBTEST_LOCAL - test_return_t memcached_create_with_options_test(memcached_st*); - -LIBTEST_LOCAL - test_return_t memcached_create_with_options_with_filename(memcached_st*); - -LIBTEST_LOCAL - test_return_t libmemcached_check_configuration_with_filename_test(memcached_st*); - -LIBTEST_LOCAL - test_return_t random_statement_build_test(memcached_st*); - -LIBTEST_LOCAL -test_return_t test_include_keyword(memcached_st*); - -LIBTEST_LOCAL -test_return_t test_end_keyword(memcached_st*); - -LIBTEST_LOCAL -test_return_t test_reset_keyword(memcached_st*); - -LIBTEST_LOCAL -test_return_t test_error_keyword(memcached_st*); - -LIBTEST_LOCAL -test_return_t server_with_weight_test(memcached_st *); - -LIBTEST_LOCAL -test_return_t test_hostname_port_weight(memcached_st *); - -LIBTEST_LOCAL -test_return_t regression_bug_71231153_connect(memcached_st *); - -LIBTEST_LOCAL -test_return_t regression_bug_71231153_poll(memcached_st *); - -LIBTEST_LOCAL -test_return_t test_parse_socket(memcached_st *); - -LIBTEST_LOCAL -test_return_t test_namespace_keyword(memcached_st*); - -#ifdef __cplusplus -} -#endif -- 2.30.2 From 558a5c5d4fd3f75e6e51540d333132fde0ff616e Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 13 Oct 2020 14:05:27 +0200 Subject: [PATCH 11/16] testing: cleanup --- include/libmemcached-1.0/t/c_sasl_test.c | 61 --- include/libmemcached-1.0/t/c_test.c | 61 --- include/libmemcached-1.0/t/cc_test.cc | 62 --- tests/libmemcached-1.0/atomsmasher.cc | 284 ------------- tests/libmemcached-1.0/pool.cc | 497 ----------------------- tests/libmemcached-1.0/print.cc | 82 ---- tests/libmemcached-1.0/replication.cc | 446 -------------------- tests/libmemcached-1.0/touch.cc | 152 ------- 8 files changed, 1645 deletions(-) delete mode 100644 include/libmemcached-1.0/t/c_sasl_test.c delete mode 100644 include/libmemcached-1.0/t/c_test.c delete mode 100644 include/libmemcached-1.0/t/cc_test.cc delete mode 100644 tests/libmemcached-1.0/atomsmasher.cc delete mode 100644 tests/libmemcached-1.0/pool.cc delete mode 100644 tests/libmemcached-1.0/print.cc delete mode 100644 tests/libmemcached-1.0/replication.cc delete mode 100644 tests/libmemcached-1.0/touch.cc diff --git a/include/libmemcached-1.0/t/c_sasl_test.c b/include/libmemcached-1.0/t/c_sasl_test.c deleted file mode 100644 index 0f52afff..00000000 --- a/include/libmemcached-1.0/t/c_sasl_test.c +++ /dev/null @@ -1,61 +0,0 @@ -/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * - * Libmemcached C sasl test app - * - * Copyright (C) 2011 Data Differential, http://datadifferential.com/ - * - * 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. - * - */ - -/* - * @file @brief C dummy test, aka testing C linking, etc - */ - -#include - -#ifdef HAVE_SASL_SASL_H -#include -#endif - -#include "libmemcached-1.0/memcached.h" - -int main(void) -{ - memcached_st *memc= memcached_create(NULL); - - if (memc == NULL) - { - return EXIT_FAILURE; - } - memcached_free(memc); - - return EXIT_SUCCESS; -} - diff --git a/include/libmemcached-1.0/t/c_test.c b/include/libmemcached-1.0/t/c_test.c deleted file mode 100644 index af25f1d0..00000000 --- a/include/libmemcached-1.0/t/c_test.c +++ /dev/null @@ -1,61 +0,0 @@ -/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * - * Libmemcached C test app - * - * Copyright (C) 2011 Data Differential, http://datadifferential.com/ - * - * 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. - * - */ - -/* - * @file @brief C dummy test, aka testing C linking, etc - */ - -#include - -#include "libmemcached-1.0/memcached.h" - -int main(void) -{ - (void)memcached_success(MEMCACHED_SUCCESS); - (void)memcached_failed(MEMCACHED_SUCCESS); - (void)memcached_continue(MEMCACHED_SUCCESS); - - memcached_st *memc= memcached_create(NULL); - - if (memc == NULL) - { - return EXIT_FAILURE; - } - memcached_free(memc); - - return EXIT_SUCCESS; -} - diff --git a/include/libmemcached-1.0/t/cc_test.cc b/include/libmemcached-1.0/t/cc_test.cc deleted file mode 100644 index c098e402..00000000 --- a/include/libmemcached-1.0/t/cc_test.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * - * Libmemcached C++ test app - * - * Copyright (C) 2011 Data Differential, http://datadifferential.com/ - * - * 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. - * - */ - -/* - * @file @brief C dummy test, aka testing C linking, etc - */ - -#include - -#include "libmemcached-1.0/memcached.h" - -int main(void) -{ - (void)memcached_success(MEMCACHED_SUCCESS); - (void)memcached_failed(MEMCACHED_SUCCESS); - (void)memcached_continue(MEMCACHED_SUCCESS); - - memcached_st *memc= memcached_create(NULL); - - if (memc == NULL) - { - return EXIT_FAILURE; - } - - memcached_free(memc); - - return EXIT_SUCCESS; -} - diff --git a/tests/libmemcached-1.0/atomsmasher.cc b/tests/libmemcached-1.0/atomsmasher.cc deleted file mode 100644 index 169f503f..00000000 --- a/tests/libmemcached-1.0/atomsmasher.cc +++ /dev/null @@ -1,284 +0,0 @@ -/* LibMemcached - * Copyright (C) 2006-2009 Brian Aker - * All rights reserved. - * - * Use and distribution licensed under the BSD license. See - * the COPYING file in the parent directory for full text. - * - * Summary: - * - */ - -/* - Sample test application. -*/ -#include "mem_config.h" - -#include "libtest/test.hpp" - -#include "libmemcached-1.0/memcached.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libtest/server.h" - -#include "tests/debug.h" - -#include "tests/libmemcached-1.0/generate.h" - -using namespace libtest; - -/* Number of items generated for tests */ -#define GLOBAL_COUNT 100000 - -/* Number of times to run the test loop */ -#define TEST_COUNTER 500000 - -static pairs_st *global_pairs; -static char *global_keys[GLOBAL_COUNT]; -static size_t global_keys_length[GLOBAL_COUNT]; - -static test_return_t cleanup_pairs_TEST(memcached_st *) -{ - pairs_free(global_pairs); - - return TEST_SUCCESS; -} - -static test_return_t generate_pairs_TEST(memcached_st *) -{ - global_pairs= pairs_generate(GLOBAL_COUNT, 400); - - for (ptrdiff_t x= 0; x < GLOBAL_COUNT; x++) - { - global_keys[x]= global_pairs[x].key; - global_keys_length[x]= global_pairs[x].key_length; - } - - return TEST_SUCCESS; -} - -static test_return_t drizzle_TEST(memcached_st *memc) -{ -infinite: - for (ptrdiff_t x= 0; x < TEST_COUNTER; x++) - { - memcached_return_t rc; - - uint32_t test_bit= (uint32_t)(random() % GLOBAL_COUNT); - uint8_t which= (uint8_t)(random() % 2); - - if (which == 0) - { - size_t return_value_length; - uint32_t flags; - char* return_value= memcached_get(memc, global_keys[test_bit], global_keys_length[test_bit], - &return_value_length, &flags, &rc); - if (rc == MEMCACHED_SUCCESS && return_value) - { - free(return_value); - } - else if (rc == MEMCACHED_NOTFOUND) - { - continue; - } - else - { - test_compare(MEMCACHED_SUCCESS, rc); - } - } - else - { - rc= memcached_set(memc, global_pairs[test_bit].key, - global_pairs[test_bit].key_length, - global_pairs[test_bit].value, - global_pairs[test_bit].value_length, - 0, 0); - if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED) - { - test_compare(MEMCACHED_SUCCESS, rc); - } - } - } - - if (getenv("MEMCACHED_ATOM_BURIN_IN")) - { - goto infinite; - } - - return TEST_SUCCESS; -} - -static test_return_t pre_nonblock(memcached_st *memc) -{ - test_skip(MEMCACHED_SUCCESS, memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0)); - - return TEST_SUCCESS; -} - -/* - Set the value, then quit to make sure it is flushed. - Come back in and test that add fails. -*/ -static test_return_t add_test(memcached_st *memc) -{ - const char *key= "foo"; - const char *value= "when we sanitize"; - - memcached_return_t rc= memcached_set(memc, key, strlen(key), - value, strlen(value), - time_t(0), uint32_t(0)); - test_true_got(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED, memcached_strerror(NULL, rc)); - memcached_quit(memc); - rc= memcached_add(memc, key, strlen(key), - value, strlen(value), - (time_t)0, (uint32_t)0); - - if (rc == MEMCACHED_CONNECTION_FAILURE) - { - print_servers(memc); - } - - /* Too many broken OS'es have broken loopback in async, so we can't be sure of the result */ - if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK)) - { - test_true(rc == MEMCACHED_NOTSTORED or rc == MEMCACHED_STORED); - } - else - { - test_compare_got(MEMCACHED_NOTSTORED, rc, memcached_strerror(NULL, rc)); - } - - return TEST_SUCCESS; -} - -/* - * repeating add_tests many times - * may show a problem in timing - */ -static test_return_t many_adds(memcached_st *memc) -{ - test_true(memc); - for (ptrdiff_t x= 0; x < TEST_COUNTER; x++) - { - test_compare_got(TEST_SUCCESS, add_test(memc), x); - } - return TEST_SUCCESS; -} - -test_st smash_tests[] ={ - {"generate_pairs", true, (test_callback_fn*)generate_pairs_TEST }, - {"drizzle", true, (test_callback_fn*)drizzle_TEST }, - {"cleanup", true, (test_callback_fn*)cleanup_pairs_TEST }, - {"many_adds", true, (test_callback_fn*)many_adds }, - {0, 0, 0} -}; - -#define BENCHMARK_TEST_LOOP 20000 - -struct benchmark_state_st -{ - bool create_init; - bool clone_init; - memcached_st *create; - memcached_st *clone; -} benchmark_state; - -static test_return_t memcached_create_benchmark(memcached_st *) -{ - benchmark_state.create_init= true; - - for (ptrdiff_t x= 0; x < BENCHMARK_TEST_LOOP; x++) - { - memcached_st *ptr= memcached_create(&benchmark_state.create[x]); - - test_true(ptr); - } - - return TEST_SUCCESS; -} - -static test_return_t memcached_clone_benchmark(memcached_st *memc) -{ - benchmark_state.clone_init= true; - - for (ptrdiff_t x= 0; x < BENCHMARK_TEST_LOOP; x++) - { - memcached_st *ptr= memcached_clone(&benchmark_state.clone[x], memc); - - test_true(ptr); - } - - return TEST_SUCCESS; -} - -static test_return_t pre_allocate(memcached_st *) -{ - memset(&benchmark_state, 0, sizeof(benchmark_state)); - - benchmark_state.create= (memcached_st *)calloc(BENCHMARK_TEST_LOOP, sizeof(memcached_st)); - test_true(benchmark_state.create); - benchmark_state.clone= (memcached_st *)calloc(BENCHMARK_TEST_LOOP, sizeof(memcached_st)); - test_true(benchmark_state.clone); - - return TEST_SUCCESS; -} - -static test_return_t post_allocate(memcached_st *) -{ - for (ptrdiff_t x= 0; x < BENCHMARK_TEST_LOOP; x++) - { - if (benchmark_state.create_init) - { - memcached_free(&benchmark_state.create[x]); - } - - if (benchmark_state.clone_init) - { - memcached_free(&benchmark_state.clone[x]); - } - } - - free(benchmark_state.create); - free(benchmark_state.clone); - - return TEST_SUCCESS; -} - - -test_st micro_tests[] ={ - {"memcached_create", 1, (test_callback_fn*)memcached_create_benchmark }, - {"memcached_clone", 1, (test_callback_fn*)memcached_clone_benchmark }, - {0, 0, 0} -}; - - -collection_st collection[] ={ - {"smash", 0, 0, smash_tests}, - {"smash_nonblock", (test_callback_fn*)pre_nonblock, 0, smash_tests}, - {"micro-benchmark", (test_callback_fn*)pre_allocate, (test_callback_fn*)post_allocate, micro_tests}, - {0, 0, 0, 0} -}; - - -#include "tests/libmemcached_world.h" - -void get_world(libtest::Framework* world) -{ - world->collections(collection); - - world->create((test_callback_create_fn*)world_create); - world->destroy((test_callback_destroy_fn*)world_destroy); - - world->set_runner(new LibmemcachedRunner); -} diff --git a/tests/libmemcached-1.0/pool.cc b/tests/libmemcached-1.0/pool.cc deleted file mode 100644 index 26932996..00000000 --- a/tests/libmemcached-1.0/pool.cc +++ /dev/null @@ -1,497 +0,0 @@ -/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * - * Libmemcached Client and Server - * - * Copyright (C) 2011 Data Differential, http://datadifferential.com/ - * All rights reserved. - * - * 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 "mem_config.h" -#include "libtest/test.hpp" - -using namespace libtest; - -#include -#include -#include -#include - -#include - -#include "libmemcached-1.0/memcached.h" -#include "libmemcachedutil-1.0/util.h" -#include "libmemcached/is.h" -#include "tests/pool.h" - -#include -#include - -#include "libmemcached/instance.hpp" - -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif - - -test_return_t memcached_pool_test(memcached_st *) -{ - 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]; - - 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(pool); - - memcached_return_t rc; - memcached_st *memc= memcached_pool_pop(pool, false, &rc); - - test_compare(rc, MEMCACHED_SUCCESS); - test_true(memc); - - /* - Release the memc_ptr that was pulled from the pool - */ - memcached_pool_push(pool, memc); - - /* - Destroy the pool. - */ - memcached_pool_destroy(pool); - - return TEST_SUCCESS; -} - - -#define POOL_SIZE 10 -test_return_t connection_pool_test(memcached_st *memc) -{ - memcached_pool_st* pool= memcached_pool_create(memc, 5, POOL_SIZE); - test_true(pool); - memcached_st *mmc[POOL_SIZE]; - - // Fill up our array that we will store the memc that are in the pool - for (size_t x= 0; x < POOL_SIZE; ++x) - { - memcached_return_t rc; - mmc[x]= memcached_pool_fetch(pool, NULL, &rc); - test_compare(MEMCACHED_SUCCESS, rc); - test_true(mmc[x]); - } - - // All memc should be gone - { - memcached_return_t rc; - test_null(memcached_pool_fetch(pool, NULL, &rc)); - test_compare(MEMCACHED_NOTFOUND, rc); - } - - // Release them.. - for (size_t x= 0; x < POOL_SIZE; ++x) - { - if (mmc[x]) - { - test_compare(MEMCACHED_SUCCESS, memcached_pool_release(pool, mmc[x])); - } - } - test_true(memcached_pool_destroy(pool) == memc); - - return TEST_SUCCESS; -} - -test_return_t connection_pool2_test(memcached_st *memc) -{ - memcached_pool_st* pool= memcached_pool_create(memc, 5, POOL_SIZE); - test_true(pool); - memcached_st *mmc[POOL_SIZE]; - - // Fill up our array that we will store the memc that are in the pool - for (size_t x= 0; x < POOL_SIZE; ++x) - { - memcached_return_t rc; - mmc[x]= memcached_pool_fetch(pool, NULL, &rc); - test_compare(MEMCACHED_SUCCESS, rc); - test_true(mmc[x]); - } - - // All memc should be gone - { - memcached_return_t rc; - test_null(memcached_pool_fetch(pool, NULL, &rc)); - test_compare(MEMCACHED_NOTFOUND, rc); - } - - // verify that I can do ops with all connections - test_compare(MEMCACHED_SUCCESS, - memcached_set(mmc[0], - test_literal_param("key"), - "0", 1, 0, 0)); - - for (uint64_t x= 0; x < POOL_SIZE; ++x) - { - uint64_t number_value; - test_compare(MEMCACHED_SUCCESS, - memcached_increment(mmc[x], - test_literal_param("key"), - 1, &number_value)); - test_compare(number_value, (x+1)); - } - - // Release them.. - for (size_t x= 0; x < POOL_SIZE; ++x) - { - test_compare(MEMCACHED_SUCCESS, memcached_pool_release(pool, mmc[x])); - } - - - /* verify that I can set behaviors on the pool when I don't have all - * of the connections in the pool. It should however be enabled - * when I push the item into the pool - */ - mmc[0]= memcached_pool_fetch(pool, NULL, NULL); - test_true(mmc[0]); - - test_compare(MEMCACHED_SUCCESS, - memcached_pool_behavior_set(pool, MEMCACHED_BEHAVIOR_IO_MSG_WATERMARK, 9999)); - - { - memcached_return_t rc; - mmc[1]= memcached_pool_fetch(pool, NULL, &rc); - test_true(mmc[1]); - test_compare(MEMCACHED_SUCCESS, rc); - } - - 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])); - - { - memcached_return_t rc; - mmc[0]= memcached_pool_fetch(pool, NULL, &rc); - test_true(mmc[0]); - test_compare(MEMCACHED_SUCCESS, rc); - } - - 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); - - return TEST_SUCCESS; -} - -struct test_pool_context_st { - volatile memcached_return_t rc; - memcached_pool_st* pool; - memcached_st* mmc; - sem_t _lock; - - test_pool_context_st(memcached_pool_st *pool_arg, memcached_st *memc_arg): - rc(MEMCACHED_FAILURE), - pool(pool_arg), - mmc(memc_arg) - { - sem_init(&_lock, 0, 0); - } - - void wait() - { - sem_wait(&_lock); - } - - void release() - { - sem_post(&_lock); - } - - ~test_pool_context_st() - { - sem_destroy(&_lock); - } -}; - -static __attribute__((noreturn)) void* connection_release(void *arg) -{ - test_pool_context_st *resource= static_cast(arg); - FATAL_IF(resource == NULL); - - // Release all of the memc we are holding - resource->rc= memcached_pool_release(resource->pool, resource->mmc); - resource->release(); - - pthread_exit(arg); -} - -test_return_t connection_pool3_test(memcached_st *memc) -{ -#ifdef __APPLE__ - return TEST_SKIPPED; -#endif - - memcached_pool_st* pool= memcached_pool_create(memc, 1, 1); - test_true(pool); - - memcached_st *pool_memc; - { - memcached_return_t rc; - pool_memc= memcached_pool_fetch(pool, NULL, &rc); - test_compare(MEMCACHED_SUCCESS, rc); - test_true(pool_memc); - } - - /* - @note This comment was written to describe what was believed to be the original authors intent. - - This portion of the test creates a thread that will wait until told to free a memcached_st - that will be grabbed by the main thread. - - It is believed that this tests whether or not we are handling ownership correctly. - */ - pthread_t tid; - test_pool_context_st item(pool, pool_memc); - - test_zero(pthread_create(&tid, NULL, connection_release, &item)); - item.wait(); - - memcached_return_t rc; - memcached_st *pop_memc; - // We do a hard loop, and try N times - int counter= 5; - do - { - struct timespec relative_time= { 0, 0 }; - pop_memc= memcached_pool_fetch(pool, &relative_time, &rc); - - if (memcached_success(rc)) - { - break; - } - - if (memcached_failed(rc)) - { - test_null(pop_memc); - test_true(rc != MEMCACHED_TIMEOUT); // As long as relative_time is zero, MEMCACHED_TIMEOUT is invalid - } - } while (--counter); - - if (memcached_failed(rc)) // Cleanup thread since we will exit once we test. - { - pthread_join(tid, NULL); - test_compare(MEMCACHED_SUCCESS, rc); - } - - { - int pthread_ret= pthread_join(tid, NULL); - test_true(pthread_ret == 0 or pthread_ret == ESRCH); - } - test_compare(MEMCACHED_SUCCESS, rc); - test_true(pool_memc == pop_memc); - - test_true(memcached_pool_destroy(pool) == 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; -} diff --git a/tests/libmemcached-1.0/print.cc b/tests/libmemcached-1.0/print.cc deleted file mode 100644 index 1e948eb4..00000000 --- a/tests/libmemcached-1.0/print.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * - * Libmemcached client and server library. - * - * Copyright (C) 2011 Data Differential, http://datadifferential.com/ - * All rights reserved. - * - * 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 "mem_config.h" -#include "libtest/test.hpp" - -using namespace libtest; - - -#include - -#include "libmemcached-1.0/memcached.h" - -#include "tests/print.h" - -memcached_return_t server_print_callback(const memcached_st*, - const memcached_instance_st * server, - void *context) -{ - if (context) - { - std::cerr << memcached_server_name(server) << ":" << memcached_server_port(server) << std::endl; - } - - return MEMCACHED_SUCCESS; -} - -memcached_return_t server_print_version_callback(const memcached_st *, - const memcached_instance_st * server, - void *) -{ - std::cerr << "Server: " << memcached_server_name(server) << ":" << memcached_server_port(server) << " " - << int(memcached_server_major_version(server)) << "." - << int(memcached_server_minor_version(server)) << "." - << int(memcached_server_micro_version(server)) - << std::endl; - - return MEMCACHED_SUCCESS; -} - -const char * print_version(memcached_st *memc) -{ - memcached_server_fn callbacks[1]; - callbacks[0]= server_print_version_callback; - memcached_server_cursor(memc, callbacks, NULL, 1); - - return "print_version()"; -} diff --git a/tests/libmemcached-1.0/replication.cc b/tests/libmemcached-1.0/replication.cc deleted file mode 100644 index a760060e..00000000 --- a/tests/libmemcached-1.0/replication.cc +++ /dev/null @@ -1,446 +0,0 @@ -/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * - * Libmemcached client and server library. - * - * Copyright (C) 2011 Data Differential, http://datadifferential.com/ - * All rights reserved. - * - * 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 "mem_config.h" -#include "libtest/test.hpp" - -using namespace libtest; - -#include "libmemcached-1.0/memcached.h" - -#include "libmemcached/server_instance.h" - -#include "tests/replication.h" -#include "tests/debug.h" - -#include "tests/libmemcached-1.0/setup_and_teardowns.h" - -test_return_t check_replication_sanity_TEST(memcached_st *memc) -{ - test_true(memc); - test_compare(uint64_t(1), - memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)); - - /* - * Make sure that we store the item on all servers - * (master + replicas == number of servers) - */ - test_compare(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS), uint64_t(memcached_server_count(memc) - 1)); - - return TEST_SUCCESS; -} - -test_return_t replication_set_test(memcached_st *memc) -{ - memcached_st *memc_clone= memcached_clone(NULL, memc); - test_true(memc_clone); - test_compare(MEMCACHED_SUCCESS, - memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0)); - - test_compare(MEMCACHED_SUCCESS, - memcached_set(memc, "bubba", 5, "0", 1, 0, 0)); - - /* - ** We are using the quiet commands to store the replicas, so we need - ** to ensure that all of them are processed before we can continue. - ** In the test we go directly from storing the object to trying to - ** receive the object from all of the different servers, so we - ** could end up in a race condition (the memcached server hasn't yet - ** processed the quiet command from the replication set when it process - ** the request from the other client (created by the clone)). As a - ** workaround for that we call memcached_quit to send the quit command - ** to the server and wait for the response ;-) If you use the test code - ** as an example for your own code, please note that you shouldn't need - ** to do this ;-) - */ - memcached_quit(memc); - - /* - ** "bubba" should now be stored on all of our servers. We don't have an - ** easy to use API to address each individual server, so I'll just iterate - ** through a bunch of "master keys" and I should most likely hit all of the - ** servers... - */ - for (int x= 'a'; x <= 'z'; ++x) - { - const char key[2]= { (char)x, 0 }; - size_t len; - uint32_t flags; - memcached_return_t rc; - char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5, - &len, &flags, &rc); - test_compare(MEMCACHED_SUCCESS, rc); - test_true(val); - free(val); - } - - memcached_free(memc_clone); - - return TEST_SUCCESS; -} - -#include "libmemcached/instance.hpp" - -test_return_t replication_get_test(memcached_st *memc) -{ - - /* - * Don't do the following in your code. I am abusing the internal details - * within the library, and this is not a supported interface. - * This is to verify correct behavior in the library - */ - for (uint32_t host= 0; host < memcached_server_count(memc); ++host) - { - memcached_st *memc_clone= memcached_clone(NULL, memc); - memcached_instance_st* instance= (memcached_instance_st*)memcached_server_instance_by_position(memc_clone, host); - - instance->port(0); - - for (int x= 'a'; x <= 'z'; ++x) - { - const char key[2]= { (char)x, 0 }; - size_t len; - uint32_t flags; - memcached_return_t rc; - char *val= memcached_get_by_key(memc_clone, key, 1, "bubba", 5, - &len, &flags, &rc); - test_compare(MEMCACHED_SUCCESS, rc); - test_true(val); - free(val); - } - - memcached_free(memc_clone); - } - - return TEST_SUCCESS; -} - -test_return_t replication_mget_test(memcached_st *memc) -{ - memcached_st *memc_clone= memcached_clone(NULL, memc); - test_true(memc_clone); - test_compare(MEMCACHED_SUCCESS, - memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0)); - - const char *keys[]= { "bubba", "key1", "key2", "key3" }; - size_t len[]= { 5, 4, 4, 4 }; - - for (size_t x= 0; x< 4; ++x) - { - test_compare(MEMCACHED_SUCCESS, memcached_set(memc, keys[x], len[x], "0", 1, 0, 0)); - } - - /* - ** We are using the quiet commands to store the replicas, so we need - ** to ensure that all of them are processed before we can continue. - ** In the test we go directly from storing the object to trying to - ** receive the object from all of the different servers, so we - ** could end up in a race condition (the memcached server hasn't yet - ** processed the quiet command from the replication set when it process - ** the request from the other client (created by the clone)). As a - ** workaround for that we call memcached_quit to send the quit command - ** to the server and wait for the response ;-) If you use the test code - ** as an example for your own code, please note that you shouldn't need - ** to do this ;-) - */ - memcached_quit(memc); - - /* - * Don't do the following in your code. I am abusing the internal details - * within the library, and this is not a supported interface. - * This is to verify correct behavior in the library - */ - memcached_result_st result_obj; - for (uint32_t host= 0; host < memcached_server_count(memc_clone); host++) - { - memcached_st *new_clone= memcached_clone(NULL, memc); - const memcached_instance_st * instance= memcached_server_instance_by_position(new_clone, host); - ((memcached_server_write_instance_st)instance)->port(0); - - for (int x= 'a'; x <= 'z'; ++x) - { - char key[2]= { (char)x, 0 }; - - test_compare(MEMCACHED_SUCCESS, - memcached_mget_by_key(new_clone, key, 1, keys, len, 4)); - - memcached_result_st *results= memcached_result_create(new_clone, &result_obj); - test_true(results); - - int hits= 0; - memcached_return_t rc; - while ((results= memcached_fetch_result(new_clone, &result_obj, &rc)) != NULL) - { - hits++; - } - test_compare(4, hits); - memcached_result_free(&result_obj); - } - - memcached_free(new_clone); - } - - memcached_free(memc_clone); - - return TEST_SUCCESS; -} - -test_return_t replication_randomize_mget_test(memcached_st *memc) -{ - memcached_result_st result_obj; - memcached_st *memc_clone= memcached_clone(NULL, memc); - memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 3); - memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, 1); - - const char *keys[]= { "key1", "key2", "key3", "key4", "key5", "key6", "key7" }; - size_t len[]= { 4, 4, 4, 4, 4, 4, 4 }; - - for (size_t x= 0; x< 7; ++x) - { - test_compare(MEMCACHED_SUCCESS, - memcached_set(memc, keys[x], len[x], "1", 1, 0, 0)); - } - - memcached_quit(memc); - - for (size_t x= 0; x< 7; ++x) - { - const char key[2]= { (char)x, 0 }; - - test_compare(MEMCACHED_SUCCESS, - memcached_mget_by_key(memc_clone, key, 1, keys, len, 7)); - - memcached_result_st *results= memcached_result_create(memc_clone, &result_obj); - test_true(results); - - int hits= 0; - memcached_return_t rc; - while ((results= memcached_fetch_result(memc_clone, &result_obj, &rc)) != NULL) - { - ++hits; - } - test_compare(hits, 7); - memcached_result_free(&result_obj); - } - memcached_free(memc_clone); - - return TEST_SUCCESS; -} - -test_return_t replication_delete_test(memcached_st *memc_just_cloned) -{ - memcached_flush(memc_just_cloned, 0); - memcached_st *memc_not_replicate= memcached_clone(NULL, memc_just_cloned); - memcached_st *memc_replicated= memcached_clone(NULL, memc_just_cloned); - const char *keys[]= { "bubba", "key1", "key2", "key3", "key4" }; - - test_compare(uint64_t(1), memcached_behavior_get(memc_replicated, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)); - test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc_replicated, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ, false)); - - // Make one copy - test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc_replicated, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 1UL)); - test_compare(uint64_t(1), memcached_behavior_get(memc_replicated, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS)); - - test_compare(MEMCACHED_SUCCESS, memcached_behavior_set(memc_not_replicate, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 0UL)); - test_compare(uint64_t(0), memcached_behavior_get(memc_not_replicate, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS)); - - for (size_t x= 0; x < test_array_length(keys); ++x) - { - memcached_set(memc_replicated, - test_string_make_from_cstr(keys[x]), // Keys - test_string_make_from_cstr(keys[x]), // We use the keys as values - 0, 0); - } - - memcached_flush_buffers(memc_replicated); - - // Confirm keys with replication read - test_compare(TEST_SUCCESS, confirm_keys_exist(memc_replicated, keys, test_array_length(keys), true, true)); - test_compare(TEST_SUCCESS, confirm_keys_exist(memc_not_replicate, keys, test_array_length(keys), true, true)); - - /* Delete the items from all of the servers except 1, we use the non replicated memc so that we know we deleted the keys */ - for (size_t x= 0; x < test_array_length(keys); ++x) - { - memcached_return_t del_rc= memcached_delete(memc_replicated, - test_string_make_from_cstr(keys[x]), // Keys - 0); - if (del_rc == MEMCACHED_SUCCESS or del_rc == MEMCACHED_NOTFOUND) - { } - else - { - test_compare(MEMCACHED_SUCCESS, del_rc); - } - } - - test_compare(TEST_SUCCESS, confirm_keys_dont_exist(memc_replicated, keys, test_array_length(keys))); - test_compare(TEST_SUCCESS, confirm_keys_dont_exist(memc_not_replicate, keys, test_array_length(keys))); -#if 0 - test_zero(confirm_key_count(memc_not_replicate)); -#endif - - memcached_free(memc_not_replicate); - memcached_free(memc_replicated); - - 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)); - test_compare(MEMCACHED_SUCCESS, - memcached_set(memc, - key, strlen(key), - key, strlen(key), 0, 0)); - } - - 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)); - uint32_t flags; - size_t value_length; - memcached_return_t rc; - char *value= memcached_get(memc_clone, key, strlen(key), &value_length, &flags, &rc); - test_compare(MEMCACHED_SUCCESS, rc); - test_compare(strlen(key), value_length); - test_strcmp(key, value); - free(value); - } - memcached_free(memc_clone); - return TEST_SUCCESS; -} - -/* Test that single miss does not cause replica reads to fail */ -test_return_t replication_miss_test(memcached_st *memc) -{ - test_skip(true, false); - - memcached_st *memc_repl= memcached_clone(NULL, memc); - test_true(memc_repl); - memcached_st *memc_single= memcached_clone(NULL, memc); - test_true(memc_single); - - const char *value = "my_value"; - size_t vlen; - uint32_t flags; - - /* this test makes sense only with 2 or more servers */ - test_true(memcached_server_count(memc_repl) > 1); - - /* Consistent hash */ - test_compare(MEMCACHED_SUCCESS, - memcached_behavior_set_distribution(memc_repl, MEMCACHED_DISTRIBUTION_CONSISTENT)); - test_compare(MEMCACHED_SUCCESS, - memcached_behavior_set_distribution(memc_single, MEMCACHED_DISTRIBUTION_CONSISTENT)); - - /* The first clone writes to all servers */ - test_compare(MEMCACHED_SUCCESS, - memcached_behavior_set(memc_repl, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, true)); - test_compare(MEMCACHED_SUCCESS, - memcached_behavior_set(memc_repl, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, - memcached_server_count(memc_repl))); - - /* Write to servers */ - { - memcached_return_t rc= memcached_set(memc_repl, - test_literal_param(__func__), - value, strlen(value), - time_t(1200), uint32_t(0)); - test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED); - } - - /* Use the second clone to remove the key from primary server. - This should remove the key from only one server */ - { - memcached_return_t rc= memcached_delete(memc_single, - test_literal_param(__func__), - 0); - test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED); - } - - /* Remove the server where the key was deleted */ - { -#if 0 - memcached_return_t rc; - const memcached_server_st *instance= memcached_server_by_key(memc_single, - test_literal_param(__func__), - &rc); - test_compare(MEMCACHED_SUCCESS, rc); - test_compare(MEMCACHED_SUCCESS, - memcached_server_remove(instance)); -#endif - } - - /* Test that others still have it */ - { - memcached_return_t rc; - char *get_value= memcached_get(memc_single, - test_literal_param(__func__), - &vlen, &flags, &rc); - test_true(rc == MEMCACHED_SUCCESS or rc == MEMCACHED_BUFFERED); - test_true(get_value and strcmp(get_value, value) == 0); - free(get_value); - } - - /* This read should still return the value as we have it on other servers */ - { - memcached_return_t rc; - char *get_value= memcached_get(memc_repl, - test_literal_param(__func__), - &vlen, &flags, &rc); - test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED); - test_true(get_value and strcmp(get_value, value) == 0); - free(get_value); - } - - memcached_free(memc_repl); - memcached_free(memc_single); - - return TEST_SUCCESS; -} diff --git a/tests/libmemcached-1.0/touch.cc b/tests/libmemcached-1.0/touch.cc deleted file mode 100644 index 5f894339..00000000 --- a/tests/libmemcached-1.0/touch.cc +++ /dev/null @@ -1,152 +0,0 @@ -/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * - * Libmemcached Client and Server - * - * Copyright (C) 2011 Data Differential, http://datadifferential.com/ - * All rights reserved. - * - * 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 "mem_config.h" -#include "libtest/test.hpp" - -using namespace libtest; - -#include "libmemcached-1.0/memcached.h" -#include "libmemcachedutil-1.0/util.h" - -#include "tests/touch.h" - -static test_return_t pre_touch(memcached_st *memc) -{ - test_compare(MEMCACHED_SUCCESS, memcached_version(memc)); - test_skip(true, libmemcached_util_version_check(memc, 1, 4, 15)); - - return TEST_SUCCESS; -} - -test_return_t test_memcached_touch(memcached_st *memc) -{ - test_skip(TEST_SUCCESS, pre_touch(memc)); - - size_t len; - uint32_t flags; - memcached_return rc; - - test_null(memcached_get(memc, - test_literal_param(__func__), - &len, &flags, &rc)); - test_zero(len); - test_compare(MEMCACHED_NOTFOUND, rc); - - test_compare(MEMCACHED_SUCCESS, - memcached_set(memc, - test_literal_param(__func__), - test_literal_param("touchval"), - 2, 0)); - - { - char *value= memcached_get(memc, - test_literal_param(__func__), - &len, &flags, &rc); - test_compare(8U, test_literal_param_size("touchval")); - test_true(value); - test_strcmp(value, "touchval"); - test_compare(MEMCACHED_SUCCESS, rc); - free(value); - } - - rc= memcached_touch(memc, test_literal_param(__func__), 60 *60); - ASSERT_EQ_(MEMCACHED_SUCCESS, rc, "%s", memcached_last_error_message(memc)); - - rc= memcached_touch(memc, test_literal_param(__func__), 60 *60 *24 *60); - ASSERT_EQ_(MEMCACHED_SUCCESS, rc, "%s", memcached_last_error_message(memc)); - - rc= memcached_exist(memc, test_literal_param(__func__)); - ASSERT_EQ_(MEMCACHED_NOTFOUND, rc, "%s", memcached_last_error_message(memc)); - - return TEST_SUCCESS; -} - -test_return_t test_memcached_touch_by_key(memcached_st *memc) -{ - test_skip(TEST_SUCCESS, pre_touch(memc)); - - size_t len; - uint32_t flags; - memcached_return rc; - - test_null(memcached_get_by_key(memc, - test_literal_param("grouping_key"), - test_literal_param(__func__), - &len, &flags, &rc)); - test_zero(len); - test_compare(MEMCACHED_NOTFOUND, rc); - - test_compare(MEMCACHED_SUCCESS, - memcached_set_by_key(memc, - test_literal_param("grouping_key"), - test_literal_param(__func__), - test_literal_param("touchval"), - 2, 0)); - - { - char *value= memcached_get_by_key(memc, - test_literal_param("grouping_key"), - test_literal_param(__func__), - &len, &flags, &rc); - test_compare(8U, test_literal_param_size("touchval")); - test_true(value); - test_strcmp(value, "touchval"); - test_compare(MEMCACHED_SUCCESS, rc); - free(value); - } - - rc= memcached_touch_by_key(memc, - test_literal_param("grouping_key"), - test_literal_param(__func__), - 60 *60); - ASSERT_EQ_(MEMCACHED_SUCCESS, rc, "%s", memcached_last_error_message(memc)); - - rc= memcached_touch_by_key(memc, - test_literal_param("grouping_key"), - test_literal_param(__func__), - 60 *60 *24 *60); - ASSERT_EQ_(MEMCACHED_SUCCESS, rc, "%s", memcached_last_error_message(memc)); - - rc= memcached_exist_by_key(memc, test_literal_param("grouping_key"),test_literal_param(__func__)); - ASSERT_EQ_(MEMCACHED_NOTFOUND, rc, "%s", memcached_last_error_message(memc)); - - return TEST_SUCCESS; -} - - - -- 2.30.2 From 959514bee40bfa6f5f84583fa9da3f3158773971 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 13 Oct 2020 14:05:59 +0200 Subject: [PATCH 12/16] testing: vbucket --- test/tests/memcached/vbucket.cpp | 37 ++++++ tests/libmemcached-1.0/virtual_buckets.cc | 146 ---------------------- 2 files changed, 37 insertions(+), 146 deletions(-) create mode 100644 test/tests/memcached/vbucket.cpp delete mode 100644 tests/libmemcached-1.0/virtual_buckets.cc diff --git a/test/tests/memcached/vbucket.cpp b/test/tests/memcached/vbucket.cpp new file mode 100644 index 00000000..5dd26e4e --- /dev/null +++ b/test/tests/memcached/vbucket.cpp @@ -0,0 +1,37 @@ +#include "test/lib/common.hpp" +#include "test/lib/ReturnMatcher.hpp" + + +TEST_CASE("memcached_vbucket") { + MemcachedPtr memc; + LoneReturnMatcher test{*memc}; + uint32_t server_map[] = {0, 1, 2, 1}; + + REQUIRE_SUCCESS(memcached_bucket_set(*memc, server_map, nullptr, 4, 2)); + REQUIRE(MEMCACHED_DISTRIBUTION_VIRTUAL_BUCKET == memcached_behavior_get_distribution(*memc)); + REQUIRE_SUCCESS(memcached_behavior_set_key_hash(*memc, MEMCACHED_HASH_CRC)); + + auto servers = memcached_servers_parse("localhost:11211, localhost1:11210, localhost2:11211"); + REQUIRE(servers); + REQUIRE_SUCCESS(memcached_server_push(*memc, servers)); + REQUIRE(3 == memcached_server_count(*memc)); + + tuple keys[] = { + {"hello", 0, 0}, + {"doctor", 0, 0}, + {"name", 1, 3}, + {"continue", 1, 3}, + {"yesterday", 0, 0}, + {"tomorrow", 1, 1}, + {"another key", 2, 2} + }; + + for (const auto &k : keys) { + auto [key, server, bucket] = k; + + REQUIRE(bucket == (memcached_generate_hash_value(S(key), memcached_behavior_get_key_hash(*memc)) % 4)); + REQUIRE(server == memcached_generate_hash(*memc, S(key))); + } + + memcached_server_list_free(servers); +} diff --git a/tests/libmemcached-1.0/virtual_buckets.cc b/tests/libmemcached-1.0/virtual_buckets.cc deleted file mode 100644 index 99b19843..00000000 --- a/tests/libmemcached-1.0/virtual_buckets.cc +++ /dev/null @@ -1,146 +0,0 @@ -/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * - * Libmemcached Client and Server - * - * Copyright (C) 2011 Data Differential, http://datadifferential.com/ - * All rights reserved. - * - * 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 "mem_config.h" -#include "libtest/test.hpp" - -using namespace libtest; - -#include "tests/virtual_buckets.h" - -#include "libmemcached-1.0/memcached.h" - -#include - -struct libtest_string_t { - const char *c_str; - size_t size; -}; - -static inline libtest_string_t libtest_string(const char *arg, size_t arg_size) -{ - libtest_string_t local= { arg, arg_size }; - return local; -} - -#define make_libtest_string(X) libtest_string((X), static_cast(sizeof(X) - 1)) - -static libtest_string_t libtest_string_t_null= { 0, 0}; - -static bool libtest_string_is_null(const libtest_string_t &string) -{ - if (string.c_str == 0 and string.size == 0) - return true; - - return false; -} - -struct expect_t { - libtest_string_t key; - uint32_t server_id; - uint32_t bucket_id; -}; - -expect_t basic_keys[]= { - { make_libtest_string("hello"), 0, 0 }, - { make_libtest_string("doctor"), 0, 0 }, - { make_libtest_string("name"), 1, 3 }, - { make_libtest_string("continue"), 1, 3 }, - { make_libtest_string("yesterday"), 0, 0 }, - { make_libtest_string("tomorrow"), 1, 1 }, - { make_libtest_string("another key"), 2, 2 }, - { libtest_string_t_null, 0, 0 } -}; - -test_return_t virtual_back_map(memcached_st *) -{ - memcached_return_t rc; - memcached_server_st *server_pool; - memcached_st *memc; - - memc= memcached_create(NULL); - test_true(memc); - - uint32_t server_map[] = { 0, 1, 2, 1 }; - rc= memcached_bucket_set(memc, server_map, NULL, 4, 2); - test_true(rc == MEMCACHED_SUCCESS); - - memcached_server_distribution_t dt; - dt= memcached_behavior_get_distribution(memc); - test_true(dt == MEMCACHED_DISTRIBUTION_VIRTUAL_BUCKET); - - memcached_behavior_set_key_hash(memc, MEMCACHED_HASH_CRC); - test_true(rc == MEMCACHED_SUCCESS); - - memcached_hash_t hash_type= memcached_behavior_get_key_hash(memc); - test_true(hash_type == MEMCACHED_HASH_CRC); - - server_pool = memcached_servers_parse("localhost:11211, localhost1:11210, localhost2:11211"); - test_true(server_pool); - memcached_server_push(memc, server_pool); - - /* verify that the server list was parsed okay. */ - test_true(memcached_server_count(memc) == 3); - test_true(strcmp(server_pool[0].hostname, "localhost") == 0); - test_true(server_pool[0].port == 11211); - - test_true(strcmp(server_pool[1].hostname, "localhost1") == 0); - test_true(server_pool[1].port == 11210); - - test_true(strcmp(server_pool[2].hostname, "localhost2") == 0); - test_true(server_pool[2].port == 11211); - - dt= memcached_behavior_get_distribution(memc); - hash_type= memcached_behavior_get_key_hash(memc); - test_true(dt == MEMCACHED_DISTRIBUTION_VIRTUAL_BUCKET); - test_true(hash_type == MEMCACHED_HASH_CRC); - - /* verify the standard ketama set. */ - for (expect_t *ptr= basic_keys; not libtest_string_is_null(ptr->key); ptr++) - { - uint32_t server_idx = memcached_generate_hash(memc, ptr->key.c_str, ptr->key.size); - - char buffer[1024]; - snprintf(buffer, sizeof(buffer), "%.*s:%lu Got/Expected %u == %u", (int)ptr->key.size, ptr->key.c_str, (unsigned long)ptr->key.size, server_idx, ptr->server_id); - test_compare(server_idx, ptr->server_id); - } - - memcached_server_list_free(server_pool); - memcached_free(memc); - - return TEST_SUCCESS; -} -- 2.30.2 From af00c49be513eef012f776b34681febf8bb74d4b Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 13 Oct 2020 15:16:20 +0200 Subject: [PATCH 13/16] testing: memcapable --- test/tests/bin/memcapable.cpp | 50 ++++++++++++++ tests/memcapable.cc | 126 ---------------------------------- 2 files changed, 50 insertions(+), 126 deletions(-) create mode 100644 test/tests/bin/memcapable.cpp delete mode 100644 tests/memcapable.cc diff --git a/test/tests/bin/memcapable.cpp b/test/tests/bin/memcapable.cpp new file mode 100644 index 00000000..1b09e062 --- /dev/null +++ b/test/tests/bin/memcapable.cpp @@ -0,0 +1,50 @@ +#include "test/lib/common.hpp" +#include "test/lib/Shell.hpp" +#include "test/lib/Server.hpp" + +using Catch::Matchers::Contains; + +TEST_CASE("bin/memcapable") { + Shell sh{string{TESTING_ROOT "/../src/bin"}}; + + SECTION("no servers provided") { + string output; + REQUIRE_FALSE(sh.run("memcapable", output)); + REQUIRE(output == "No hostname was provided.\n"); + } + + SECTION("--help") { + string output; + + REQUIRE(sh.run("memcapable --help", output)); + REQUIRE_THAT(output, Contains("memcapable") && Contains("binary") && Contains("ascii")); + } + + SECTION("with server") { + Server server{MEMCACHED_BINARY, {"-p", random_port_string}}; + + REQUIRE(server.ensureListening()); + + SECTION("ascii only") { + string output; + REQUIRE(sh.run("memcapable -a -h localhost -p " + to_string(get(server.getSocketOrPort())), output)); + REQUIRE_THAT(output, Contains("pass") && Contains("ascii")); + REQUIRE_THAT(output, !Contains("fail") && !Contains("binary")); + } + SECTION("binary only") { + string output; + REQUIRE(sh.run("memcapable -b -h localhost -p " + to_string(get(server.getSocketOrPort())), output)); + REQUIRE_THAT(output, Contains("pass") && Contains("binary")); + REQUIRE_THAT(output, !Contains("fail") && !Contains("ascii")); + } + SECTION("ascii and binary") { + string output; + REQUIRE(sh.run("memcapable -h localhost -p " + to_string(get(server.getSocketOrPort())), output)); + REQUIRE_THAT(output, Contains("pass") && Contains("ascii") && Contains("binary")); + REQUIRE_THAT(output, !Contains("fail")); + } + + // fast exit + server.signal(SIGKILL); + } +} diff --git a/tests/memcapable.cc b/tests/memcapable.cc deleted file mode 100644 index 2bd1aec2..00000000 --- a/tests/memcapable.cc +++ /dev/null @@ -1,126 +0,0 @@ -/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * - * Test memcapable - * - * Copyright (C) 2011 Data Differential, http://datadifferential.com/ - * - * 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. - * - */ - - -/* - Test that we are cycling the servers we are creating during testing. -*/ - -#include "mem_config.h" - -#include "libtest/test.hpp" -#include "libmemcached-1.0/memcached.h" - -using namespace libtest; - -#ifndef __INTEL_COMPILER -# pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif - -static std::string executable; - -static test_return_t quiet_test(void *) -{ - char buffer[1024]; - snprintf(buffer, sizeof(buffer), "%d", int(get_free_port())); - const char *args[]= { "-p", buffer, "-q", 0 }; - - test_compare(EXIT_FAILURE, exec_cmdline(executable, args, true)); - - return TEST_SUCCESS; -} - -static test_return_t help_test(void *) -{ - const char *args[]= { "-h", 0 }; - - test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true)); - - return TEST_SUCCESS; -} - -static test_return_t ascii_test(void *) -{ - char buffer[1024]; - snprintf(buffer, sizeof(buffer), "%d", int(default_port())); - const char *args[]= { "-p", buffer, "-a", 0 }; - - test_true(exec_cmdline(executable, args, true) <= EXIT_FAILURE); - - return TEST_SUCCESS; -} - -static test_return_t binary_test(void *) -{ - char buffer[1024]; - snprintf(buffer, sizeof(buffer), "%d", int(default_port())); - const char *args[]= { "-p", buffer, "-b", 0 }; - - test_true(exec_cmdline(executable, args, true) <= EXIT_FAILURE); - - return TEST_SUCCESS; -} - -test_st memcapable_tests[] ={ - {"--quiet", 0, quiet_test}, - {"-h", 0, help_test}, - {"-a, ascii", 0, ascii_test}, - {"-b, binary", 0, binary_test}, - {0, 0, 0} -}; - -collection_st collection[] ={ - {"memcapable", 0, 0, memcapable_tests }, - {0, 0, 0, 0} -}; - -static void *world_create(server_startup_st& servers, test_return_t&) -{ - SKIP_UNLESS(libtest::has_memcached()); - - SKIP_UNLESS(server_startup(servers, "memcached", libtest::default_port(), NULL)); - - return &servers; -} - - -void get_world(libtest::Framework* world) -{ - executable= "./src/bin/memcapable"; - world->collections(collection); - world->create(world_create); -} - -- 2.30.2 From 52d10244d2cb8059106b483da7170a4c9acc3b0a Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 13 Oct 2020 15:40:19 +0200 Subject: [PATCH 14/16] testing: memslap --- src/bin/memslap.cc | 6 +- test/tests/bin/memslap.cpp | 43 +++++++++ tests/memslap.cc | 192 ------------------------------------- 3 files changed, 46 insertions(+), 195 deletions(-) create mode 100644 test/tests/bin/memslap.cpp delete mode 100644 tests/memslap.cc diff --git a/src/bin/memslap.cc b/src/bin/memslap.cc index 89649764..59fef02a 100644 --- a/src/bin/memslap.cc +++ b/src/bin/memslap.cc @@ -1,5 +1,5 @@ /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * + * * Libmemcached library * * Copyright (C) 2011-2012 Data Differential, http://datadifferential.com/ @@ -214,10 +214,10 @@ int main(int argc, char *argv[]) { opt_servers= strdup(temp); } - + if (opt_servers == NULL) { - std::cerr << "No Servers provided" << std::endl; + std::cerr << "No servers provided" << std::endl; exit(EXIT_FAILURE); } } diff --git a/test/tests/bin/memslap.cpp b/test/tests/bin/memslap.cpp new file mode 100644 index 00000000..dee7ebc3 --- /dev/null +++ b/test/tests/bin/memslap.cpp @@ -0,0 +1,43 @@ +#include "test/lib/common.hpp" +#include "test/lib/Shell.hpp" +#include "test/lib/MemcachedCluster.hpp" + +using Catch::Matchers::Contains; + +TEST_CASE("bin/memslap") { + Shell sh{string{TESTING_ROOT "/../src/bin"}}; + + SECTION("no servers provided") { + string output; + REQUIRE_FALSE(sh.run("memslap", output)); + REQUIRE(output == "No servers provided\n"); + } + + SECTION("--help") { + string output; + + REQUIRE(sh.run("memslap --help", output)); + REQUIRE_THAT(output, Contains("memslap")); + REQUIRE_THAT(output, Contains("v1")); + REQUIRE_THAT(output, Contains("help")); + REQUIRE_THAT(output, Contains("version")); + REQUIRE_THAT(output, Contains("option")); + REQUIRE_THAT(output, Contains("--")); + REQUIRE_THAT(output, Contains("=")); + } + + SECTION("with servers") { + auto test = MemcachedCluster::udp(); + auto flags = {"--binary", "--udp", "--flush", "--test=mget", "--test=get", "--tcp-nodelay", + "--non-blocking", "--initial-load=1000"}; + string servers{"--servers="}; + + for (const auto &server : test.cluster.getServers()) { + servers += "localhost:" + to_string(get(server.getSocketOrPort())) + ", "; + } + + for (const auto flag : flags) { + REQUIRE(sh.run("memslap --quiet --concurrency=2 " + servers + flag)); + } + } +} diff --git a/tests/memslap.cc b/tests/memslap.cc deleted file mode 100644 index a8fd1747..00000000 --- a/tests/memslap.cc +++ /dev/null @@ -1,192 +0,0 @@ -/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: - * - * Test memslap - * - * Copyright (C) 2011 Data Differential, http://datadifferential.com/ - * - * 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. - * - */ - - -/* - Test that we are cycling the servers we are creating during testing. -*/ - -#include "mem_config.h" - -#include "libtest/test.hpp" -#include "libmemcached-1.0/memcached.h" - -using namespace libtest; - -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif - -static std::string executable; - -static test_return_t quiet_test(void *) -{ - const char *args[]= { "--quiet", 0 }; - - test_compare(EXIT_FAILURE, exec_cmdline(executable, args, true)); - - return TEST_SUCCESS; -} - -static test_return_t help_test(void *) -{ - const char *args[]= { "--help", 0 }; - - test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true)); - - return TEST_SUCCESS; -} - -static test_return_t server_test(void *) -{ - char buffer[1024]; - snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port())); - const char *args[]= { buffer, 0 }; - - test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true)); - - return TEST_SUCCESS; -} - -static test_return_t server_concurrency_test(void *) -{ - char buffer[1024]; - snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port())); - const char *args[]= { buffer, "--concurrency=10", 0 }; - - test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true)); - - return TEST_SUCCESS; -} - -static test_return_t server_concurrency_initial_load_test(void *) -{ - char buffer[1024]; - snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port())); - const char *args[]= { buffer, "--concurrency=10", "--initial-load=1000", 0 }; - - test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true)); - - return TEST_SUCCESS; -} - -static test_return_t server_concurrency_initial_load_execute_number_test(void *) -{ - char buffer[1024]; - snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port())); - const char *args[]= { buffer, "--concurrency=10", "--initial-load=1000", "--execute-number=10", 0 }; - - test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true)); - - return TEST_SUCCESS; -} - -static test_return_t server_concurrency_initial_load_execute_number_test_get_test(void *) -{ - char buffer[1024]; - snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port())); - const char *args[]= { buffer, "--concurrency=10", "--initial-load=1000", "--execute-number=10", "--test=get", 0 }; - - test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true)); - - return TEST_SUCCESS; -} - -static test_return_t server_concurrency_initial_load_execute_number_test_set_test(void *) -{ - char buffer[1024]; - snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port())); - const char *args[]= { buffer, "--concurrency=10", "--initial-load=1000", "--execute-number=10", "--test=set", 0 }; - - test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true)); - - return TEST_SUCCESS; -} - -static test_return_t server_concurrency_initial_load_execute_number_test_set_non_blocking_test(void *) -{ - char buffer[1024]; - snprintf(buffer, sizeof(buffer), "--servers=localhost:%d", int(default_port())); - const char *args[]= { buffer, "--concurrency=10", "--initial-load=1000", "--execute-number=10", "--test=set", "--non-blocking", 0 }; - - test_compare(EXIT_SUCCESS, exec_cmdline(executable, args, true)); - - return TEST_SUCCESS; -} - -test_st memslap_tests[] ={ - {"--quiet", true, quiet_test }, - {"--help", true, help_test }, - {"--server_test", true, server_test }, - {"--concurrency=10", true, server_concurrency_test }, - {"--initial-load=1000", true, server_concurrency_initial_load_test }, - {"--execute-number=10", true, server_concurrency_initial_load_execute_number_test }, - {"--test=get", true, server_concurrency_initial_load_execute_number_test_get_test }, - {"--test=set", true, server_concurrency_initial_load_execute_number_test_set_test }, - {"--test=set --non-blockin", true, server_concurrency_initial_load_execute_number_test_set_non_blocking_test }, - {0, 0, 0} -}; - -collection_st collection[] ={ - {"memslap", 0, 0, memslap_tests }, - {0, 0, 0, 0} -}; - -static void *world_create(server_startup_st& servers, test_return_t& error) -{ - if (libtest::has_memcached() == false) - { - error= TEST_SKIPPED; - return NULL; - } - - const char *argv[]= { "memslap", 0 }; - if (server_startup(servers, "memcached", libtest::default_port(), argv) == false) - { - error= TEST_FAILURE; - } - - return &servers; -} - - -void get_world(libtest::Framework* world) -{ - executable= "./src/bin/memslap"; - world->collections(collection); - world->create(world_create); -} - -- 2.30.2 From a93908cc9c40eef179d33a89fc011e2e3c54c438 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 13 Oct 2020 17:16:19 +0200 Subject: [PATCH 15/16] testing: bin/memaslap --- src/bin/memaslap.c | 45 ++++++++++++++-------------- src/bin/memaslap/ms_conn.c | 4 +-- src/bin/memaslap/ms_setting.c | 4 +-- test/CMakeLists.txt | 4 +++ test/conf.h.in | 1 + test/tests/bin/memaslap.cpp | 55 +++++++++++++++++++++++++++++++++++ 6 files changed, 86 insertions(+), 27 deletions(-) create mode 100644 test/tests/bin/memaslap.cpp diff --git a/src/bin/memaslap.c b/src/bin/memaslap.c index c94ead2d..77f74b36 100644 --- a/src/bin/memaslap.c +++ b/src/bin/memaslap.c @@ -1,5 +1,5 @@ /* - * memslap + * memaslap * * (c) Copyright 2009, Schooner Information Technology, Inc. * All rights reserved. @@ -41,7 +41,7 @@ ms_stats_t ms_stats; /* global statistic structure */ ms_statistic_t ms_statistic; -#define PROGRAM_NAME "memslap" +#define PROGRAM_NAME "memaslap" #define PROGRAM_DESCRIPTION \ "Generates workload against memcached servers." @@ -120,7 +120,7 @@ static int ms_check_para(void); static void ms_statistic_init(void); static void ms_stats_init(void); static void ms_print_statistics(int in_time); -static void ms_print_memslap_stats(struct timeval *start_time, +static void ms_print_memaslap_stats(struct timeval *start_time, struct timeval *end_time); static void ms_monitor_slap_mode(void); @@ -131,7 +131,7 @@ static void ms_monitor_slap_mode(void); * @param description, description of this process * @param long_options, global options array */ -static __attribute__((noreturn)) void ms_help_command(const char *command_name, const char *description) +static void ms_help_command(const char *command_name, const char *description) { char *help_message= NULL; @@ -139,7 +139,7 @@ static __attribute__((noreturn)) void ms_help_command(const char *command_name, printf(" %s\n\n", description); printf( "Usage:\n" - " memslap -hV | -s servers [-F config_file] [-t time | -x exe_num] [...]\n\n" + " memaslap -hV | -s servers [-F config_file] [-t time | -x exe_num] [...]\n\n" "Options:\n"); for (int x= 0; long_options[x].name; x++) @@ -155,15 +155,13 @@ static __attribute__((noreturn)) void ms_help_command(const char *command_name, printf( "\nExamples:\n" - " memslap -s 127.0.0.1:11211 -S 5s\n" - " memslap -s 127.0.0.1:11211 -t 2m -v 0.2 -e 0.05 -b\n" - " memslap -s 127.0.0.1:11211 -F config -t 2m -w 40k -S 20s -o 0.2\n" - " memslap -s 127.0.0.1:11211 -F config -t 2m -T 4 -c 128 -d 20 -P 40k\n" - " memslap -s 127.0.0.1:11211 -F config -t 2m -d 50 -a -n 40\n" - " memslap -s 127.0.0.1:11211,127.0.0.1:11212 -F config -t 2m\n" - " memslap -s 127.0.0.1:11211,127.0.0.1:11212 -F config -t 2m -p 2\n\n"); - - exit(0); + " memaslap -s 127.0.0.1:11211 -S 5s\n" + " memaslap -s 127.0.0.1:11211 -t 2m -v 0.2 -e 0.05 -b\n" + " memaslap -s 127.0.0.1:11211 -F config -t 2m -w 40k -S 20s -o 0.2\n" + " memaslap -s 127.0.0.1:11211 -F config -t 2m -T 4 -c 128 -d 20 -P 40k\n" + " memaslap -s 127.0.0.1:11211 -F config -t 2m -d 50 -a -n 40\n" + " memaslap -s 127.0.0.1:11211,127.0.0.1:11212 -F config -t 2m\n" + " memaslap -s 127.0.0.1:11211,127.0.0.1:11212 -F config -t 2m -p 2\n\n"); } /* ms_help_command */ @@ -295,7 +293,7 @@ static const char *ms_lookup_help(ms_options_t option) case OPT_UDP: return - "UDP support, default memslap uses TCP, TCP port and UDP port of\n" + "UDP support, by default memaslap uses TCP; TCP port and UDP port of\n" " server must be same."; case OPT_EXPIRE: @@ -442,6 +440,7 @@ static void ms_options_parse(int argc, char *argv[]) case OPT_HELP: /* --help or -h */ ms_help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION); + exit(0); break; case OPT_SERVERS: /* --servers or -s */ @@ -660,7 +659,7 @@ static int ms_check_para() } else { - fprintf(stderr, "No Servers provided\n\n"); + fprintf(stderr, "No servers provided\n\n"); return -1; } } @@ -717,11 +716,11 @@ static void ms_print_statistics(int in_time) } /* ms_print_statistics */ -/* used to print the states of memslap */ -static void ms_print_memslap_stats(struct timeval *start_time, +/* used to print the states of memaslap */ +static void ms_print_memaslap_stats(struct timeval *start_time, struct timeval *end_time) { - char buf[1024]; + char buf[0x2000]; char *pos= buf; pos+= snprintf(pos, @@ -808,11 +807,11 @@ static void ms_print_memslap_stats(struct timeval *start_time, ms_stats.bytes_written + ms_stats.bytes_read) / 1024 / 1024 / ((double)time_diff / 1000000)); - assert(pos <= buf); + assert(pos <= (buf + sizeof(buf))); - fprintf(stdout, "%s", buf); + fwrite(buf, 1, pos - buf, stdout); fflush(stdout); -} /* ms_print_memslap_stats */ +} /* ms_print_memaslap_stats */ /* the loop of the main thread, wait the work threads to complete */ @@ -892,7 +891,7 @@ static void ms_monitor_slap_mode() gettimeofday(&end_time, NULL); } - ms_print_memslap_stats(&start_time, &end_time); + ms_print_memaslap_stats(&start_time, &end_time); } /* ms_monitor_slap_mode */ diff --git a/src/bin/memaslap/ms_conn.c b/src/bin/memaslap/ms_conn.c index 71353d5b..39f284b0 100644 --- a/src/bin/memaslap/ms_conn.c +++ b/src/bin/memaslap/ms_conn.c @@ -826,7 +826,7 @@ static int ms_network_connect(ms_conn_t *c, if (error != EAI_SYSTEM) fprintf(stderr, "getaddrinfo(): %s.\n", gai_strerror(error)); else - perror("getaddrinfo()\n"); + perror("getaddrinfo()"); return -1; } @@ -1169,7 +1169,7 @@ static int ms_ascii_process_line(ms_conn_t *c, char *command) { printf("<%d ERROR %s\n", c->sfd, strerror(errno)); } - c->currcmd.key_prefix= *(uint64_t *)tokens[KEY_TOKEN].value; + memcpy(&c->currcmd.key_prefix, tokens[KEY_TOKEN].value, sizeof(c->currcmd.key_prefix)); /* * We read the \r\n into the string since not doing so is more diff --git a/src/bin/memaslap/ms_setting.c b/src/bin/memaslap/ms_setting.c index 6cb367a3..289466e0 100644 --- a/src/bin/memaslap/ms_setting.c +++ b/src/bin/memaslap/ms_setting.c @@ -320,7 +320,7 @@ static void ms_no_config_file() if (fd == NULL) { fprintf(stderr, "Could not create default configure file %s\n", userpath); - perror(strerror(errno)); + perror("fopen"); exit(1); } fprintf(fd, "%s", DEFAULT_CONGIF_STR); @@ -843,7 +843,7 @@ static void ms_init_random_block() */ static void ms_print_setting() { - fprintf(stdout, "servers : %s\n", ms_setting.srv_str); + fprintf(stdout, "servers: %s\n", ms_setting.srv_str); fprintf(stdout, "threads count: %d\n", ms_setting.nthreads); fprintf(stdout, "concurrency: %d\n", ms_setting.nconns); if (ms_setting.run_time > 0) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ebb39afe..9ea8cd2c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -8,6 +8,10 @@ check_decl(pipe2 unistd.h) check_decl(SOCK_NONBLOCK sys/socket.h) check_decl(SOCK_CLOEXEC sys/socket.h) +if(ENABLE_MEMASLAP AND LIBEVENT AND HAVE_C_STDATOMIC) + set(HAVE_MEMASLAP 1) +endif() + file(GLOB_RECURSE TESTING_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) set(TESTING_ROOT ${CMAKE_CURRENT_BINARY_DIR}) set_source_files_properties(main.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) diff --git a/test/conf.h.in b/test/conf.h.in index 91843964..40101a63 100644 --- a/test/conf.h.in +++ b/test/conf.h.in @@ -1,5 +1,6 @@ #pragma once +#cmakedefine HAVE_MEMASLAP 1 #cmakedefine HAVE_PIPE2 1 #cmakedefine HAVE_SOCK_NONBLOCK 1 #cmakedefine HAVE_SOCK_CLOEXEC 1 diff --git a/test/tests/bin/memaslap.cpp b/test/tests/bin/memaslap.cpp new file mode 100644 index 00000000..e2c61829 --- /dev/null +++ b/test/tests/bin/memaslap.cpp @@ -0,0 +1,55 @@ +#include "test/lib/common.hpp" +#include "test/lib/Shell.hpp" +#include "test/lib/MemcachedCluster.hpp" + +#if HAVE_MEMASLAP + +using Catch::Matchers::Contains; + +TEST_CASE("bin/memaslap") { + Shell sh{string{TESTING_ROOT "/../src/bin"}}; + + SECTION("no servers provided") { + string output; + REQUIRE_FALSE(sh.run("memaslap", output)); + REQUIRE_THAT(output, Contains("No servers provided\n")); + } + + SECTION("--help") { + string output; + + REQUIRE(sh.run("memaslap --help", output)); + REQUIRE_THAT(output, Contains("memaslap")); + REQUIRE_THAT(output, Contains("v1")); + /* FIXME + REQUIRE_THAT(output, Contains("help")); + REQUIRE_THAT(output, Contains("version")); + REQUIRE_THAT(output, Contains("option")); + */ + REQUIRE_THAT(output, Contains("--")); + REQUIRE_THAT(output, Contains("=")); + } + + SECTION("with servers") { + auto test = MemcachedCluster::network(); + auto examples = { + " -t 2s -S 1s", + " -t 2s -v 0.2 -e 0.05 -b", + " -t 2s -w 40k -S 20s -o 0.2", + " -t 2s -T 4 -c 128 -d 20 -P 40k", + " -t 2s -d 50 -a -n 10", + }; + string servers{"-s "}; + + for (const auto &server : test.cluster.getServers()) { + servers += "127.0.0.1:" + to_string(get(server.getSocketOrPort())) + ","; + } + for (const auto args : examples) { + string output; + INFO(args); + REQUIRE(sh.run("memaslap " + servers + args, output)); + REQUIRE_THAT(output, Contains("TPS")); + } + } +} +#endif // HAVE_MEMASLAP -- 2.30.2 From 5b0307a7a34f2b53e93a18be5f81439180b07ac4 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 13 Oct 2020 18:00:07 +0200 Subject: [PATCH 16/16] memcapable: fix test for 1.6 --- src/bin/memcapable.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bin/memcapable.cc b/src/bin/memcapable.cc index 65ae027f..33d93485 100644 --- a/src/bin/memcapable.cc +++ b/src/bin/memcapable.cc @@ -212,7 +212,7 @@ static ssize_t timeout_io_op(memcached_socket_t fd, short direction, void *buf, ret= recv(fd, buf, len, 0); } - if (ret == SOCKET_ERROR && get_socket_errno() == EWOULDBLOCK) + if (ret == SOCKET_ERROR && get_socket_errno() == EWOULDBLOCK) { struct pollfd fds; memset(&fds, 0, sizeof(struct pollfd)); @@ -1271,7 +1271,7 @@ static enum test_return test_ascii_quit(void) execute(send_string("quit noreply\r\n")); execute(receive_error_response()); } - + /* Verify that quit works */ execute(send_string("quit\r\n")); @@ -1290,8 +1290,8 @@ static enum test_return test_ascii_version(void) execute(receive_line(buffer, sizeof(buffer))); verify(strncmp(buffer, "VERSION ", 8) == 0); - char *version = &buffer[sizeof("VERSION") + 2]; - if (version[0] >= '1' || (version[0] == '1' && version[2] >= '6')) { + char *version = &buffer[sizeof("VERSION")]; + if (version[0] > '1' || (version[0] == '1' && version[2] >= '6')) { v16x_or_greater = true; } -- 2.30.2