Adding gtest framework.
authorBrian Aker <brian@gaz>
Tue, 29 Jun 2010 22:04:05 +0000 (15:04 -0700)
committerBrian Aker <brian@gaz>
Tue, 29 Jun 2010 22:04:05 +0000 (15:04 -0700)
35 files changed:
.bzrignore
ChangeLog
Makefile.am
clients/execute.c
clients/execute.h
clients/generator.c
clients/memcat.c
clients/memcp.c
clients/memdump.c
clients/memerror.c
clients/memflush.c
clients/memrm.c
clients/memstat.c
clients/utilities.c
clients/utilities.h
libmemcached/behavior.c
libmemcached/common.h
libmemcached/connect.c
libmemcached/delete.c
libmemcached/include.am
libmemcached/io.c
libmemcached/util/version.c
libmemcached/util/version.h
m4/pandora_warnings.m4
tests/atomsmasher.c
tests/hashkit_functions.c
tests/include.am
tests/main.cc [deleted file]
tests/mem_functions.c
tests/mem_udp.c
tests/start.c
tests/test.c
unittests/include.am [new file with mode: 0644]
unittests/main.cc [new file with mode: 0644]
unittests/strings.cc [new file with mode: 0644]

index e28af860bad8ee84ce4753e5f9900b3dec5a3ace..ea78c2ef1c78cf4f788d1d4cf0a44097ea267005 100644 (file)
@@ -181,3 +181,4 @@ tests/testapp
 tests/testhashkit
 tests/testplus
 tests/testudp
+unittests/unittests
index 85cc97287c55b9fa32dd684ce38e9323661e7efd..608d492bc3e8583baede07c712d456158b54b80f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,9 @@
 0.41
   * Added --file for memcat.
   * Added limemcached_ping() to libmemcached_util
+  * Bugfix for some cases where connect would have issues with timeout.
+  * Wrong value for errno given as error on an IO failure inside of poll.
+  * Bug fix for issue where multiple interfaces with bad DNS were not being caught.
 
 0.40 Thu Apr 22 19:01:25 PDT 2010
   * Placed retry logic in for busted resolvers
index d855c8f493ba29053ac88e4af8f9605065283fea..38f87c5e76f02c643bba3927fb707831afb4ec89 100644 (file)
@@ -38,6 +38,7 @@ test-docs:
 include libmemcached/include.am
 include clients/include.am
 include libhashkit/include.am
+include unittests/include.am
 include tests/include.am
 include example/include.am
 include support/include.am
index daede9ec583edb4101a3cca5fd5db4cb52b0ff6b..0beaae4bd85229208b704568dac68f854ca435f2 100644 (file)
@@ -14,8 +14,7 @@
   Return the number of rows set.
 */
 
-#include "libmemcached/common.h"
-
+#include "config.h"
 #include "execute.h"
 
 unsigned int execute_set(memcached_st *memc, pairs_st *pairs, unsigned int number_of)
