Extended server_sort_test() test.
[awesomized/libmemcached] / tests / function.c
index 6ca61d7d5addb443a35899af8f99e8a49f9e2f0b..19c104df4689e602aac42e2e33ae42fb4f3d2178 100644 (file)
@@ -2,7 +2,6 @@
   Sample test application.
 */
 #include <assert.h>
-#include <memcached.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -11,9 +10,9 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <time.h>
-#include "../lib/common.h"
-#include "../src/generator.h"
-#include "../src/execute.h"
+#include "server.h"
+#include "../clients/generator.h"
+#include "../clients/execute.h"
 
 #ifndef INT64_MAX
 #define INT64_MAX LONG_MAX
@@ -26,6 +25,9 @@
 #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];
@@ -57,6 +59,46 @@ uint8_t server_list_null_test(memcached_st *ptr)
   return 0;
 }
 
+#define TEST_PORT_COUNT 7
+uint32_t test_ports[TEST_PORT_COUNT];
+
+memcached_return server_display_function(memcached_st *ptr, memcached_server_st *server, void *context)
+{
+  /* Do Nothing */
+  uint32_t *bigger= (uint32_t *)context;
+  assert(*bigger <= server->port);
+
+  return MEMCACHED_SUCCESS;
+}
+
+uint8_t server_sort_test(memcached_st *ptr)
+{
+  uint8_t x;
+  uint32_t bigger= 0; /* Prime the value for the assert in server_display_function */
+  memcached_return rc;
+  memcached_server_function callbacks[1];
+  memcached_st *local_memc;
+
+  local_memc= memcached_create(NULL);
+  assert(local_memc);
+  memcached_behavior_set(local_memc, MEMCACHED_BEHAVIOR_SORT_HOSTS, 1);
+
+  for (x= 0; x < TEST_PORT_COUNT; x++)
+  {
+    test_ports[x]= random() % 64000;
+    rc= memcached_server_add(local_memc, "localhost", test_ports[x]);
+    assert(rc == MEMCACHED_SUCCESS);
+  }
+
+  callbacks[0]= server_display_function;
+  memcached_server_cursor(local_memc, callbacks, (void *)&bigger,  1);
+
+
+  memcached_free(local_memc);
+
+  return 0;
+}
+
 uint8_t allocation_test(memcached_st *not_used)
 {
   memcached_st *memc;
@@ -239,7 +281,7 @@ uint8_t cas2_test(memcached_st *memc)
   rc= memcached_flush(memc, 0);
   assert(rc == MEMCACHED_SUCCESS);
 
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, &set);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
 
   for (x= 0; x < 3; x++)
   {
@@ -282,7 +324,7 @@ uint8_t cas_test(memcached_st *memc)
   rc= memcached_flush(memc, 0);
   assert(rc == MEMCACHED_SUCCESS);
 
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, &set);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
 
   rc= memcached_set(memc, key, strlen(key), 
                     value, strlen(value),
@@ -302,6 +344,19 @@ uint8_t cas_test(memcached_st *memc)
   assert(strlen("we the people") == value_length);
   assert(rc == MEMCACHED_SUCCESS);
 
+  rc= memcached_cas(memc, key, key_length,
+                    "change the value", strlen("change the value"), 
+                    0, 0, memcached_result_cas(results));
+
+  assert(rc == MEMCACHED_SUCCESS);
+
+  rc= memcached_cas(memc, key, key_length,
+                    "change the value", strlen("change the value"), 
+                    0, 0, 23);
+
+  assert(rc == MEMCACHED_DATA_EXISTS);
+
+
   memcached_result_free(&results_obj);
 
   return 0;
@@ -352,6 +407,9 @@ 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),
@@ -361,7 +419,12 @@ uint8_t add_test(memcached_st *memc)
   rc= memcached_add(memc, key, strlen(key), 
                     value, strlen(value),
                     (time_t)0, (uint32_t)0);
