Merge in additional tests/remove any usages of STL from main library.
authorBrian Aker <brian@tangent.org>
Sat, 26 Mar 2011 23:56:28 +0000 (16:56 -0700)
committerBrian Aker <brian@tangent.org>
Sat, 26 Mar 2011 23:56:28 +0000 (16:56 -0700)
15 files changed:
libmemcached/common.h
libmemcached/include.am
libmemcached/io.h
libmemcached/options/build.cc [new file with mode: 0644]
libmemcached/options/build.h [new file with mode: 0644]
libmemcached/options/include.am
libmemcached/options/parser.yy
libmemcached/string.c
libmemcached/string.h
tests/error_conditions.cc
tests/include.am
tests/mem_functions.c
tests/parser.cc
tests/string.cc [new file with mode: 0644]
tests/string.h [new file with mode: 0644]

index c4cd0e535d076e3f92550fa80915ed84438e6290..1a813a02443315036767e9c6343c3d3a904de34d 100644 (file)
@@ -47,6 +47,7 @@
 #include "libmemcached/memcached.h"
 #include "libmemcached/watchpoint.h"
 #include "libmemcached/is.h"
+#include "libmemcached/prefix_key.h"
 
 typedef struct memcached_server_st * memcached_server_write_instance_st;
 
index c290989ec56ee6b2cd519a5a9f7a2baf557687f8..de354b4c9f5f9a73df3a50c8258bea115b7ce87b 100644 (file)
@@ -89,6 +89,7 @@ libmemcached_libmemcachedcallbacks_la_SOURCES = libmemcached/callback.c
 # These symbols will not be exposed in the shipped .so
 noinst_LTLIBRARIES+= libmemcached/libmemcachedinternal.la
 libmemcached_libmemcachedinternal_la_SOURCES= \
+                                             libmemcached/error.c \
                                              libmemcached/string.c
 
 lib_LTLIBRARIES+= libmemcached/libmemcached.la
@@ -103,7 +104,6 @@ libmemcached_libmemcached_la_SOURCES+= \
                                       libmemcached/delete.c \
                                       libmemcached/do.c \
                                       libmemcached/dump.c \
-                                      libmemcached/error.c \
                                       libmemcached/fetch.c \
                                       libmemcached/flush.c \
                                       libmemcached/flush_buffers.c \
index 3662954ddc291e3ac310abf26403616390169e97..b4f7806f1d40a02040088fcbaca0781142bb9177 100644 (file)
 
 #include "libmemcached/memcached.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #define MAX_UDP_DATAGRAM_LENGTH 1400
 #define UDP_DATAGRAM_HEADER_LENGTH 8
 #define UDP_REQUEST_ID_MSG_SIG_DIGITS 10
@@ -46,6 +42,10 @@ struct libmemcached_io_vector_st
   const void *buffer;
 };
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 LIBMEMCACHED_LOCAL
 memcached_return_t memcached_io_wait_for_write(memcached_server_write_instance_st ptr);
 
diff --git a/libmemcached/options/build.cc b/libmemcached/options/build.cc
new file mode 100644 (file)
index 0000000..9381b51
--- /dev/null
@@ -0,0 +1,69 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  LibMemcached
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  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.
+ *
+ */
+
+#include <libmemcached/common.h>
+#include <libmemcached/options/context.h>
+#include <libmemcached/options/build.h>
+
+namespace parser {
+
+void abort_func(Context *context, const char *error)
+{
+  if (context->rc == MEMCACHED_SUCCESS)
+    context->rc= MEMCACHED_PARSE_ERROR;
+
+  memcached_string_st *error_string= memcached_string_create(context->memc, NULL, 1024);
+  memcached_string_append(error_string, memcached_string_with_size("Error occured while parsing: "));
+  memcached_string_append(error_string, memcached_string_make_from_cstr(context->begin));
+  memcached_string_append(error_string, memcached_string_with_size(" ("));
+
+  if (context->rc == MEMCACHED_PARSE_ERROR and error)
+  {
+    memcached_string_append(error_string, memcached_string_make_from_cstr(error));
+  }
+  else
+  {
+    memcached_string_append(error_string, memcached_string_make_from_cstr(memcached_strerror(NULL, context->rc)));
+  }
+  memcached_string_append(error_string, memcached_string_with_size(")"));
+
+  memcached_set_error_string(context->memc, context->rc, memcached_string_value(error_string), memcached_string_length(error_string));
+
+  memcached_string_free(error_string);
+}
+
+} // namespace parser
diff --git a/libmemcached/options/build.h b/libmemcached/options/build.h
new file mode 100644 (file)
index 0000000..d267354
--- /dev/null
@@ -0,0 +1,46 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  LibMemcached
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  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.
+ *
+ */
+
+#pragma once
+
+class Conext;
+
+namespace parser {
+
+void abort_func(Context *context, const char *error);
+
+}
index d110a943f6eca52a89d215b1a5e401dab6b4aece..562a32788dfebe49f19e40506a562543b8f1d37c 100644 (file)
@@ -14,6 +14,7 @@ EXTRA_DIST+= \
             libmemcached/options/parser.yy
 
 noinst_HEADERS+= \