@@ -108,12 +107,11 @@ unsigned int execute_mget(memcached_st *memc,
   rc= memcached_mget_execute(memc, keys, key_length,
                              (size_t)number_of, callbacks, &retrieved, 1);
 
-  likely (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOTFOUND ||
+  if (rc == MEMCACHED_SUCCESS || rc == MEMCACHED_NOTFOUND ||
           rc == MEMCACHED_BUFFERED || rc == MEMCACHED_END)
   {
     rc= memcached_fetch_execute(memc, callbacks, (void *)&retrieved, 1);
-    unlikely (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_NOTFOUND &&
-              rc != MEMCACHED_END)
+    if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_NOTFOUND && rc != MEMCACHED_END)
     {
       fprintf(stderr, "Failed to execute mget: %s\n",
               memcached_strerror(memc, rc));
index ba54d8d2947294eff86dfb2e79088ad4ee7dbb12..176c6fff81d6ebe82aaafc318a1f92538ddae927 100644 (file)
@@ -11,6 +11,9 @@
 
 #ifndef CLIENTS_EXECUTE_H
 #define CLIENTS_EXECUTE_H
+
+#include <stdio.h>
+
 #include "libmemcached/memcached.h"
 #include "generator.h"
 
index 6e2f27953a5d48c50f88e3a8eb548240c64a386f..80b398b251df3a73b0f476f0439a91553f8951b1 100644 (file)
@@ -9,7 +9,7 @@
  *
  */
 
-#include "libmemcached/common.h"
+#include "config.h"
 
 #include <stdio.h>
 #include <stdlib.h>
index d0a6b38faf769e8e2a3c87b11d7c0a524f850555..f50b069dc53844095fe6a4c17a188eaafca8fb62 100644 (file)
@@ -9,7 +9,8 @@
  *
  */
 
-#include "libmemcached/common.h"
+#include "config.h"
+
 #include <stdio.h>
 #include <inttypes.h>
 #include <string.h>
index 1dc30631900eed71032fa4424c6201eceed8b9b0..df3ca77e315e46fa205955fcd880c11eee697af3 100644 (file)
@@ -9,7 +9,8 @@
  *
  */
 
-#include "libmemcached/common.h"
+#include "config.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
@@ -54,7 +55,7 @@ static long strtol_wrapper(const char *nptr, int base, bool *error)
 
   /* Check for various possible errors */
 
-  if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
+  if ((errno == ERANGE && (val == INTMAX_MAX || val == INTMAX_MIN))
       || (errno != 0 && val == 0))
   {
     *error= true;
index 40ab430a4ceca1a0b339569068c02b1b2173217e..3654be2b0d3a9f529b15e83cdfcf0a764be85845 100644 (file)
@@ -9,7 +9,8 @@
  *
  */
 
-#include "libmemcached/common.h"
+#include "config.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <inttypes.h>
index 286ef0e142b6630193b6a96b88032268d8bc6ea9..1ac091186f67f57436ce0041f1bc4226c2274675 100644 (file)
@@ -8,8 +8,8 @@
  * Summary:
  *
  */
+#include "config.h"
 
-#include "libmemcached/common.h"
 #include <stdio.h>
 #include <inttypes.h>
 #include <string.h>
index 4cce8cb0b0fb49d150a61f1018fe238f5395de8a..9f2b57c65ff9ba2fff11ba793a1b31d274316f64 100644 (file)
@@ -8,8 +8,8 @@
  * Summary:
  *
  */
+#include "config.h"
 
-#include "libmemcached/common.h"
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
index dfb2c2fbe00a074b01086ee65ca41f91e03c84df..c5637608786f0a886182a11d9e26a5c366ed5e42 100644 (file)
@@ -8,8 +8,8 @@
  * Summary:
  *
  */
+#include "config.h"
 
-#include "libmemcached/common.h"
 #include <stdio.h>
 #include <unistd.h>
 #include <getopt.h>
index db96364e7dcffbd91d35f7bef1f2649c63694396..510cb359937e5702ed2721ca988d234df50ae2a0 100644 (file)
@@ -11,8 +11,8 @@
  *          Brian Aker
  *          Toru Maesaka
  */
+#include "config.h"
 
-#include "libmemcached/common.h"
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
index 6353ff6b97e8b0894195c4b44353bb451613a044..de2bdf442eba9a866c84485b36b060d12598216a 100644 (file)
@@ -8,8 +8,8 @@
  * Summary:
  *
  */
+#include "config.h"
 
-#include "libmemcached/common.h"
 #include <stdio.h>
 #include <ctype.h>
 #include <string.h>
index 162366ab82d48403cbb11dc1b92c9254b56d0719..f74626480028cade60eb37128ac6c8ef3c5715dc 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <getopt.h>
 #include <libmemcached/memcached.h>
+#include "libmemcached/watchpoint.h"
 #include "client_options.h"
 
 #if TIME_WITH_SYS_TIME
index f1573b608653e86dc0629b4438736130c835fcde..2f5311e5a01ddac70d96cc9c36576983d3b66f79 100644 (file)
@@ -55,6 +55,7 @@ memcached_return_t memcached_behavior_set(memcached_st *ptr,
     ptr->server_failure_limit= (uint32_t)data;
     break;
   case MEMCACHED_BEHAVIOR_BINARY_PROTOCOL:
+    memcached_quit(ptr); // We need t shutdown all of the connections to make sure we do the correct protocol
     if (data)
     {
       ptr->flags.verify_key= false;
index bfbc9220950569b45fddc320d22cb4b503b3b402..b45bf80791ac83de883cbbd239145dcabfefee20 100644 (file)
@@ -79,7 +79,7 @@ struct memcached_continuum_item_st
 typedef enum {
   MEM_NOT= -1,
   MEM_FALSE= false,
-  MEM_TRUE= true,
+  MEM_TRUE= true
 } memcached_ternary_t;
 
 
index a43de9563a89d2017b4658a3404abc8ad534bfd8..84423702cf992655971b5adc86b1109ec17bf0f6 100644 (file)
@@ -1,9 +1,96 @@
+/* LibMemcached
+ * Copyright (C) 2006-2010 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in the parent directory for full text.
+ *
+ * Summary: Server IO, Not public!
+ *
+ */
+
 #include "common.h"
 #include <netdb.h>
 #include <poll.h>
 #include <sys/time.h>
 #include <time.h>
 
+static memcached_return_t connect_poll(memcached_server_st *ptr)
+{
+  struct pollfd fds[1];
+  fds[0].fd = ptr->fd;
+  fds[0].events = POLLOUT;
+
+  int timeout= ptr->root->connect_timeout;
+  if (ptr->root->flags.no_block == true)
+    timeout= -1;
+
+  int error;
+  size_t loop_max= 5;
+
+  while (--loop_max) // Should only loop on cases of ERESTART or EINTR
+  {
+    error= poll(fds, 1, timeout);
+
+    switch (error)
+    {
+    case 1:
+      {
+        int err;
+        socklen_t len= sizeof (err);
+        (void)getsockopt(ptr->fd, SOL_SOCKET, SO_ERROR, &err, &len);
+
+        // We check the value to see what happened wth the socket.
+        if (err == 0)
+        {
+          return MEMCACHED_SUCCESS;
+        }
+        else
+        {
+          ptr->cached_errno= errno;
+
+          return MEMCACHED_ERRNO;
+        }
+      }
+    case 0:
+      return MEMCACHED_TIMEOUT;
+    default: // A real error occurred and we need to completely bail
+      WATCHPOINT_ERRNO(errno);
+      switch (errno)
+      {
+#ifdef TARGET_OS_LINUX
+      case ERESTART:
+#endif
+      case EINTR:
+        continue;
+      default:
+        if (fds[0].revents & POLLERR)
+        {
+          int err;
+          socklen_t len= sizeof (err);
+          (void)getsockopt(ptr->fd, SOL_SOCKET, SO_ERROR, &err, &len);
+          ptr->cached_errno= (err == 0) ? errno : err;
+        }
+        else
+        {
+          ptr->cached_errno= errno;
+        }
+
+        (void)close(ptr->fd);
+        ptr->fd= -1;
+
+        return MEMCACHED_ERRNO;
+      }
+    }
+    WATCHPOINT_ASSERT(0); // Programming error
+  }
+
+  // This should only be possible from ERESTART or EINTR;
+  ptr->cached_errno= errno;
+
+  return MEMCACHED_ERRNO;
+}
+
 static memcached_return_t set_hostinfo(memcached_server_st *server)
 {
   struct addrinfo *ai;
@@ -225,36 +312,35 @@ static memcached_return_t unix_socket_connect(memcached_server_st *ptr)
 {
   struct sockaddr_un servAddr;
 
-  if (ptr->fd == -1)
+  WATCHPOINT_ASSERT(ptr->fd == -1);
+
+  if ((ptr->fd= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
   {
-    if ((ptr->fd= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
-    {
-      ptr->cached_errno= errno;
-      return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE;
-    }
+    ptr->cached_errno= errno;
+    return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE;
+  }
 
-    memset(&servAddr, 0, sizeof (struct sockaddr_un));
-    servAddr.sun_family= AF_UNIX;
-    strcpy(servAddr.sun_path, ptr->hostname); /* Copy filename */
+  memset(&servAddr, 0, sizeof (struct sockaddr_un));
+  servAddr.sun_family= AF_UNIX;
+  strcpy(servAddr.sun_path, ptr->hostname); /* Copy filename */
 
 test_connect:
-    if (connect(ptr->fd,
-                (struct sockaddr *)&servAddr,
-                sizeof(servAddr)) < 0)
+  if (connect(ptr->fd,
+              (struct sockaddr *)&servAddr,
+              sizeof(servAddr)) < 0)
+  {
+    switch (errno)
     {
-      switch (errno)
-      {
-      case EINPROGRESS:
-      case EALREADY:
-      case EINTR:
-        goto test_connect;
-      case EISCONN: /* We were spinning waiting on connect */
-        break;
-      default:
-        WATCHPOINT_ERRNO(errno);
-        ptr->cached_errno= errno;
-        return MEMCACHED_ERRNO;
-      }
+    case EINPROGRESS:
+    case EALREADY:
+    case EINTR:
+      goto test_connect;
+    case EISCONN: /* We were spinning waiting on connect */
+      break;
+    default:
+      WATCHPOINT_ERRNO(errno);
+      ptr->cached_errno= errno;
+      return MEMCACHED_ERRNO;
     }
   }
 
@@ -265,134 +351,78 @@ test_connect:
 
 static memcached_return_t network_connect(memcached_server_st *ptr)
 {
-  if (ptr->fd == -1)
+  bool timeout_error_occured= false;
+
+  
+  WATCHPOINT_ASSERT(ptr->fd == -1);
+  WATCHPOINT_ASSERT(ptr->cursor_active == 0);
+
+  if (! ptr->options.sockaddr_inited || (!(ptr->root->flags.use_cache_lookups)))
   {
-    struct addrinfo *use;
+    memcached_return_t rc;
 
-    WATCHPOINT_ASSERT(ptr->cursor_active == 0);
+    rc= set_hostinfo(ptr);
+    if (rc != MEMCACHED_SUCCESS)
+      return rc;
+    ptr->options.sockaddr_inited= true;
+  }
 
-    if (! ptr->options.sockaddr_inited ||
-        (!(ptr->root->flags.use_cache_lookups)))
+  struct addrinfo *use= ptr->address_info;
+  /* Create the socket */
+  while (use != NULL)
+  {
+    /* Memcache server does not support IPV6 in udp mode, so skip if not ipv4 */
+    if (ptr->type == MEMCACHED_CONNECTION_UDP && use->ai_family != AF_INET)
     {
-      memcached_return_t rc;
-
-      rc= set_hostinfo(ptr);
-      if (rc != MEMCACHED_SUCCESS)
-        return rc;
-      ptr->options.sockaddr_inited= true;
+      use= use->ai_next;
+      continue;
     }
 
-    use= ptr->address_info;
-    /* Create the socket */
-    while (use != NULL)
+    if ((ptr->fd= socket(use->ai_family,
+                         use->ai_socktype,
+                         use->ai_protocol)) < 0)
     {
-      /* Memcache server does not support IPV6 in udp mode, so skip if not ipv4 */
-      if (ptr->type == MEMCACHED_CONNECTION_UDP && use->ai_family != AF_INET)
-      {
-        use= use->ai_next;
-        continue;
-      }
-
-      if ((ptr->fd= socket(use->ai_family,
-                           use->ai_socktype,
-                           use->ai_protocol)) < 0)
-      {
-        ptr->cached_errno= errno;
-        WATCHPOINT_ERRNO(errno);
-        return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE;
-      }
-
-      (void)set_socket_options(ptr);
+      ptr->cached_errno= errno;
+      WATCHPOINT_ERRNO(errno);
+      return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE;
+    }
 
-      /* connect to server */
-      if ((connect(ptr->fd, use->ai_addr, use->ai_addrlen) == -1))
-      {
-        ptr->cached_errno= errno;
-        if (errno == EINPROGRESS || /* nonblocking mode - first return, */
-            errno == EALREADY) /* nonblocking mode - subsequent returns */
-        {
-          struct pollfd fds[1];
-          fds[0].fd = ptr->fd;
-          fds[0].events = POLLOUT;
-
-          int timeout= ptr->root->connect_timeout;
-          if (ptr->root->flags.no_block == true)
-            timeout= -1;
-
-          size_t loop_max= 5;
-          while (--loop_max)
-          {
-            int error= poll(fds, 1, timeout);
-
-            switch (error)
-            {
-            case 1:
-              loop_max= 1;
-              break;
-            case 0:
-              if (loop_max==1) 
-                return MEMCACHED_TIMEOUT;
-              continue;
-              // A real error occurred and we need to completely bail
-            default:
-              WATCHPOINT_ERRNO(errno);
-              switch (errno)
-              {
-#ifdef TARGET_OS_LINUX
-              case ERESTART:
-#endif
-              case EINTR:
-                continue;
-              default:
-                if (fds[0].revents & POLLERR)
-                {
-                  int err;
-                  socklen_t len= sizeof (err);
-                  (void)getsockopt(ptr->fd, SOL_SOCKET, SO_ERROR, &err, &len);
-                  ptr->cached_errno= (err == 0) ? errno : err;
-                }
-
-                (void)close(ptr->fd);
-                ptr->fd= -1;
-
-                break;
-              }
-            }
-          }
-        }
-        else if (errno == EISCONN) /* we are connected :-) */
-        {
-          break;
-        }
-        else if (errno != EINTR)
-        {
-          (void)close(ptr->fd);
-          ptr->fd= -1;
-          break;
-        }
-      }
+    (void)set_socket_options(ptr);
 
-#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
-      if (ptr->fd != -1 && ptr->root->sasl && ptr->root->sasl->callbacks)
-      {
-        memcached_return rc= memcached_sasl_authenticate_connection(ptr);
-        if (rc != MEMCACHED_SUCCESS)
-        {
-          (void)close(ptr->fd);
-          ptr->fd= -1;
+    /* connect to server */
+    if ((connect(ptr->fd, use->ai_addr, use->ai_addrlen) > -1))
+    {
+      break; // Success
+    }
 
-          return rc;
-        }
-      }
-#endif
+    /* An error occurred */
+    ptr->cached_errno= errno;
+    if (errno == EINPROGRESS || /* nonblocking mode - first return, */
+        errno == EALREADY) /* nonblocking mode - subsequent returns */
+    {
+      memcached_return_t rc;
+      rc= connect_poll(ptr);
 
+      if (rc == MEMCACHED_TIMEOUT)
+        timeout_error_occured= true;
 
-      if (ptr->fd != -1)
-      {
-        return MEMCACHED_SUCCESS;
-      }
-      use = use->ai_next;
+      if (rc == MEMCACHED_SUCCESS)
+        break;
+    }
+    else if (errno == EISCONN) /* we are connected :-) */
+    {
+      break;
     }
+    else if (errno == EINTR) // Special case, we retry ai_addr
+    {
+      (void)close(ptr->fd);
+      ptr->fd= -1;
+      continue;
+    }
+
+    (void)close(ptr->fd);
+    ptr->fd= -1;
+    use= use->ai_next;
   }
 
   if (ptr->fd == -1)
@@ -408,7 +438,7 @@ static memcached_return_t network_connect(memcached_server_st *ptr)
         ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout;
     }
 
-    if (ptr->cached_errno == 0)
+    if (timeout_error_occured)
       return MEMCACHED_TIMEOUT;
 
     return MEMCACHED_ERRNO; /* The last error should be from connect() */
@@ -435,6 +465,10 @@ void set_last_disconnected_host(memcached_server_write_instance_st ptr)
 memcached_return_t memcached_connect(memcached_server_write_instance_st ptr)
 {
   memcached_return_t rc= MEMCACHED_NO_SERVERS;
+
+  if (ptr->fd > -1)
+    return MEMCACHED_SUCCESS;
+
   LIBMEMCACHED_MEMCACHED_CONNECT_START();
 
   /* both retry_timeout and server_failure_limit must be set in order to delay retrying a server on error. */
@@ -481,6 +515,17 @@ memcached_return_t memcached_connect(memcached_server_write_instance_st ptr)
   case MEMCACHED_CONNECTION_UDP:
   case MEMCACHED_CONNECTION_TCP:
     rc= network_connect(ptr);
+#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
+    if (ptr->fd != -1 && ptr->root->sasl && ptr->root->sasl->callbacks)
+    {
+      rc= memcached_sasl_authenticate_connection(ptr);
+      if (rc != MEMCACHED_SUCCESS)
+      {
+        (void)close(ptr->fd);
+        ptr->fd= -1;
+      }
+    }
+#endif
     break;
   case MEMCACHED_CONNECTION_UNIX_SOCKET:
     rc= unix_socket_connect(ptr);
index 2af6e159154403961540baa80c5bb6ecdd62d870..70553d94e651112b217fea5cf535b18b0ebc17ab 100644 (file)
@@ -45,7 +45,7 @@ memcached_return_t memcached_delete_by_key(memcached_st *ptr,
 
   if (ptr->flags.binary_protocol)
   {
-    likely (!expiration)
+    likely (! expiration)
     {
       rc= binary_delete(ptr, server_key, key, key_length, to_write);
     }
index 3321a4f6ca46e61afcf53f744bde8f7d70c75d99..123b1af3f4660c7720d3b7690c4cb64b766aa14d 100644 (file)
@@ -158,6 +158,7 @@ endif
 if DTRACE_NEEDS_OBJECTS
 libmemcached_libmemcached_la_SOURCES += libmemcached/libmemcached_probes.d
 libmemcached_libmemcached_la_DEPENDENCIES += libmemcached/libmemcached_probes.o
+CLEANFILES+= libmemcached/libmemcached_probes.o
 endif
 
 SUFFIXES+= .d
@@ -165,7 +166,7 @@ SUFFIXES+= .d
 libmemcached/dtrace_probes.h: libmemcached/libmemcached_probes.d
        $(DTRACE) $(DTRACEFLAGS) -h -o libmemcached/dtrace_probes.h -s ${top_srcdir}/libmemcached/libmemcached_probes.d
 
-libmemcached/libmemcached_probes.o: libmemcached/libmemcached_probes.d ${libmemcached_libmemcached_OBJECTS} config.h
+libmemcached/libmemcached_probes.o: libmemcached/libmemcached_probes.d ${libmemcached_libmemcached_la_OBJECTS} config.h
 
 .d.o:
        $(DTRACE) $(DTRACEFLAGS) -o libmemcached/libmemcached_probes.o -G -s ${top_srcdir}/libmemcached/libmemcached_probes.d `grep '^pic_object' ${top_builddir}/libmemcached/*.lo | cut -f 2 -d\' | sed "s/^/${top_builddir}\//"`
index d6129b850f909862c8d8a24529f7c11fd4f60cae..30a2a1a4921396a967b71bd92bda79ec57ce3bb6 100644 (file)
@@ -62,45 +62,50 @@ static memcached_return_t io_wait(memcached_server_write_instance_st ptr,
     timeout= -1;
 
   size_t loop_max= 5;
-  while (--loop_max)
+  while (--loop_max) // While loop is for ERESTART or EINTR
   {
     error= poll(&fds, 1, timeout);
 
     switch (error)
     {
-    case 1:
+    case 1: // Success!
       WATCHPOINT_IF_LABELED_NUMBER(read_or_write && loop_max < 4, "read() times we had to loop, decremented down from 5", loop_max);
       WATCHPOINT_IF_LABELED_NUMBER(!read_or_write && loop_max < 4, "write() times we had to loop, decremented down from 5", loop_max);
 
       return MEMCACHED_SUCCESS;
-    case 0:
+    case 0: // Timeout occured, we let the while() loop do its thing.
       return MEMCACHED_TIMEOUT;
     default:
       WATCHPOINT_ERRNO(errno);
+      switch (errno)
       {
-        switch (errno)
-        {
 #ifdef TARGET_OS_LINUX
-        case ERESTART:
+      case ERESTART:
 #endif
-        case EINTR:
-          continue;
-        default:
-          ptr->cached_errno= error;
-          memcached_quit_server(ptr, true);
-
-          return MEMCACHED_FAILURE;
+      case EINTR:
+        break;
+      default:
+        if (fds.revents & POLLERR)
+        {
+          int err;
+          socklen_t len= sizeof (err);
+          (void)getsockopt(ptr->fd, SOL_SOCKET, SO_ERROR, &err, &len);
+          ptr->cached_errno= (err == 0) ? errno : err;
         }
+        else
+        {
+          ptr->cached_errno= errno;
+        }
+        memcached_quit_server(ptr, true);
+
+        return MEMCACHED_FAILURE;
       }
     }
   }
 
-  if (loop_max == 0 && error == 0)
-    return MEMCACHED_TIMEOUT;
-
   /* Imposssible for anything other then -1 */
   WATCHPOINT_ASSERT(error == -1);
-  ptr->cached_errno= error;
+  ptr->cached_errno= errno;
   memcached_quit_server(ptr, true);
 
   return MEMCACHED_FAILURE;
index 000db326cc8b87f2c8fddc8efa6937602e86f3d1..e5b5ae1df8f17ec965826b259e6524d4ce49e2f5 100644 (file)
@@ -16,8 +16,8 @@
 struct local_context
 {
   uint8_t major_version;
-  uint8_t micro_version;
   uint8_t minor_version;
+  uint8_t micro_version;
 
   bool truth;
 };
@@ -30,8 +30,8 @@ static memcached_return_t check_server_version(const memcached_st *ptr __attribu
   struct local_context *check= (struct local_context *)context;
 
   if (instance->major_version >= check->major_version &&
-      instance->micro_version >= check->micro_version &&
-      instance->minor_version >= check->minor_version)
+      instance->minor_version >= check->minor_version &&
+      instance->micro_version >= check->micro_version )
   {
     return MEMCACHED_SUCCESS;
   }
@@ -43,13 +43,13 @@ static memcached_return_t check_server_version(const memcached_st *ptr __attribu
 
 bool libmemcached_util_version_check(memcached_st *memc, 
                                      uint8_t major_version,
-                                     uint8_t micro_version,
-                                     uint8_t minor_version)
+                                     uint8_t minor_version,
+                                     uint8_t micro_version)
 {
   memcached_server_fn callbacks[1];
   memcached_version(memc);
 
- struct local_context check= { .major_version= major_version, .micro_version= micro_version, .minor_version= minor_version, .truth= true };
+ struct local_context check= { .major_version= major_version, .minor_version= minor_version, .micro_version= micro_version, .truth= true };
 
   callbacks[0]= check_server_version;
   memcached_server_cursor(memc, callbacks, (void *)&check,  1);
index 7d0b026074db49147f1684d56737612c0055b231..57be9b856ba599f733b79253319e08073044cddf 100644 (file)
@@ -19,8 +19,8 @@ extern "C" {
 LIBMEMCACHED_API
   bool libmemcached_util_version_check(memcached_st *memc, 
                                        uint8_t major_version,
-                                       uint8_t micro_version,
-                                       uint8_t minor_version);
+                                       uint8_t minor_version,
+                                       uint8_t micro_version);
 
 #ifdef __cplusplus
 }
index 1731870d6f94fc28b17548305660724194103220..9ee365a023537af1539f10a425170aa3c9f76ca9 100644 (file)
@@ -145,7 +145,7 @@ uint16_t x= htons(80);
       m4_if(PW_LESS_WARNINGS,[no],[
         BASE_WARNINGS_FULL="-Wformat=2 ${W_CONVERSION} -Wstrict-aliasing"
         CC_WARNINGS_FULL="-Wswitch-default -Wswitch-enum -Wwrite-strings"
-        CXX_WARNINGS_FULL="-Weffc++ -Wold-style-cast"
+        CXX_WARNINGS_FULL="-Wold-style-cast"
         NO_OLD_STYLE_CAST="-Wno-old-style-cast"
         NO_EFF_CXX="-Wno-effc++"
       ],[
index b7e5924e0d2a364041e061c124bc9930c22b3710..a7e49c91c119259ff98359b4e3736835442a6c9c 100644 (file)
 /*
   Sample test application.
 */
-#include "libmemcached/common.h"
+#include "config.h"
+
+#include "libmemcached/memcached.h"
+#include "libmemcached/watchpoint.h"
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <string.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #include "../clients/generator.h"
 #include "../clients/execute.h"
 
-#ifndef INT64_MAX
-#define INT64_MAX LONG_MAX
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX INT_MAX
-#endif
-
-
 #include "test.h"
 
 /* Number of items generated for tests */
index 842f511f0f34db0a21426f8d4f0bef69adb562c0..46f53934d7d48fc71ff9f646847c1370aa5ef7ed 100644 (file)
@@ -6,6 +6,8 @@
  * the COPYING file in the parent directory for full text.
  */
 
+#include "config.h"
+
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
index 21450f6df26178039889229c793f144f223fc2c4..3631a81e25713fc083b4b2d24ff9f2b33a3ab866 100644 (file)
@@ -10,10 +10,6 @@ DEBUG_COMMAND= $(LIBTOOL) --mode=execute gdb
 
 PAHOLE_COMMAND= $(LIBTOOL) --mode=execute pahole
 
-if HAVE_LIBGTEST
-check_PROGRAMS += tests/unittests
-endif
-
 if BUILD_LIBMEMCACHEDUTIL
 TESTS_LDADDS+= libmemcached/libmemcachedutil.la
 endif
@@ -42,16 +38,10 @@ tests_libserver_la_SOURCES= tests/server.c
 noinst_LTLIBRARIES+= tests/libtest.la
 tests_libtest_la_SOURCES= tests/test.c
 
-tests_unittests_SOURCES= \
-                        tests/main.cc
-tests_unittests_LDADD= \
-                      tests/libserver.la \
-                      libmemcached/libmemcachedinternal.la \
-                      ${TESTS_LDADDS} ${LTLIBGTEST}
-
 tests_testapp_CFLAGS= $(AM_CFLAGS) $(NO_CONVERSION) $(NO_STRICT_ALIASING)
 tests_testapp_SOURCES= tests/mem_functions.c
 tests_testapp_DEPENDENCIES= \
+                           $(BUILT_SOURCES) \
                            clients/libgenexec.la \
                            tests/libserver.la \
                            tests/libtest.la \
@@ -99,7 +89,7 @@ tests_memplus_CXXFLAGS = $(AM_CXXFLAGS) $(NO_EFF_CXX)
 tests_memplus_DEPENDENCIES = tests/libtest.la tests/libserver.la libmemcached/libmemcached.la
 tests_memplus_LDADD = $(tests_memplus_DEPENDENCIES)
 
-test: test-docs test-mem test-hash memcapable
+test: unittests-run test-docs test-mem test-hash memcapable
        echo "Tests completed"
 
 test-x: test-docs test-plus test-mem test-hash memcapable test-memcat test-memcp test-memrm test-memerror test-memdump test-memflush test-memstat
diff --git a/tests/main.cc b/tests/main.cc
deleted file mode 100644 (file)
index 7e575c3..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
- *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- *
- *  Copyright (C) 2010 Monty Taylor
- *
- *  All rights reserved.
- *
- *  Use and distribution licensed under the BSD license.  See
- *  the COPYING file in the parent directory for full text.
- */
-
-#include "config.h"
-
-#include <gtest/gtest.h>
-
-
-int main(int argc, char **argv)
-{
-  ::testing::InitGoogleTest(&argc, argv);
-  return RUN_ALL_TESTS();
-}
index e12ad3f7d9a70a6ef4977b040370300f2f50332d..ba555111134fa4fd97b847bee43f98318419eb10 100644 (file)
   Sample test application.
 */
 
-#include "libmemcached/common.h"
+#include "config.h"
 
 #include <assert.h>
 #include <stdio.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/time.h>
 #include <signal.h>
 #include <unistd.h>
 #include <time.h>
+
+#include "libmemcached/common.h"
+
 #include "server.h"
 #include "clients/generator.h"
 #include "clients/execute.h"
 
-#ifndef INT64_MAX
-#define INT64_MAX LONG_MAX
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX INT_MAX
-#endif
-
+#define SMALL_STRING_LEN 1024
 
 #include "test.h"
 
+
 #ifdef HAVE_LIBMEMCACHEDUTIL
 #include <pthread.h>
 #include "libmemcached/memcached_util.h"
@@ -682,7 +681,6 @@ static test_return_t add_test(memcached_st *memc)
 */
 static test_return_t add_wrapper(memcached_st *memc)
 {
-  unsigned int x;
   unsigned int max= 10000;
 #ifdef __sun
   max= 10;
@@ -691,7 +689,7 @@ static test_return_t add_wrapper(memcached_st *memc)
   max= 10;
 #endif
 
-  for (x= 0; x < max; x++)
+  for (uint32_t x= 0; x < max; x++)
     add_test(memc);
 
   return TEST_SUCCESS;
@@ -3599,7 +3597,7 @@ static test_return_t pre_nonblock_binary(memcached_st *memc)
   // will not toggle protocol on an connection.
   memcached_version(memc_clone);
 
-  if (libmemcached_util_version_check(memc_clone, 1, 2, 0))
+  if (libmemcached_util_version_check(memc_clone, 1, 3, 0))
   {
     memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0);
     rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
@@ -3724,23 +3722,14 @@ static test_return_t pre_behavior_ketama_weighted(memcached_st *memc)
 static test_return_t pre_binary(memcached_st *memc)
 {
   memcached_return_t rc= MEMCACHED_FAILURE;
-  memcached_st *memc_clone;
 
-  memc_clone= memcached_clone(NULL, memc);
-  test_true(memc_clone);
-  // The memcached_version needs to be done on a clone, because the server
-  // will not toggle protocol on an connection.
-  memcached_version(memc_clone);
-
-  if (libmemcached_util_version_check(memc_clone, 1, 2, 0))
+  if (libmemcached_util_version_check(memc, 1, 3, 0))
   {
     rc = memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1);
     test_true(rc == MEMCACHED_SUCCESS);
     test_true(memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) == 1);
   }
 
-  memcached_free(memc_clone);
-
   return rc == MEMCACHED_SUCCESS ? TEST_SUCCESS : TEST_SKIPPED;
 }
 
@@ -4432,24 +4421,24 @@ static test_return_t util_version_test(memcached_st *memc)
   memcached_version(memc);
 
   // We only use one binary when we test, so this should be just fine.
-  if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->micro_version, instance->minor_version);
+  if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version);
   test_true(if_successful == true);
 
-  if (instance->minor_version > 0)
-    if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->micro_version, instance->minor_version -1);
-  else if (instance->micro_version > 0)
-    if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->micro_version - 1, instance->minor_version);
+  if (instance->micro_version > 0)
+    if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version -1);
+  else if (instance->minor_version > 0)
+    if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version - 1, instance->micro_version);
   else if (instance->major_version > 0)
-    if_successful= libmemcached_util_version_check(memc, instance->major_version -1, instance->micro_version, instance->minor_version);
+    if_successful= libmemcached_util_version_check(memc, instance->major_version -1, instance->minor_version, instance->micro_version);
 
   test_true(if_successful == true);
 
-  if (instance->minor_version > 0)
-    if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->micro_version, instance->minor_version +1);
-  else if (instance->micro_version > 0)
-    if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->micro_version +1, instance->minor_version);
+  if (instance->micro_version > 0)
+    if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version, instance->micro_version +1);
+  else if (instance->minor_version > 0)
+    if_successful= libmemcached_util_version_check(memc, instance->major_version, instance->minor_version +1, instance->micro_version);
   else if (instance->major_version > 0)
-    if_successful= libmemcached_util_version_check(memc, instance->major_version +1, instance->micro_version, instance->minor_version);
+    if_successful= libmemcached_util_version_check(memc, instance->major_version +1, instance->minor_version, instance->micro_version);
 
   test_true(if_successful == false);
 
@@ -5018,7 +5007,7 @@ static test_return_t memcached_get_hashkit_test (memcached_st *memc)
   We are testing the error condition when we connect to a server via memcached_get() 
   but find that the server is not available.
 */
-static test_return_t memcached_get_MEMCACHED_SOME_ERRORS(memcached_st *memc)
+static test_return_t memcached_get_MEMCACHED_ERRNO(memcached_st *memc)
 {
   (void)memc;
   memcached_st *tl_memc_h;
@@ -5032,7 +5021,7 @@ static test_return_t memcached_get_MEMCACHED_SOME_ERRORS(memcached_st *memc)
 
   // Create a handle.
   tl_memc_h= memcached_create(NULL);
-  servers= memcached_servers_parse("localhost:9898"); // This server should not exist
+  servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
   memcached_server_push(tl_memc_h, servers);
   memcached_server_list_free(servers);
 
@@ -5046,7 +5035,7 @@ static test_return_t memcached_get_MEMCACHED_SOME_ERRORS(memcached_st *memc)
   }
 
   test_true(len == 0);
-  test_true(rc == MEMCACHED_SOME_ERRORS);
+  test_true(rc == MEMCACHED_ERRNO);
 
   return TEST_SUCCESS;
 }
@@ -5083,7 +5072,7 @@ static test_return_t memcached_get_MEMCACHED_NOTFOUND(memcached_st *memc)
   We are testing the error condition when we connect to a server via memcached_get_by_key() 
   but find that the server is not available.
 */
-static test_return_t memcached_get_by_key_MEMCACHED_SOME_ERRORS(memcached_st *memc)
+static test_return_t memcached_get_by_key_MEMCACHED_ERRNO(memcached_st *memc)
 {
   (void)memc;
   memcached_st *tl_memc_h;
@@ -5097,7 +5086,7 @@ static test_return_t memcached_get_by_key_MEMCACHED_SOME_ERRORS(memcached_st *me
 
   // Create a handle.
   tl_memc_h= memcached_create(NULL);
-  servers= memcached_servers_parse("localhost:9898"); // This server should not exist
+  servers= memcached_servers_parse("localhost:9898,localhost:9899"); // This server should not exist
   memcached_server_push(tl_memc_h, servers);
   memcached_server_list_free(servers);
 
@@ -5111,7 +5100,7 @@ static test_return_t memcached_get_by_key_MEMCACHED_SOME_ERRORS(memcached_st *me
   }
 
   test_true(len == 0);
-  test_true(rc == MEMCACHED_SOME_ERRORS);
+  test_true(rc == MEMCACHED_ERRNO);
 
   return TEST_SUCCESS;
 }
@@ -5575,54 +5564,58 @@ static test_return_t regression_bug_447342(memcached_st *memc)
 
 static test_return_t regression_bug_463297(memcached_st *memc)
 {
-  memcached_st *memc_clone= memcached_clone(NULL, memc);
-  test_true(memc_clone != NULL);
-  test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS);
+  memcached_st *memc_clone= memcached_clone(NULL, memc); 
+  test_true(memc_clone != NULL); 
+  test_true(memcached_version(memc_clone) == MEMCACHED_SUCCESS); 
 
+  memcached_server_instance_st instance= 
+    memcached_server_instance_by_position(memc_clone, 0); 
 
-  if (libmemcached_util_version_check(memc_clone, 1, 1, 2))
+  if (instance->major_version > 1 || 
+      (instance->major_version == 1 && 
+       instance->minor_version > 2)) 
   {
-     /* Binary protocol doesn't support deferred delete */
-     memcached_st *bin_clone= memcached_clone(NULL, memc);
-     test_true(bin_clone != NULL);
-     test_true(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS);
-     test_true(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
-     memcached_free(bin_clone);
+    /* Binary protocol doesn't support deferred delete */
+    memcached_st *bin_clone= memcached_clone(NULL, memc);
+    test_true(bin_clone != NULL);
+    test_true(memcached_behavior_set(bin_clone, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1) == MEMCACHED_SUCCESS);
+    test_true(memcached_delete(bin_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
+    memcached_free(bin_clone);
 
-     memcached_quit(memc_clone);
+    memcached_quit(memc_clone);
 
-     /* If we know the server version, deferred delete should fail
-      * with invalid arguments */
-     test_true(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
+    /* If we know the server version, deferred delete should fail
+     * with invalid arguments */
+    test_true(memcached_delete(memc_clone, "foo", 3, 1) == MEMCACHED_INVALID_ARGUMENTS);
 
-     /* If we don't know the server version, we should get a protocol error */
-     memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
+    /* If we don't know the server version, we should get a protocol error */
+    memcached_return_t rc= memcached_delete(memc, "foo", 3, 1);
 
-     /* but there is a bug in some of the memcached servers (1.4) that treats
-      * the counter as noreply so it doesn't send the proper error message
-      */
-     test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
+    /* but there is a bug in some of the memcached servers (1.4) that treats
+     * the counter as noreply so it doesn't send the proper error message
+   */
+    test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
 
-     /* And buffered mode should be disabled and we should get protocol error */
-     test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
-     rc= memcached_delete(memc, "foo", 3, 1);
-     test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
+    /* And buffered mode should be disabled and we should get protocol error */
+    test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 1) == MEMCACHED_SUCCESS);
+    rc= memcached_delete(memc, "foo", 3, 1);
+    test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
 
-     /* Same goes for noreply... */
-     test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS);
-     rc= memcached_delete(memc, "foo", 3, 1);
-     test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
+    /* Same goes for noreply... */
+    test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 1) == MEMCACHED_SUCCESS);
+    rc= memcached_delete(memc, "foo", 3, 1);
+    test_true(rc == MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_NOTFOUND || rc == MEMCACHED_CLIENT_ERROR);
 
-     /* but a normal request should go through (and be buffered) */
-     test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED);
-     test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
+    /* but a normal request should go through (and be buffered) */
+    test_true((rc= memcached_delete(memc, "foo", 3, 0)) == MEMCACHED_BUFFERED);
+    test_true(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
 
-     test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS);
-     /* unbuffered noreply should be success */
-     test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS);
-     /* unbuffered with reply should be not found... */
-     test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS);
-     test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND);
+    test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BUFFER_REQUESTS, 0) == MEMCACHED_SUCCESS);
+    /* unbuffered noreply should be success */
+    test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_SUCCESS);
+    /* unbuffered with reply should be not found... */
+    test_true(memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NOREPLY, 0) == MEMCACHED_SUCCESS);
+    test_true(memcached_delete(memc, "foo", 3, 0) == MEMCACHED_NOTFOUND);
   }
 
   memcached_free(memc_clone);
