Fix for non-blocking IO error. The refactoring bit broke some cases where
[awesomized/libmemcached] / tests / function.c
index c3d764c4981653c1c529367a4ebcde7da1032b3c..a1c817a4a3c08bcd8475797281492d3e2ef67cb8 100644 (file)
 #include "../src/generator.h"
 #include "../src/execute.h"
 
+#ifndef INT64_MAX
+#define INT64_MAX LONG_MAX
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX INT_MAX
+#endif
+
+
 #include "test.h"
 
 #define GLOBAL_COUNT 100000
+#define GLOBAL2_COUNT 1000
+static uint32_t global_count;
+
 static pairs_st *global_pairs;
 static char *global_keys[GLOBAL_COUNT];
 static size_t global_keys_length[GLOBAL_COUNT];
@@ -32,6 +43,23 @@ uint8_t init_test(memcached_st *not_used)
   return 0;
 }
 
+uint8_t server_list_null_test(memcached_st *ptr)
+{
+  memcached_server_st *server_list;
+  memcached_return rc;
+
+  server_list= memcached_server_list_append(NULL, NULL, 0, NULL);
+  assert(server_list == NULL);
+
+  server_list= memcached_server_list_append(NULL, "localhost", 0, NULL);
+  assert(server_list == NULL);
+
+  server_list= memcached_server_list_append(NULL, NULL, 0, &rc);
+  assert(server_list == NULL);
+
+  return 0;
+}
+
 uint8_t allocation_test(memcached_st *not_used)
 {
   memcached_st *memc;
@@ -111,9 +139,8 @@ uint8_t set_test(memcached_st *memc)
 
   rc= memcached_set(memc, key, strlen(key), 
                     value, strlen(value),
-                    (time_t)0, (uint16_t)0);
-  WATCHPOINT_ERROR(rc);
-  assert(rc == MEMCACHED_SUCCESS);
+                    (time_t)0, (uint32_t)0);
+  assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
 
   return 0;
 }
@@ -124,24 +151,24 @@ uint8_t append_test(memcached_st *memc)
   char *key= "fig";
   char *value= "we";
   size_t value_length;
-  uint16_t flags;
+  uint32_t flags;
 
   rc= memcached_flush(memc, 0);
   assert(rc == MEMCACHED_SUCCESS);
 
   rc= memcached_set(memc, key, strlen(key), 
                     value, strlen(value),
-                    (time_t)0, (uint16_t)0);
+                    (time_t)0, (uint32_t)0);
   assert(rc == MEMCACHED_SUCCESS);
 
   rc= memcached_append(memc, key, strlen(key), 
                        " the", strlen(" the"),
-                       (time_t)0, (uint16_t)0);
+                       (time_t)0, (uint32_t)0);
   assert(rc == MEMCACHED_SUCCESS);
 
   rc= memcached_append(memc, key, strlen(key), 
                        " people", strlen(" people"),
-                       (time_t)0, (uint16_t)0);
+                       (time_t)0, (uint32_t)0);
   assert(rc == MEMCACHED_SUCCESS);
 
   value= memcached_get(memc, key, strlen(key),
@@ -162,7 +189,7 @@ uint8_t append_binary_test(memcached_st *memc)
   unsigned int store_list[] = { 23, 56, 499, 98, 32847, 0 };
   char *value;
   size_t value_length;
-  uint16_t flags;
+  uint32_t flags;
   unsigned int x;
 
   rc= memcached_flush(memc, 0);
@@ -171,7 +198,7 @@ uint8_t append_binary_test(memcached_st *memc)
   rc= memcached_set(memc, 
                     key, strlen(key), 
                     NULL, 0,
-                    (time_t)0, (uint16_t)0);
+                    (time_t)0, (uint32_t)0);
   assert(rc == MEMCACHED_SUCCESS);
 
   for (x= 0; store_list[x] ; x++)
@@ -179,7 +206,7 @@ uint8_t append_binary_test(memcached_st *memc)
     rc= memcached_append(memc, 
                          key, strlen(key), 
                          (char *)&store_list[x], sizeof(unsigned int),
-                         (time_t)0, (uint16_t)0);
+                         (time_t)0, (uint32_t)0);
     assert(rc == MEMCACHED_SUCCESS);
   }
 
@@ -221,7 +248,7 @@ uint8_t cas2_test(memcached_st *memc)
   {
     rc= memcached_set(memc, keys[x], key_length[x], 
                       keys[x], key_length[x],
-                      (time_t)50, (uint16_t)9);
+                      (time_t)50, (uint32_t)9);
     assert(rc == MEMCACHED_SUCCESS);
   }
 
@@ -262,7 +289,7 @@ uint8_t cas_test(memcached_st *memc)
 
   rc= memcached_set(memc, key, strlen(key), 
                     value, strlen(value),
-                    (time_t)0, (uint16_t)0);
+                    (time_t)0, (uint32_t)0);
   assert(rc == MEMCACHED_SUCCESS);
 
   rc= memcached_mget(memc, &key, &key_length, 1);
@@ -289,24 +316,24 @@ uint8_t prepend_test(memcached_st *memc)
   char *key= "fig";
   char *value= "people";
   size_t value_length;