-  assert(rc == MEMCACHED_NOTSTORED);
+
+  /* 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;
 }
@@ -381,6 +444,12 @@ 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),
@@ -417,6 +486,102 @@ uint8_t flush_test(memcached_st *memc)
   return 0;
 }
 
+memcached_return server_function(memcached_st *ptr, memcached_server_st *server, void *context)
+{
+  /* Do Nothing */
+
+  return MEMCACHED_SUCCESS;
+}
+
+uint8_t memcached_server_cursor_test(memcached_st *memc)
+{
+  char *context= "foo bad";
+  memcached_server_function callbacks[1];
+
+  callbacks[0]= server_function;
+  memcached_server_cursor(memc, callbacks, context,  1);
+
+  return 0;
+}
+
+uint8_t bad_key_test(memcached_st *memc)
+{
+  memcached_return rc;
+  char *key= "foo bad";
+  char *string;
+  size_t string_length;
+  uint32_t flags;
+  memcached_st *clone;
+  unsigned int set= 1;
+
+  clone= memcached_clone(NULL, memc);
+  assert(clone);
+
+  (void)memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
+
+  string= memcached_get(clone, key, strlen(key),
+                        &string_length, &flags, &rc);
+  assert(rc == MEMCACHED_BAD_KEY_PROVIDED);
+  assert(string_length ==  0);
+  assert(!string);
+
+  set= 0;
+  (void)memcached_behavior_set(clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
+  string= memcached_get(clone, key, strlen(key),
+                        &string_length, &flags, &rc);
+  assert(rc == MEMCACHED_NOTFOUND);
+  assert(string_length ==  0);
+  assert(!string);
+
+  memcached_free(clone);
+
+  return 0;
+}
+
+#define READ_THROUGH_VALUE "set for me"
+memcached_return read_through_trigger(memcached_st *memc,  
+                                      char *key, size_t key_length, 
+                                      memcached_result_st *result)
+{
+  
+  return memcached_result_set_value(result, READ_THROUGH_VALUE, strlen(READ_THROUGH_VALUE));
+}
+
+uint8_t read_through(memcached_st *memc)
+{
+  memcached_return rc;
+  char *key= "foo";
+  char *string;
+  size_t string_length;
+  uint32_t flags;
+
+  string= memcached_get(memc, key, strlen(key),
+                        &string_length, &flags, &rc);
+
+  assert(rc == MEMCACHED_NOTFOUND);
+  assert(string_length ==  0);
+  assert(!string);
+
+  rc= memcached_callback_set(memc, MEMCACHED_CALLBACK_GET_FAILURE, read_through_trigger);
+  assert(rc == MEMCACHED_SUCCESS);
+
+  string= memcached_get(memc, key, strlen(key),
+                        &string_length, &flags, &rc);
+
+  assert(rc == MEMCACHED_SUCCESS);
+  assert(string_length ==  strlen(READ_THROUGH_VALUE));
+  assert(!strcmp(READ_THROUGH_VALUE, string));
+
+  string= memcached_get(memc, key, strlen(key),
+                        &string_length, &flags, &rc);
+
+  assert(rc == MEMCACHED_SUCCESS);
+  assert(string_length ==  strlen(READ_THROUGH_VALUE));
+  assert(!strcmp(READ_THROUGH_VALUE, string));
+
+  return 0;
+}
+
 uint8_t get_test(memcached_st *memc)
 {
   memcached_return rc;
@@ -792,7 +957,7 @@ uint8_t mget_result_function(memcached_st *memc)
   size_t key_length[]= {5, 3, 4};
   unsigned int x;
   unsigned int counter;
-  unsigned int (*callbacks[1])(memcached_st *, memcached_result_st *, void *);
+  memcached_execute_function callbacks[1];
 
   /* We need to empty the server before continueing test */
   rc= memcached_flush(memc, 0);
@@ -889,6 +1054,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;
@@ -975,23 +1151,23 @@ uint8_t callback_test(memcached_st *memc)
 
   /* Test Clone Callback */
   {
-    clone_func temp_function;
+    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= (clone_func)memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
+    temp_function= (memcached_clone_func)memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
     assert(temp_function == clone_test_callback);
   }
 
   /* Test Cleanup Callback */
   {
-    cleanup_func temp_function;
+    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= (cleanup_func)memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
+    temp_function= (memcached_cleanup_func)memcached_callback_get(memc, MEMCACHED_CALLBACK_CLONE_FUNCTION, &rc);
     assert(temp_function == cleanup_test_callback);
   }
 
@@ -1004,36 +1180,36 @@ uint8_t behavior_test(memcached_st *memc)
   unsigned long long value;
   unsigned int set= 1;
 
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, &set);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
   value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
   assert(value == 1);
 
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &set);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
   value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
   assert(value == 1);
 
   set= MEMCACHED_HASH_MD5;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &set);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
   value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
   assert(value == MEMCACHED_HASH_MD5);
 
   set= 0;
 
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, &set);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, set);
   value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_NO_BLOCK);
   assert(value == 0);
 
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &set);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, set);
   value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY);
   assert(value == 0);
 
   set= MEMCACHED_HASH_DEFAULT;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &set);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
   value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
   assert(value == MEMCACHED_HASH_DEFAULT);
 
   set= MEMCACHED_HASH_CRC;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &set);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, set);
   value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_HASH);
   assert(value == MEMCACHED_HASH_CRC);
 
