Fix issue where hash might not be quite initialized. Also remove redundant bit to...
[m6w6/libmemcached] / tests / mem_functions.c
index bd01908e2ddc5923e83cf85c098080c84f479cf9..91cb2b2347187e78105d32ffaead02daed626727 100644 (file)
@@ -1,11 +1,41 @@
-/* libMemcached Functions Test
- * Copyright (C) 2006-2009 Brian Aker
- * All rights reserved.
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Libmemcached library
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  Copyright (C) 2006-2009 Brian Aker All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
  */
 
+
 /*
   Sample test application.
 */
@@ -34,7 +64,9 @@
 #define SMALL_STRING_LEN 1024
 
 #include <libtest/test.h>
+#include "tests/deprecated.h"
 #include "tests/parser.h"
+#include "tests/pool.h"
 #include "tests/string.h"
 #include "tests/replication.h"
 #include "tests/basic.h"
@@ -74,24 +106,6 @@ static test_return_t init_test(memcached_st *not_used)
   return TEST_SUCCESS;
 }
 
-static test_return_t server_list_null_test(memcached_st *ptr)
-{
-  memcached_server_st *server_list;
-  memcached_return_t rc;
-  (void)ptr;
-
-  server_list= memcached_server_list_append_with_weight(NULL, NULL, 0, 0, NULL);
-  test_true(server_list == NULL);
-
-  server_list= memcached_server_list_append_with_weight(NULL, "localhost", 0, 0, NULL);
-  test_true(server_list == NULL);
-
-  server_list= memcached_server_list_append_with_weight(NULL, NULL, 0, 0, &rc);
-  test_true(server_list == NULL);
-
-  return TEST_SUCCESS;
-}
-
 #define TEST_PORT_COUNT 7
 in_port_t test_ports[TEST_PORT_COUNT];
 