-  uint16_t flags;
+  uint32_t flags;
 
   rc= memcached_flush(memc, 0);
   assert(rc == MEMCACHED_SUCCESS);
 
   rc= memcached_set(memc, key, strlen(key), 
                     value, strlen(value),
-                    (time_t)0, (uint16_t)0);
+                    (time_t)0, (uint32_t)0);
   assert(rc == MEMCACHED_SUCCESS);
 
   rc= memcached_prepend(memc, key, strlen(key), 
                        "the ", strlen("the "),
-                       (time_t)0, (uint16_t)0);
+                       (time_t)0, (uint32_t)0);
   assert(rc == MEMCACHED_SUCCESS);
 
   rc= memcached_prepend(memc, key, strlen(key), 
                        "we ", strlen("we "),
-                       (time_t)0, (uint16_t)0);
+                       (time_t)0, (uint32_t)0);
   assert(rc == MEMCACHED_SUCCESS);
 
   value= memcached_get(memc, key, strlen(key),
@@ -319,16 +346,43 @@ uint8_t prepend_test(memcached_st *memc)
   return 0;
 }
 
+/* 
+  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, (uint16_t)0);
-  assert(rc == MEMCACHED_NOTSTORED);
+                    (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;
+}
+
+uint8_t add_wrapper(memcached_st *memc)
+{
+  unsigned int x;
+
+  for (x= 0; x < 10000; x++)
+    add_test(memc);
 
   return 0;
 }
@@ -338,10 +392,16 @@ uint8_t replace_test(memcached_st *memc)
   memcached_return rc;
   char *key= "foo";
   char *value= "when we sanitize";
+  char *original= "first we insert some data";
+
+  rc= memcached_set(memc, key, strlen(key), 
+                    original, strlen(original),
+                    (time_t)0, (uint32_t)0);
+  assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
 
   rc= memcached_replace(memc, key, strlen(key), 
                     value, strlen(value),
-                    (time_t)0, (uint16_t)0);
+                    (time_t)0, (uint32_t)0);
   assert(rc == MEMCACHED_SUCCESS);
 
   return 0;
@@ -355,11 +415,11 @@ uint8_t delete_test(memcached_st *memc)
 
   rc= memcached_set(memc, key, strlen(key), 
                     value, strlen(value),
-                    (time_t)0, (uint16_t)0);
-  assert(rc == MEMCACHED_SUCCESS);
+                    (time_t)0, (uint32_t)0);
+  assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
 
   rc= memcached_delete(memc, key, strlen(key), (time_t)0);
-  assert(rc == MEMCACHED_SUCCESS);
+  assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
 
   return 0;
 }
@@ -380,10 +440,10 @@ uint8_t get_test(memcached_st *memc)
   char *key= "foo";
   char *string;
   size_t string_length;
-  uint16_t flags;
+  uint32_t flags;
 
   rc= memcached_delete(memc, key, strlen(key), (time_t)0);
-  assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOTFOUND);
+  assert(rc == MEMCACHED_BUFFERED || rc == MEMCACHED_NOTFOUND);
 
   string= memcached_get(memc, key, strlen(key),
                         &string_length, &flags, &rc);
@@ -402,12 +462,12 @@ uint8_t get_test2(memcached_st *memc)
   char *value= "when we sanitize";
   char *string;
   size_t string_length;
-  uint16_t flags;
+  uint32_t flags;
 
   rc= memcached_set(memc, key, strlen(key), 
                     value, strlen(value),
-                    (time_t)0, (uint16_t)0);
-  assert(rc == MEMCACHED_SUCCESS);
+                    (time_t)0, (uint32_t)0);
+  assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
 
   string= memcached_get(memc, key, strlen(key),
                         &string_length, &flags, &rc);
@@ -434,8 +494,8 @@ uint8_t set_test2(memcached_st *memc)
   {
     rc= memcached_set(memc, key, strlen(key), 
                       value, value_length,
-                      (time_t)0, (uint16_t)0);
-    assert(rc == MEMCACHED_SUCCESS);
+                      (time_t)0, (uint32_t)0);
+    assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
   }
 
   return 0;
@@ -459,8 +519,8 @@ uint8_t set_test3(memcached_st *memc)
   {
     rc= memcached_set(memc, key, strlen(key), 
                       value, value_length,
-                      (time_t)0, (uint16_t)0);
-    assert(rc == MEMCACHED_SUCCESS);
+                      (time_t)0, (uint32_t)0);
+    assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
   }
 
   free(value);
@@ -476,7 +536,7 @@ uint8_t get_test3(memcached_st *memc)
   size_t value_length= 8191;
   char *string;
   size_t string_length;
-  uint16_t flags;
+  uint32_t flags;
   int x;
 
   value = (char*)malloc(value_length);
@@ -487,8 +547,8 @@ uint8_t get_test3(memcached_st *memc)
 
   rc= memcached_set(memc, key, strlen(key), 
                     value, value_length,
-                    (time_t)0, (uint16_t)0);
-  assert(rc == MEMCACHED_SUCCESS);
+                    (time_t)0, (uint32_t)0);
+  assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
 
   string= memcached_get(memc, key, strlen(key),
                         &string_length, &flags, &rc);
@@ -512,7 +572,7 @@ uint8_t get_test4(memcached_st *memc)
   size_t value_length= 8191;
   char *string;
   size_t string_length;
-  uint16_t flags;
+  uint32_t flags;
   int x;
 
   value = (char*)malloc(value_length);
@@ -523,8 +583,8 @@ uint8_t get_test4(memcached_st *memc)
 
   rc= memcached_set(memc, key, strlen(key), 
                     value, value_length,
-                    (time_t)0, (uint16_t)0);
-  assert(rc == MEMCACHED_SUCCESS);
+                    (time_t)0, (uint32_t)0);
+  assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
 
   for (x= 0; x < 10; x++)
   {
@@ -564,8 +624,8 @@ uint8_t increment_test(memcached_st *memc)
 
   rc= memcached_set(memc, key, strlen(key), 
                     value, strlen(value),
-                    (time_t)0, (uint16_t)0);
-  assert(rc == MEMCACHED_SUCCESS);
+                    (time_t)0, (uint32_t)0);
+  assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
 
   rc= memcached_increment(memc, key, strlen(key),
                           1, &new_number);
@@ -589,8 +649,8 @@ uint8_t decrement_test(memcached_st *memc)
 
   rc= memcached_set(memc, key, strlen(key), 
                     value, strlen(value),
-                    (time_t)0, (uint16_t)0);
-  assert(rc == MEMCACHED_SUCCESS);
+                    (time_t)0, (uint32_t)0);
+  assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
 
   rc= memcached_decrement(memc, key, strlen(key),
                           1, &new_number);
@@ -613,14 +673,14 @@ uint8_t quit_test(memcached_st *memc)
 
   rc= memcached_set(memc, key, strlen(key), 
                     value, strlen(value),
-                    (time_t)10, (uint16_t)3);
-  assert(rc == MEMCACHED_SUCCESS);
+                    (time_t)10, (uint32_t)3);
+  assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
   memcached_quit(memc);
 
   rc= memcached_set(memc, key, strlen(key), 
                     value, strlen(value),
-                    (time_t)50, (uint16_t)9);
-  assert(rc == MEMCACHED_SUCCESS);
+                    (time_t)50, (uint32_t)9);
+  assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
 
   return 0;
 }
@@ -653,14 +713,14 @@ uint8_t mget_result_test(memcached_st *memc)
 
   while ((results= memcached_fetch_result(memc, &results_obj, &rc)) != NULL)
   assert(!results);
-  assert(rc == MEMCACHED_NOTFOUND);
+  assert(rc == MEMCACHED_END);
 
   for (x= 0; x < 3; x++)
   {
     rc= memcached_set(memc, keys[x], key_length[x], 
                       keys[x], key_length[x],
-                      (time_t)50, (uint16_t)9);
-    assert(rc == MEMCACHED_SUCCESS);
+                      (time_t)50, (uint32_t)9);
+    assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
   }
 
   rc= memcached_mget(memc, keys, key_length, 3);
@@ -703,14 +763,14 @@ uint8_t mget_result_alloc_test(memcached_st *memc)
     assert(results);
   }
   assert(!results);
-  assert(rc == MEMCACHED_NOTFOUND);
+  assert(rc == MEMCACHED_END);
 
   for (x= 0; x < 3; x++)
   {
     rc= memcached_set(memc, keys[x], key_length[x], 
                       keys[x], key_length[x],
-                      (time_t)50, (uint16_t)9);
-    assert(rc == MEMCACHED_SUCCESS);
+                      (time_t)50, (uint32_t)9);
+    assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
   }
 
   rc= memcached_mget(memc, keys, key_length, 3);
@@ -732,13 +792,54 @@ uint8_t mget_result_alloc_test(memcached_st *memc)
   return 0;
 }
 
+/* Count the results */
+unsigned int callback_counter(memcached_st *ptr, memcached_result_st *result, void *context)
+{
+  unsigned int *counter= (unsigned int *)context;
+
+  *counter= *counter + 1;
+
+  return 0;
+}
+
+uint8_t mget_result_function(memcached_st *memc)
+{
+  memcached_return rc;
+  char *keys[]= {"fudge", "son", "food"};
+  size_t key_length[]= {5, 3, 4};
+  unsigned int x;
+  unsigned int counter;
+  unsigned int (*callbacks[1])(memcached_st *, memcached_result_st *, void *);
+
+  /* We need to empty the server before continueing test */
+  rc= memcached_flush(memc, 0);
+  for (x= 0; x < 3; x++)
+  {
+    rc= memcached_set(memc, keys[x], key_length[x], 
+                      keys[x], key_length[x],
+                      (time_t)50, (uint32_t)9);
+    assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+  }
+
+  rc= memcached_mget(memc, keys, key_length, 3);
+  assert(rc == MEMCACHED_SUCCESS);
+
+  callbacks[0]= &callback_counter;
+  counter= 0;
+  rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1); 
+
+  assert(counter == 3);
+
+  return 0;
+}
+
 uint8_t mget_test(memcached_st *memc)
 {
   memcached_return rc;
   char *keys[]= {"fudge", "son", "food"};
   size_t key_length[]= {5, 3, 4};
   unsigned int x;
-  uint16_t flags;
+  uint32_t flags;
 
   char return_key[MEMCACHED_MAX_KEY];
   size_t return_key_length;
@@ -759,14 +860,14 @@ uint8_t mget_test(memcached_st *memc)
   }
   assert(!return_value);
   assert(return_value_length == 0);