@@ -1043,15 +1219,6 @@ uint8_t behavior_test(memcached_st *memc)
   value= memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
   assert(value > 0);
 
-  {
-    int x= 5;
-    int *test_ptr;
-
-    memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_USER_DATA, &x);
-    test_ptr= (int *)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_USER_DATA);
-    assert(*test_ptr == x);
-  }
-
   return 0;
 }
 
@@ -1072,8 +1239,8 @@ uint8_t user_supplied_bug1(memcached_st *memc)
   /* We just keep looking at the same values over and over */
   srandom(10);
 
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, &setter);
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &setter);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
 
 
   /* add key */
@@ -1111,13 +1278,13 @@ uint8_t user_supplied_bug2(memcached_st *memc)
   unsigned long long total;
 
   setter= 1;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, &setter);
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &setter);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
 #ifdef NOT_YET
   setter = 20 * 1024576;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, &setter);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
   setter = 20 * 1024576;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, &setter);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
   getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
   getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
 
@@ -1142,7 +1309,10 @@ uint8_t user_supplied_bug2(memcached_st *memc)
       if (rc == MEMCACHED_NOTFOUND)
         errors++;
       else
+      {
+        WATCHPOINT_ERROR(rc);
         assert(0);
+      }
 
       continue;
     }
@@ -1165,13 +1335,13 @@ uint8_t user_supplied_bug3(memcached_st *memc)
   size_t key_lengths[KEY_COUNT];
 
   setter= 1;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, &setter);
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &setter);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, setter);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, setter);
 #ifdef NOT_YET
   setter = 20 * 1024576;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, &setter);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE, setter);
   setter = 20 * 1024576;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, &setter);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE, setter);
   getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_SEND_SIZE);
   getter = memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_SOCKET_RECV_SIZE);
 #endif
@@ -1534,10 +1704,10 @@ uint8_t user_supplied_bug10(memcached_st *memc)
   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);
+  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);
+  memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
 
   value = (char*)malloc(value_length * sizeof(char));
 
@@ -1575,10 +1745,10 @@ uint8_t user_supplied_bug11(memcached_st *memc)
   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);
+  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);
+  memcached_behavior_set(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
 
   timeout= (int32_t)memcached_behavior_get(mclone, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
 
@@ -1600,6 +1770,170 @@ uint8_t user_supplied_bug11(memcached_st *memc)
   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);
+    if (current_length > 0)
+      assert(string);
+    assert(string_length == current_length);
+    assert(!memcmp(string, value, string_length));
+
+    free(string);
+  }
+
+  free(value);
+
+  return 0;
+}
+
+/*
+  Look for zero length value problems
+  */
+uint8_t user_supplied_bug15(memcached_st *memc)
+{
+  uint32_t x;
+  memcached_return rc;
+  char *key= "mykey";
+  char *value;
+  size_t length;
+  uint32_t flags;
+
+  for (x= 0; x < 2; x++)
+  {
+    rc= memcached_set(memc, key, strlen(key), 
+                      NULL, 0,
+                      (time_t)0, (uint32_t)0);
+
+    assert(rc == MEMCACHED_SUCCESS);
+
+    value= memcached_get(memc, key, strlen(key),
+                         &length, &flags, &rc);
+
+    assert(rc == MEMCACHED_SUCCESS);
+    assert(value == NULL);
+    assert(length == 0);
+    assert(flags == 0);
+
+    value= memcached_get(memc, key, strlen(key),
+                         &length, &flags, &rc);
+
+    assert(rc == MEMCACHED_SUCCESS);
+    assert(value == NULL);
+    assert(length == 0);
+    assert(flags == 0);
+  }
+
+  return 0;
+}
+
 uint8_t result_static(memcached_st *memc)
 {
   memcached_result_st result;
@@ -1724,13 +2058,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;
@@ -1739,34 +2073,38 @@ uint8_t generate_data(memcached_st *memc)
   return 0;
 }
 