@@ -198,23 +212,13 @@ static test_return_t server_sort2_test(memcached_st *ptr)
 
 static test_return_t memcached_server_remove_test(memcached_st *ptr)
 {
-  memcached_return_t rc;
-  memcached_st local_memc;
-  memcached_st *memc;
-  memcached_server_st *servers;
-  memcached_server_fn callbacks[1];
-
-  const char *server_string= "localhost:4444, localhost:4445, localhost:4446, localhost:4447, localhost, memcache1.memcache.bk.sapo.pt:11211, memcache1.memcache.bk.sapo.pt:11212, memcache1.memcache.bk.sapo.pt:11213, memcache1.memcache.bk.sapo.pt:11214, memcache2.memcache.bk.sapo.pt:11211, memcache2.memcache.bk.sapo.pt:11212, memcache2.memcache.bk.sapo.pt:11213, memcache2.memcache.bk.sapo.pt:11214";
+  const char *server_string= "--server=localhost:4444 --server=localhost:4445 --server=localhost:4446 --server=localhost:4447 --server=localhost --server=memcache1.memcache.bk.sapo.pt:11211 --server=memcache1.memcache.bk.sapo.pt:11212 --server=memcache1.memcache.bk.sapo.pt:11213 --server=memcache1.memcache.bk.sapo.pt:11214 --server=memcache2.memcache.bk.sapo.pt:11211 --server=memcache2.memcache.bk.sapo.pt:11212 --server=memcache2.memcache.bk.sapo.pt:11213 --server=memcache2.memcache.bk.sapo.pt:11214";
   (void)ptr;
 
-  memc= memcached_create(&local_memc);
-
-  servers= memcached_servers_parse(server_string);
-  assert(servers);
-
-  rc= memcached_server_push(memc, servers);
-  memcached_server_list_free(servers);
+  memcached_st *memc= memcached(server_string, strlen(server_string));
+  test_true(memc);
 
+  memcached_server_fn callbacks[1];
   callbacks[0]= server_print_callback;
   memcached_server_cursor(memc, callbacks, NULL,  1);
 
@@ -231,7 +235,12 @@ static memcached_return_t server_display_unsort_function(const memcached_st *ptr
   uint32_t x= *((uint32_t *)(context));
   (void)ptr;
 
-  assert(test_ports[x] == server->port);
+  if (! (test_ports[x] == server->port))
+  {
+    fprintf(stderr, "%lu -> %lu\n", (unsigned long)test_ports[x], (unsigned long)server->port);
+    return MEMCACHED_FAILURE;
+  }
+
   *((uint32_t *)(context))= ++x;
 
   return MEMCACHED_SUCCESS;
@@ -314,8 +323,6 @@ static test_return_t clone_test(memcached_st *memc)
     { // Test all of the flags
       test_true(memc_clone->flags.no_block == memc->flags.no_block);
       test_true(memc_clone->flags.tcp_nodelay == memc->flags.tcp_nodelay);
-      test_true(memc_clone->flags.reuse_memory == memc->flags.reuse_memory);
-      test_true(memc_clone->flags.use_cache_lookups == memc->flags.use_cache_lookups);
       test_true(memc_clone->flags.support_cas == memc->flags.support_cas);
       test_true(memc_clone->flags.buffer_requests == memc->flags.buffer_requests);
       test_true(memc_clone->flags.use_sort_hosts == memc->flags.use_sort_hosts);
@@ -330,7 +337,6 @@ static test_return_t clone_test(memcached_st *memc)
     }
     test_true(memc_clone->get_key_failure == memc->get_key_failure);
     test_true(hashkit_compare(&memc_clone->hashkit, &memc->hashkit));
-    test_true(hashkit_compare(&memc_clone->distribution_hashkit, &memc->distribution_hashkit));
     test_true(memc_clone->io_bytes_watermark == memc->io_bytes_watermark);
     test_true(memc_clone->io_msg_watermark == memc->io_msg_watermark);
     test_true(memc_clone->io_key_prefetch == memc->io_key_prefetch);
@@ -405,7 +411,7 @@ static test_return_t error_test(memcached_st *memc)
                         54481931U, 4186304426U, 1741088401U, 2979625118U,
                         4159057246U, 3425930182U, 2593724503U,  1868899624U,
                         1769812374U, 2302537950U, 1110330676U, 3365377466U, 
-                        1336171666U, 3365377466U };
+                        1336171666U, 3021258493U, 3365377466U };
 
   // You have updated the memcache_error messages but not updated docs/tests.
   for (rc= MEMCACHED_SUCCESS; rc < MEMCACHED_MAXIMUM_RETURN; rc++)
@@ -421,7 +427,7 @@ static test_return_t error_test(memcached_st *memc)
     }
     test_true(values[rc] == hash_val);
   }
-  test_true(MEMCACHED_MAXIMUM_RETURN == 45);
+  test_true(MEMCACHED_MAXIMUM_RETURN == 46);
 
   return TEST_SUCCESS;
 }
@@ -760,8 +766,10 @@ static test_return_t flush_test(memcached_st *memc)
 {
   memcached_return_t rc;
 
+  uint64_t query_id= memcached_query_id(memc);
   rc= memcached_flush(memc, 0);
-  test_true(rc == MEMCACHED_SUCCESS);
+  test_compare(rc, MEMCACHED_SUCCESS);
+  test_compare(query_id +1, memcached_query_id(memc));
 
   return TEST_SUCCESS;
 }
@@ -799,18 +807,23 @@ static test_return_t bad_key_test(memcached_st *memc)
   size_t max_keylen= 0xffff;
 
   // Just skip if we are in binary mode.
+  uint64_t query_id= memcached_query_id(memc);
   if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL))
     return TEST_SKIPPED;
+  test_compare(query_id, memcached_query_id(memc)); // We should not increase the query_id for memcached_behavior_get()
 
   memc_clone= memcached_clone(NULL, memc);
   test_true(memc_clone);
 
+  query_id= memcached_query_id(memc_clone);
   rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
   test_true(rc == MEMCACHED_SUCCESS);
