Fix for bad location of include directory
[awesomized/libmemcached] / tests / function.c
index b2bcd4ad5f1499087530703962e49d44255d7b34..8d84c16f4f8d58e2b6d2de4ee7162cc2348a842c 100644 (file)
@@ -11,6 +11,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <time.h>
+#include "server.h"
 #include "../lib/common.h"
 #include "../src/generator.h"
 #include "../src/execute.h"
@@ -60,6 +61,32 @@ uint8_t server_list_null_test(memcached_st *ptr)
   return 0;
 }
 
+uint8_t server_sort_test(memcached_st *ptr)
+{
+  unsigned int setting;
+  memcached_server_st *server_list;
+  memcached_return rc;
+
+  setting= 1;
+  memcached_behavior_set(ptr, MEMCACHED_BEHAVIOR_SORT_HOSTS, &setting);
+
+  server_list= memcached_server_list_append(NULL, "arg", 0, &rc);
+  assert(server_list);
+
+  server_list= memcached_server_list_append(server_list, "localhost", 0, &rc);
+  assert(server_list);
+
+  server_list= memcached_server_list_append(server_list, "c", 0, &rc);
+  assert(server_list);
+
+  server_list= memcached_server_list_append(server_list, "abba", 0, &rc);
+  assert(server_list);
+
+  free(server_list);
+
+  return 0;
+}
+
 uint8_t allocation_test(memcached_st *not_used)
 {
   memcached_st *memc;
@@ -305,6 +332,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;
@@ -355,6 +395,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),
@@ -364,7 +407,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;
 }
@@ -384,6 +432,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),
@@ -420,6 +474,58 @@ 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;
+}
+
 uint8_t get_test(memcached_st *memc)
 {
   memcached_return rc;
@@ -795,7 +901,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);
@@ -1147,7 +1253,10 @@ uint8_t user_supplied_bug2(memcached_st *memc)
       if (rc == MEMCACHED_NOTFOUND)
         errors++;
       else
+      {
+        WATCHPOINT_ERROR(rc);
         assert(0);
+      }
 
       continue;
     }
@@ -1643,6 +1752,131 @@ uint8_t user_supplied_bug12(memcached_st *memc)
   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;
+}
+
+/*
+  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;
@@ -1982,6 +2216,14 @@ memcached_return pre_nonblock(memcached_st *memc)
   return MEMCACHED_SUCCESS;
 }
 
+memcached_return pre_murmur(memcached_st *memc)
+{
+  memcached_hash value= MEMCACHED_HASH_MURMUR;
+  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_HASH, &value);
+
+  return MEMCACHED_SUCCESS;
+}
+
 memcached_return pre_md5(memcached_st *memc)
 {
   memcached_hash value= MEMCACHED_HASH_MD5;
@@ -2209,13 +2451,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 },
@@ -2235,6 +2478,8 @@ test_st tests[] ={
   {"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 },
   {0, 0, 0}
 };
 
@@ -2281,6 +2526,9 @@ test_st user_tests[] ={
   {"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}
 };
 
@@ -2332,11 +2580,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;
 }