-  assert(rc == MEMCACHED_NOTFOUND);
+  assert(rc == MEMCACHED_END);
 
   for (x= 0; x < 3; x++)
   {
     rc= memcached_set(memc, keys[x], key_length[x], 
                       keys[x], key_length[x],
-                      (time_t)50, (uint16_t)9);
-    assert(rc == MEMCACHED_SUCCESS);
+                      (time_t)50, (uint32_t)9);
+    assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
   }
 
   rc= memcached_mget(memc, keys, key_length, 3);
@@ -797,7 +898,7 @@ uint8_t get_stats_keys(memcached_st *memc)
  list= memcached_stat_get_keys(memc, &stat, &rc);
  assert(rc == MEMCACHED_SUCCESS);
  for (ptr= list; *ptr; ptr++)
-   printf("Found key %s\n", *ptr);
+   assert(*ptr);
  fflush(stdout);
 
  free(list);
@@ -805,6 +906,17 @@ uint8_t get_stats_keys(memcached_st *memc)
  return 0;
 }
 
+uint8_t version_string_test(memcached_st *memc)
+{
+  const char *version_string;
+
+  version_string= memcached_lib_version();
+
+  assert(!strcmp(version_string, LIBMEMCACHED_VERSION_STRING));
+
+  return 0;
+}
+
 uint8_t get_stats(memcached_st *memc)
 {
  unsigned int x;
@@ -865,6 +977,55 @@ uint8_t add_host_test(memcached_st *memc)
   return 0;
 }
 