+  test_compare(query_id, memcached_query_id(memc_clone)); // We should not increase the query_id for memcached_behavior_set()
 
   /* All keys are valid in the binary protocol (except for length) */
   if (memcached_behavior_get(memc_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 0)
   {
+    query_id= memcached_query_id(memc_clone);
     string= memcached_get(memc_clone, key, strlen(key),
                           &string_length, &flags, &rc);
     test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
@@ -818,7 +831,9 @@ static test_return_t bad_key_test(memcached_st *memc)
     test_true(!string);
 
     set= 0;
+    query_id= memcached_query_id(memc_clone);
     rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
+    test_compare(query_id, memcached_query_id(memc_clone)); // We should not increase the query_id for memcached_behavior_set()
     test_true(rc == MEMCACHED_SUCCESS);
     string= memcached_get(memc_clone, key, strlen(key),
                           &string_length, &flags, &rc);
@@ -830,14 +845,20 @@ static test_return_t bad_key_test(memcached_st *memc)
     const char *keys[] = { "GoodKey", "Bad Key", "NotMine" };
     size_t key_lengths[] = { 7, 7, 7 };
     set= 1;
+    query_id= memcached_query_id(memc_clone);
     rc= memcached_behavior_set(memc_clone, MEMCACHED_BEHAVIOR_VERIFY_KEY, set);
     test_true(rc == MEMCACHED_SUCCESS);
+    test_compare(query_id, memcached_query_id(memc_clone));
 
+    query_id= memcached_query_id(memc_clone);
     rc= memcached_mget(memc_clone, keys, key_lengths, 3);
     test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
+    test_compare(query_id +1, memcached_query_id(memc_clone));
 
+    query_id= memcached_query_id(memc_clone);
     rc= memcached_mget_by_key(memc_clone, "foo daddy", 9, keys, key_lengths, 1);
     test_true(rc == MEMCACHED_BAD_KEY_PROVIDED);
+    test_compare(query_id +1, memcached_query_id(memc_clone));
 
     max_keylen= 250;
 
@@ -963,8 +984,10 @@ static test_return_t get_test(memcached_st *memc)
   size_t string_length;
   uint32_t flags;
 
+  uint64_t query_id= memcached_query_id(memc);
   rc= memcached_delete(memc, key, strlen(key), (time_t)0);
   test_true(rc == MEMCACHED_BUFFERED || rc == MEMCACHED_NOTFOUND);
+  test_compare(query_id +1, memcached_query_id(memc));
 
   string= memcached_get(memc, key, strlen(key),
                         &string_length, &flags, &rc);
@@ -985,18 +1008,22 @@ static test_return_t get_test2(memcached_st *memc)
   size_t string_length;
   uint32_t flags;
 
+  uint64_t query_id= memcached_query_id(memc);
   rc= memcached_set(memc, key, strlen(key),
                     value, strlen(value),
                     (time_t)0, (uint32_t)0);
   test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+  test_compare(query_id +1, memcached_query_id(memc));
 
+  query_id= memcached_query_id(memc);
   string= memcached_get(memc, key, strlen(key),
                         &string_length, &flags, &rc);
+  test_compare(query_id +1, memcached_query_id(memc));
 
   test_true(string);
   test_true(rc == MEMCACHED_SUCCESS);
   test_true(string_length == strlen(value));
-  test_true(!memcmp(string, value, string_length));
+  test_memcmp(string, value, string_length);
 
   free(string);
 
@@ -1027,25 +1054,26 @@ static test_return_t set_test3(memcached_st *memc)
   memcached_return_t rc;
   char *value;
   size_t value_length= 8191;
-  unsigned int x;
 
   value = (char*)malloc(value_length);
   test_true(value);
 
-  for (x= 0; x < value_length; x++)
+  for (uint32_t x= 0; x < value_length; x++)
     value[x] = (char) (x % 127);
 
   /* The dump test relies on there being at least 32 items in memcached */
-  for (x= 0; x < 32; x++)
+  for (uint32_t x= 0; x < 32; x++)
   {
     char key[16];
 
     snprintf(key, sizeof(key), "foo%u", x);
 
+    uint64_t query_id= memcached_query_id(memc);
     rc= memcached_set(memc, key, strlen(key),
                       value, value_length,
                       (time_t)0, (uint32_t)0);
     test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+    test_compare(query_id +1, memcached_query_id(memc));
   }
 
   free(value);
@@ -1713,8 +1741,10 @@ static test_return_t mget_execute(memcached_st *memc)
     key_length[x]= (size_t)snprintf(k, sizeof(k), "0200%lu", (unsigned long)x);
     keys[x]= strdup(k);
     test_true(keys[x] != NULL);
+    uint64_t query_id= memcached_query_id(memc);
     rc= memcached_add(memc, keys[x], key_length[x], blob, sizeof(blob), 0, 0);
     test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_BUFFERED);
+    test_compare(query_id +1, memcached_query_id(memc));
   }
 
   /* Try to get all of them with a large multiget */