-uint8_t generate_buffer_data(memcached_st *memc)
+uint8_t generate_large_pairs(memcached_st *memc)
 {
-  int latch= 0;
+  unsigned long long x;
+  global_pairs= pairs_generate(GLOBAL2_COUNT, MEMCACHED_MAX_BUFFER+10);
+  global_count= GLOBAL2_COUNT;
 
-  latch= 1;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, &latch);
-  generate_data(memc);
+  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;
 }
 
-#ifdef NOT_DONE
-uint8_t mset_data(memcached_st *memc)
+uint8_t generate_data(memcached_st *memc)
 {
-  unsigned long long x;
-  global_pairs= pairs_generate(GLOBAL_COUNT);
+  execute_set(memc, global_pairs, global_count);
 
-  (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
+  return 0;
+}
 
-  for (x= 0; x < GLOBAL_COUNT; x++)
-  {
-    global_keys[x]= global_pairs[x].key; 
-    global_keys_length[x]=  global_pairs[x].key_length;
-  }
+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;
 }
-#endif
 
 uint8_t get_read(memcached_st *memc)
 {
@@ -1778,7 +2116,7 @@ uint8_t get_read(memcached_st *memc)
     size_t return_value_length;
     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);
@@ -1798,7 +2136,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 */
   {
@@ -1824,7 +2162,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 */
   {
@@ -1851,7 +2189,7 @@ uint8_t mget_read_function(memcached_st *memc)
   unsigned int counter;
   unsigned int (*callbacks[1])(memcached_st *, memcached_result_st *, void *);
 
-  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);
 
   callbacks[0]= &callback_counter;
@@ -1865,7 +2203,7 @@ uint8_t delete_generate(memcached_st *memc)
 {
   unsigned int x;
 
-  for (x= 0; x < GLOBAL_COUNT; x++)
+  for (x= 0; x < global_count; x++)
   {
     (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
   }
@@ -1879,9 +2217,9 @@ uint8_t delete_buffer_generate(memcached_st *memc)
   unsigned int x;
 
   latch= 1;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, &latch);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, latch);
 
-  for (x= 0; x < GLOBAL_COUNT; x++)
+  for (x= 0; x < global_count; x++)
   {
     (void)memcached_delete(memc, global_keys[x], global_keys_length[x], (time_t)0);
   }
@@ -1930,71 +2268,123 @@ uint8_t add_host_test1(memcached_st *memc)
 
 memcached_return pre_nonblock(memcached_st *memc)
 {
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, NULL);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
+
+  return MEMCACHED_SUCCESS;
+}
+
+memcached_return pre_murmur(memcached_st *memc)
+{
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MURMUR);
 
   return MEMCACHED_SUCCESS;
 }
 
 memcached_return pre_md5(memcached_st *memc)
 {
-  memcached_hash value= MEMCACHED_HASH_MD5;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &value);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_MD5);
 
   return MEMCACHED_SUCCESS;
 }
 
 memcached_return pre_crc(memcached_st *memc)
 {
-  memcached_hash value= MEMCACHED_HASH_CRC;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &value);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_CRC);
 
   return MEMCACHED_SUCCESS;
 }
 
 memcached_return pre_hsieh(memcached_st *memc)
 {
-  memcached_hash value= MEMCACHED_HASH_HSIEH;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &value);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_HSIEH);
 
   return MEMCACHED_SUCCESS;
 }
 
 memcached_return pre_hash_fnv1_64(memcached_st *memc)
 {
-  memcached_hash value= MEMCACHED_HASH_FNV1_64;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &value);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_64);
 
   return MEMCACHED_SUCCESS;
 }
 
 memcached_return pre_hash_fnv1a_64(memcached_st *memc)
 {
-  memcached_hash value= MEMCACHED_HASH_FNV1A_64;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &value);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_64);
 
   return MEMCACHED_SUCCESS;
 }
 
 memcached_return pre_hash_fnv1_32(memcached_st *memc)
 {
-  memcached_hash value= MEMCACHED_HASH_FNV1_32;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &value);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1_32);
 
   return MEMCACHED_SUCCESS;
 }
 
 memcached_return pre_hash_fnv1a_32(memcached_st *memc)
 {
-  memcached_hash value= MEMCACHED_HASH_FNV1A_32;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &value);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_FNV1A_32);
 
   return MEMCACHED_SUCCESS;
 }
 
 memcached_return pre_hash_ketama(memcached_st *memc)
 {
-  memcached_hash value= MEMCACHED_HASH_KETAMA;
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &value);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, (uint64_t)MEMCACHED_HASH_KETAMA);
+
+  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;
 }
