testing: rename regression tests
authorMichael Wallner <mike@php.net>
Thu, 17 Sep 2020 07:43:57 +0000 (09:43 +0200)
committerMichael Wallner <mike@php.net>
Mon, 28 Sep 2020 15:44:28 +0000 (17:44 +0200)
14 files changed:
test/tests/memcached/regression/lp1048945.cpp [deleted file]
test/tests/memcached/regression/lp434484.cpp [deleted file]
test/tests/memcached/regression/lp434843.cpp [deleted file]
test/tests/memcached/regression/lp442914.cpp [deleted file]
test/tests/memcached/regression/lp447342.cpp [deleted file]
test/tests/memcached/regression/lp490486.cpp [deleted file]
test/tests/memcached/regression/lp996813.cpp [deleted file]
test/tests/memcached/regression/lp_000-434-484.cpp [new file with mode: 0644]
test/tests/memcached/regression/lp_000-434-843.cpp [new file with mode: 0644]
test/tests/memcached/regression/lp_000-442-914.cpp [new file with mode: 0644]
test/tests/memcached/regression/lp_000-447-342.cpp [new file with mode: 0644]
test/tests/memcached/regression/lp_000-490-486.cpp [new file with mode: 0644]
test/tests/memcached/regression/lp_000-996-813.cpp [new file with mode: 0644]
test/tests/memcached/regression/lp_001-048-945.cpp [new file with mode: 0644]