@@ -1726,8 +1756,10 @@ static test_return_t mget_execute(memcached_st *memc)
   if (rc == MEMCACHED_SUCCESS)
   {
     test_true(binary);
+    uint64_t query_id= memcached_query_id(memc);
     rc= memcached_fetch_execute(memc, callbacks, (void *)&counter, 1);
     test_true(rc == MEMCACHED_END);
+    test_compare(query_id, memcached_query_id(memc));
 
     /* Verify that we got all of the items */
     test_true(counter == max_keys);
@@ -2000,21 +2032,15 @@ static test_return_t MEMCACHED_BEHAVIOR_CORK_test(memcached_st *memc)
 {
   memcached_return_t rc;
   bool set= true;
-  bool value;
 
   rc= memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_CORK, set);
-  test_true(rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOT_SUPPORTED);
-
-  value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CORK);
+  test_true(rc == MEMCACHED_DEPRECATED);
 
-  if (rc == MEMCACHED_SUCCESS)
-  {
-    test_true((bool)value == set);
-  }
-  else
-  {
-    test_false((bool)value == set);
-  }
+  // Platform dependent
+#if 0
+  bool value= (bool)memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_CORK);
+  test_false(value);
+#endif
 
   return TEST_SUCCESS;
 }
@@ -2256,7 +2282,7 @@ static test_return_t user_supplied_bug4(memcached_st *memc)
 
   /* We need to empty the server before continueing test */
   rc= memcached_flush(memc, 0);
-  test_true(rc == MEMCACHED_NO_SERVERS);
+  test_compare(rc, MEMCACHED_NO_SERVERS);
 
   rc= memcached_mget(memc, keys, key_length, 3);
   test_true(rc == MEMCACHED_NO_SERVERS);
@@ -2266,7 +2292,7 @@ static test_return_t user_supplied_bug4(memcached_st *memc)
   {
     test_true(return_value);
   }
-  test_true(!return_value);
+  test_false(return_value);
   test_true(return_value_length == 0);
   test_true(rc == MEMCACHED_NO_SERVERS);
 
@@ -2288,7 +2314,7 @@ static test_return_t user_supplied_bug4(memcached_st *memc)
     test_true(return_value);
     test_true(rc == MEMCACHED_SUCCESS);
     test_true(return_key_length == return_value_length);
-    test_true(!memcmp(return_value, return_key, return_value_length));
+    test_memcmp(return_value, return_key, return_value_length);
     free(return_value);
     x++;
   }
@@ -4309,6 +4335,7 @@ static void* connection_release(void *arg)
   } *resource= arg;
 
   usleep(250);
+  // Release all of the memc we are holding
   assert(memcached_pool_push(resource->pool, resource->mmc) == MEMCACHED_SUCCESS);
   return arg;
 }
@@ -4321,6 +4348,7 @@ static test_return_t connection_pool_test(memcached_st *memc)
   memcached_st *mmc[POOL_SIZE];
   memcached_return_t rc;
 
+  // Fill up our array that we will store the memc that are in the pool
   for (size_t x= 0; x < POOL_SIZE; ++x)
   {
     mmc[x]= memcached_pool_pop(pool, false, &rc);
@@ -4328,6 +4356,7 @@ static test_return_t connection_pool_test(memcached_st *memc)
     test_true(rc == MEMCACHED_SUCCESS);
   }
 