+memcached_return clone_test_callback(memcached_st *parent, memcached_st *clone)
+{
+  return MEMCACHED_SUCCESS;
+}
+
+memcached_return cleanup_test_callback(memcached_st *ptr)
+{
+  return MEMCACHED_SUCCESS;
+}
+
+uint8_t callback_test(memcached_st *memc)
+{
+  /* Test User Data */
+  {
+    int x= 5;
+    int *test_ptr;
+    memcached_return rc;
+
+    rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_USER_DATA, &x);
+    assert(rc == MEMCACHED_SUCCESS);
+    test_ptr= (int *)memcached_callback_get(memc, MEMCACHED_CALLBACK_USER_DATA, &rc);
+    assert(*test_ptr == x);
+  }
+
+  /* Test Clone Callback */
+  {
+    memcached_clone_func temp_function;
+    memcached_return rc;
+
+    rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, clone_test_callback);
+    assert(rc == MEMCACHED_SUCCESS);
+    temp_function= (memcached_clone_func)memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
+    assert(temp_function == clone_test_callback);
+  }
+
+  /* Test Cleanup Callback */
+  {
+    memcached_cleanup_func temp_function;
+    memcached_return rc;
+
+    rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, cleanup_test_callback);
+    assert(rc == MEMCACHED_SUCCESS);
+    temp_function= (memcached_cleanup_func)memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
+    assert(temp_function == cleanup_test_callback);
+  }
+
+  return 0;
+}
+
 /* We don't test the behavior itself, we test the switches */
 uint8_t behavior_test(memcached_st *memc)
 {
@@ -951,10 +1112,10 @@ uint8_t user_supplied_bug1(memcached_st *memc)
     rc = memcached_set(memc, key, strlen(key), 
                        randomstuff, strlen(randomstuff), 10, 0);
     /* If we fail, lets try again */
-    if (rc != MEMCACHED_SUCCESS)
+    if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED)
       rc = memcached_set(memc, key, strlen(key), 
                          randomstuff, strlen(randomstuff), 10, 0);
-    assert(rc == MEMCACHED_SUCCESS);
+    assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
   }
 
   return 0;
@@ -986,7 +1147,7 @@ uint8_t user_supplied_bug2(memcached_st *memc)
   {
     memcached_return rc= MEMCACHED_SUCCESS;
     char buffer[SMALL_STRING_LEN];
-    uint16_t flags= 0;
+    uint32_t flags= 0;
     size_t val_len= 0;
     char *getval;
 
@@ -1000,7 +1161,10 @@ uint8_t user_supplied_bug2(memcached_st *memc)
       if (rc == MEMCACHED_NOTFOUND)
         errors++;
       else
+      {
+        WATCHPOINT_ERROR(rc);
         assert(0);
+      }
 
       continue;
     }
@@ -1055,7 +1219,7 @@ uint8_t user_supplied_bug3(memcached_st *memc)
     size_t return_key_length;
     char *return_value;
     size_t return_value_length;
-    uint16_t flags;
+    uint32_t flags;
 
     while ((return_value= memcached_fetch(memc, return_key, &return_key_length, 
                                           &return_value_length, &flags, &rc)))
@@ -1080,7 +1244,11 @@ uint8_t user_supplied_bug4(memcached_st *memc)
   char *keys[]= {"fudge", "son", "food"};
   size_t key_length[]= {5, 3, 4};
   unsigned int x;
-  uint16_t flags;
+  uint32_t flags;
+  char return_key[MEMCACHED_MAX_KEY];
+  size_t return_key_length;
+  char *return_value;
+  size_t return_value_length;
 
   /* Here we free everything before running a bunch of mget tests */
   {
@@ -1089,10 +1257,6 @@ uint8_t user_supplied_bug4(memcached_st *memc)
     memc->number_of_hosts= 0;
   }
 
-  char return_key[MEMCACHED_MAX_KEY];
-  size_t return_key_length;
-  char *return_value;
-  size_t return_value_length;
 
   /* We need to empty the server before continueing test */
   rc= memcached_flush(memc, 0);
@@ -1114,7 +1278,7 @@ uint8_t user_supplied_bug4(memcached_st *memc)
   {
     rc= memcached_set(memc, keys[x], key_length[x], 
                       keys[x], key_length[x],
-                      (time_t)50, (uint16_t)9);
+                      (time_t)50, (uint32_t)9);
     assert(rc == MEMCACHED_NO_SERVERS);
   }
 
@@ -1146,7 +1310,7 @@ uint8_t user_supplied_bug5(memcached_st *memc)
   size_t return_key_length;
   char *value;
   size_t value_length;