@@ -6080,6 +6073,7 @@ static test_return_t sasl_auth_test(memcached_st *memc)
 
 /* Clean the server before beginning testing */
 test_st tests[] ={
+  {"util_version", 1, (test_callback_fn)util_version_test },
   {"flush", 0, (test_callback_fn)flush_test },
   {"init", 0, (test_callback_fn)init_test },
   {"allocation", 0, (test_callback_fn)allocation_test },
@@ -6135,7 +6129,6 @@ test_st tests[] ={
 #ifdef HAVE_LIBMEMCACHEDUTIL
   {"connectionpool", 1, (test_callback_fn)connection_pool_test },
   {"ping", 1, (test_callback_fn)ping_test },
-  {"util_version", 1, (test_callback_fn)util_version_test },
 #endif
   {"test_get_last_disconnect", 1, (test_callback_fn)test_get_last_disconnect},
   {"verbosity", 1, (test_callback_fn)test_verbosity},
@@ -6332,9 +6325,9 @@ test_st hash_tests[] ={
 };
 
 test_st error_conditions[] ={
-  {"memcached_get_MEMCACHED_SOME_ERRORS", 0, (test_callback_fn)memcached_get_MEMCACHED_SOME_ERRORS },
+  {"memcached_get_MEMCACHED_ERRNO", 0, (test_callback_fn)memcached_get_MEMCACHED_ERRNO },
   {"memcached_get_MEMCACHED_NOTFOUND", 0, (test_callback_fn)memcached_get_MEMCACHED_NOTFOUND },
-  {"memcached_get_by_key_MEMCACHED_SOME_ERRORS", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_SOME_ERRORS },
+  {"memcached_get_by_key_MEMCACHED_ERRNO", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_ERRNO },
   {"memcached_get_by_key_MEMCACHED_NOTFOUND", 0, (test_callback_fn)memcached_get_by_key_MEMCACHED_NOTFOUND },
   {0, 0, (test_callback_fn)0}
 };
index 5a41c53a58d3065e3676e598764cb83f34855da2..76aab981a3e21f90198bd83251ca47032154c001 100644 (file)
   Sample test application.
 */
 
+#include "config.h"
+
 #include "libmemcached/common.h"
 
 #include <assert.h>
 #include <stdio.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/time.h>
 
 #include "server.h"
 
-#ifndef INT64_MAX
-#define INT64_MAX LONG_MAX
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX INT_MAX
-#endif
-
-
 #include "test.h"
 
 #define SERVERS_TO_CREATE 5
index eb37357d6b5b43e1b1d7a8f4bff8fafaa848c76f..e3f2a64c874dd4a3df0e0984eeaf59eebc8e2a6f 100644 (file)
@@ -9,6 +9,8 @@
  *
  */
 
+#include "config.h"
+
 #include <stdio.h>
 #include <string.h>
 #include "server.h"
index 45ee3ab46e9f07454d68384f78fdd9117470018d..215218c5f068e5a3f9bfc26c26a419d03bf9cd72 100644 (file)
@@ -9,6 +9,9 @@
 /*
   Sample test application.
 */
+
+#include "config.h"
+
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/unittests/include.am b/unittests/include.am
new file mode 100644 (file)
index 0000000..fc67e93
--- /dev/null
@@ -0,0 +1,23 @@
+# vim:ft=automake
+# included from Top Level Makefile.am
+# All paths should be given relative to the root
+
+if HAVE_LIBGTEST
+UNITTEST_PROGRAM= unittests/unittests
+
+noinst_PROGRAMS += $(UNITTEST_PROGRAM)
+
+unittests_unittests_SOURCES= \
+                            unittests/strings.cc \
+                            unittests/main.cc
+unittests_unittests_LDADD= \
+                          tests/libserver.la \
+                          libmemcached/libmemcachedinternal.la \
+                          ${TESTS_LDADDS} ${LTLIBGTEST}
+endif
+
+# Shorthand
+unit: unittests-run
+
+unittests-run: $(UNITTEST_PROGRAM)
+       $(UNITTEST_PROGRAM)
diff --git a/unittests/main.cc b/unittests/main.cc
new file mode 100644 (file)
index 0000000..7e575c3
--- /dev/null
@@ -0,0 +1,21 @@
+/* -*- mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
+ *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ *  Copyright (C) 2010 Monty Taylor
+ *
+ *  All rights reserved.
+ *
+ *  Use and distribution licensed under the BSD license.  See
+ *  the COPYING file in the parent directory for full text.
+ */
+
+#include "config.h"
+
+#include <gtest/gtest.h>
+
+
+int main(int argc, char **argv)
+{
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/unittests/strings.cc b/unittests/strings.cc
new file mode 100644 (file)
index 0000000..8728926
--- /dev/null
@@ -0,0 +1,131 @@
+/* libMemcached
+ * Copyright (C) 2010 Brian Aker
+ * All rights reserved.
+ *
+ * Use and distribution licensed under the BSD license.  See
+ * the COPYING file in the parent directory for full text.
+ */
+
+#include "config.h"
+
+#include <gtest/gtest.h>
+
+#include <libmemcached/common.h>
+
+TEST(memcached_string_st, memcached_create_static)
+{
+  memcached_string_st string;
+  memcached_string_st *string_ptr;
+
+  memcached_st *memc= memcached_create(NULL);
+  string_ptr= memcached_string_create(memc, &string, 0);
+  ASSERT_TRUE(string.options.is_initialized);
+  ASSERT_TRUE(string_ptr);
+
+  /* The following two better be the same! */
+  ASSERT_FALSE(memcached_is_allocated(string_ptr));
+  ASSERT_FALSE(memcached_is_allocated(&string));
+  EXPECT_EQ(&string, string_ptr);
+
+  ASSERT_TRUE(string.options.is_initialized);
+  ASSERT_TRUE(memcached_is_initialized(&string));
+  memcached_string_free(&string);
+  ASSERT_FALSE(memcached_is_initialized(&string));
+
+  memcached_free(memc);
+}
+
+TEST(memcached_string_st, memcached_create_null)
+{
+  memcached_string_st *string;
+  memcached_st *memc= memcached_create(NULL);
+
+  string= memcached_string_create(memc, NULL, 0);
+  ASSERT_TRUE(string);
+  ASSERT_TRUE(memcached_is_allocated(string));
+  ASSERT_TRUE(memcached_is_initialized(string));
+  memcached_string_free(string);
+
+  memcached_free(memc);
+}
+
+TEST(memcached_string_st, string_alloc_with_size)
+{
+  memcached_string_st *string;
+  memcached_st *memc= memcached_create(NULL);
+
+  string= memcached_string_create(memc, NULL, 1024);
+  ASSERT_TRUE(string);
+  ASSERT_TRUE(memcached_is_allocated(string));
+  ASSERT_TRUE(memcached_is_initialized(string));
+  memcached_string_free(string);
+
+  memcached_free(memc);
+}
+
+TEST(memcached_string_st, string_alloc_with_size_toobig)
+{
+  memcached_st *memc= memcached_create(NULL);
+  memcached_string_st *string;
+
+  string= memcached_string_create(memc, NULL, SIZE_MAX);
+  ASSERT_FALSE(string);
+
+  memcached_free(memc);
+}
+
+TEST(memcached_string_st, string_alloc_append)
+{
+  char buffer[SMALL_STRING_LEN];
+  memcached_string_st *string;
+
+  memcached_st *memc= memcached_create(NULL);
+
+  /* Ring the bell! */
+  memset(buffer, 6, SMALL_STRING_LEN);
+
+  string= memcached_string_create(memc, NULL, 100);
+  ASSERT_TRUE(string);
+  ASSERT_TRUE(memcached_is_allocated(string));
+  ASSERT_TRUE(memcached_is_initialized(string));
+
+  for (uint32_t x= 0; x < 1024; x++)
+  {
+    memcached_return_t rc;
+    rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
+    EXPECT_EQ(rc, MEMCACHED_SUCCESS);
+  }
+  ASSERT_TRUE(memcached_is_allocated(string));
+  memcached_string_free(string);
+
+  memcached_free(memc);
+}
+
+TEST(memcached_string_st, string_alloc_append_toobig)
+{
+  memcached_return_t rc;
+  char buffer[SMALL_STRING_LEN];
+  memcached_string_st *string;
+
+  memcached_st *memc= memcached_create(NULL);
+
+  /* Ring the bell! */
+  memset(buffer, 6, SMALL_STRING_LEN);
+
+  string= memcached_string_create(memc, NULL, 100);
+  ASSERT_TRUE(string);
+  ASSERT_TRUE(memcached_is_allocated(string));
+  ASSERT_TRUE(memcached_is_initialized(string));
+
+  for (uint32_t x= 0; x < 1024; x++)
+  {
+    rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
+    EXPECT_EQ(rc, MEMCACHED_SUCCESS);
+  }
+  rc= memcached_string_append(string, buffer, SIZE_MAX);
+  EXPECT_EQ(rc, MEMCACHED_MEMORY_ALLOCATION_FAILURE);
+  ASSERT_TRUE(memcached_is_allocated(string));
+  memcached_string_free(string);
+
+  memcached_free(memc);
+}