+                libmemcached/options/build.h \
                 libmemcached/options/context.h \
                 libmemcached/options/parser.h \
                 libmemcached/options/scanner.h \
@@ -22,6 +23,7 @@ noinst_HEADERS+= \
                 libmemcached/options/symbol.h
 
 libmemcached_libmemcached_la_SOURCES+= \
+                                      libmemcached/options/build.cc \
                                       libmemcached/options/parser.cc \
                                       libmemcached/options/scanner.cc
 
index adf3dc019bc41f7324604c7950a465684d711571..fb7ccd8601a244872525d47349eebfb3a3c4de46 100644 (file)
 #include <stdint.h>
 
 #include <libmemcached/options/context.h>
+#include <libmemcached/options/build.h>
 #include <libmemcached/options/string.h>
 #include <libmemcached/options/symbol.h>
+#include <libmemcached/visibility.h>
+#include <libmemcached/prefix_key.h>
 
 #pragma GCC diagnostic ignored "-Wold-style-cast"
 #include <libmemcached/options/scanner.h>
 
 int libmemcached_lex(YYSTYPE* lvalp, void* scanner);
 
-#define parser_abort(A, B) do { parser_abort_func((A), (B)); YYABORT; } while (0) 
-
-inline void parser_abort_func(Context *context, const char *error)
-{
-  (void)error;
-  if (context->rc == MEMCACHED_SUCCESS)
-    context->rc= MEMCACHED_PARSE_ERROR;
-
-  std::string error_message;
-  error_message+= "Error occured while parsing: ";
-  error_message+= context->begin;
-  error_message+= " (";
-  if (context->rc == MEMCACHED_PARSE_ERROR and error)
-  {
-    error_message+= error;
-  }
-  else
-  {
-    error_message+= memcached_strerror(NULL, context->rc);
-  }
-  error_message+= ")";
-
-  memcached_set_error_string(context->memc, context->rc, error_message.c_str(), error_message.size());
-}
+#define parser_abort(A, B) do { parser::abort_func((A), (B)); YYABORT; } while (0) 
 
 inline void libmemcached_error(Context *context, yyscan_t *scanner, const char *error)
 {
   if (not context->end())
-    parser_abort_func(context, error);
+    parser::abort_func(context, error);
 }
 
 int libmemcached_parse(Context*, yyscan_t *);