-  uint16_t flags;
+  uint32_t flags;
   unsigned int count;
   unsigned int x;
   char insert_data[VALUE_SIZE_BUG5];
@@ -1170,7 +1334,7 @@ uint8_t user_supplied_bug5(memcached_st *memc)
   {
     rc= memcached_set(memc, keys[x], key_length[x], 
                       insert_data, VALUE_SIZE_BUG5,
-                      (time_t)0, (uint16_t)0);
+                      (time_t)0, (uint32_t)0);
     assert(rc == MEMCACHED_SUCCESS);
   }
 
@@ -1204,7 +1368,7 @@ uint8_t user_supplied_bug6(memcached_st *memc)
   size_t return_key_length;
   char *value;
   size_t value_length;
-  uint16_t flags;
+  uint32_t flags;
   unsigned int count;
   unsigned int x;
   char insert_data[VALUE_SIZE_BUG5];
@@ -1216,23 +1380,26 @@ uint8_t user_supplied_bug6(memcached_st *memc)
   value= memcached_get(memc, keys[0], key_length[0],
                         &value_length, &flags, &rc);           
   assert(value == NULL);
+  assert(rc == MEMCACHED_NOTFOUND);
   rc= memcached_mget(memc, keys, key_length, 4);
+  assert(rc == MEMCACHED_SUCCESS);
 
   count= 0;
   while ((value= memcached_fetch(memc, return_key, &return_key_length, 
                                         &value_length, &flags, &rc)))
     count++;
   assert(count == 0);
+  assert(rc == MEMCACHED_END);
 
   for (x= 0; x < 4; x++)
   {
     rc= memcached_set(memc, keys[x], key_length[x], 
                       insert_data, VALUE_SIZE_BUG5,
-                      (time_t)0, (uint16_t)0);
+                      (time_t)0, (uint32_t)0);
     assert(rc == MEMCACHED_SUCCESS);
   }
 
-  for (x= 0; x < 10; x++)
+  for (x= 0; x < 2; x++)
   {
     value= memcached_get(memc, keys[0], key_length[0],
                          &value_length, &flags, &rc);          
@@ -1240,14 +1407,17 @@ uint8_t user_supplied_bug6(memcached_st *memc)
     free(value);
 
     rc= memcached_mget(memc, keys, key_length, 4);
+    assert(rc == MEMCACHED_SUCCESS);
     count= 3;
     /* We test for purge of partial complete fetches */
     for (count= 3; count; count--)
     {
       value= memcached_fetch(memc, return_key, &return_key_length, 
                              &value_length, &flags, &rc);
-      free(value);
       assert(rc == MEMCACHED_SUCCESS);
+      assert(!(memcmp(value, insert_data, value_length)));
+      assert(value_length);
+      free(value);
     }
   }
 
@@ -1294,7 +1464,7 @@ uint8_t user_supplied_bug7(memcached_st *memc)
   size_t return_key_length;
   char *value;
   size_t value_length;
-  uint16_t flags;
+  uint32_t flags;
   unsigned int x;
   char insert_data[VALUE_SIZE_BUG5];
 
@@ -1329,6 +1499,253 @@ uint8_t user_supplied_bug7(memcached_st *memc)
   return 0;
 }
 