diff --git a/test/tests/memcached/regression/lp1048945.cpp b/test/tests/memcached/regression/lp1048945.cpp
deleted file mode 100644 (file)
index b4d3ae5..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#include "test/lib/common.hpp"
-#include "test/lib/MemcachedCluster.hpp"
-
-TEST_CASE("memcached_regression_lp1048945") {
-    MemcachedPtr memc_ptr(memcached_create(nullptr));
-    auto memc = *memc_ptr;
-    LoneReturnMatcher test{memc};
-    memcached_return status;
-
-    auto list = memcached_server_list_append_with_weight(nullptr, "a", 11211, 0, &status);
-    REQUIRE_SUCCESS(status);
-
-    list = memcached_server_list_append_with_weight(list, "b", 11211, 0, &status);
-    REQUIRE_SUCCESS(status);
-
-    list = memcached_server_list_append_with_weight(list, "c", 11211, 0, &status);
-    REQUIRE_SUCCESS(status);
-
-    REQUIRE(3 == memcached_server_list_count(list));
-
-    REQUIRE_SUCCESS(memcached_server_push(memc, list));
-    REQUIRE_SUCCESS(memcached_server_push(memc, list));
-    memcached_server_list_free(list);
-
-    auto server = memcached_server_by_key(memc, S(__func__), &status);
-    REQUIRE(server);
-    REQUIRE_SUCCESS(status);
-}
diff --git a/test/tests/memcached/regression/lp434484.cpp b/test/tests/memcached/regression/lp434484.cpp
deleted file mode 100644 (file)
index 48fd840..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "test/lib/common.hpp"
-#include "test/lib/MemcachedCluster.hpp"
-
-TEST_CASE("memcached_regression_lp434484") {
-  MemcachedCluster test;
-  auto memc = &test.memc;
-
-  test.enableBinaryProto();
-
-  REQUIRE_RC(MEMCACHED_NOTFOUND, memcached_exist(memc, S(__func__)));
-
-  vector<char> blob;
-  blob.resize(2048 * 1024);
-  REQUIRE_RC(MEMCACHED_E2BIG, memcached_set(memc, S(__func__), blob.data(), blob.size(), 0, 0));
-
-}
diff --git a/test/tests/memcached/regression/lp434843.cpp b/test/tests/memcached/regression/lp434843.cpp
deleted file mode 100644 (file)
index dc839d5..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#include "test/lib/common.hpp"
-#include "test/lib/MemcachedCluster.hpp"
-
-static memcached_return_t callback_counter(const memcached_st *, memcached_result_st *, void *context) {
-  auto *counter= reinterpret_cast<size_t *>(context);
-  *counter = *counter + 1;
-
-  return MEMCACHED_SUCCESS;
-}
-
-#define NUM_KEYS 1024
-
-TEST_CASE("memcached_regression_lp434843") {
-  MemcachedCluster test{Cluster{Server{MEMCACHED_BINARY, {"-p", random_port_string}}, 1}};
-  auto memc = &test.memc;
-  auto buffering = GENERATE(0, 1);
-
-  test.enableBinaryProto();
-  test.enableBuffering(buffering);
-
-  INFO("buffering: " << buffering);
-
-  size_t counter = 0;
-  memcached_execute_fn cb[] = {&callback_counter};
-
-  array<string, NUM_KEYS> str;
-  array<char *, NUM_KEYS> chr;
-  array<size_t, NUM_KEYS> len;
-  
-  for (auto i = 0; i < NUM_KEYS; ++i) {
-    str[i] = random_ascii_string(12) + to_string(i);
-    chr[i] = str[i].data();
-    len[i] = str[i].length();
-  }
-
-  REQUIRE_SUCCESS(memcached_mget(memc, chr.data(), len.data(), NUM_KEYS));
-  REQUIRE_RC(MEMCACHED_NOTFOUND, memcached_fetch_execute(memc, cb, &counter, 1));
-  REQUIRE(counter == 0);
-
-  for (auto i = 0; i < NUM_KEYS; ++i) {
-    char data[1024];
-    REQUIRE_SUCCESS(memcached_add(memc, chr[i], len[i], data, sizeof(data), 0, 0));
-  }
-
-  REQUIRE_SUCCESS(memcached_mget(memc, chr.data(), len.data(), NUM_KEYS));
-  REQUIRE_SUCCESS( memcached_fetch_execute(memc, cb, &counter, 1));
-  REQUIRE(counter == NUM_KEYS);
-}
diff --git a/test/tests/memcached/regression/lp442914.cpp b/test/tests/memcached/regression/lp442914.cpp
deleted file mode 100644 (file)
index a71449b..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "test/lib/common.hpp"
-#include "test/lib/MemcachedCluster.hpp"
-
-#include <iomanip>
-
-/* Original Comment:
- * The test case isn't obvious so I should probably document why
- * it works the way it does. Bug 442914 was caused by a bug
- * in the logic in memcached_purge (it did not handle the case
- * where the number of bytes sent was equal to the watermark).
- * In this test case, create messages so that we hit that case
- * and then disable noreply mode and issue a new command to
- * verify that it isn't stuck. If we change the format for the
- * delete command or the watermarks, we need to update this
- * test....
- */
-
-TEST_CASE("memcached_regression_lp442914") {
-  MemcachedCluster test{Cluster{Server{MEMCACHED_BINARY, {"-p", random_port_string}}, 1}};
-  auto memc = &test.memc;
-
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1));
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
-
-
-  for (auto x = 0; x < 250; ++x) {
-    stringstream ss;
-    ss << setfill('0') << setw(250) << x;
-    REQUIRE_SUCCESS(memcached_delete(memc, ss.str().c_str(), ss.str().length(), 0));
-  }
-
-  stringstream key;
-  key << setfill('0') << setw(37) << 251;
-  REQUIRE_SUCCESS(memcached_delete(memc, key.str().c_str(), key.str().length(), 0));
-
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0));
-
-  REQUIRE_RC(MEMCACHED_NOTFOUND, memcached_delete(memc, key.str().c_str(), key.str().length(), 0));
-}
diff --git a/test/tests/memcached/regression/lp447342.cpp b/test/tests/memcached/regression/lp447342.cpp
deleted file mode 100644 (file)
index 9e6c078..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-#include "test/lib/common.hpp"
-#include "test/lib/MemcachedCluster.hpp"
-
-#include "libmemcached/instance.hpp"
-
-static memcached_return_t callback_counter(const memcached_st *, memcached_result_st *, void *context) {
-  auto *counter= reinterpret_cast<size_t *>(context);
-  *counter = *counter + 1;
-
-  return MEMCACHED_SUCCESS;
-}
-
-#define NUM_KEYS 100U
-
-TEST_CASE("memcached_regression_lp447342") {
-  auto test = MemcachedCluster::mixed();
-  auto memc = &test.memc;
-  
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2));
-  
-  array<string, NUM_KEYS> str;
-  array<char *, NUM_KEYS> chr;
-  array<size_t, NUM_KEYS> len;
-  
-  for (auto i = 0U; i < NUM_KEYS; ++i) {
-    str[i] = random_ascii_string(random_num(12, 16)) + to_string(i);
-    chr[i] = str[i].data();
-    len[i] = str[i].length();
-    REQUIRE_SUCCESS(memcached_set(memc, chr[i], len[i], chr[i], len[i], 0, 0));
-  }
-
- /*
- ** We are using the qiet command 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);
- REQUIRE_SUCCESS(memcached_mget(memc, chr.data(), len.data(), NUM_KEYS));
-
- size_t counter = 0;
- memcached_execute_fn cb[] = {&callback_counter};
- REQUIRE_SUCCESS(memcached_fetch_execute(memc, cb, &counter, 1));
- REQUIRE(counter == NUM_KEYS);
- 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. Fake that two servers
-  * are dead..
-  */
-  auto instance_one= memcached_server_instance_by_position(memc, 0);
-  auto instance_two= memcached_server_instance_by_position(memc, 2);
-  in_port_t port0= instance_one->port();
-  in_port_t port2= instance_two->port();
-
-  const_cast<memcached_instance_st*>(instance_one)->port(0);
-  const_cast<memcached_instance_st*>(instance_two)->port(0);
-
-  REQUIRE_SUCCESS(memcached_mget(memc, chr.data(), len.data(), NUM_KEYS));
-
-  counter = 0;
-  REQUIRE_SUCCESS(memcached_fetch_execute(memc, cb, &counter, 1));
-  REQUIRE(counter == NUM_KEYS);
-
-  /* restore the memc handle */
-  const_cast<memcached_instance_st*>(instance_one)->port(port0);
-  const_cast<memcached_instance_st*>(instance_two)->port(port2);
-
-  memcached_quit(memc);
-
-  for (auto i = 0U; i < NUM_KEYS; ++i) {
-    if (i & 1U) {
-      REQUIRE_SUCCESS(memcached_delete(memc, chr[i], len[i], 0));
-    }
-  }
-
-  memcached_quit(memc);
-
-  const_cast<memcached_instance_st*>(instance_one)->port(0);
-  const_cast<memcached_instance_st*>(instance_two)->port(0);
-
-  /* now retry the command, this time we should have cache misses */
-  REQUIRE_SUCCESS(memcached_mget(memc, chr.data(), len.data(), NUM_KEYS));
-
-  counter = 0;
-  REQUIRE_SUCCESS(memcached_fetch_execute(memc, cb, &counter, 1));
-  REQUIRE(counter == NUM_KEYS>>1U);
-}
diff --git a/test/tests/memcached/regression/lp490486.cpp b/test/tests/memcached/regression/lp490486.cpp
deleted file mode 100644 (file)
index 1731d2d..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "test/lib/common.hpp"
-#include "test/lib/MemcachedCluster.hpp"
-
-#define NUM_KEYS 20480U
-
-static memcached_return_t callback_counter(const memcached_st *, memcached_result_st *, void *context) {
-  auto *counter= reinterpret_cast<size_t *>(context);
-  *counter = *counter + 1;
-
-  return MEMCACHED_SUCCESS;
-}
-
-TEST_CASE("memcached_regression_lp490486") {
-  MemcachedCluster test{Cluster{Server{MEMCACHED_BINARY, {"-p", random_port_string}}, 1}};
-  auto memc = &test.memc;
-
-  test.enableBinaryProto();
-
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000));
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, 1));
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600));
-
-  array<string, NUM_KEYS> str;
-  array<char *, NUM_KEYS> chr;
-  array<size_t, NUM_KEYS> len;
-
-  for (auto i = 0U; i < NUM_KEYS; ++i) {
-    char blob[1024];
-
-    str[i] = random_ascii_string(12) + to_string(i);
-    chr[i] = str[i].data();
-    len[i] = str[i].length();
-
-    REQUIRE_SUCCESS(memcached_set(memc, chr[i], len[i], blob, sizeof(blob), 0, 0));
-  }
-
-  size_t counter = 0;
-  memcached_return_t rc;
-  memcached_execute_fn cb[] = {&callback_counter};
-  REQUIRE_SUCCESS(memcached_mget_execute(memc, chr.data(), len.data(), NUM_KEYS, cb, &counter, 1));
-
-  do {
-    char key_buf[MEMCACHED_MAX_KEY];
-    size_t key_len;
-
-    Malloced value(memcached_fetch(memc, key_buf, &key_len, nullptr, nullptr, &rc));
-    counter += !!*value;
-  } while(rc == MEMCACHED_SUCCESS);
-
-  REQUIRE_RC(MEMCACHED_END, rc);
-  REQUIRE(counter == NUM_KEYS);
-}
diff --git a/test/tests/memcached/regression/lp996813.cpp b/test/tests/memcached/regression/lp996813.cpp
deleted file mode 100644 (file)
index 5a4b47d..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "test/lib/common.hpp"
-#include "test/lib/MemcachedCluster.hpp"
-
-TEST_CASE("memcached_regression_lp996813") {
-  MemcachedPtr memc_ptr;
-  auto memc = *memc_ptr;
-  LoneReturnMatcher test{memc};
-
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA));
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1));
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1));
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 300));
-  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 30));
-
-  // We will never connect to these servers
-  in_port_t base_port = 11211;
-  for (size_t x = 0; x < 17; x++) {
-    REQUIRE_SUCCESS(memcached_server_add(memc, "10.2.3.4", base_port + x));
-  }
-
-  REQUIRE(6U == memcached_generate_hash(memc, S("SZ6hu0SHweFmpwpc0w2R")));
-  REQUIRE(1U == memcached_generate_hash(memc, S("SQCK9eiCf53YxHWnYA.o")));
-  REQUIRE(9U == memcached_generate_hash(memc, S("SUSDkGXuuZC9t9VhMwa.")));
-  REQUIRE(0U == memcached_generate_hash(memc, S("SnnqnJARfaCNT679iAF_")));
-}
diff --git a/test/tests/memcached/regression/lp_000-434-484.cpp b/test/tests/memcached/regression/lp_000-434-484.cpp
new file mode 100644 (file)
index 0000000..48fd840
--- /dev/null
@@ -0,0 +1,16 @@
+#include "test/lib/common.hpp"
+#include "test/lib/MemcachedCluster.hpp"
+
+TEST_CASE("memcached_regression_lp434484") {
+  MemcachedCluster test;
+  auto memc = &test.memc;
+
+  test.enableBinaryProto();
+
+  REQUIRE_RC(MEMCACHED_NOTFOUND, memcached_exist(memc, S(__func__)));
+
+  vector<char> blob;
+  blob.resize(2048 * 1024);
+  REQUIRE_RC(MEMCACHED_E2BIG, memcached_set(memc, S(__func__), blob.data(), blob.size(), 0, 0));
+
+}
diff --git a/test/tests/memcached/regression/lp_000-434-843.cpp b/test/tests/memcached/regression/lp_000-434-843.cpp
new file mode 100644 (file)
index 0000000..dc839d5
--- /dev/null
@@ -0,0 +1,48 @@
+#include "test/lib/common.hpp"
+#include "test/lib/MemcachedCluster.hpp"
+
+static memcached_return_t callback_counter(const memcached_st *, memcached_result_st *, void *context) {
+  auto *counter= reinterpret_cast<size_t *>(context);
+  *counter = *counter + 1;
+
+  return MEMCACHED_SUCCESS;
+}
+
+#define NUM_KEYS 1024
+
+TEST_CASE("memcached_regression_lp434843") {
+  MemcachedCluster test{Cluster{Server{MEMCACHED_BINARY, {"-p", random_port_string}}, 1}};
+  auto memc = &test.memc;
+  auto buffering = GENERATE(0, 1);
+
+  test.enableBinaryProto();
+  test.enableBuffering(buffering);
+
+  INFO("buffering: " << buffering);
+
+  size_t counter = 0;
+  memcached_execute_fn cb[] = {&callback_counter};
+
+  array<string, NUM_KEYS> str;
+  array<char *, NUM_KEYS> chr;
+  array<size_t, NUM_KEYS> len;
+  
+  for (auto i = 0; i < NUM_KEYS; ++i) {
+    str[i] = random_ascii_string(12) + to_string(i);
+    chr[i] = str[i].data();
+    len[i] = str[i].length();
+  }
+
+  REQUIRE_SUCCESS(memcached_mget(memc, chr.data(), len.data(), NUM_KEYS));
+  REQUIRE_RC(MEMCACHED_NOTFOUND, memcached_fetch_execute(memc, cb, &counter, 1));
+  REQUIRE(counter == 0);
+
+  for (auto i = 0; i < NUM_KEYS; ++i) {
+    char data[1024];
+    REQUIRE_SUCCESS(memcached_add(memc, chr[i], len[i], data, sizeof(data), 0, 0));
+  }
+
+  REQUIRE_SUCCESS(memcached_mget(memc, chr.data(), len.data(), NUM_KEYS));
+  REQUIRE_SUCCESS( memcached_fetch_execute(memc, cb, &counter, 1));
+  REQUIRE(counter == NUM_KEYS);
+}
diff --git a/test/tests/memcached/regression/lp_000-442-914.cpp b/test/tests/memcached/regression/lp_000-442-914.cpp
new file mode 100644 (file)
index 0000000..a71449b
--- /dev/null
@@ -0,0 +1,39 @@
+#include "test/lib/common.hpp"
+#include "test/lib/MemcachedCluster.hpp"
+
+#include <iomanip>
+
+/* Original Comment:
+ * The test case isn't obvious so I should probably document why
+ * it works the way it does. Bug 442914 was caused by a bug
+ * in the logic in memcached_purge (it did not handle the case
+ * where the number of bytes sent was equal to the watermark).
+ * In this test case, create messages so that we hit that case
+ * and then disable noreply mode and issue a new command to
+ * verify that it isn't stuck. If we change the format for the
+ * delete command or the watermarks, we need to update this
+ * test....
+ */
+
+TEST_CASE("memcached_regression_lp442914") {
+  MemcachedCluster test{Cluster{Server{MEMCACHED_BINARY, {"-p", random_port_string}}, 1}};
+  auto memc = &test.memc;
+
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1));
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
+
+
+  for (auto x = 0; x < 250; ++x) {
+    stringstream ss;
+    ss << setfill('0') << setw(250) << x;
+    REQUIRE_SUCCESS(memcached_delete(memc, ss.str().c_str(), ss.str().length(), 0));
+  }
+
+  stringstream key;
+  key << setfill('0') << setw(37) << 251;
+  REQUIRE_SUCCESS(memcached_delete(memc, key.str().c_str(), key.str().length(), 0));
+
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0));
+
+  REQUIRE_RC(MEMCACHED_NOTFOUND, memcached_delete(memc, key.str().c_str(), key.str().length(), 0));
+}
diff --git a/test/tests/memcached/regression/lp_000-447-342.cpp b/test/tests/memcached/regression/lp_000-447-342.cpp
new file mode 100644 (file)
index 0000000..9e6c078
--- /dev/null
@@ -0,0 +1,100 @@
+#include "test/lib/common.hpp"
+#include "test/lib/MemcachedCluster.hpp"
+
+#include "libmemcached/instance.hpp"
+
+static memcached_return_t callback_counter(const memcached_st *, memcached_result_st *, void *context) {
+  auto *counter= reinterpret_cast<size_t *>(context);
+  *counter = *counter + 1;
+
+  return MEMCACHED_SUCCESS;
+}
+
+#define NUM_KEYS 100U
+
+TEST_CASE("memcached_regression_lp447342") {
+  auto test = MemcachedCluster::mixed();
+  auto memc = &test.memc;
+  
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS, 2));
+  
+  array<string, NUM_KEYS> str;
+  array<char *, NUM_KEYS> chr;
+  array<size_t, NUM_KEYS> len;
+  
+  for (auto i = 0U; i < NUM_KEYS; ++i) {
+    str[i] = random_ascii_string(random_num(12, 16)) + to_string(i);
+    chr[i] = str[i].data();
+    len[i] = str[i].length();
+    REQUIRE_SUCCESS(memcached_set(memc, chr[i], len[i], chr[i], len[i], 0, 0));
+  }
+
+ /*
+ ** We are using the qiet command 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);
+ REQUIRE_SUCCESS(memcached_mget(memc, chr.data(), len.data(), NUM_KEYS));
+
+ size_t counter = 0;
+ memcached_execute_fn cb[] = {&callback_counter};
+ REQUIRE_SUCCESS(memcached_fetch_execute(memc, cb, &counter, 1));
+ REQUIRE(counter == NUM_KEYS);
+ 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. Fake that two servers
+  * are dead..
+  */
+  auto instance_one= memcached_server_instance_by_position(memc, 0);
+  auto instance_two= memcached_server_instance_by_position(memc, 2);
+  in_port_t port0= instance_one->port();
+  in_port_t port2= instance_two->port();
+
+  const_cast<memcached_instance_st*>(instance_one)->port(0);
+  const_cast<memcached_instance_st*>(instance_two)->port(0);
+
+  REQUIRE_SUCCESS(memcached_mget(memc, chr.data(), len.data(), NUM_KEYS));
+
+  counter = 0;
+  REQUIRE_SUCCESS(memcached_fetch_execute(memc, cb, &counter, 1));
+  REQUIRE(counter == NUM_KEYS);
+
+  /* restore the memc handle */
+  const_cast<memcached_instance_st*>(instance_one)->port(port0);
+  const_cast<memcached_instance_st*>(instance_two)->port(port2);
+
+  memcached_quit(memc);
+
+  for (auto i = 0U; i < NUM_KEYS; ++i) {
+    if (i & 1U) {
+      REQUIRE_SUCCESS(memcached_delete(memc, chr[i], len[i], 0));
+    }
+  }
+
+  memcached_quit(memc);
+
+  const_cast<memcached_instance_st*>(instance_one)->port(0);
+  const_cast<memcached_instance_st*>(instance_two)->port(0);
+
+  /* now retry the command, this time we should have cache misses */
+  REQUIRE_SUCCESS(memcached_mget(memc, chr.data(), len.data(), NUM_KEYS));
+
+  counter = 0;
+  REQUIRE_SUCCESS(memcached_fetch_execute(memc, cb, &counter, 1));
+  REQUIRE(counter == NUM_KEYS>>1U);
+}
diff --git a/test/tests/memcached/regression/lp_000-490-486.cpp b/test/tests/memcached/regression/lp_000-490-486.cpp
new file mode 100644 (file)
index 0000000..1731d2d
--- /dev/null
@@ -0,0 +1,52 @@
+#include "test/lib/common.hpp"
+#include "test/lib/MemcachedCluster.hpp"
+
+#define NUM_KEYS 20480U
+
+static memcached_return_t callback_counter(const memcached_st *, memcached_result_st *, void *context) {
+  auto *counter= reinterpret_cast<size_t *>(context);
+  *counter = *counter + 1;
+
+  return MEMCACHED_SUCCESS;
+}
+
+TEST_CASE("memcached_regression_lp490486") {
+  MemcachedCluster test{Cluster{Server{MEMCACHED_BINARY, {"-p", random_port_string}}, 1}};
+  auto memc = &test.memc;
+
+  test.enableBinaryProto();
+
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1000));
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS, 1));
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 3600));
+
+  array<string, NUM_KEYS> str;
+  array<char *, NUM_KEYS> chr;
+  array<size_t, NUM_KEYS> len;
+
+  for (auto i = 0U; i < NUM_KEYS; ++i) {
+    char blob[1024];
+
+    str[i] = random_ascii_string(12) + to_string(i);
+    chr[i] = str[i].data();
+    len[i] = str[i].length();
+
+    REQUIRE_SUCCESS(memcached_set(memc, chr[i], len[i], blob, sizeof(blob), 0, 0));
+  }
+
+  size_t counter = 0;
+  memcached_return_t rc;
+  memcached_execute_fn cb[] = {&callback_counter};
+  REQUIRE_SUCCESS(memcached_mget_execute(memc, chr.data(), len.data(), NUM_KEYS, cb, &counter, 1));
+
+  do {
+    char key_buf[MEMCACHED_MAX_KEY];
+    size_t key_len;
+
+    Malloced value(memcached_fetch(memc, key_buf, &key_len, nullptr, nullptr, &rc));
+    counter += !!*value;
+  } while(rc == MEMCACHED_SUCCESS);
+
+  REQUIRE_RC(MEMCACHED_END, rc);
+  REQUIRE(counter == NUM_KEYS);
+}
diff --git a/test/tests/memcached/regression/lp_000-996-813.cpp b/test/tests/memcached/regression/lp_000-996-813.cpp
new file mode 100644 (file)
index 0000000..5a4b47d
--- /dev/null
@@ -0,0 +1,27 @@
+#include "test/lib/common.hpp"
+#include "test/lib/MemcachedCluster.hpp"
+
+TEST_CASE("memcached_regression_lp996813") {
+  MemcachedPtr memc_ptr;
+  auto memc = *memc_ptr;
+  LoneReturnMatcher test{memc};
+
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA));
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 1));
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1));
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1));
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, 1));
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, 300));
+  REQUIRE_SUCCESS(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_RETRY_TIMEOUT, 30));
+
+  // We will never connect to these servers
+  in_port_t base_port = 11211;
+  for (size_t x = 0; x < 17; x++) {
+    REQUIRE_SUCCESS(memcached_server_add(memc, "10.2.3.4", base_port + x));
+  }
+
+  REQUIRE(6U == memcached_generate_hash(memc, S("SZ6hu0SHweFmpwpc0w2R")));
+  REQUIRE(1U == memcached_generate_hash(memc, S("SQCK9eiCf53YxHWnYA.o")));
+  REQUIRE(9U == memcached_generate_hash(memc, S("SUSDkGXuuZC9t9VhMwa.")));
+  REQUIRE(0U == memcached_generate_hash(memc, S("SnnqnJARfaCNT679iAF_")));
+}
diff --git a/test/tests/memcached/regression/lp_001-048-945.cpp b/test/tests/memcached/regression/lp_001-048-945.cpp
new file mode 100644 (file)
index 0000000..b4d3ae5
--- /dev/null
@@ -0,0 +1,28 @@
+#include "test/lib/common.hpp"
+#include "test/lib/MemcachedCluster.hpp"
+
+TEST_CASE("memcached_regression_lp1048945") {
+    MemcachedPtr memc_ptr(memcached_create(nullptr));
+    auto memc = *memc_ptr;
+    LoneReturnMatcher test{memc};
+    memcached_return status;
+
+    auto list = memcached_server_list_append_with_weight(nullptr, "a", 11211, 0, &status);
+    REQUIRE_SUCCESS(status);
+
+    list = memcached_server_list_append_with_weight(list, "b", 11211, 0, &status);
+    REQUIRE_SUCCESS(status);
+
+    list = memcached_server_list_append_with_weight(list, "c", 11211, 0, &status);
+    REQUIRE_SUCCESS(status);
+
+    REQUIRE(3 == memcached_server_list_count(list));
+
+    REQUIRE_SUCCESS(memcached_server_push(memc, list));
+    REQUIRE_SUCCESS(memcached_server_push(memc, list));
+    memcached_server_list_free(list);
+
+    auto server = memcached_server_by_key(memc, S(__func__), &status);
+    REQUIRE(server);
+    REQUIRE_SUCCESS(status);
+}