@@ -242,7 +222,7 @@ expression:
 behaviors:
           PREFIX_KEY '=' string
           {
-            if ((context->rc= memcached_callback_set(context->memc, MEMCACHED_CALLBACK_PREFIX_KEY, std::string($3.c_str, $3.length).c_str())) != MEMCACHED_SUCCESS)
+            if ((context->rc= memcached_set_prefix_key(context->memc, $3.c_str, $3.length)) != MEMCACHED_SUCCESS)
             {
               parser_abort(context, NULL);;
             }
index 10a295814ddb9d8e1fd21d5218854041c0cd3016..34597067b157edcbb818100da12a79061bbbd5d0 100644 (file)
@@ -212,12 +212,3 @@ void memcached_string_set_length(memcached_string_st *self, size_t length)
 {
   self->end= self->string + length;
 }
-
-memcached_string_t memcached_string_make(const char *str, size_t length)
-{
-  memcached_string_t tmp;
-  tmp.c_str= str;
-  tmp.size= length;
-
-  return tmp;
-}
index 5dd7d8dd7b0cdde0ef595f9ac13603d82713d6d9..77c55489a2056291bdebf94e3cf9dda44af6b743 100644 (file)
@@ -80,18 +80,22 @@ char *memcached_string_value_mutable(const memcached_string_st *self);
 LIBMEMCACHED_LOCAL
 void memcached_string_set_length(memcached_string_st *self, size_t length);
 
-LIBMEMCACHED_LOCAL
-memcached_string_t memcached_string_make(const char *str, size_t length);
-
 #ifdef __cplusplus
 }
 #endif
 
+#ifdef BUILDING_LIBMEMCACHED
 
 #ifdef __cplusplus
 #define memcached_string_with_size(X) (X), (static_cast<size_t>((sizeof(X) - 1)))
+#define memcached_string_make(X) (static_cast<size_t>((sizeof(X) - 1))), (X)
 #else
 #define memcached_string_with_size(X) (X), ((size_t)((sizeof(X) - 1)))
+#define memcached_string_make(X) (((size_t)((sizeof(X) - 1))), (X)
+#endif
+
+#define memcached_string_make_from_cstr(X) (X), ((X) ? strlen(X) : 0)
+
 #endif
 
 #endif /* __LIBMEMCACHED_STRING_H__ */
index b46b3ca28bab3dff9df2f605daad5aac36df7c06..d06f422559397bbb6834c8698d63f35522bca72e 100644 (file)
@@ -37,6 +37,8 @@
 
 #include <config.h>
 
+#define BUILDING_LIBMEMCACHED
+
 #include <libmemcached/memcached.h>
 #include <libmemcached/is.h>
 #include <libtest/test.h>
index 232cce936b983abf828241a4735dfa05d295ce27..bd5ef260f8aa9845cd0edf0e8613f6619d1fd11d 100644 (file)
@@ -36,7 +36,9 @@ noinst_HEADERS+= \
                 tests/libmemcached_world.h \
                 tests/parser.h \
                 tests/print.h \
-                tests/replication.h
+                tests/replication.h \
+                tests/string.h
+  
 
 noinst_PROGRAMS+= \
                  tests/atomsmasher \
@@ -55,7 +57,8 @@ tests_testapp_SOURCES= \
                       tests/mem_functions.c \
                       tests/parser.cc \
                       tests/print.cc \
-                      tests/replication.cc
+                      tests/replication.cc \
+                      tests/string.cc
 
 tests_testapp_DEPENDENCIES= \
                            $(BUILT_SOURCES) \
@@ -243,7 +246,7 @@ UDP_COMMAND= tests/testudp $(COLLECTION) $(SUITE)
 
 HASH_COMMAND= tests/testhashkit $(COLLECTION) $(SUITE)
 
-test-mem: tests/testapp
+test-mem: tests/testapp support/example.cnf
        $(MEM_COMMAND)
 
 test-udp: tests/testudp
index c3f5c30ed9b3c87072432046594de0e2bb881f90..93722602a544aaf599f1e8a21649fed7040dc35e 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <libtest/test.h>
 #include "tests/parser.h"
+#include "tests/string.h"
 #include "tests/replication.h"
 #include "tests/basic.h"
 #include "tests/error_conditions.h"
@@ -3229,118 +3230,6 @@ static test_return_t result_alloc(memcached_st *memc)
   return TEST_SUCCESS;
 }
 