+uint8_t user_supplied_bug9(memcached_st *memc)
+{
+  memcached_return rc;
+  char *keys[]= {"UDATA:edevil@sapo.pt", "fudge&*@#", "for^#@&$not"};
+  size_t key_length[3];
+  unsigned int x;
+  uint32_t flags;
+  unsigned count= 0;
+
+  char return_key[MEMCACHED_MAX_KEY];
+  size_t return_key_length;
+  char *return_value;
+  size_t return_value_length;
+
+
+  key_length[0]= strlen("UDATA:edevil@sapo.pt");
+  key_length[1]= strlen("fudge&*@#");
+  key_length[2]= strlen("for^#@&$not");
+
+
+  for (x= 0; x < 3; x++)
+  {
+    rc= memcached_set(memc, keys[x], key_length[x], 
+                      keys[x], key_length[x],
+                      (time_t)50, (uint32_t)9);
+    assert(rc == MEMCACHED_SUCCESS);
+  }
+
+  rc= memcached_mget(memc, keys, key_length, 3);
+  assert(rc == MEMCACHED_SUCCESS);
+
+  /* We need to empty the server before continueing test */
+  while ((return_value= memcached_fetch(memc, return_key, &return_key_length, 
+                      &return_value_length, &flags, &rc)) != NULL)
+  {
+    assert(return_value);
+    free(return_value);
+    count++;
+  }
+  assert(count == 3);
+
+  return 0;
+}
+
+/* We are testing with aggressive timeout to get failures */
+uint8_t user_supplied_bug10(memcached_st *memc)
+{
+  char *key= "foo";
+  char *value;
+  size_t value_length= 512;
+  unsigned int x;
+  int key_len= 3;
+  memcached_return rc;
+  unsigned int set= 1;
+  memcached_st *mclone= memcached_clone(NULL, memc);
+  int32_t timeout;
+
+  memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, &set);
+  memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, &set);
+  timeout= 2;
+  memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, &timeout);
+
+  value = (char*)malloc(value_length * sizeof(char));
+
+  for (x= 0; x < value_length; x++)
+    value[x]= (char) (x % 127);
+
+  for (x= 1; x <= 100000; ++x)
+  {
+    rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
+
+    assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_WRITE_FAILURE || rc == MEMCACHED_BUFFERED);
+
+    if (rc == MEMCACHED_WRITE_FAILURE)
+      x--;
+  }
+
+  free(value);
+  memcached_free(mclone);
+
+  return 0;
+}
+
+/*
+  We are looking failures in the async protocol
+*/
+uint8_t user_supplied_bug11(memcached_st *memc)
+{
+  char *key= "foo";
+  char *value;
+  size_t value_length= 512;
+  unsigned int x;
+  int key_len= 3;
+  memcached_return rc;
+  unsigned int set= 1;
+  int32_t timeout;
+  memcached_st *mclone= memcached_clone(NULL, memc);
+
+  memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_NO_BLOCK, &set);
+  memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_TCP_NODELAY, &set);
+  timeout= -1;
+  memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, &timeout);
+
+  timeout= (int32_t)memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
+
+  assert(timeout == -1);
+
+  value = (char*)malloc(value_length * sizeof(char));
+
+  for (x= 0; x < value_length; x++)
+    value[x]= (char) (x % 127);
+
+  for (x= 1; x <= 100000; ++x)
+  {
+    rc= memcached_set(mclone, key, key_len,value, value_length, 0, 0);
+  }
+
+  free(value);
+  memcached_free(mclone);
+
+  return 0;
+}
+
+/*
+  Bug found where incr was not returning MEMCACHED_NOTFOUND when object did not exist.
+*/
+uint8_t user_supplied_bug12(memcached_st *memc)
+{
+  memcached_return rc;
+  uint32_t flags;
+  size_t value_length;
+  char *value;
+  uint64_t number_value;
+
+  value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
+                        &value_length, &flags, &rc);           
+  assert(value == NULL);
+  assert(rc == MEMCACHED_NOTFOUND);
+
+  rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
+                          1, &number_value);
+
+  assert(value == NULL);
+  assert(rc == MEMCACHED_NOTFOUND);
+
+  rc= memcached_set(memc, "autoincrement", strlen("autoincrement"), "1", 1, 0, 0);
+
+  value= memcached_get(memc, "autoincrement", strlen("autoincrement"),
+                        &value_length, &flags, &rc);           
+  assert(value);
+  assert(rc == MEMCACHED_SUCCESS);
+  free(value);
+
+  rc= memcached_increment(memc, "autoincrement", strlen("autoincrement"),
+                          1, &number_value);
+  assert(number_value == 2);
+  assert(rc == MEMCACHED_SUCCESS);
+
+  return 0;
+}
+
+/*
+  Bug found where command total one more than MEMCACHED_MAX_BUFFER
+  set key34567890 0 0 8169 \r\n is sent followed by buffer of size 8169, followed by 8169
+ */
+uint8_t user_supplied_bug13(memcached_st *memc)
+{
+  char key[] = "key34567890";
+  char *overflow;
+  memcached_return rc;
+  size_t overflowSize;
+
+  char commandFirst[]= "set key34567890 0 0 ";
+  char commandLast[] = " \r\n"; /* first line of command sent to server */
+  size_t commandLength;
+  size_t testSize;
+
+  commandLength = strlen(commandFirst) + strlen(commandLast) + 4; /* 4 is number of characters in size, probably 8196 */
+
+  overflowSize = MEMCACHED_MAX_BUFFER - commandLength;
+
+  for (testSize= overflowSize - 1; testSize < overflowSize + 1; testSize++)
+  {
+    overflow= malloc(testSize);
+    assert(overflow != NULL);
+
+    memset(overflow, 'x', testSize);
+    rc= memcached_set(memc, key, strlen(key),
+                      overflow, testSize, 0, 0);
+    assert(rc == MEMCACHED_SUCCESS);
+    free(overflow);
+  }
+
+  return 0;
+}
+
+
+/*
+  Test values of many different sizes
+  Bug found where command total one more than MEMCACHED_MAX_BUFFER
+  set key34567890 0 0 8169 \r\n
+  is sent
+  followed by buffer of size 8169, followed by 8169
+ */
+uint8_t user_supplied_bug14(memcached_st *memc)
+{
+  int setter= 1;
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &setter);
+  memcached_return rc;
+  char *key= "foo";
+  char *value;
+  size_t value_length= 18000;
+  char *string;
+  size_t string_length;
+  uint32_t flags;
+  unsigned int x;
+  size_t current_length;
+
+  value = (char*)malloc(value_length);
+  assert(value);
+
+  for (x= 0; x < value_length; x++)
+    value[x] = (char) (x % 127);
+
+  for (current_length = 0; current_length < value_length; current_length++)
+  {
+    rc= memcached_set(memc, key, strlen(key), 
+                      value, current_length,
+                      (time_t)0, (uint32_t)0);
+    assert(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+
+    string= memcached_get(memc, key, strlen(key),
+                          &string_length, &flags, &rc);
+
+    assert(rc == MEMCACHED_SUCCESS);
+    assert(string);
+    assert(string_length == current_length);
+    assert(!memcmp(string, value, string_length));
+
+    free(string);
+  }
+
+  free(value);
+
+  return 0;
+}
+
 uint8_t result_static(memcached_st *memc)
 {
   memcached_result_st result;
@@ -1453,13 +1870,13 @@ uint8_t cleanup_pairs(memcached_st *memc)
   return 0;
 }
 
