flush [ci skip]
authorMichael Wallner <mike@php.net>
Thu, 3 Sep 2020 11:59:05 +0000 (13:59 +0200)
committerMichael Wallner <mike@php.net>
Thu, 3 Sep 2020 11:59:05 +0000 (13:59 +0200)
testing/hashkit/basic.cpp
testing/lib/Cluster.hpp
testing/lib/MemcachedCluster.cpp
testing/lib/MemcachedCluster.hpp
testing/lib/Server.hpp
testing/lib/common.hpp
testing/memcached/dump.cpp
testing/memcached/encoding_key.cpp
testing/memcached/exist.cpp
testing/memcached/servers.cpp

index b162b9c97865e3ac1dcba00dbbd38c6353874ee6..8393266f44995ef5c233626a90c3e3a181c2539c 100644 (file)
@@ -168,8 +168,8 @@ TEST_CASE("hashkit") {
   }
 
   SECTION("can digest default") {
-    REQUIRE(2297466611U == stack.digest(LITERAL("apple")));
-    REQUIRE(2297466611U == hashkit_digest(&st, LITERAL("apple")));
+    REQUIRE(2297466611U == stack.digest(S("apple")));
+    REQUIRE(2297466611U == hashkit_digest(&st, S("apple")));
   }
 
   SECTION("can set hash function") {
@@ -191,9 +191,9 @@ TEST_CASE("hashkit") {
         auto n = 0;
 
         for (auto i : input) {
-          CHECK(output[f][n] == stack.digest(LITERAL(i)));
-          CHECK(output[f][n] == hashkit_digest(&st, LITERAL(i)));
-          CHECK(output[f][n] == libhashkit_digest(LITERAL(i), h));
+          CHECK(output[f][n] == stack.digest(S(i)));
+          CHECK(output[f][n] == hashkit_digest(&st, S(i)));
+          CHECK(output[f][n] == libhashkit_digest(S(i), h));
           ++n;
         }
       }
index 416da13849067386af93ad13b34c1b67aba5c3a0..efc5eefdd93d15ba45fefbf9ee37f547536abf30 100644 (file)
@@ -13,8 +13,18 @@ public:
   Cluster(const Cluster &c) = delete;
   Cluster &operator = (const Cluster &c) = delete;
 
-  Cluster(Cluster &&c) = default;
-  Cluster &operator = (Cluster &&c) = default;
+  Cluster(Cluster &&c)
+  : proto{}
+  {
+    *this = move(c);
+  };
+  Cluster &operator = (Cluster &&c) {
+    count = exchange(c.count, 0);
+    proto = exchange(c.proto, Server{});
+    cluster = exchange(c.cluster, {});
+    pids = exchange(c.pids, {});
+    return *this;
+  }
 
   const vector<Server> &getServers() const;
 
index 4a330247eaf4cab4846ce51883cc995eca14f3cb..40f2a963e1f1be0b68e25f89d966fc441e1d2169 100644 (file)
@@ -1,6 +1,8 @@
 #include "MemcachedCluster.hpp"
 #include "Retry.hpp"
 
+const memcached_st MemcachedCluster::empty_memc{};
+
 void MemcachedCluster::init() {
   REQUIRE(cluster.start());
 
@@ -21,7 +23,9 @@ void MemcachedCluster::init() {
 }
 
 MemcachedCluster::~MemcachedCluster() {
-  memcached_free(&memc);
+  if (memcmp(&memc, &empty_memc, sizeof(memc))) {
+    memcached_free(&memc);
+  }
 }
 
 void MemcachedCluster::flush() {
@@ -29,7 +33,10 @@ void MemcachedCluster::flush() {
 }
 
 MemcachedCluster::MemcachedCluster()
-: cluster{Server{getenv_else("MEMCACHED_BINARY", "memcached"), {random_socket_or_port_arg()}}}
+: cluster{Server{
+  getenv_else("MEMCACHED_BINARY", "memcached"),
+  {random_socket_or_port_arg()}
+}}
 {
   init();
 }
@@ -44,14 +51,21 @@ MemcachedCluster MemcachedCluster::mixed() {
   return MemcachedCluster{};
 }
 
-MemcachedCluster MemcachedCluster::net() {
-  return MemcachedCluster{Cluster{Server{getenv_else("MEMCACHED_BINARY", "memcached"), {"-p", random_socket_or_port_string}}}};
+MemcachedCluster MemcachedCluster::network() {
+  return MemcachedCluster{Cluster{Server{
+    getenv_else("MEMCACHED_BINARY", "memcached"),
+    {"-p", random_socket_or_port_string}
+  }}};
 }
 
 MemcachedCluster MemcachedCluster::socket() {
-  return MemcachedCluster{Cluster{Server{getenv_else("MEMCACHED_BINARY", "memcached"), {"-s", random_socket_or_port_string}}}};
+  return MemcachedCluster{Cluster{Server{
+    getenv_else("MEMCACHED_BINARY", "memcached"),
+    {"-s", random_socket_or_port_string}
+  }}};
 }
 
-void MemcachedCluster::enableBinary(bool enable) {
-  REQUIRE(MEMCACHED_SUCCESS == memcached_behavior_set(&memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, enable));
+void MemcachedCluster::enableBinaryProto(bool enable) {
+  REQUIRE(MEMCACHED_SUCCESS == memcached_behavior_set(&memc,
+      MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, enable));
 }
index 45fce24c0d53d3f8cde3c725ed7e48a154b4e9a2..685cf6fbef22564c1ad4625bbb2fc6ed8a4169d2 100644 (file)
@@ -3,23 +3,87 @@
 #include "common.hpp"
 #include "Cluster.hpp"
 
+class ReturnMatcher : public Catch::MatcherBase<memcached_return_t> {
+public:
+  explicit ReturnMatcher(const memcached_st *memc_, memcached_return_t expected_ = MEMCACHED_SUCCESS)
+      : memc{memc_}
+      , expected{expected_}
+  {}
+
+  ReturnMatcher(const ReturnMatcher &) = default;
+  ReturnMatcher &operator = (const ReturnMatcher &) = default;
+
+  ReturnMatcher(ReturnMatcher &&rm) {
+    *this = move(rm);
+  }
+  ReturnMatcher &operator = (ReturnMatcher &&rm) {
+    memc = exchange(rm.memc, nullptr);
+    expected = rm.expected;
+    return *this;
+  }
+
+  bool match(const memcached_return_t &arg) const override {
+    return arg == expected;
+  }
+
+  ReturnMatcher success() {
+    return ReturnMatcher{memc};
+  }
+
+  ReturnMatcher operator () (memcached_return_t expected_) {
+    return ReturnMatcher{memc, expected_};
+  }
+
+protected:
+  string describe() const override {
+    return string{"is "}
+           + to_string(expected)
+           + " (" + memcached_strerror(memc, expected) + ") "
+           + "\n\tlast error: "
+      + memcached_last_error_message(memc);
+  }
+
+private:
+  const memcached_st *memc;
+  memcached_return_t expected;
+};
+
 class MemcachedCluster {
 public:
   Cluster cluster;
-  memcached_st memc;
+  memcached_st memc{empty_memc};
+  ReturnMatcher returns{&memc};
 
   MemcachedCluster();
   explicit
   MemcachedCluster(Cluster &&cluster);
   ~MemcachedCluster();
 
-  void enableBinary(bool enable = true);
+  MemcachedCluster(const MemcachedCluster &) = delete;
+  MemcachedCluster &operator=(const MemcachedCluster &) = delete;
+
+  MemcachedCluster(MemcachedCluster &&mc)
+  : cluster{Server{}}
+  {
+    *this = move(mc);
+  };
+  MemcachedCluster &operator=(MemcachedCluster &&mc)
+  {
+    cluster = move(mc.cluster);
+    memcached_clone(&memc, &mc.memc);
+    returns = ReturnMatcher{&memc};
+    return *this;
+  }
+
+  void enableBinaryProto(bool enable = true);
   void flush();
 
   static MemcachedCluster mixed();
-  static MemcachedCluster net();
+  static MemcachedCluster network();
   static MemcachedCluster socket();
 
 private:
+  static const memcached_st empty_memc;
+
   void init();
 };
index 08ab57734ef28a1512c723c1d157ca29a2b96460..5891dea27fb83dc3b0377e977c16aee1bfe924bf 100644 (file)
@@ -15,15 +15,25 @@ public:
   using argv_t = vector<variant<arg_t, arg_pair_t>>;
 
   explicit
-  Server(string &&binary_, argv_t && args_ = {});
+  Server(string &&binary_ = "false", argv_t && args_ = {});
 
   ~Server();
 
   Server(const Server &s);
   Server &operator = (const Server &s);
 
-  Server &operator = (Server &&s) = default;
-  Server(Server &&s) = default;
+  Server(Server &&s) {
+    *this = move(s);
+  };
+  Server &operator = (Server &&s) {
+    binary = exchange(s.binary, "false");
+    args = exchange(s.args, {});
+    pid = exchange(s.pid, 0);
+    status = exchange(s.status, 0);
+    signalled = exchange(s.signalled, {});
+    socket_or_port = exchange(s.socket_or_port, {});
+    return *this;
+  };
 
   pid_t getPid() const;
 
index b516d669a66cb43d470754bfdca058e78c8a2308..82c6156702853d21fb35e6e01506b645a4a7e557 100644 (file)
 
 #include "libmemcached/memcached.h"
 
-#define LITERAL(s) (s),strlen(s)
-#define LOOPED_SECTION(tests) \
-  auto i_=0;                  \
-  for (auto &&test : tests) DYNAMIC_SECTION("test" << i_++)
-
 using namespace std;
-
 using socket_or_port_t = variant<string, int>;
 
+/**
+ * Useful macros for testing
+ */
+#define S(s) (s),strlen(s)
+#define LOOPED_SECTION(tests) \
+  for (auto &[name, test] : tests) DYNAMIC_SECTION("test " << name)
+#define REQUIRE_SUCCESS(rc) REQUIRE_THAT(rc, test.returns.success())
+#define REQUIRE_RC(rc, call) REQUIRE_THAT(call, test.returns(rc))
+
+
 const char *getenv_else(const char *var, const char *defval);
 unsigned random_num(unsigned min, unsigned max);
 unsigned random_port();
index 016dabaa42d2655ba8bea3ec1c9d2b0041161537..6add5666a1b6c05cbf1a14934c3f3e4dd0567aae 100644 (file)
@@ -2,16 +2,16 @@
 #include "../lib/MemcachedCluster.hpp"
 
 memcached_return_t dump_cb(const memcached_st *, const char *, size_t, void *ctx) {
-  size_t *c = reinterpret_cast<size_t *>(ctx);
+  auto *c = reinterpret_cast<size_t *>(ctx);
   ++(*c);
   return MEMCACHED_SUCCESS;
 }
 
 TEST_CASE("memcached dump") {
-  MemcachedCluster tests[]{
-      MemcachedCluster::mixed(),
-      MemcachedCluster::net(),
-      MemcachedCluster::socket()
+  pair<string, MemcachedCluster> tests[]{
+    {"mixed", MemcachedCluster::mixed()},
+    {"network", MemcachedCluster::network()},
+    {"socket", MemcachedCluster::socket()}
   };
 
   LOOPED_SECTION(tests) {
@@ -23,9 +23,7 @@ TEST_CASE("memcached dump") {
         int len = snprintf(key, sizeof(key) - 1, "k_%d", i);
 
         CHECKED_IF(len) {
-          auto rc = memcached_set(memc, key, len, key, len, 0, 0);
-          INFO("last error: " << memcached_last_error(memc));
-          REQUIRE(MEMCACHED_SUCCESS == rc);
+          REQUIRE_SUCCESS(memcached_set(memc, key, len, key, len, 0, 0));
         }
       }
 
@@ -39,7 +37,7 @@ TEST_CASE("memcached dump") {
         size_t counter = 0;
         memcached_dump_fn fn[] = {dump_cb};
 
-        REQUIRE(MEMCACHED_SUCCESS == memcached_dump(memc, fn, &counter, 1));
+        REQUIRE_SUCCESS(memcached_dump(memc, fn, &counter, 1));
         REQUIRE(counter == 64);
       }
     }
index cb7620ae032b5aff0d1f93f5f397e216707855a5..a924b4a9b979bb8a23581c42aea005bf4f039e5b 100644 (file)
@@ -1,9 +1,9 @@
 #include "../lib/common.hpp"
 #include "../lib/MemcachedCluster.hpp"
 
-#define TEST_KEY LITERAL("test")
-#define INITIAL_VAL LITERAL("initial")
-#define REPLACED_VAL LITERAL("replaced")
+#define TEST_KEY S("test")
+#define INITIAL_VAL S("initial")
+#define REPLACED_VAL S("replaced")
 
 static inline void check(memcached_st *enc, memcached_st *raw, const char *val, size_t len) {
   memcached_return_t enc_rc, raw_rc;
@@ -20,10 +20,9 @@ static inline void check(memcached_st *enc, memcached_st *raw, const char *val,
 }
 
 TEST_CASE("memcached encoding_key") {
-  MemcachedCluster tests[]{
-      MemcachedCluster::mixed(),
-      MemcachedCluster::net(),
-      MemcachedCluster::socket()
+  pair<string, MemcachedCluster> tests[]{
+    {"network", MemcachedCluster::network()},
+    {"socket", MemcachedCluster::socket()}
   };
 
   LOOPED_SECTION(tests) {
@@ -32,12 +31,10 @@ TEST_CASE("memcached encoding_key") {
     SECTION("accepts encoding key") {
       MemcachedPtr copy(memc);
 
-      REQUIRE(MEMCACHED_SUCCESS ==
-              memcached_set_encoding_key(memc, LITERAL(__func__)));
+      REQUIRE_SUCCESS(memcached_set_encoding_key(memc, S(__func__)));
 
       SECTION("sets encoded value") {
-        REQUIRE(MEMCACHED_SUCCESS ==
-                memcached_set(memc, TEST_KEY, INITIAL_VAL, 0, 0));
+        REQUIRE_SUCCESS(memcached_set(memc, TEST_KEY, INITIAL_VAL, 0, 0));
 
         SECTION("gets encoded value") {
           check(memc, &copy.memc, INITIAL_VAL);
@@ -52,17 +49,14 @@ TEST_CASE("memcached encoding_key") {
 
       SECTION("adds encoded value") {
 
-        REQUIRE(MEMCACHED_SUCCESS ==
-                memcached_set(memc, TEST_KEY, INITIAL_VAL, 0, 0));
-        REQUIRE(MEMCACHED_NOTSTORED ==
-                memcached_add(memc, TEST_KEY, REPLACED_VAL, 0, 0));
+        REQUIRE_SUCCESS(memcached_set(memc, TEST_KEY, INITIAL_VAL, 0, 0));
+        REQUIRE_RC(MEMCACHED_NOTSTORED, memcached_add(memc, TEST_KEY, REPLACED_VAL, 0, 0));
 
         check(memc, &copy.memc, INITIAL_VAL);
 
         test.flush();
 
-        REQUIRE(MEMCACHED_SUCCESS ==
-                memcached_add(memc, TEST_KEY, REPLACED_VAL, 0, 0));
+        REQUIRE_SUCCESS(memcached_add(memc, TEST_KEY, REPLACED_VAL, 0, 0));
 
         SECTION("gets encoded value") {
           check(memc, &copy.memc, REPLACED_VAL);
@@ -70,13 +64,11 @@ TEST_CASE("memcached encoding_key") {
       }
 
       SECTION("replaces encoded value") {
-        REQUIRE(MEMCACHED_SUCCESS ==
-                memcached_set(memc, TEST_KEY, INITIAL_VAL, 0, 0));
+        REQUIRE_SUCCESS(memcached_set(memc, TEST_KEY, INITIAL_VAL, 0, 0));
 
         check(memc, &copy.memc, INITIAL_VAL);
 
-        REQUIRE(MEMCACHED_SUCCESS ==
-                memcached_replace(memc, TEST_KEY, REPLACED_VAL, 0, 0));
+        REQUIRE_SUCCESS(memcached_replace(memc, TEST_KEY, REPLACED_VAL, 0, 0));
 
         SECTION("gets encoded value") {
           check(memc, &copy.memc, REPLACED_VAL);
@@ -84,20 +76,12 @@ TEST_CASE("memcached encoding_key") {
       }
 
       SECTION("unsupported") {
-        REQUIRE(MEMCACHED_NOT_SUPPORTED ==
-                memcached_increment(memc, TEST_KEY, 0, nullptr));
-        REQUIRE(MEMCACHED_NOT_SUPPORTED ==
-                memcached_decrement(memc, TEST_KEY, 0, nullptr));
-        REQUIRE(MEMCACHED_NOT_SUPPORTED ==
-                memcached_increment_with_initial(memc, TEST_KEY, 0, 0,
-                                                 0, nullptr));
-        REQUIRE(MEMCACHED_NOT_SUPPORTED ==
-                memcached_decrement_with_initial(memc, TEST_KEY, 0, 0,
-                                                 0, nullptr));
-        REQUIRE(MEMCACHED_NOT_SUPPORTED ==
-                memcached_append(memc, TEST_KEY, REPLACED_VAL, 0, 0));
-        REQUIRE(MEMCACHED_NOT_SUPPORTED ==
-                memcached_prepend(memc, TEST_KEY, REPLACED_VAL, 0, 0));
+        REQUIRE_RC(MEMCACHED_NOT_SUPPORTED, memcached_increment(memc, TEST_KEY, 0, nullptr));
+        REQUIRE_RC(MEMCACHED_NOT_SUPPORTED, memcached_decrement(memc, TEST_KEY, 0, nullptr));
+        REQUIRE_RC(MEMCACHED_NOT_SUPPORTED, memcached_increment_with_initial(memc, TEST_KEY, 0, 0, 0, nullptr));
+        REQUIRE_RC(MEMCACHED_NOT_SUPPORTED, memcached_decrement_with_initial(memc, TEST_KEY, 0, 0, 0, nullptr));
+        REQUIRE_RC(MEMCACHED_NOT_SUPPORTED, memcached_append(memc, TEST_KEY, REPLACED_VAL, 0, 0));
+        REQUIRE_RC(MEMCACHED_NOT_SUPPORTED, memcached_prepend(memc, TEST_KEY, REPLACED_VAL, 0, 0));
       }
     }
   }
index 663deecb830c007686919e1f30ed3a1930a24c90..29c0f253a7db7e8dc0a28f638839dfd31fa23cbb 100644 (file)
@@ -2,61 +2,47 @@
 #include "../lib/MemcachedCluster.hpp"
 
 TEST_CASE("memcached exist") {
-  MemcachedCluster tests[]{
-      MemcachedCluster::mixed(),
-      MemcachedCluster::net(),
-      MemcachedCluster::socket()
+  pair<string, MemcachedCluster> tests[]{
+    {"bin_mixed", MemcachedCluster::mixed()},
+    {"network", MemcachedCluster::network()},
+    {"socket", MemcachedCluster::socket()}
   };
 
-  tests[0].enableBinary();
+  tests[0].second.enableBinaryProto();
 
   LOOPED_SECTION(tests) {
     auto memc = &test.memc;
+    auto &returns = test.returns;
 
     SECTION("initial not found") {
-      REQUIRE(
-          MEMCACHED_NOTFOUND == memcached_exist(memc, LITERAL("frog")));
+      REQUIRE_RC(MEMCACHED_NOTFOUND,memcached_exist(memc, S("frog")));
     }
 
     SECTION("set found") {
-      REQUIRE(MEMCACHED_SUCCESS ==
-              memcached_set(memc, LITERAL("frog"), LITERAL("frog"), 0,
-                            0));
-      REQUIRE(
-          MEMCACHED_SUCCESS == memcached_exist(memc, LITERAL("frog")));
-
-      SECTION("deleted not found") {
-        REQUIRE(MEMCACHED_SUCCESS ==
-                memcached_delete(memc, LITERAL("frog"), 0));
-        REQUIRE(MEMCACHED_NOTFOUND ==
-                memcached_exist(memc, LITERAL("frog")));
-      }
+        REQUIRE_SUCCESS(memcached_set(memc, S("frog"), S("frog"), 0, 0));
+        REQUIRE_SUCCESS(memcached_exist(memc, S("frog")));
+
+        SECTION("deleted not found") {
+          REQUIRE_SUCCESS(memcached_delete(memc, S("frog"), 0));
+          REQUIRE_RC(MEMCACHED_NOTFOUND, memcached_exist(memc, S("frog")));
+        }
     }
 
     SECTION("by key") {
       SECTION("initial not found") {
-        REQUIRE(MEMCACHED_NOTFOUND ==
-                memcached_exist_by_key(memc, LITERAL("master"),
-                                       LITERAL("frog")));
+        REQUIRE_RC(MEMCACHED_NOTFOUND, memcached_exist_by_key(memc, S("master"), S("frog")));
       }
 
       SECTION("set found") {
-        REQUIRE(MEMCACHED_SUCCESS ==
-                memcached_set_by_key(memc, LITERAL("master"),
-                                     LITERAL("frog"), LITERAL("frog"), 0, 0));
-        REQUIRE(MEMCACHED_SUCCESS ==
-                memcached_exist_by_key(memc, LITERAL("master"),
-                                       LITERAL("frog")));
+        REQUIRE_SUCCESS(memcached_set_by_key(memc, S("master"), S("frog"), S("frog"), 0, 0));
+        REQUIRE_SUCCESS(memcached_exist_by_key(memc, S("master"), S("frog")));
 
         SECTION("deleted not found") {
-          REQUIRE(MEMCACHED_SUCCESS ==
-                  memcached_delete_by_key(memc, LITERAL("master"),
-                                          LITERAL("frog"), 0));
-          REQUIRE(MEMCACHED_NOTFOUND ==
-                  memcached_exist_by_key(memc, LITERAL("master"),
-                                         LITERAL("frog")));
+          REQUIRE_SUCCESS(memcached_delete_by_key(memc, S("master"), S("frog"), 0));
+          REQUIRE_RC(MEMCACHED_NOTFOUND, memcached_exist_by_key(memc, S("master"), S("frog")));
         }
       }
     }
   }
+
 }
index 69f76bd38e32ebdb87a6845f63ec5ae245051031..9c32416a1843d208cb90858d2d239a8e111e27a3 100644 (file)
@@ -35,6 +35,6 @@ TEST_CASE("memcached servers") {
   SECTION("no configured servers") {
     MemcachedPtr memc;
 
-    REQUIRE(MEMCACHED_NO_SERVERS == memcached_increment(*memc, LITERAL("key"), 1, nullptr));
+    REQUIRE(MEMCACHED_NO_SERVERS == memcached_increment(*memc, S("key"), 1, nullptr));
   }
 }