@@ -2003,7 +2393,7 @@ 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);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, value);
   pre_hsieh(memc);
 
   value= (memcached_server_distribution)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_DISTRIBUTION);
@@ -2026,7 +2416,7 @@ memcached_return enable_cas(memcached_st *memc)
       memc->hosts[0].minor_version >= 2 &&
       memc->hosts[0].micro_version >= 4)
   {
-    memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, &set);
+    memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_SUPPORT_CAS, set);
 
     return MEMCACHED_SUCCESS;
   }
@@ -2081,8 +2471,8 @@ memcached_return pre_udp(memcached_st *memc)
 
 memcached_return pre_nodelay(memcached_st *memc)
 {
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, NULL);
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, NULL);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 0);
 
   return MEMCACHED_SUCCESS;
 }
@@ -2093,7 +2483,7 @@ memcached_return poll_timeout(memcached_st *memc)
 
   timeout= 100;
 
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, &timeout);
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT, timeout);
 
   timeout= (int32_t)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_POLL_TIMEOUT);
 
@@ -2109,13 +2499,14 @@ test_st tests[] ={
   {"init", 0, init_test },
   {"allocation", 0, allocation_test },
   {"server_list_null_test", 0, server_list_null_test},
+  {"server_sort", 0, server_sort_test},
   {"clone_test", 0, clone_test },
   {"error", 0, error_test },
   {"set", 0, set_test },
   {"set2", 0, set_test2 },
   {"set3", 0, set_test3 },
   {"add", 1, add_test },
-  {"replace", 0, replace_test },
+  {"replace", 1, replace_test },
   {"delete", 1, delete_test },
   {"get", 1, get_test },
   {"get2", 0, get_test2 },
@@ -2134,6 +2525,10 @@ test_st tests[] ={
   {"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},
+  {"bad_key", 1, bad_key_test },
+  {"memcached_server_cursor", 1, memcached_server_cursor_test },
+  {"read_through", 1, read_through },
   {0, 0, 0}
 };
 
@@ -2179,10 +2574,15 @@ test_st user_tests[] ={
   {"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 },
+  {"user_supplied_bug15", 1, user_supplied_bug15 },
   {0, 0, 0}
 };
 
 test_st generate_tests[] ={
+  {"generate_pairs", 1, generate_pairs },
   {"generate_data", 1, generate_data },
   {"get_read", 0, get_read },
   {"delete_generate", 0, delete_generate },
@@ -2193,6 +2593,10 @@ test_st generate_tests[] ={
   {"mget_read_result", 0, mget_read_result },
   {"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}
 };
 
@@ -2214,6 +2618,7 @@ collection_st collection[] ={
   {"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},
@@ -2224,11 +2629,39 @@ collection_st collection[] ={
   {"generate_hsieh", pre_hsieh, 0, generate_tests},
   {"generate_hsieh_consistent", enable_consistent, 0, generate_tests},
   {"generate_md5", pre_md5, 0, generate_tests},
+  {"generate_murmur", pre_murmur, 0, generate_tests},
   {"generate_nonblock", pre_nonblock, 0, generate_tests},
   {0, 0, 0, 0}
 };
 
-collection_st *gets_collections(void)
+#define SERVERS_TO_CREATE 5
+
+void *world_create(void)
+{
+  server_startup_st *construct;
+
+  construct= (server_startup_st *)malloc(sizeof(server_startup_st));
+  memset(construct, 0, sizeof(server_startup_st));
+  construct->count= SERVERS_TO_CREATE;
+  construct->udp= 0;
+  server_startup(construct);
+
+  return construct;
+}
+
+void world_destroy(void *p)
+{
+  server_startup_st *construct= (server_startup_st *)p;
+  memcached_server_st *servers= (memcached_server_st *)construct->servers;
+  memcached_server_list_free(servers);
+
+  server_shutdown(construct);
+  free(construct);
+}
+
+void get_world(world_st *world)
 {
-  return collection;
+  world->collections= collection;
+  world->create= world_create;
+  world->destroy= world_destroy;
 }