-uint8_t generate_data(memcached_st *memc)
+uint8_t generate_pairs(memcached_st *memc)
 {
   unsigned long long x;
-  global_pairs= pairs_generate(GLOBAL_COUNT);
-  execute_set(memc, global_pairs, GLOBAL_COUNT);
+  global_pairs= pairs_generate(GLOBAL_COUNT, 400);
+  global_count= GLOBAL_COUNT;
 
-  for (x= 0; x < GLOBAL_COUNT; x++)
+  for (x= 0; x < global_count; x++)
   {
     global_keys[x]= global_pairs[x].key; 
     global_keys_length[x]=  global_pairs[x].key_length;
@@ -1468,6 +1885,39 @@ uint8_t generate_data(memcached_st *memc)
   return 0;
 }
 
+uint8_t generate_large_pairs(memcached_st *memc)
+{
+  unsigned long long x;
+  global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
+  global_count= GLOBAL2_COUNT;
+
+  for (x= 0; x < global_count; x++)
+  {
+    global_keys[x]= global_pairs[x].key; 
+    global_keys_length[x]=  global_pairs[x].key_length;
+  }
+
+  return 0;
+}
+
+uint8_t generate_data(memcached_st *memc)
+{
+  execute_set(memc, global_pairs, global_count);
+
+  return 0;
+}
+
+uint8_t generate_buffer_data(memcached_st *memc)
+{
+  int latch= 0;
+
+  latch= 1;
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, &latch);
+  generate_data(memc);
+
+  return 0;
+}
+
 uint8_t get_read(memcached_st *memc)
 {
   unsigned int x;
@@ -1476,9 +1926,9 @@ uint8_t get_read(memcached_st *memc)
   {
     char *return_value;
     size_t return_value_length;
-    uint16_t flags;
+    uint32_t flags;
 
-    for (x= 0; x < GLOBAL_COUNT; x++)
+    for (x= 0; x < global_count; x++)
     {
       return_value= memcached_get(memc, global_keys[x], global_keys_length[x],
                                   &return_value_length, &flags, &rc);
@@ -1498,7 +1948,7 @@ uint8_t mget_read(memcached_st *memc)
 {
   memcached_return rc;
 
-  rc= memcached_mget(memc, global_keys, global_keys_length, GLOBAL_COUNT);
+  rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
   assert(rc == MEMCACHED_SUCCESS);
   /* Turn this into a help function */
   {
@@ -1506,7 +1956,7 @@ uint8_t mget_read(memcached_st *memc)
     size_t return_key_length;
     char *return_value;
     size_t return_value_length;
-    uint16_t flags;
+    uint32_t flags;
 
     while ((return_value= memcached_fetch(memc, return_key, &return_key_length,
                                           &return_value_length, &flags, &rc)))
@@ -1524,7 +1974,7 @@ uint8_t mget_read_result(memcached_st *memc)
 {
   memcached_return rc;
 
-  rc= memcached_mget(memc, global_keys, global_keys_length, GLOBAL_COUNT);
+  rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
   assert(rc == MEMCACHED_SUCCESS);
   /* Turn this into a help function */
   {
@@ -1545,6 +1995,50 @@ uint8_t mget_read_result(memcached_st *memc)
   return 0;
 }
 
+uint8_t mget_read_function(memcached_st *memc)
+{
+  memcached_return rc;
+  unsigned int counter;
+  unsigned int (*callbacks[1])(memcached_st *, memcached_result_st *, void *);
+
+  rc= memcached_mget(memc, global_keys, global_keys_length, global_count);
+  assert(rc == MEMCACHED_SUCCESS);
+
+  callbacks[0]= &callback_counter;
+  counter= 0;
+  rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1); 
+
+  return 0;
+}
+
+uint8_t delete_generate(memcached_st *memc)
+{
+  unsigned int x;
+
+  for (x= 0; x < global_count; x++)
+  {
+    (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
+  }
+
+  return 0;
+}
+
+uint8_t delete_buffer_generate(memcached_st *memc)
+{
+  int latch= 0;
+  unsigned int x;
+
+  latch= 1;
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, &latch);
+
+  for (x= 0; x < global_count; x++)
+  {
+    (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
+  }
+
+  return 0;
+}
+
 uint8_t free_data(memcached_st *memc)
 {
   pairs_free(global_pairs);
@@ -1655,6 +2149,76 @@ memcached_return pre_hash_ketama(memcached_st *memc)
   return MEMCACHED_SUCCESS;
 }
 
+void my_free(memcached_st *ptr, void *mem)
+{
+  free(mem);
+}
+
+void *my_malloc(memcached_st *ptr, const size_t size)
+{
+  return malloc(size);
+}
+
+void *my_realloc(memcached_st *ptr, void *mem, const size_t size)
+{
+  return realloc(mem, size);
+}
+
+memcached_return set_memory_alloc(memcached_st *memc)
+{
+  {
+    memcached_malloc_function test_ptr;
+    memcached_return rc;
+
+    rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &my_malloc);
+    assert(rc == MEMCACHED_SUCCESS);
+    test_ptr= (memcached_malloc_function)memcached_callback_get(memc, MEMCACHED_CALLBACK_MALLOC_FUNCTION, &rc);
+    assert(rc == MEMCACHED_SUCCESS);
+    assert(test_ptr == my_malloc);
+  }
+
+  {
+    memcached_realloc_function test_ptr;
+    memcached_return rc;
+
+    rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &my_realloc);
+    assert(rc == MEMCACHED_SUCCESS);
+    test_ptr= (memcached_realloc_function)memcached_callback_get(memc, MEMCACHED_CALLBACK_REALLOC_FUNCTION, &rc);
+    assert(rc == MEMCACHED_SUCCESS);
+    assert(test_ptr == my_realloc);
+  }
+
+  {
+    memcached_free_function test_ptr;
+    memcached_return rc;
+
+    rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, my_free);
+    assert(rc == MEMCACHED_SUCCESS);
+    test_ptr= (memcached_free_function)memcached_callback_get(memc, MEMCACHED_CALLBACK_FREE_FUNCTION, &rc);
+    assert(rc == MEMCACHED_SUCCESS);
+    assert(test_ptr == my_free);
+  }
+
+  return MEMCACHED_SUCCESS;
+}
+
+memcached_return enable_consistent(memcached_st *memc)
+{
+  memcached_server_distribution value= MEMCACHED_DISTRIBUTION_CONSISTENT;
+  memcached_hash hash;
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, &value);
+  pre_hsieh(memc);
+
+  value= (memcached_server_distribution)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
+  assert(value == MEMCACHED_DISTRIBUTION_CONSISTENT);
+
+  hash= (memcached_hash)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
+  assert(hash == MEMCACHED_HASH_HSIEH);
+
+
+  return MEMCACHED_SUCCESS;
+}
+
 memcached_return enable_cas(memcached_st *memc)
 {
   unsigned int set= 1;
@@ -1747,13 +2311,14 @@ test_st tests[] ={
   {"flush", 0, flush_test },
   {"init", 0, init_test },
   {"allocation", 0, allocation_test },
+  {"server_list_null_test", 0, server_list_null_test},
   {"clone_test", 0, clone_test },
   {"error", 0, error_test },
   {"set", 0, set_test },
   {"set2", 0, set_test2 },
   {"set3", 0, set_test3 },
-  {"add", 0, add_test },
-  {"replace", 0, replace_test },
+  {"add", 1, add_test },
+  {"replace", 1, replace_test },
   {"delete", 1, delete_test },
   {"get", 1, get_test },
   {"get2", 0, get_test2 },
@@ -1766,10 +2331,18 @@ test_st tests[] ={
   {"mget", 1, mget_test },
   {"mget_result", 1, mget_result_test },
   {"mget_result_alloc", 1, mget_result_alloc_test },
+  {"mget_result_function", 1, mget_result_function },
   {"get_stats", 0, get_stats },
   {"add_host_test", 0, add_host_test },
   {"get_stats_keys", 0, get_stats_keys },
   {"behavior_test", 0, get_stats_keys },
+  {"callback_test", 0, get_stats_keys },
+  {"version_string_test", 0, version_string_test},
+  {0, 0, 0}
+};
+
+test_st async_tests[] ={
+  {"add", 1, add_wrapper },
   {0, 0, 0}
 };
 
@@ -1807,15 +2380,31 @@ test_st user_tests[] ={
   {"user_supplied_bug6", 1, user_supplied_bug6 },
   {"user_supplied_bug7", 1, user_supplied_bug7 },
   {"user_supplied_bug8", 1, user_supplied_bug8 },
+  {"user_supplied_bug9", 1, user_supplied_bug9 },
+  {"user_supplied_bug10", 1, user_supplied_bug10 },
+  {"user_supplied_bug11", 1, user_supplied_bug11 },
+  {"user_supplied_bug12", 1, user_supplied_bug12 },
+  {"user_supplied_bug13", 1, user_supplied_bug13 },
+  {"user_supplied_bug14", 1, user_supplied_bug14 },
   {0, 0, 0}
 };
 
 test_st generate_tests[] ={
-  {"generate_data", 0, generate_data },
+  {"generate_pairs", 1, generate_pairs },
+  {"generate_data", 1, generate_data },
   {"get_read", 0, get_read },
+  {"delete_generate", 0, delete_generate },
+  {"generate_buffer_data", 1, generate_buffer_data },
+  {"delete_buffer", 0, delete_buffer_generate},
+  {"generate_data", 1, generate_data },
   {"mget_read", 0, mget_read },
   {"mget_read_result", 0, mget_read_result },
-  {"cleanup", 0, cleanup_pairs },
+  {"mget_read_function", 0, mget_read_function },
+  {"cleanup", 1, cleanup_pairs },
+  {"generate_large_pairs", 1, generate_large_pairs },
+  {"generate_data", 1, generate_data },
+  {"generate_buffer_data", 1, generate_buffer_data },
+  {"cleanup", 1, cleanup_pairs },
   {0, 0, 0}
 };
 
@@ -1836,13 +2425,18 @@ collection_st collection[] ={
   {"unix_socket_nodelay", pre_nodelay, 0, tests},
   {"poll_timeout", poll_timeout, 0, tests},
   {"gets", enable_cas, 0, tests},
+  {"consistent", enable_consistent, 0, tests},
+  {"memory_allocators", set_memory_alloc, 0, tests},
 //  {"udp", pre_udp, 0, tests},
   {"version_1_2_3", check_for_1_2_3, 0, version_1_2_3},
   {"string", 0, 0, string_tests},
   {"result", 0, 0, result_tests},
+  {"async", pre_nonblock, 0, async_tests},
   {"user", 0, 0, user_tests},
   {"generate", 0, 0, generate_tests},
   {"generate_hsieh", pre_hsieh, 0, generate_tests},
+  {"generate_hsieh_consistent", enable_consistent, 0, generate_tests},
+  {"generate_md5", pre_md5, 0, generate_tests},
   {"generate_nonblock", pre_nonblock, 0, generate_tests},
   {0, 0, 0, 0}
 };