-static test_return_t string_static_null(memcached_st *memc)
-{
-  memcached_string_st string;
-  memcached_string_st *string_ptr;
-
-  string_ptr= memcached_string_create(memc, &string, 0);
-  test_true(string.options.is_initialized == true);
-  test_true(string_ptr);
-
-  /* The following two better be the same! */
-  test_true(memcached_is_allocated(string_ptr) == false);
-  test_true(memcached_is_allocated(&string) == false);
-  test_true(&string == string_ptr);
-
-  test_true(string.options.is_initialized == true);
-  test_true(memcached_is_initialized(&string) == true);
-  memcached_string_free(&string);
-  test_true(memcached_is_initialized(&string) == false);
-
-  return TEST_SUCCESS;
-}
-
-static test_return_t string_alloc_null(memcached_st *memc)
-{
-  memcached_string_st *string;
-
-  string= memcached_string_create(memc, NULL, 0);
-  test_true(string);
-  test_true(memcached_is_allocated(string) == true);
-  test_true(memcached_is_initialized(string) == true);
-  memcached_string_free(string);
-
-  return TEST_SUCCESS;
-}
-
-static test_return_t string_alloc_with_size(memcached_st *memc)
-{
-  memcached_string_st *string;
-
-  string= memcached_string_create(memc, NULL, 1024);
-  test_true(string);
-  test_true(memcached_is_allocated(string) == true);
-  test_true(memcached_is_initialized(string) == true);
-  memcached_string_free(string);
-
-  return TEST_SUCCESS;
-}
-
-static test_return_t string_alloc_with_size_toobig(memcached_st *memc)
-{
-  memcached_string_st *string;
-
-  string= memcached_string_create(memc, NULL, SIZE_MAX);
-  test_true(string == NULL);
-
-  return TEST_SUCCESS;
-}
-
-static test_return_t string_alloc_append(memcached_st *memc)
-{
-  unsigned int x;
-  char buffer[SMALL_STRING_LEN];
-  memcached_string_st *string;
-
-  /* Ring the bell! */
-  memset(buffer, 6, SMALL_STRING_LEN);
-
-  string= memcached_string_create(memc, NULL, 100);
-  test_true(string);
-  test_true(memcached_is_allocated(string) == true);
-  test_true(memcached_is_initialized(string) == true);
-
-  for (x= 0; x < 1024; x++)
-  {
-    memcached_return_t rc;
-    rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
-    test_true(rc == MEMCACHED_SUCCESS);
-  }
-  test_true(memcached_is_allocated(string) == true);
-  memcached_string_free(string);
-
-  return TEST_SUCCESS;
-}
-
-static test_return_t string_alloc_append_toobig(memcached_st *memc)
-{
-  memcached_return_t rc;
-  unsigned int x;
-  char buffer[SMALL_STRING_LEN];
-  memcached_string_st *string;
-
-  /* Ring the bell! */
-  memset(buffer, 6, SMALL_STRING_LEN);
-
-  string= memcached_string_create(memc, NULL, 100);
-  test_true(string);
-  test_true(memcached_is_allocated(string) == true);
-  test_true(memcached_is_initialized(string) == true);
-
-  for (x= 0; x < 1024; x++)
-  {
-    rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
-    test_true(rc == MEMCACHED_SUCCESS);
-  }
-  rc= memcached_string_append(string, buffer, SIZE_MAX);
-  test_true(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE);
-  test_true(memcached_is_allocated(string) == true);
-  memcached_string_free(string);
-
-  return TEST_SUCCESS;
-}
-
 static test_return_t cleanup_pairs(memcached_st *memc)
 {
   (void)memc;
@@ -6138,6 +6027,7 @@ test_st string_tests[] ={
   {"string alloc with malloc failure", 0, (test_callback_fn)string_alloc_with_size_toobig },
   {"string append", 0, (test_callback_fn)string_alloc_append },
   {"string append failure (too big)", 0, (test_callback_fn)string_alloc_append_toobig },
+  {"string_alloc_append_multiple", 0, (test_callback_fn)string_alloc_append_multiple },
   {0, 0, (test_callback_fn)0}
 };
 
index 717859b469e6b65ac58807ca8f2b65519d60b2e8..d559b84d1776188f0a59bbc0eae21f1863fa541c 100644 (file)
@@ -41,6 +41,7 @@
 #include <iostream>
 #include <string>
 
+#define BUILDING_LIBMEMCACHED
 #include <libmemcached/memcached.h>
 
 #include "tests/parser.h"
@@ -345,15 +346,21 @@ test_return_t parser_key_prefix_test(memcached_st *junk)
   return _test_option(distribution_strings);
 }
 
