flush
authorMichael Wallner <mike@php.net>
Wed, 9 Sep 2020 11:39:48 +0000 (13:39 +0200)
committerMichael Wallner <mike@php.net>
Wed, 9 Sep 2020 11:39:48 +0000 (13:39 +0200)
testing/CMakeLists.txt
testing/fixtures/hashes.hpp [new file with mode: 0644]
testing/lib/ForkAndExec.cpp
testing/lib/ForkAndExec.hpp
testing/lib/Server.hpp
testing/tests/hashkit/basic.cpp
testing/tests/memcached/generate_hash.cpp [new file with mode: 0644]
testing/tests/memcached/noreply.cpp [new file with mode: 0644]
testing/tests/memcached/util.cpp [new file with mode: 0644]
testing/tests/noreply.cpp [deleted file]

index b019302e0dda586fe07b163c6b579b1268bb075f..145e6ada2e6b89f867c062c0da3a2800f4f03cf3 100644 (file)
@@ -3,4 +3,4 @@ file(GLOB_RECURSE TESTING_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp)
 
 add_executable(catch_main ${TESTING_SRC})
 set_target_properties(catch_main PROPERTIES CXX_STANDARD 17)
-target_link_libraries(catch_main libhashkit libmemcached)
+target_link_libraries(catch_main libhashkit libmemcached libmemcachedutil)
diff --git a/testing/fixtures/hashes.hpp b/testing/fixtures/hashes.hpp
new file mode 100644 (file)
index 0000000..c3e344f
--- /dev/null
@@ -0,0 +1,139 @@
+#pragma once
+
+#include "mem_config.h"
+
+static const char *input[] = {
+    "apple",
+    "beat",
+    "carrot",
+    "daikon",
+    "eggplant",
+    "flower",
+    "green",
+    "hide",
+    "ick",
+    "jack",
+    "kick",
+    "lime",
+    "mushrooms",
+    "nectarine",
+    "orange",
+    "peach",
+    "quant",
+    "ripen",
+    "strawberry",
+    "tang",
+    "up",
+    "volumne",
+    "when",
+    "yellow",
+    "zip",
+};
+
+static const uint32_t output[][sizeof(input)/sizeof(*input)] = {
+    // one_at_a_time
+    { 2297466611U, 3902465932U, 469785835U, 1937308741U,
+      261917617U, 3785641677U, 1439605128U, 1649152283U,
+      1493851484U, 1246520657U, 2221159044U, 1973511823U,
+      384136800U, 214358653U, 2379473940U, 4269788650U,
+      2864377005U, 2638630052U, 427683330U, 990491717U,
+      1747111141U, 792127364U, 2599214128U, 2553037199U,
+      2509838425U },
+
+    // md5
+    { 3195025439U, 2556848621U, 3724893440U, 3332385401U,
+      245758794U, 2550894432U, 121710495U, 3053817768U,
+      1250994555U, 1862072655U, 2631955953U, 2951528551U,
+      1451250070U, 2820856945U, 2060845566U, 3646985608U,
+      2138080750U, 217675895U, 2230934345U, 1234361223U,
+      3968582726U, 2455685270U, 1293568479U, 199067604U,
+      2042482093U },
+
+    // crc
+    { 10542U, 22009U, 14526U, 19510U, 19432U, 10199U, 20634U,
+      9369U, 11511U, 10362U, 7893U, 31289U, 11313U, 9354U,
+      7621U, 30628U, 15218U, 25967U, 2695U, 9380U,
+      17300U, 28156U, 9192U, 20484U, 16925U },
+
+    // fnv1_64
+    { 473199127U, 4148981457U, 3971873300U, 3257986707U,
+      1722477987U, 2991193800U, 4147007314U, 3633179701U,
+      1805162104U, 3503289120U, 3395702895U, 3325073042U,
+      2345265314U, 3340346032U, 2722964135U, 1173398992U,
+      2815549194U, 2562818319U, 224996066U, 2680194749U,
+      3035305390U, 246890365U, 2395624193U, 4145193337U,
+      1801941682U },
+
+    // fnv1a_64
+    { 1488911807U, 2500855813U, 1510099634U, 1390325195U,
+      3647689787U, 3241528582U, 1669328060U, 2604311949U,
+      734810122U, 1516407546U, 560948863U, 1767346780U,
+      561034892U, 4156330026U, 3716417003U, 3475297030U,
+      1518272172U, 227211583U, 3938128828U, 126112909U,
+      3043416448U, 3131561933U, 1328739897U, 2455664041U,
+      2272238452U },
+
+    // fnv1_32
+    { 67176023U, 1190179409U, 2043204404U, 3221866419U,
+      2567703427U, 3787535528U, 4147287986U, 3500475733U,
+      344481048U, 3865235296U, 2181839183U, 119581266U,
+      510234242U, 4248244304U, 1362796839U, 103389328U,
+      1449620010U, 182962511U, 3554262370U, 3206747549U,
+      1551306158U, 4127558461U, 1889140833U, 2774173721U,
+      1180552018U },
+
+    // fnv1a_32
+    { 280767167U, 2421315013U, 3072375666U, 855001899U,
+      459261019U, 3521085446U, 18738364U, 1625305005U,
+      2162232970U, 777243802U, 3323728671U, 132336572U,
+      3654473228U, 260679466U, 1169454059U, 2698319462U,
+      1062177260U, 235516991U, 2218399068U, 405302637U,
+      1128467232U, 3579622413U, 2138539289U, 96429129U,
+      2877453236U },
+
+    // hsieh
+#ifdef HAVE_HSIEH_HASH
+    { 3738850110U, 3636226060U, 3821074029U, 3489929160U, 3485772682U, 80540287U,
+      1805464076U, 1895033657U, 409795758U, 979934958U, 3634096985U, 1284445480U,
+      2265380744U, 707972988U, 353823508U, 1549198350U, 1327930172U, 9304163U,
+      4220749037U, 2493964934U, 2777873870U, 2057831732U, 1510213931U, 2027828987U,
+      3395453351U },
+#else
+    {  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+#endif
+
+    // murmur
+#ifdef HAVE_MURMUR_HASH
+    { 4142305122U, 734504955U, 3802834688U, 4076891445U,
+      387802650U, 560515427U, 3274673488U, 3150339524U,
+      1527441970U, 2728642900U, 3613992239U, 2938419259U,
+      2321988328U, 1145154116U, 4038540960U, 2224541613U,
+      264013145U, 3995512858U, 2400956718U, 2346666219U,
+      926327338U, 442757446U, 1770805201U, 560483147U,
+      3902279934U },
+#endif
+
+    // jenkins
+    { 1442444624U, 4253821186U, 1885058256U, 2120131735U,
+      3261968576U, 3515188778U, 4232909173U, 4288625128U,
+      1812047395U, 3689182164U, 2502979932U, 1214050606U,
+      2415988847U, 1494268927U, 1025545760U, 3920481083U,
+      4153263658U, 3824871822U, 3072759809U, 798622255U,
+      3065432577U, 1453328165U, 2691550971U, 3408888387U,
+      2629893356U },
+
+    // murmur3
+#ifdef HAVE_MURMUR_HASH
+    { 1120212521U, 1448785489U, 4186307405U, 2686268514U,
+      444808887U, 221750260U, 3074673162U, 1946933257U,
+      2826416675U, 2430719166U, 3200429559U, 297894347U,
+      732888124U, 4050076964U, 3298336176U, 1336207361U,
+      810553576U, 3748182674U, 3860119212U, 3439537197U,
+      3044240981U, 1464271804U, 3896193724U, 2915115798U,
+      1702843840U },
+#else
+    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+#endif
+};
+
index b882eb435e7da935596bedd9e0e70758ee267d91..271af306681f5e1c86abf03feda7dc22b2c864d2 100644 (file)
@@ -11,7 +11,7 @@ ForkAndExec::ForkAndExec(const char *binary_, char **argv_)
 : binary{binary_}
 , argv{argv_}
 {
-  if (pipe2(pipes, O_CLOEXEC|O_NONBLOCK)) {
+  if (pipe2(ready, O_CLOEXEC | O_NONBLOCK)) {
     int error = errno;
     perror("Server::start pipe2()");
     throw system_error(error, system_category());
@@ -19,21 +19,21 @@ ForkAndExec::ForkAndExec(const char *binary_, char **argv_)
 }
 
 ForkAndExec::~ForkAndExec() {
-  if (pipes[0] != -1) {
-    close(pipes[0]);
+  if (ready[0] != -1) {
+    close(ready[0]);
   }
-  if (pipes[1] != -1) {
-    close(pipes[1]);
+  if (ready[1] != -1) {
+    close(ready[1]);
   }
 }
 
 optional<pid_t> ForkAndExec::operator()()  {
-  if (pipes[0] == -1) {
+  if (ready[0] == -1) {
     return {};
   }
-  if (pipes[1] != -1) {
-    close(pipes[1]);
-    pipes[1] = -1;
+  if (ready[1] != -1) {
+    close(ready[1]);
+    ready[1] = -1;
   }
 
   switch (pid_t pid = fork()) {
@@ -45,7 +45,7 @@ optional<pid_t> ForkAndExec::operator()()  {
       return {};
 
     default:
-      pollfd fd{pipes[0], 0, 0};
+      pollfd fd{ready[0], 0, 0};
       if (1 > poll(&fd, 1, 5000)) {
         cerr << "exec() timed out" << endl;
       }
index b88c56a727a1a0ba575765926a8a17b4afca675f..ff70abb98f20e40825b37496681d85ad08529f7b 100644 (file)
@@ -4,6 +4,8 @@
 
 class ForkAndExec {
 public:
+  enum { READ, WRITE } pipe;
+
   ForkAndExec(const char *binary, char **argv);
   ~ForkAndExec();
 
@@ -15,7 +17,7 @@ public:
   optional<pid_t> operator () ();
 
 private:
-  int pipes[2];
+  int ready[2], pipes[2];
   const char *binary;
   char **argv;
 };
index bb4bfa7f9bfea4410fbfaf275d2cdca2b96891ae..49f75cb0d0c1089f95ffa9ae22d443a281df74c9 100644 (file)
@@ -70,7 +70,7 @@ inline ostream &operator << (ostream &out, const socket_or_port_t sop) {
   if (holds_alternative<string>(sop)) {
     out << get<string>(sop);
   } else {
-    out << get<int>(sop);
+    out << ":" << get<int>(sop);
   }
   return out;
 }
index a5a4e8fdb71dbbd41678fd947ff08d937dd7e76c..42dda2920d1bdc8a12ba1da0e801823145b7a737 100644 (file)
@@ -1,140 +1,8 @@
 #include "testing/lib/common.hpp"
+#include "testing/fixtures/hashes.hpp"
 
 #include "libhashkit-1.0/hashkit.hpp"
 
-static const char *input[] = {
-    "apple",
-    "beat",
-    "carrot",
-    "daikon",
-    "eggplant",
-    "flower",
-    "green",
-    "hide",
-    "ick",
-    "jack",
-    "kick",
-    "lime",
-    "mushrooms",
-    "nectarine",
-    "orange",
-    "peach",
-    "quant",
-    "ripen",
-    "strawberry",
-    "tang",
-    "up",
-    "volumne",
-    "when",
-    "yellow",
-    "zip",
-};
-
-static const uint32_t output[][sizeof(input)/sizeof(*input)] = {
-          // one_at_a_time
-          { 2297466611U, 3902465932U, 469785835U, 1937308741U,
-          261917617U, 3785641677U, 1439605128U, 1649152283U,
-          1493851484U, 1246520657U, 2221159044U, 1973511823U,
-          384136800U, 214358653U, 2379473940U, 4269788650U,
-          2864377005U, 2638630052U, 427683330U, 990491717U,
-          1747111141U, 792127364U, 2599214128U, 2553037199U,
-          2509838425U },
-
-          // md5
-          { 3195025439U, 2556848621U, 3724893440U, 3332385401U,
-          245758794U, 2550894432U, 121710495U, 3053817768U,
-          1250994555U, 1862072655U, 2631955953U, 2951528551U,
-          1451250070U, 2820856945U, 2060845566U, 3646985608U,
-          2138080750U, 217675895U, 2230934345U, 1234361223U,
-          3968582726U, 2455685270U, 1293568479U, 199067604U,
-          2042482093U },
-
-          // crc
-          { 10542U, 22009U, 14526U, 19510U, 19432U, 10199U, 20634U,
-          9369U, 11511U, 10362U, 7893U, 31289U, 11313U, 9354U,
-          7621U, 30628U, 15218U, 25967U, 2695U, 9380U,
-          17300U, 28156U, 9192U, 20484U, 16925U },
-
-          // fnv1_64
-          { 473199127U, 4148981457U, 3971873300U, 3257986707U,
-          1722477987U, 2991193800U, 4147007314U, 3633179701U,
-          1805162104U, 3503289120U, 3395702895U, 3325073042U,
-          2345265314U, 3340346032U, 2722964135U, 1173398992U,
-          2815549194U, 2562818319U, 224996066U, 2680194749U,
-          3035305390U, 246890365U, 2395624193U, 4145193337U,
-          1801941682U },
-
-          // fnv1a_64
-          { 1488911807U, 2500855813U, 1510099634U, 1390325195U,
-          3647689787U, 3241528582U, 1669328060U, 2604311949U,
-          734810122U, 1516407546U, 560948863U, 1767346780U,
-          561034892U, 4156330026U, 3716417003U, 3475297030U,
-          1518272172U, 227211583U, 3938128828U, 126112909U,
-          3043416448U, 3131561933U, 1328739897U, 2455664041U,
-          2272238452U },
-
-          // fnv1_32
-          { 67176023U, 1190179409U, 2043204404U, 3221866419U,
-          2567703427U, 3787535528U, 4147287986U, 3500475733U,
-          344481048U, 3865235296U, 2181839183U, 119581266U,
-          510234242U, 4248244304U, 1362796839U, 103389328U,
-          1449620010U, 182962511U, 3554262370U, 3206747549U,
-          1551306158U, 4127558461U, 1889140833U, 2774173721U,
-          1180552018U },
-
-          // fnv1a_32
-          { 280767167U, 2421315013U, 3072375666U, 855001899U,
-          459261019U, 3521085446U, 18738364U, 1625305005U,
-          2162232970U, 777243802U, 3323728671U, 132336572U,
-          3654473228U, 260679466U, 1169454059U, 2698319462U,
-          1062177260U, 235516991U, 2218399068U, 405302637U,
-          1128467232U, 3579622413U, 2138539289U, 96429129U,
-          2877453236U },
-
-          // hsieh
-#ifdef HAVE_HSIEH_HASH
-          { 3738850110U, 3636226060U, 3821074029U, 3489929160U, 3485772682U, 80540287U,
-          1805464076U, 1895033657U, 409795758U, 979934958U, 3634096985U, 1284445480U,
-          2265380744U, 707972988U, 353823508U, 1549198350U, 1327930172U, 9304163U,
-          4220749037U, 2493964934U, 2777873870U, 2057831732U, 1510213931U, 2027828987U,
-          3395453351U },
-#else
-          {  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
-#endif
-
-          // murmur
-#ifdef HAVE_MURMUR_HASH
-          // murmur
-          { 4142305122U, 734504955U, 3802834688U, 4076891445U,
-          387802650U, 560515427U, 3274673488U, 3150339524U,
-          1527441970U, 2728642900U, 3613992239U, 2938419259U,
-          2321988328U, 1145154116U, 4038540960U, 2224541613U,
-          264013145U, 3995512858U, 2400956718U, 2346666219U,
-          926327338U, 442757446U, 1770805201U, 560483147U,
-          3902279934U },
-          // murmur3
-          { 1120212521U, 1448785489U, 4186307405U, 2686268514U,
-          444808887U, 221750260U, 3074673162U, 1946933257U,
-          2826416675U, 2430719166U, 3200429559U, 297894347U,
-          732888124U, 4050076964U, 3298336176U, 1336207361U,
-          810553576U, 3748182674U, 3860119212U, 3439537197U,
-          3044240981U, 1464271804U, 3896193724U, 2915115798U,
-          1702843840U },
-#else
-          { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
-          { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
-#endif
-
-          // jenkins
-          { 1442444624U, 4253821186U, 1885058256U, 2120131735U,
-          3261968576U, 3515188778U, 4232909173U, 4288625128U,
-          1812047395U, 3689182164U, 2502979932U, 1214050606U,
-          2415988847U, 1494268927U, 1025545760U, 3920481083U,
-          4153263658U, 3824871822U, 3072759809U, 798622255U,
-          3065432577U, 1453328165U, 2691550971U, 3408888387U,
-          2629893356U }
-};
-
 TEST_CASE("hashkit") {
   hashkit_st st, *hp = hashkit_create(nullptr);
   Hashkit stack;
@@ -184,10 +52,12 @@ TEST_CASE("hashkit") {
         continue;
       }
 
+      INFO("hash: " << libhashkit_string_hash(h));
+
       REQUIRE(HASHKIT_SUCCESS == stack.set_function(h));
       REQUIRE(HASHKIT_SUCCESS == hashkit_set_function(&st, h));
 
-      SECTION("can digest set hash function") {
+      DYNAMIC_SECTION("can digest hash function: " << libhashkit_string_hash(h)) {
         auto n = 0;
 
         for (auto i : input) {
diff --git a/testing/tests/memcached/generate_hash.cpp b/testing/tests/memcached/generate_hash.cpp
new file mode 100644 (file)
index 0000000..30e02e1
--- /dev/null
@@ -0,0 +1,47 @@
+#include "testing/lib/common.hpp"
+#include "testing/fixtures/hashes.hpp"
+
+static constexpr const uint32_t md5_hosts[] = {4U, 1U, 0U, 1U, 4U, 2U, 0U, 3U, 0U, 0U, 3U, 1U, 0U, 0U, 1U, 3U, 0U, 0U, 0U, 3U, 1U, 0U, 4U, 4U, 3U};
+static constexpr const uint32_t crc_hosts[] = {2U, 4U, 1U, 0U, 2U, 4U, 4U, 4U, 1U, 2U, 3U, 4U, 3U, 4U, 1U, 3U, 3U, 2U, 0U, 0U, 0U, 1U, 2U, 4U, 0U};
+static constexpr const uint32_t *hosts[] = {nullptr, md5_hosts, crc_hosts};
+
+TEST_CASE("memcached generate_hash") {
+  MemcachedPtr memc(memcached(S("--server=localhost:1 --server=localhost:2 --server=localhost:3 --server=localhost:4 --server=localhost5 --DISTRIBUTION=modula")));
+
+  REQUIRE(*memc);
+
+  SECTION("generate hash value") {
+    for (int f = MEMCACHED_HASH_DEFAULT; f < MEMCACHED_HASH_MAX; ++f) {
+      auto h = static_cast<memcached_hash_t>(f);
+
+      if (h == MEMCACHED_HASH_CUSTOM) {
+        continue;
+      }
+      if (MEMCACHED_SUCCESS != memcached_behavior_set_key_hash(*memc, h)) {
+        WARN("hash algorithm not enabled: " << libmemcached_string_hash(h) << " (" << f << ")");
+        continue;
+      }
+
+      INFO("hash: " << libmemcached_string_hash(h));
+
+      auto n = 0;
+      for (auto i : input) {
+        CHECK(output[f][n] == memcached_generate_hash_value(S(i), h));
+        ++n;
+      }
+    }
+  }
+
+  SECTION("generate hash") {
+    auto hash = GENERATE(as<memcached_hash_t>{}, MEMCACHED_HASH_MD5, MEMCACHED_HASH_CRC);
+
+    INFO("hash: " << libmemcached_string_hash(hash));
+    REQUIRE(MEMCACHED_SUCCESS == memcached_behavior_set_key_hash(*memc, hash));
+
+    auto n = 0;
+    for (auto i : input) {
+      CHECK(hosts[hash][n] == memcached_generate_hash(*memc, S(i)));
+      ++n;
+    }
+  }
+}
diff --git a/testing/tests/memcached/noreply.cpp b/testing/tests/memcached/noreply.cpp
new file mode 100644 (file)
index 0000000..ec32458
--- /dev/null
@@ -0,0 +1,61 @@
+#include "testing/lib/common.hpp"
+#include "testing/lib/MemcachedCluster.hpp"
+
+enum action_t {ADD, REPLACE, SET, APPEND, PREPEND};
+inline action_t operator ++ (action_t &a) {
+  return a = static_cast<action_t>(underlying_type<action_t>::type(a) + 1);
+}
+
+constexpr static const int keys = 5000;
+
+TEST_CASE("memcached noreply") {
+  auto test{MemcachedCluster::mixed()};
+  auto memc = &test.memc;
+
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, true));
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true));
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
+
+  for (auto action = ADD; action <= PREPEND; ++action) {
+    for (auto i = 0; i < keys; ++i) {
+      auto key = to_string(i);
+      memcached_return_t rc;
+
+      switch (action) {
+      case ADD:     rc = memcached_add(memc, key.c_str(), key.length(), key.c_str(), key.length(), 0, 0); break;
+      case REPLACE: rc = memcached_replace(memc, key.c_str(), key.length(), key.c_str(), key.length(), 0, 0); break;
+      case SET:     rc = memcached_set(memc, key.c_str(), key.length(), key.c_str(), key.length(), 0, 0); break;
+      case APPEND:  rc = memcached_append(memc, key.c_str(), key.length(), key.c_str(), key.length(), 0, 0); break;
+      case PREPEND: rc = memcached_prepend(memc, key.c_str(), key.length(), key.c_str(), key.length(), 0, 0); break;
+      default:      FAIL();
+      }
+
+      if (rc != MEMCACHED_BUFFERED) {
+        REQUIRE_SUCCESS(rc);
+      }
+    }
+
+    REQUIRE_SUCCESS(memcached_flush_buffers(memc));
+
+    for (auto i = 0; i < keys; ++i) {
+      auto key = to_string(i);
+
+      size_t len;
+      memcached_return_t rc;
+      uint32_t flags;
+      Malloced val(memcached_get(memc, key.c_str(), key.length(), &len, &flags, &rc));
+
+      REQUIRE_SUCCESS(rc);
+      REQUIRE(*val);
+
+      switch (action) {
+      case ADD:     [[fallthrough]];
+      case REPLACE: [[fallthrough]];
+      case SET:     REQUIRE(key == *val);  break;
+      case APPEND:  REQUIRE(key + key == *val); break;
+      case PREPEND: REQUIRE(key + key + key == *val); break;
+      default:      FAIL();
+      }
+    }
+  }
+}
diff --git a/testing/tests/memcached/util.cpp b/testing/tests/memcached/util.cpp
new file mode 100644 (file)
index 0000000..11f2a46
--- /dev/null
@@ -0,0 +1,66 @@
+#include "testing/lib/common.hpp"
+#include "testing/lib/MemcachedCluster.hpp"
+
+#include "libmemcached/instance.hpp"
+#include "libmemcachedutil/common.h"
+
+static memcached_return_t ping_callback(const memcached_st *, const memcached_instance_st *instance, void *) {
+  memcached_return_t rc;
+
+  REQUIRE(libmemcached_util_ping(memcached_server_name(instance), memcached_server_port(instance), &rc));
+  REQUIRE(rc == MEMCACHED_SUCCESS);
+  return MEMCACHED_SUCCESS;
+}
+
+TEST_CASE("memcached util") {
+  SECTION("version_check") {
+    auto test = MemcachedCluster::mixed();
+    auto memc = &test.memc;
+
+    REQUIRE_SUCCESS(memcached_version(memc));
+    REQUIRE(libmemcached_util_version_check(memc, 0, 0, 0));
+    REQUIRE_FALSE(libmemcached_util_version_check(memc, 255, 255, 255));
+
+    auto instance = memcached_server_instance_by_position(memc, 0);
+    REQUIRE(libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version));
+    if (instance->micro_version) {
+      REQUIRE(libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version - 1));
+      if (instance->micro_version < 255) {
+        REQUIRE_FALSE(libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version + 1));
+      }
+    }
+    if (instance->minor_version) {
+      REQUIRE(libmemcached_util_version_check(memc, instance->major_version, instance->minor_version - 1, 255));
+      if (instance->minor_version < 255) {
+        REQUIRE_FALSE(libmemcached_util_version_check(memc, instance->major_version, instance->minor_version + 1, 0));
+      }
+    }
+    if (instance->major_version) {
+      REQUIRE(libmemcached_util_version_check(memc, instance->major_version - 1, 255, 255));
+      if (instance->major_version < 255) {
+        REQUIRE_FALSE(libmemcached_util_version_check(memc, instance->major_version + 1, 0, 0));
+      }
+    }
+  }
+
+  SECTION("getpid") {
+    auto test = MemcachedCluster::network();
+    memcached_return_t rc;
+
+    for (auto &server : test.cluster.getServers()) {
+      REQUIRE(server.getPid() == libmemcached_util_getpid("localhost", get<int>(server.getSocketOrPort()), &rc));
+      REQUIRE_SUCCESS(rc);
+    }
+
+    REQUIRE(-1 == libmemcached_util_getpid("localhost", 1, &rc));
+    REQUIRE_RC(MEMCACHED_CONNECTION_FAILURE, rc);
+  }
+
+  SECTION("ping") {
+    auto test = MemcachedCluster::network();
+    auto memc = &test.memc;
+    memcached_server_fn fptr[] = {&ping_callback};
+
+    REQUIRE_SUCCESS(memcached_server_cursor(memc, fptr, nullptr, 1));
+  }
+}
diff --git a/testing/tests/noreply.cpp b/testing/tests/noreply.cpp
deleted file mode 100644 (file)
index ec32458..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "testing/lib/common.hpp"
-#include "testing/lib/MemcachedCluster.hpp"
-
-enum action_t {ADD, REPLACE, SET, APPEND, PREPEND};
-inline action_t operator ++ (action_t &a) {
-  return a = static_cast<action_t>(underlying_type<action_t>::type(a) + 1);
-}
-
-constexpr static const int keys = 5000;
-
-TEST_CASE("memcached noreply") {
-  auto test{MemcachedCluster::mixed()};
-  auto memc = &test.memc;
-
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, true));
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, true));
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, true));
-
-  for (auto action = ADD; action <= PREPEND; ++action) {
-    for (auto i = 0; i < keys; ++i) {
-      auto key = to_string(i);
-      memcached_return_t rc;
-
-      switch (action) {
-      case ADD:     rc = memcached_add(memc, key.c_str(), key.length(), key.c_str(), key.length(), 0, 0); break;
-      case REPLACE: rc = memcached_replace(memc, key.c_str(), key.length(), key.c_str(), key.length(), 0, 0); break;
-      case SET:     rc = memcached_set(memc, key.c_str(), key.length(), key.c_str(), key.length(), 0, 0); break;
-      case APPEND:  rc = memcached_append(memc, key.c_str(), key.length(), key.c_str(), key.length(), 0, 0); break;
-      case PREPEND: rc = memcached_prepend(memc, key.c_str(), key.length(), key.c_str(), key.length(), 0, 0); break;
-      default:      FAIL();
-      }
-
-      if (rc != MEMCACHED_BUFFERED) {
-        REQUIRE_SUCCESS(rc);
-      }
-    }
-
-    REQUIRE_SUCCESS(memcached_flush_buffers(memc));
-
-    for (auto i = 0; i < keys; ++i) {
-      auto key = to_string(i);
-
-      size_t len;
-      memcached_return_t rc;
-      uint32_t flags;
-      Malloced val(memcached_get(memc, key.c_str(), key.length(), &len, &flags, &rc));
-
-      REQUIRE_SUCCESS(rc);
-      REQUIRE(*val);
-
-      switch (action) {
-      case ADD:     [[fallthrough]];
-      case REPLACE: [[fallthrough]];
-      case SET:     REQUIRE(key == *val);  break;
-      case APPEND:  REQUIRE(key + key == *val); break;
-      case PREPEND: REQUIRE(key + key + key == *val); break;
-      default:      FAIL();
-      }
-    }
-  }
-}