+  // All memc should be gone
   test_true(memcached_pool_pop(pool, false, &rc) == NULL);
   test_true(rc == MEMCACHED_SUCCESS);
 
@@ -4336,11 +4365,12 @@ static test_return_t connection_pool_test(memcached_st *memc)
     memcached_pool_st* pool;
     memcached_st* mmc;
   } item= { .pool = pool, .mmc = mmc[9] };
+
   pthread_create(&tid, NULL, connection_release, &item);
   mmc[9]= memcached_pool_pop(pool, true, &rc);
   test_true(rc == MEMCACHED_SUCCESS);
   pthread_join(tid, NULL);
-  test_true(mmc[9] == item.mmc);
+  test_true(mmc[9]);
   const char *key= "key";
   size_t keylen= strlen(key);
 
@@ -5477,7 +5507,7 @@ static test_return_t test_cull_servers(memcached_st *memc)
   uint32_t count = memcached_server_count(memc);
 
   // Do not do this in your code, it is not supported.
-  memc->servers[1].state.is_dead= true;
+  memc->servers[1].options.is_dead= true;
   memc->state.is_time_for_rebuild= true;
 
   uint32_t new_count= memcached_server_count(memc);
@@ -5759,17 +5789,6 @@ static test_return_t regression_bug_583031(memcached_st *unused)
     return TEST_SUCCESS;
 }
 
-// Look for memory leak
-static test_return_t regression_bug_728286(memcached_st *unused)
-{
-  (void)unused;
-  memcached_server_st *servers = memcached_servers_parse("1.2.3.4:99");
-  assert(servers);
-  memcached_server_free(servers);
-
-  return TEST_SUCCESS;
-}
-
 static test_return_t regression_bug_581030(memcached_st *unused)
 {
   (void)unused;
@@ -5983,10 +6002,9 @@ test_st tests[] ={
   {"delete_through", 1, (test_callback_fn)delete_through },
   {"noreply", 1, (test_callback_fn)noreply_test},
   {"analyzer", 1, (test_callback_fn)analyzer_test},
-#ifdef HAVE_LIBMEMCACHEDUTIL
   {"connectionpool", 1, (test_callback_fn)connection_pool_test },
+  {"memcached_pool_test", 1, (test_callback_fn)memcached_pool_test },
   {"ping", 1, (test_callback_fn)ping_test },
-#endif
   {"test_get_last_disconnect", 1, (test_callback_fn)test_get_last_disconnect},
   {"verbosity", 1, (test_callback_fn)test_verbosity},
   {"test_server_failure", 1, (test_callback_fn)test_server_failure},
@@ -6220,12 +6238,12 @@ test_st parser_tests[] ={
   {"hash", 0, (test_callback_fn)parser_hash_test },
   {"libmemcached_check_configuration", 0, (test_callback_fn)libmemcached_check_configuration_test },
   {"libmemcached_check_configuration_with_filename", 0, (test_callback_fn)libmemcached_check_configuration_with_filename_test },
-  {"memcached_parse_configure_file", 0, (test_callback_fn)memcached_parse_configure_file_test },
   {"number_options", 0, (test_callback_fn)parser_number_options_test },
   {"randomly generated options", 0, (test_callback_fn)random_statement_build_test },
   {"prefix_key", 0, (test_callback_fn)parser_key_prefix_test },
   {"server", 0, (test_callback_fn)server_test },
-  {"servers", 0, (test_callback_fn)servers_test },
+  {"bad server strings", 0, (test_callback_fn)servers_bad_test },
+  {"server with weights", 0, (test_callback_fn)server_with_weight_test },
   {0, 0, (test_callback_fn)0}
 };
 
@@ -6302,9 +6320,7 @@ collection_st collection[] ={
   {0, 0, 0, 0}
 };
 
-#define SERVERS_TO_CREATE 5
-
-#include "libmemcached_world.h"
+#include "tests/libmemcached_world.h"
 
 void get_world(world_st *world)
 {