+#define SUPPORT_EXAMPLE_CNF "support/example.cnf"
+
 test_return_t memcached_parse_configure_file_test(memcached_st *junk)
 {
   (void)junk;
+
+  if (access(SUPPORT_EXAMPLE_CNF, R_OK))
+    return TEST_SKIPPED;
+
   memcached_st memc;
   memcached_st *memc_ptr= memcached_create(&memc);
 
   test_true(memc_ptr);
 
-  memcached_return_t rc= memcached_parse_configure_file(memc_ptr, memcached_string_with_size("support/example.cnf"));
+  memcached_return_t rc= memcached_parse_configure_file(memc_ptr, memcached_string_with_size(SUPPORT_EXAMPLE_CNF));
   test_true_got(rc == MEMCACHED_SUCCESS, memcached_last_error_message(memc_ptr) ? memcached_last_error_message(memc_ptr) : memcached_strerror(NULL, rc));
   memcached_free(memc_ptr);
 
@@ -363,6 +370,8 @@ test_return_t memcached_parse_configure_file_test(memcached_st *junk)
 test_return_t memcached_create_with_options_with_filename(memcached_st *junk)
 {
   (void)junk;
+  if (access(SUPPORT_EXAMPLE_CNF, R_OK))
+    return TEST_SKIPPED;
 
   memcached_st *memc_ptr;
   memc_ptr= memcached_create_with_options(STRING_WITH_LEN("--CONFIGURE-FILE=\"support/example.cnf\""));
@@ -375,6 +384,10 @@ test_return_t memcached_create_with_options_with_filename(memcached_st *junk)
 test_return_t libmemcached_check_configuration_with_filename_test(memcached_st *junk)
 {
   (void)junk;
+
+  if (access(SUPPORT_EXAMPLE_CNF, R_OK))
+    return TEST_SKIPPED;
+
   memcached_return_t rc;
   char buffer[BUFSIZ];
 
@@ -424,6 +437,9 @@ test_return_t memcached_create_with_options_test(memcached_st *junk)
 
 test_return_t test_include_keyword(memcached_st *junk)
 {
+  if (access(SUPPORT_EXAMPLE_CNF, R_OK))
+    return TEST_SKIPPED;
+
   (void)junk;
   char buffer[BUFSIZ];
   memcached_return_t rc;
diff --git a/tests/string.cc b/tests/string.cc
new file mode 100644 (file)
index 0000000..827d0f2
--- /dev/null
@@ -0,0 +1,168 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Gearmand client and server library.
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  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.
+ *
+ */
+
+#include "libmemcached/common.h"
+#include "libmemcached/error.h"
+#include "tests/string.h"
+
+test_return_t string_static_null(memcached_st *memc)
+{
+  memcached_string_st string;
+  memcached_string_st *string_ptr;
+
+  string_ptr= memcached_string_create(memc, &string, 0);
+  test_true(string.options.is_initialized == true);
+  test_true(string_ptr);
+
+  /* The following two better be the same! */
+  test_true(memcached_is_allocated(string_ptr) == false);
+  test_true(memcached_is_allocated(&string) == false);
+  test_true(&string == string_ptr);
+
+  test_true(string.options.is_initialized == true);
+  test_true(memcached_is_initialized(&string) == true);
+  memcached_string_free(&string);
+  test_true(memcached_is_initialized(&string) == false);
+
+  return TEST_SUCCESS;
+}
+
+test_return_t string_alloc_null(memcached_st *memc)
+{
+  memcached_string_st *string;
+
+  string= memcached_string_create(memc, NULL, 0);
+  test_true(string);
+  test_true(memcached_is_allocated(string) == true);
+  test_true(memcached_is_initialized(string) == true);
+  memcached_string_free(string);
+
+  return TEST_SUCCESS;
+}
+
+test_return_t string_alloc_with_size(memcached_st *memc)
+{
+  memcached_string_st *string;
+
+  string= memcached_string_create(memc, NULL, 1024);
+  test_true(string);
+  test_true(memcached_is_allocated(string) == true);
+  test_true(memcached_is_initialized(string) == true);
+  memcached_string_free(string);
+
+  return TEST_SUCCESS;
+}
+
+test_return_t string_alloc_with_size_toobig(memcached_st *memc)
+{
+  memcached_string_st *string;
+
+  string= memcached_string_create(memc, NULL, SIZE_MAX);
+  test_true(string == NULL);
+
+  return TEST_SUCCESS;
+}
+
+test_return_t string_alloc_append(memcached_st *memc)
+{
+  unsigned int x;
+  char buffer[SMALL_STRING_LEN];
+  memcached_string_st *string;
+
+  /* Ring the bell! */
+  memset(buffer, 6, SMALL_STRING_LEN);
+
+  string= memcached_string_create(memc, NULL, 100);
+  test_true(string);
+  test_true(memcached_is_allocated(string) == true);
+  test_true(memcached_is_initialized(string) == true);
+
+  for (x= 0; x < 1024; x++)
+  {
+    memcached_return_t rc;
+    rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
+    test_true(rc == MEMCACHED_SUCCESS);
+  }
+  test_true(memcached_is_allocated(string) == true);
+  memcached_string_free(string);
+
+  return TEST_SUCCESS;
+}
+
+test_return_t string_alloc_append_toobig(memcached_st *memc)
+{
+  memcached_return_t rc;
+  char buffer[SMALL_STRING_LEN];
+  memcached_string_st *string;
+
+  /* Ring the bell! */
+  memset(buffer, 6, sizeof(buffer));
+
+  string= memcached_string_create(memc, NULL, 100);
+  test_true(string);
+  test_true(memcached_is_allocated(string) == true);
+  test_true(memcached_is_initialized(string) == true);
+
+  for (unsigned int x= 0; x < 1024; x++)
+  {
+    rc= memcached_string_append(string, buffer, SMALL_STRING_LEN);
+    test_true(rc == MEMCACHED_SUCCESS);
+  }
+  rc= memcached_string_append(string, buffer, SIZE_MAX);
+  test_true(rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE);
+  test_true(memcached_is_allocated(string) == true);
+  memcached_string_free(string);
+
+  return TEST_SUCCESS;
+}
+
+test_return_t string_alloc_append_multiple(memcached_st *memc)
+{
+  memcached_string_st *error_string= memcached_string_create(memc, NULL, 1024);
+  memcached_string_append(error_string, memcached_string_with_size("Error occured while parsing: "));
+  memcached_string_append(error_string, memcached_string_make_from_cstr("jog the strlen() method"));
+  memcached_string_append(error_string, memcached_string_with_size(" ("));
+
+  memcached_string_append(error_string, memcached_string_make_from_cstr(memcached_strerror(NULL, MEMCACHED_SUCCESS)));
+  memcached_string_append(error_string, memcached_string_with_size(")"));
+
+  memcached_set_error_string(memc, MEMCACHED_FAILURE, memcached_string_value(error_string), memcached_string_length(error_string));
+
+  memcached_string_free(error_string);
+
+  return TEST_SUCCESS;
+}
diff --git a/tests/string.h b/tests/string.h
new file mode 100644 (file)
index 0000000..eebd0c1
--- /dev/null
@@ -0,0 +1,69 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  Gearmand client and server library.
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  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.
+ *
+ */
+
+#pragma once
+
+#include <libtest/test.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBTEST_INTERNAL_API
+test_return_t string_static_null(memcached_st *memc);
+
+LIBTEST_INTERNAL_API
+test_return_t string_alloc_null(memcached_st *memc);
+
+LIBTEST_INTERNAL_API
+test_return_t string_alloc_with_size(memcached_st *memc);
+
+LIBTEST_INTERNAL_API
+test_return_t string_alloc_with_size_toobig(memcached_st *memc);
+
+LIBTEST_INTERNAL_API
+test_return_t string_alloc_append(memcached_st *memc);
+
+LIBTEST_INTERNAL_API
+test_return_t string_alloc_append_toobig(memcached_st *memc);
+
+LIBTEST_INTERNAL_API
+test_return_t string_alloc_append_multiple(memcached_st *memc);
+
+#ifdef __cplusplus
+}
+#endif