After quit is issued, client reads all data from server,
author <kevin@laminaria> <>
Wed, 20 Feb 2008 22:24:23 +0000 (14:24 -0800)
committer <kevin@laminaria> <>
Wed, 20 Feb 2008 22:24:23 +0000 (14:24 -0800)
insuring that server reads all data.
atom_smasher many_adds tests for errors when this is not done.

lib/memcached_quit.c
tests/atomsmasher.c

index 366f7872cd76a229a3d547eb43e43ca683e8c691..9874bb6ea45f66ad9a1876dabf7ae729ea53e633 100644 (file)
@@ -16,9 +16,23 @@ void memcached_quit_server(memcached_server_st *ptr, uint8_t io_death)
     if (io_death == 0)
     {
       memcached_return rc;
+      ssize_t read_length;
+      char buffer[MEMCACHED_MAX_BUFFER];
+
       rc= memcached_do(ptr, "quit\r\n", 6, 1);
       WATCHPOINT_ASSERT(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_FETCH_NOTFINISHED);
 
+      /* read until socket is closed, or there is an error
+       * closing the socket before all data is read
+       * results in server throwing away all data which is
+       * not read
+       */
+      while ((read_length=
+             memcached_io_read(ptr, buffer, sizeof(buffer)/sizeof(*buffer)))
+            > 0)
+       {
+         ;
+       }
       memcached_io_close(ptr);
     }
 
index abe3a21e9cec52ab99e7d868ff099a5f7cba2a33..c43788775b75c58676bf1ac9530142228b4738ba 100644 (file)
@@ -151,10 +151,55 @@ memcached_return enable_consistent(memcached_st *memc)
   return MEMCACHED_SUCCESS;
 }
 
+/* 
+  Set the value, then quit to make sure it is flushed.
+  Come back in and test that add fails.
+*/
+uint8_t add_test(memcached_st *memc)
+{
+  memcached_return rc;
+  char *key= "foo";
+  char *value= "when we sanitize";
+  unsigned long long setting_value;
+
+  setting_value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
+
+  rc= memcached_set(memc, key, strlen(key), 
+                    value, strlen(value),
+                    (time_t)0, (uint32_t)0);
+  assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+  memcached_quit(memc);
+  rc= memcached_add(memc, key, strlen(key), 
+                    value, strlen(value),
+                    (time_t)0, (uint32_t)0);
+
+  /* Too many broken OS'es have broken loopback in async, so we can't be sure of the result */
+  if (setting_value)
+    assert(rc == MEMCACHED_NOTSTORED || MEMCACHED_STORED);
+  else
+    assert(rc == MEMCACHED_NOTSTORED);
+
+  return 0;
+}
+
+/*
+ * repeating add_tests many times
+ * may show a problem in timing
+ */
+uint8_t many_adds(memcached_st *memc)
+{
+  unsigned int i;
+  for (i = 0; i < TEST_COUNTER; i++){
+    add_test(memc);
+  }
+  return 0;
+}
+
 test_st smash_tests[] ={
   {"generate_pairs", 1, generate_pairs },
   {"drizzle", 1, drizzle },
   {"cleanup", 1, cleanup_pairs },
+  {"many_adds", 1, many_adds },
   {0, 0, 0}
 };