testing: improve sanitizer handling
[awesomized/libmemcached] / testing / lib / common.hpp
index 82c6156702853d21fb35e6e01506b645a4a7e557..ee177003bac8fbf3b2a5a0cff0b4be838158fb36 100644 (file)
@@ -11,7 +11,9 @@
 #include <variant>
 #include <vector>
 
-#include "../lib/catch.hpp"
+#include "testing/conf.h"
+#include "testing/lib/catch.hpp"
+#include "testing/lib/random.hpp"
 
 #include "libmemcached/memcached.h"
 
@@ -22,53 +24,100 @@ using socket_or_port_t = variant<string, int>;
  * Useful macros for testing
  */
 #define S(s) (s),strlen(s)
+#define DECLARE_STREQUAL static auto strequal = equal_to<string>();
 #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))
-
+#define REQUIRE_SUCCESS(rc) do { \
+    INFO("expected: SUCCESS");   \
+    REQUIRE_THAT(rc, test.returns.success()); \
+  } while(0)
+#define REQUIRE_RC(rc, call) do { \
+    INFO("expected: " << memcached_strerror(nullptr, rc)); \
+    REQUIRE_THAT(call, test.returns(rc));                  \
+  } while(0)
 
 const char *getenv_else(const char *var, const char *defval);
-unsigned random_num(unsigned min, unsigned max);
-unsigned random_port();
-string random_socket();
-string random_socket_or_port_string(const string &what);
-string random_socket_or_port_flag(const string &binary);
 
-inline auto random_socket_or_port_arg() {
-  return make_pair(&random_socket_or_port_flag, &random_socket_or_port_string);
+inline memcached_return_t fetch_all_results(memcached_st *memc, unsigned int &keys_returned, memcached_return_t &rc) {
+  keys_returned = 0;
+
+  memcached_result_st *result = nullptr;
+  while ((result = memcached_fetch_result(memc, result, &rc))) {
+    REQUIRE(MEMCACHED_SUCCESS == rc);
+    keys_returned += 1;
+  }
+  memcached_result_free(result);
+  return MEMCACHED_SUCCESS;
+}
+
+inline memcached_return_t fetch_all_results(memcached_st *memc, unsigned int &keys_returned) {
+  memcached_return_t rc;
+  fetch_all_results(memc, keys_returned, rc);
+  return rc;
 }
 
+#include <cstdlib>
+#include <unistd.h>
+
+class Tempfile {
+public:
+  explicit Tempfile(const char templ_[] = "memc.test.XXXXXX") {
+    *copy(S(templ_)+templ_, fn) = '\0';
+    fd = mkstemp(fn);
+  }
+  ~Tempfile() {
+    close(fd);
+    unlink(fn);
+  }
+  int getFd() const {
+    return fd;
+  }
+  const char *getFn() const {
+    return fn;
+  }
+  bool put(const char *buf, size_t len) const {
+    return static_cast<ssize_t >(len) == write(fd, buf, len);
+  }
+private:
+  char fn[80];
+  int fd;
+};
+
 class MemcachedPtr {
 public:
-  memcached_st memc;
+  memcached_st *memc;
 
   explicit
   MemcachedPtr(memcached_st *memc_) {
-    memset(&memc, 0, sizeof(memc));
-    REQUIRE(memcached_clone(&memc, memc_));
+    memc = memc_;
   }
   MemcachedPtr()
-  : MemcachedPtr(nullptr)
+  : MemcachedPtr(memcached_create(nullptr))
   {}
   ~MemcachedPtr() {
-    memcached_free(&memc);
+    memcached_free(memc);
   }
   memcached_st *operator * () {
-    return &memc;
+    return memc;
   }
 };
 
+template<class T>
 class Malloced {
-  void *ptr;
+  T *ptr;
 public:
-  Malloced(void *ptr_)
+  explicit
+  Malloced(T *ptr_)
   : ptr{ptr_}
   {}
   ~Malloced() {
-    free(ptr);
+    if(ptr)
+      free(ptr);
+  }
+  auto operator *() {
+    return ptr;
   }
-  void *operator *() {
+  auto operator ->() {
     return ptr;
   }
 };